feat(layout-gap): use CSS gap instead of child margins (#43) - #110
Merged
Conversation
fxLayoutGap previously applied `margin` to each child except the last, which left two rendering bugs with `fxLayout="row wrap"`: - no spacing between wrapped rows, and - an extra leading margin on the last/short row. Switch fxLayoutGap to set the native CSS `gap` property on the flex container itself. `gap` spaces items within a row/column AND between wrapped rows, fixing both issues, and is direction-independent so RTL and reversed flows need no special handling. This removes the MutationObserver, child sorting, layout tracking, and the grid negative-margin/padding machinery; BaseDirective2's default update path now applies the gap to the host. BREAKING CHANGE: fxLayoutGap now emits CSS `gap` on the container rather than `margin` on children, so the element must be a flex container (apply fxLayout) for the gap to take effect. The legacy " grid" suffix is still accepted but is now equivalent to a plain gap. Closes #43 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "Layout Gap" demo used the legacy `fxLayoutGap="10px 5px grid"` with `fxFlex="25"` children, relying on the old negative-margin grid hack so four 25%-basis items fit per row with gutters. With CSS `gap`, the gap is added on top of the flex-basis, so size the children with `calc(25% - 7.5px)` to keep four per row, and use a plain `fxLayoutGap="10px"` (the ` grid` suffix is now a no-op). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
Runtime verification — Layout Gap demo ✅Ran the built Verdict: PASS — the page renders a 4-per-row wrapping grid (A B C D / E F G) with visible spacing between items and between the wrapped rows, and the last row starts flush-left (no extra leading margin). These are exactly the two symptoms reported in #43. Confirmed the mechanism from the live DOM, not just pixels:
Note (pre-existing, not a regression): the last-row tiles render wider because Screenshot hosted on the throwaway |
This was referenced Jun 11, 2026
DuncanFaulkner
added a commit
that referenced
this pull request
Jun 15, 2026
* feat: update universal-demo-app to support BootstrapContext in main.server.ts chore: update peer dependency for @angular/cdk to version 21.0.0 in flex-layout package.json fix: correct schema path in flex-layout project.json and add tsConfig option for packaging * chore: update version to 21.0.0-rc.1 in package.json * Refactor code structure for improved readability and maintainability * feat: add markdown page and sitemap, implement section page component - Created a new markdown page (index.html) for standalone content. - Added a sitemap.xml for better SEO and navigation. - Implemented SectionPageComponent with dynamic content rendering and layout using Angular Material and ngx-layout directives. * feat: enhance components with ChangeDetectionStrategy.Eager for improved performance - Updated multiple components in the responsive and stackoverflow pages to use ChangeDetectionStrategy.Eager. - Modified tsconfig.app.json to include angularCompilerOptions for nullish coalescing and optional chaining checks. - Adjusted various test files to import necessary components instead of declaring them. - Added .npmrc file to set legacy-peer-deps to true for compatibility. - Changed module resolution strategy in tsconfig.json from node to bundler. * refactor: migrate tests from Jasmine to Vitest and remove custom matchers - Replaced Jasmine spies with Vitest spies in media-marshaller tests. - Removed custom matchers from various spec files and set up Vitest environment. - Updated TypeScript configuration to use Vitest types instead of Jasmine. - Deleted obsolete Karma configuration files and test setup. * fix: update output paths for updated-demo and universal-demo-app builds * chore: remove Netlify configuration file * fix: update output paths for updated-demo and universal-demo-app builds * fix: remove duplicate dependencies from package.json * fix: update version to 22.0.0-rc in package.json * fix: add ignoreDeprecations option to tsconfig.json * chore: update dependencies and refactor tests - Updated @docusaurus/preset-classic to ^3.10.1 and related Docusaurus packages. - Replaced conventional-changelog-cli with conventional-changelog. - Added jsdom as a dependency. - Removed unused expect imports from various test files. - Refactored test imports to use Default directives from ngx-layout. - Updated test setup for Vitest compatibility, including ProxyZone handling. - Added vitest-base.config.ts for base Vitest configuration. - Adjusted tsconfig.spec.json to include test-setup.ts. * feat: add SSR testing support for flex-layout library - Introduced a new test target for server-side rendering (SSR) in angular.json. - Updated package.json to use the new SSR test command. - Removed deprecated SSR test files and configurations. - Added a new provider file for SSR tests to set PLATFORM_ID. - Adjusted flex directive tests to handle null styles during SSR. - Updated TypeScript configuration to include the new SSR provider file. * fix: update CI badge and remove deprecated dependencies from package.json and package-lock.json * fix(layout-gap): use direction-independent CSS properties for fxLayoutGap (#95) (#106) fxLayoutGap emitted physical margin properties (margin-right/left) and selected between them by reading the CDK Directionality (the `dir` attribute). That broke layouts when the writing direction was set via CSS `direction: rtl`, and required LTR/RTL branching throughout the directive. Switch to logical properties, which the browser resolves against the writing direction automatically: row -> margin-inline-end row-reverse -> margin-inline-start column -> margin-block-end column-reverse -> margin-block-start grid margin -> margin-inline / margin-block grid padding -> padding-inline / padding-block This both fixes the RTL bug and removes now-dead direction handling: the Directionality injection and its change trigger, the four direction-keyed style caches and their selection in updateWithValue, and the `directionality` field on LayoutGapParent. Tests updated to assert the logical properties; full library suite passes (478/478). Closes #95 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * update to 22.0.1 * refactor!: remove deprecated Default* directives (#112) The Default<X>Directive classes were deprecated in v21 ("will be removed in version 21") but were never removed. They are redundant subclasses — the base directives already carry the same selector and inputs — so they add nothing but a duplicate public symbol. Remove all 22 Default* directives and repoint the Flex/Extended/Grid modules (and specs/demo) to the base directives. Grid directive descriptions that were attached to the Default* classes are moved onto the corresponding base directives so no docs are lost. The NgModules are intentionally kept for now. BREAKING CHANGE: The deprecated Default* directives have been removed. Replace each `Default<X>Directive` with `<X>Directive` (e.g. `DefaultFlexDirective` -> `FlexDirective`). The base directives have identical selectors and behavior, so only the import/symbol name changes. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): guard against undefined element.style during style flush (#57) (#108) On a media/breakpoint change (e.g. window resize), MediaMarshaller.updateStyles() iterates elementMap (a strong Map) and flushes styles for every tracked element. An element can be detached/destroyed between the resize event firing and the flush, leaving element.style undefined and causing "TypeError: Cannot read properties of undefined (reading 'setProperty')". Because the throw aborted the whole forEach pass, a single stale element broke styling for all remaining elements too. Guard the browser setProperty call with optional chaining so a non-styleable element is skipped instead of throwing. The server path is unaffected. Closes #57 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(layout-gap): use CSS `gap` instead of child margins (#43) (#110) * feat(layout-gap): use CSS `gap` instead of child margins (#43) fxLayoutGap previously applied `margin` to each child except the last, which left two rendering bugs with `fxLayout="row wrap"`: - no spacing between wrapped rows, and - an extra leading margin on the last/short row. Switch fxLayoutGap to set the native CSS `gap` property on the flex container itself. `gap` spaces items within a row/column AND between wrapped rows, fixing both issues, and is direction-independent so RTL and reversed flows need no special handling. This removes the MutationObserver, child sorting, layout tracking, and the grid negative-margin/padding machinery; BaseDirective2's default update path now applies the gap to the host. BREAKING CHANGE: fxLayoutGap now emits CSS `gap` on the container rather than `margin` on children, so the element must be a flex container (apply fxLayout) for the gap to take effect. The legacy " grid" suffix is still accepted but is now equivalent to a plain gap. Closes #43 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(demo): update layout-gap demo for CSS gap behavior The "Layout Gap" demo used the legacy `fxLayoutGap="10px 5px grid"` with `fxFlex="25"` children, relying on the old negative-margin grid hack so four 25%-basis items fit per row with gutters. With CSS `gap`, the gap is added on top of the flex-basis, so size the children with `calc(25% - 7.5px)` to keep four per row, and use a plain `fxLayoutGap="10px"` (the ` grid` suffix is now a no-op). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(breakpoints): add opt-in MATERIAL_BREAKPOINTS preset (#26) (#111) The default breakpoints retain the original @angular/flex-layout ranges where `md` starts at 960px, which is dated. Rather than change the defaults (a breaking change for migrants), add an importable MATERIAL_BREAKPOINTS preset with modern Material 3 values: xs <600 | sm 600 | md 900 | lg 1200 | xl 1536 It uses the same xs/sm/md/lg/xl (+ lt-*/gt-*) alias set as the defaults, so responsive selectors are unchanged — only the activation ranges. Opt in by disabling the built-ins and providing the preset: FlexLayoutModule.withConfig({ disableDefaultBps: true }, MATERIAL_BREAKPOINTS) Also fixes the breakpoints doc, which referenced a non-existent DISABLE_DEFAULT_BREAKPOINTS token (the real option is `disableDefaultBps`). Closes #26 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Merged
DuncanFaulkner
added a commit
that referenced
this pull request
Jun 15, 2026
* feat: update universal-demo-app to support BootstrapContext in main.server.ts chore: update peer dependency for @angular/cdk to version 21.0.0 in flex-layout package.json fix: correct schema path in flex-layout project.json and add tsConfig option for packaging * chore: update version to 21.0.0-rc.1 in package.json * Refactor code structure for improved readability and maintainability * feat: add markdown page and sitemap, implement section page component - Created a new markdown page (index.html) for standalone content. - Added a sitemap.xml for better SEO and navigation. - Implemented SectionPageComponent with dynamic content rendering and layout using Angular Material and ngx-layout directives. * feat: enhance components with ChangeDetectionStrategy.Eager for improved performance - Updated multiple components in the responsive and stackoverflow pages to use ChangeDetectionStrategy.Eager. - Modified tsconfig.app.json to include angularCompilerOptions for nullish coalescing and optional chaining checks. - Adjusted various test files to import necessary components instead of declaring them. - Added .npmrc file to set legacy-peer-deps to true for compatibility. - Changed module resolution strategy in tsconfig.json from node to bundler. * refactor: migrate tests from Jasmine to Vitest and remove custom matchers - Replaced Jasmine spies with Vitest spies in media-marshaller tests. - Removed custom matchers from various spec files and set up Vitest environment. - Updated TypeScript configuration to use Vitest types instead of Jasmine. - Deleted obsolete Karma configuration files and test setup. * fix: update output paths for updated-demo and universal-demo-app builds * chore: remove Netlify configuration file * fix: update output paths for updated-demo and universal-demo-app builds * fix: remove duplicate dependencies from package.json * fix: update version to 22.0.0-rc in package.json * fix: add ignoreDeprecations option to tsconfig.json * chore: update dependencies and refactor tests - Updated @docusaurus/preset-classic to ^3.10.1 and related Docusaurus packages. - Replaced conventional-changelog-cli with conventional-changelog. - Added jsdom as a dependency. - Removed unused expect imports from various test files. - Refactored test imports to use Default directives from ngx-layout. - Updated test setup for Vitest compatibility, including ProxyZone handling. - Added vitest-base.config.ts for base Vitest configuration. - Adjusted tsconfig.spec.json to include test-setup.ts. * feat: add SSR testing support for flex-layout library - Introduced a new test target for server-side rendering (SSR) in angular.json. - Updated package.json to use the new SSR test command. - Removed deprecated SSR test files and configurations. - Added a new provider file for SSR tests to set PLATFORM_ID. - Adjusted flex directive tests to handle null styles during SSR. - Updated TypeScript configuration to include the new SSR provider file. * fix: update CI badge and remove deprecated dependencies from package.json and package-lock.json * fix(layout-gap): use direction-independent CSS properties for fxLayoutGap (#95) (#106) fxLayoutGap emitted physical margin properties (margin-right/left) and selected between them by reading the CDK Directionality (the `dir` attribute). That broke layouts when the writing direction was set via CSS `direction: rtl`, and required LTR/RTL branching throughout the directive. Switch to logical properties, which the browser resolves against the writing direction automatically: row -> margin-inline-end row-reverse -> margin-inline-start column -> margin-block-end column-reverse -> margin-block-start grid margin -> margin-inline / margin-block grid padding -> padding-inline / padding-block This both fixes the RTL bug and removes now-dead direction handling: the Directionality injection and its change trigger, the four direction-keyed style caches and their selection in updateWithValue, and the `directionality` field on LayoutGapParent. Tests updated to assert the logical properties; full library suite passes (478/478). Closes #95 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * update to 22.0.1 * refactor!: remove deprecated Default* directives (#112) The Default<X>Directive classes were deprecated in v21 ("will be removed in version 21") but were never removed. They are redundant subclasses — the base directives already carry the same selector and inputs — so they add nothing but a duplicate public symbol. Remove all 22 Default* directives and repoint the Flex/Extended/Grid modules (and specs/demo) to the base directives. Grid directive descriptions that were attached to the Default* classes are moved onto the corresponding base directives so no docs are lost. The NgModules are intentionally kept for now. BREAKING CHANGE: The deprecated Default* directives have been removed. Replace each `Default<X>Directive` with `<X>Directive` (e.g. `DefaultFlexDirective` -> `FlexDirective`). The base directives have identical selectors and behavior, so only the import/symbol name changes. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): guard against undefined element.style during style flush (#57) (#108) On a media/breakpoint change (e.g. window resize), MediaMarshaller.updateStyles() iterates elementMap (a strong Map) and flushes styles for every tracked element. An element can be detached/destroyed between the resize event firing and the flush, leaving element.style undefined and causing "TypeError: Cannot read properties of undefined (reading 'setProperty')". Because the throw aborted the whole forEach pass, a single stale element broke styling for all remaining elements too. Guard the browser setProperty call with optional chaining so a non-styleable element is skipped instead of throwing. The server path is unaffected. Closes #57 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(layout-gap): use CSS `gap` instead of child margins (#43) (#110) * feat(layout-gap): use CSS `gap` instead of child margins (#43) fxLayoutGap previously applied `margin` to each child except the last, which left two rendering bugs with `fxLayout="row wrap"`: - no spacing between wrapped rows, and - an extra leading margin on the last/short row. Switch fxLayoutGap to set the native CSS `gap` property on the flex container itself. `gap` spaces items within a row/column AND between wrapped rows, fixing both issues, and is direction-independent so RTL and reversed flows need no special handling. This removes the MutationObserver, child sorting, layout tracking, and the grid negative-margin/padding machinery; BaseDirective2's default update path now applies the gap to the host. BREAKING CHANGE: fxLayoutGap now emits CSS `gap` on the container rather than `margin` on children, so the element must be a flex container (apply fxLayout) for the gap to take effect. The legacy " grid" suffix is still accepted but is now equivalent to a plain gap. Closes #43 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(demo): update layout-gap demo for CSS gap behavior The "Layout Gap" demo used the legacy `fxLayoutGap="10px 5px grid"` with `fxFlex="25"` children, relying on the old negative-margin grid hack so four 25%-basis items fit per row with gutters. With CSS `gap`, the gap is added on top of the flex-basis, so size the children with `calc(25% - 7.5px)` to keep four per row, and use a plain `fxLayoutGap="10px"` (the ` grid` suffix is now a no-op). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(breakpoints): add opt-in MATERIAL_BREAKPOINTS preset (#26) (#111) The default breakpoints retain the original @angular/flex-layout ranges where `md` starts at 960px, which is dated. Rather than change the defaults (a breaking change for migrants), add an importable MATERIAL_BREAKPOINTS preset with modern Material 3 values: xs <600 | sm 600 | md 900 | lg 1200 | xl 1536 It uses the same xs/sm/md/lg/xl (+ lt-*/gt-*) alias set as the defaults, so responsive selectors are unchanged — only the activation ranges. Opt in by disabling the built-ins and providing the preset: FlexLayoutModule.withConfig({ disableDefaultBps: true }, MATERIAL_BREAKPOINTS) Also fixes the breakpoints doc, which referenced a non-existent DISABLE_DEFAULT_BREAKPOINTS token (the real option is `disableDefaultBps`). Closes #26 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * chore: update version to 22.0.0 and add conventional-changelog-angular dependency * docs(changelog): remove duplicate 22.0.0-rc sections The changelog regeneration emitted two identical 22.0.0-rc (2026-06-15) blocks that duplicate the new 22.0.0 release section. Remove them, keeping the original historical 22.0.0-rc (2026-06-03) entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(readme): document standalone usage and Default* removal Update the library README to reflect that ngx-layout is now fully standalone: add a standalone component / provideFlexLayout example and call out the removal of the deprecated Default* directives. The NgModule usage is retained as still supported. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
DuncanFaulkner
added a commit
that referenced
this pull request
Jul 20, 2026
* feat: update universal-demo-app to support BootstrapContext in main.server.ts chore: update peer dependency for @angular/cdk to version 21.0.0 in flex-layout package.json fix: correct schema path in flex-layout project.json and add tsConfig option for packaging * chore: update version to 21.0.0-rc.1 in package.json * Refactor code structure for improved readability and maintainability * feat: add markdown page and sitemap, implement section page component - Created a new markdown page (index.html) for standalone content. - Added a sitemap.xml for better SEO and navigation. - Implemented SectionPageComponent with dynamic content rendering and layout using Angular Material and ngx-layout directives. * feat: enhance components with ChangeDetectionStrategy.Eager for improved performance - Updated multiple components in the responsive and stackoverflow pages to use ChangeDetectionStrategy.Eager. - Modified tsconfig.app.json to include angularCompilerOptions for nullish coalescing and optional chaining checks. - Adjusted various test files to import necessary components instead of declaring them. - Added .npmrc file to set legacy-peer-deps to true for compatibility. - Changed module resolution strategy in tsconfig.json from node to bundler. * refactor: migrate tests from Jasmine to Vitest and remove custom matchers - Replaced Jasmine spies with Vitest spies in media-marshaller tests. - Removed custom matchers from various spec files and set up Vitest environment. - Updated TypeScript configuration to use Vitest types instead of Jasmine. - Deleted obsolete Karma configuration files and test setup. * fix: update output paths for updated-demo and universal-demo-app builds * chore: remove Netlify configuration file * fix: update output paths for updated-demo and universal-demo-app builds * fix: remove duplicate dependencies from package.json * fix: update version to 22.0.0-rc in package.json * fix: add ignoreDeprecations option to tsconfig.json * chore: update dependencies and refactor tests - Updated @docusaurus/preset-classic to ^3.10.1 and related Docusaurus packages. - Replaced conventional-changelog-cli with conventional-changelog. - Added jsdom as a dependency. - Removed unused expect imports from various test files. - Refactored test imports to use Default directives from ngx-layout. - Updated test setup for Vitest compatibility, including ProxyZone handling. - Added vitest-base.config.ts for base Vitest configuration. - Adjusted tsconfig.spec.json to include test-setup.ts. * feat: add SSR testing support for flex-layout library - Introduced a new test target for server-side rendering (SSR) in angular.json. - Updated package.json to use the new SSR test command. - Removed deprecated SSR test files and configurations. - Added a new provider file for SSR tests to set PLATFORM_ID. - Adjusted flex directive tests to handle null styles during SSR. - Updated TypeScript configuration to include the new SSR provider file. * fix: update CI badge and remove deprecated dependencies from package.json and package-lock.json * fix(layout-gap): use direction-independent CSS properties for fxLayoutGap (#95) (#106) fxLayoutGap emitted physical margin properties (margin-right/left) and selected between them by reading the CDK Directionality (the `dir` attribute). That broke layouts when the writing direction was set via CSS `direction: rtl`, and required LTR/RTL branching throughout the directive. Switch to logical properties, which the browser resolves against the writing direction automatically: row -> margin-inline-end row-reverse -> margin-inline-start column -> margin-block-end column-reverse -> margin-block-start grid margin -> margin-inline / margin-block grid padding -> padding-inline / padding-block This both fixes the RTL bug and removes now-dead direction handling: the Directionality injection and its change trigger, the four direction-keyed style caches and their selection in updateWithValue, and the `directionality` field on LayoutGapParent. Tests updated to assert the logical properties; full library suite passes (478/478). Closes #95 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * update to 22.0.1 * refactor!: remove deprecated Default* directives (#112) The Default<X>Directive classes were deprecated in v21 ("will be removed in version 21") but were never removed. They are redundant subclasses — the base directives already carry the same selector and inputs — so they add nothing but a duplicate public symbol. Remove all 22 Default* directives and repoint the Flex/Extended/Grid modules (and specs/demo) to the base directives. Grid directive descriptions that were attached to the Default* classes are moved onto the corresponding base directives so no docs are lost. The NgModules are intentionally kept for now. BREAKING CHANGE: The deprecated Default* directives have been removed. Replace each `Default<X>Directive` with `<X>Directive` (e.g. `DefaultFlexDirective` -> `FlexDirective`). The base directives have identical selectors and behavior, so only the import/symbol name changes. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): guard against undefined element.style during style flush (#57) (#108) On a media/breakpoint change (e.g. window resize), MediaMarshaller.updateStyles() iterates elementMap (a strong Map) and flushes styles for every tracked element. An element can be detached/destroyed between the resize event firing and the flush, leaving element.style undefined and causing "TypeError: Cannot read properties of undefined (reading 'setProperty')". Because the throw aborted the whole forEach pass, a single stale element broke styling for all remaining elements too. Guard the browser setProperty call with optional chaining so a non-styleable element is skipped instead of throwing. The server path is unaffected. Closes #57 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(layout-gap): use CSS `gap` instead of child margins (#43) (#110) * feat(layout-gap): use CSS `gap` instead of child margins (#43) fxLayoutGap previously applied `margin` to each child except the last, which left two rendering bugs with `fxLayout="row wrap"`: - no spacing between wrapped rows, and - an extra leading margin on the last/short row. Switch fxLayoutGap to set the native CSS `gap` property on the flex container itself. `gap` spaces items within a row/column AND between wrapped rows, fixing both issues, and is direction-independent so RTL and reversed flows need no special handling. This removes the MutationObserver, child sorting, layout tracking, and the grid negative-margin/padding machinery; BaseDirective2's default update path now applies the gap to the host. BREAKING CHANGE: fxLayoutGap now emits CSS `gap` on the container rather than `margin` on children, so the element must be a flex container (apply fxLayout) for the gap to take effect. The legacy " grid" suffix is still accepted but is now equivalent to a plain gap. Closes #43 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(demo): update layout-gap demo for CSS gap behavior The "Layout Gap" demo used the legacy `fxLayoutGap="10px 5px grid"` with `fxFlex="25"` children, relying on the old negative-margin grid hack so four 25%-basis items fit per row with gutters. With CSS `gap`, the gap is added on top of the flex-basis, so size the children with `calc(25% - 7.5px)` to keep four per row, and use a plain `fxLayoutGap="10px"` (the ` grid` suffix is now a no-op). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(breakpoints): add opt-in MATERIAL_BREAKPOINTS preset (#26) (#111) The default breakpoints retain the original @angular/flex-layout ranges where `md` starts at 960px, which is dated. Rather than change the defaults (a breaking change for migrants), add an importable MATERIAL_BREAKPOINTS preset with modern Material 3 values: xs <600 | sm 600 | md 900 | lg 1200 | xl 1536 It uses the same xs/sm/md/lg/xl (+ lt-*/gt-*) alias set as the defaults, so responsive selectors are unchanged — only the activation ranges. Opt in by disabling the built-ins and providing the preset: FlexLayoutModule.withConfig({ disableDefaultBps: true }, MATERIAL_BREAKPOINTS) Also fixes the breakpoints doc, which referenced a non-existent DISABLE_DEFAULT_BREAKPOINTS token (the real option is `disableDefaultBps`). Closes #26 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * chore: update version to 22.0.0 and add conventional-changelog-angular dependency * docs(changelog): remove duplicate 22.0.0-rc sections The changelog regeneration emitted two identical 22.0.0-rc (2026-06-15) blocks that duplicate the new 22.0.0 release section. Remove them, keeping the original historical 22.0.0-rc (2026-06-03) entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(readme): document standalone usage and Default* removal Update the library README to reflect that ngx-layout is now fully standalone: add a standalone component / provideFlexLayout example and call out the removal of the deprecated Default* directives. The NgModule usage is retained as still supported. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(layout-gap): use native CSS gap instead of child margins (#117) Replace the margin-based gap implementation (onLayoutChange, updateWithValue, clearStyles override, willDisplay, MutationObserver child observation) with the container's native CSS `gap` property. Update the spec to assert `gap` on the container rather than margin-inline-end / margin-block-end on individual children. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * fix(deps): patch known security vulnerabilities in build toolchain (#116) Resolve all 12 npm audit findings (5 high, 4 moderate, 3 low) in transitive dev/build dependencies by pinning each to its minimum patched version within the compatible major via package.json overrides: - @babel/core 7.29.6, esbuild 0.28.1, hono 4.12.31, http-proxy-middleware 2.0.10, joi 17.13.4, js-yaml 4.2.0, piscina 5.2.0, undici 7.28.0, vite 7.3.5, webpack-dev-server 5.2.5 - gray-matter scoped to js-yaml 3.15.0 (needs 3.x API) - node-gyp scoped to undici 6.27.0 (needs ^6); jsdom uses undici 7.28.0 npm audit now reports 0 vulnerabilities; library build and all 468 tests pass. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Fixes #43 —
fxLayout="row wrap"+fxLayoutGaprendering inconsistencies.fxLayoutGappreviously appliedmarginto each child except the last. This caused two bugs the reporter documented:This PR switches
fxLayoutGapto set the native CSSgapproperty on the flex container itself.gapspaces items both within a row/column and between wrapped rows, which fixes both issues. It's also direction-agnostic, so RTL and reversed flows need no special casing.Changes
layout-gap.ts—LayoutGapStyleBuilder.buildStylesnow returns{ gap }applied to the host. Removed theMutationObserver, child querying/sorting, layout-direction tracking, and the grid negative-margin/padding machinery (buildGridMargin/buildGridPadding/getMarginType/buildGapCSS/CLEAR_MARGIN_CSS).BaseDirective2's default update path applies the gap. Net −820 lines.gap: X(row + column). Two values → CSSgapshorthand<row-gap> <column-gap>.layout-gap.spec.ts— replaced the margin/child-based suite with a focused suite assertinggapon the container (static values, multiplier, default unit, two-value, responsive activate/clear, RTL no-op, legacygridsuffix).fxLayoutGap-API.md— documented the new behavior and the breaking change.Breaking change
fxLayoutGapnow emits CSSgapon the container rather thanmarginon children, so the element must be a flex container (applyfxLayout) for the gap to take effect. The legacy" grid"suffix (e.g.fxLayoutGap="10px grid") is still accepted but is now equivalent to a plain gap, sincegapalready handles wrapped rows.Verification
ng test @ngbracket/ngx-layout— 464 tests pass (incl. rewritten layout-gap suite; flex/layout-align/show-hide/grid specs that interact via thelayout-gapmarshaller key still pass)ng build @ngbracket/ngx-layout— builds cleancc @Alexi996 — this implements the CSS
gapapproach you proposed.🤖 Generated with Claude Code