Commit Graph

2132 Commits

Author SHA1 Message Date
Ashley Hunter 42ee5519a4 fix(cli): harden angular-cli tsconfig include and embla major guard
Preserve the implicit `src/**/*.ts` coverage when `tsconfig.app.json` has no
`include` key, so seeding the array for the generated libs no longer drops the
app's own `src` from the editor program.

Use a strict `!== null` guard before pinning `embla-carousel-angular` so the
intent is explicit rather than relying on Angular majors never being 0.
2026-06-18 19:21:33 +01:00
Ashley Hunter 5fcd3fbd39 fix(cli): narrow angular-cli tsconfig include 2026-06-18 18:16:14 +01:00
Ashley Hunter ce25093007 fix(cli): include generated libs in tsconfig.app.json for angular-cli
ng g @spartan-ng/cli:ui generates libraries under the configured directory (e.g.
libs/ui), outside the app's src. The app still builds - the Angular builder
follows the path-mapped imports into the libs - but the TS language server treats
the generated files as orphans compiled without the root paths mapping, so
cross-lib imports (@spartan-ng/helm/utils, ...) show as "cannot find module" in
the editor.

Add the components base dir to tsconfig.app.json's include so the generated files
belong to the app project and resolve in-editor. Idempotent and a no-op when there
is no tsconfig.app.json.
2026-06-18 17:39:19 +01:00
Ashley Hunter 9f94cea97c fix(cli): pin embla-carousel-angular to the installed Angular major
The carousel primitive declared embla-carousel-angular as ">=21.0.0 <23.0.0".
That package's major tracks the Angular major (v21 -> Angular 21, v22 -> Angular
22), so on an Angular 21 workspace npm resolved the highest match (22.x), whose
peer is @angular/common >=22.0.0, and the install failed with ERESOLVE.

A static range in supported-ui-libraries.json can't know the consumer's Angular
version, so pin embla-carousel-angular to the installed Angular major at generate
time. Falls back to the declared range when Angular can't be resolved.
2026-06-18 17:39:19 +01:00
moosme 467fbe905a Merge pull request #1499 from spartan-ng/ci/gate-nightly-release-on-checks
ci: gate nightly release on commitlint and cli-smoke
2026-06-18 13:22:15 +02:00
Leonidas 33892b9bcb chore: add new contributors to our 300 2026-06-18 10:22:30 +00:00
Ashley Hunter 825a1bed52 Merge pull request #1500 from spartan-ng/fix/healthcheck-version-registry 2026-06-18 10:23:58 +01:00
goetzrobin e1d349e431 ci: gate nightly release on commitlint and cli-smoke
The release job ran in parallel with cli-smoke. Because release publishes new
@spartan-ng versions to npm mid-run, the smoke healthcheck saw the package
"latest" change underneath it and the angular-cli cells failed.

Add commitlint and cli-smoke to the release job's `needs` so a red suite blocks
the publish, and so release waits for cli-smoke to finish before publishing -
which removes the concurrent-publish race.
2026-06-18 10:05:51 +02:00
moosme 9236788c8f Merge pull request #1495 from mehrabix/feat/provide-spartan-hlm
feat(utils): add provideSpartanHlm utility to fix CDK overlay z-index…
2026-06-18 08:29:44 +02:00
moosme a7d13e0188 Merge pull request #1498 from spartan-ng/fix/migrate-helm-libraries-tsconfig-include-explosion
fix(cli): prevent tsconfig include explosion when migrating many helm libraries
2026-06-18 08:28:19 +02:00
Leonidas f1cdfcbc9b chore: nightly release 2026-06-18 ⚡ 2026-06-18 04:04:01 +00:00
Ashley Hunter be61667f17 fix(cli): respect configured npm registry in version healthcheck
The dependency healthcheck hardcoded registry.npmjs.org when resolving the
latest @spartan-ng/brain and @spartan-ng/cli versions. Under cli-smoke this
flagged the locally published packages as outdated, and `--auto-fix` then
rewrote package.json to a version absent from the local registry, so the
Angular CLI's post-generate install failed and the smoke test errored.

Resolve the latest version against npm_config_registry (falling back to npmjs)
so the check matches whatever registry the project installs from - the smoke
local registry, or a private registry for real users.
2026-06-17 23:48:28 +01:00
Patrick bc471546ef fix(radio-group): restore native tab behavior (#1492)
* fix(radio-group): restore native tab behavior

* test(radio-group): cover disabled reset tab target
2026-06-18 00:48:00 +02:00
Ashley Hunter c5205c04a9 fix(cli): narrow glob-variant matching and require() the remove generator by path
Addresses review feedback:
- dedupeEntrypointGlobs now only treats a pattern as an entrypoint variant when it
  contains a `/**/` segment (the shape nx prepends), so flat custom globs like
  `tools/*.ts` are preserved rather than widened to `**/*.ts`.
- Load the @nx/workspace remove generator with `require(absolutePath)` instead of
  dynamic import: it bypasses the package exports gate and accepts native Windows
  paths without a file:// URL (this generator runs as CommonJS).
2026-06-17 19:42:52 +01:00
Ashley Hunter 39236d3235 test(cli): run migrate-helm-libraries end-to-end as an installed package
No cell exercised the headline command as a published package, so the deep-import
breakage above shipped undetected. Each nx cell now runs migrate-helm-libraries
against the freshly scaffolded workspace before generating anything: with no spartan
libraries it no-ops ("No libraries to migrate") without prompting, but loading it
resolves the @nx/workspace/@nx/devkit deep imports in the installed CLI - so a
consumer's stricter exports map turns the cell red instead of reaching users.
2026-06-17 19:29:54 +01:00
Ashley Hunter 859029b409 fix(cli): pre-normalize tsconfig and tighten entrypoint glob dedupe
- Normalize tsconfig.lib.json before the nx secondary-entrypoint call as well as
  after: a workspace left bloated by an earlier run would otherwise re-double its
  arrays and could throw "Invalid string length" before the post-call cleanup runs.
- dedupeEntrypointGlobs now restores a recursive glob only when a scoped variant of
  it was present, and no longer treats a root-only `*.ts` as redundant. This stops it
  injecting spec/test excludes a tsconfig never had and stops it widening `*.ts` to
  `**/*.ts`. Exported with unit tests covering these cases.
2026-06-17 19:29:54 +01:00
Ashley Hunter 57614d3488 fix(cli): resolve @nx/workspace remove generator robustly across nx versions
migrate-helm-libraries imported removeGenerator from the deep path
@nx/workspace/src/generators/remove/remove at module top level. On nx 23 that
specifier is blocked by the package's exports map (and the compiled file moved to
dist/), so the generator failed to load with "Package subpath ... is not defined by
exports" - in every mode, before doing any work. The package entry point can't be
used either: it eagerly evaluates convert-to-nx-project whose output.js crashes
("Cannot read properties of undefined (reading 'inverse')").

Load it lazily, only when a library is actually removed (generateAs: library), and
resolve the compiled file by absolute path - bypassing the exports gate and never
loading the crashing barrel - trying dist/ (nx 23+) then src/ (nx <= 22).
2026-06-17 19:29:54 +01:00
Ashley Hunter 1f138b14b2 test(cli): cover all components on nx and harden the cli-smoke cell matrix
- Add an all-components-nx-entry cell: all primitives as buildable secondary
  entrypoints on nx. This is the shape that previously crashed with "Invalid string
  length" and is now the regression guard for that fix. The existing all-components
  cell stays on angular-cli.
- Fix per-cell filtering: describe.each('$id') rendered the id wrapped in quotes
  (e.g. 'nx-entry-buildable'), so the CI --testNamePattern matched nothing and every
  cell silently skipped. Use a plain describe(cell.id) loop for clean names.
- Disable the nx daemon in the throwaway workspaces. Under 50+ back-to-back generators
  it intermittently crashed with "Failed to process project graph"; daemonless is
  reliable and faster (no slow daemon retries).
- Register the new cell in the cli-smoke workflow matrix so the drift-guard passes.
2026-06-17 18:54:10 +01:00
Ashley Hunter 5eb1002765 fix(cli): vendor string-change util so healthcheck runs when the CLI is installed
migrate-icon and migrate-scroll-area imported applyChangesToString/ChangeType from
the deep path @nx/devkit/src/utils/string-change. That resolves inside this monorepo
(the dev @nx/devkit has no exports map) but throws "Package subpath ./src/utils/
string-change is not defined by exports" once the CLI is installed against a devkit
that declares exports, crashing the healthcheck generator that loads these migrations.

Those helpers are not part of devkit's public entry, so vendor the small (MIT) impl
locally and import it instead.
2026-06-17 18:54:10 +01:00
Ashley Hunter 7e243905a3 fix(cli): prevent tsconfig.lib.json include explosion when migrating helm libraries
nx's librarySecondaryEntryPointGenerator appends an entrypoint-prefixed copy of
every existing include/exclude glob each time it runs. Generating many entrypoints
into one buildable library (migrate-helm-libraries or ui with "all") doubles these
arrays on every primitive until JSON.stringify throws "Invalid string length",
surfaced as "NX Invalid string length". A few primitives stay under the limit, so
the failure only showed up with ~22+ components.

Collapse the redundant prefixed globs back to their recursive equivalents after each
secondary entrypoint is generated. The library's recursive **/*.ts include already
matches every entrypoint subdirectory, so the per-entrypoint copies add nothing. The
normalization is idempotent, so the arrays stay bounded regardless of primitive count.
Angular CLI is unaffected: it never generates buildable secondary entrypoints.
2026-06-17 18:54:10 +01:00
mehrabix f396e32df9 feat: add provideSpartanHlm utility to fix CDK overlay z-index conflict
In Angular 21, the CDK overlay defaults to using the popover attribute,
which causes overlay-based components (sheets, dialogs, tooltips) to
always render above position: fixed elements like hlm-toaster. This
adds a provideSpartanHlm() utility that configures OVERLAY_DEFAULT_CONFIG
with usePopover: false, and documents the issue in the sonner docs.

Closes #1280
2026-06-17 19:08:20 +03:30
Ban117 7ada58e03d fix(select): select option with a falsy value on enter keypress (#1493)
selectActiveItem() guarded the commit with a truthiness check (if (value)), so an
option whose value is falsy (false, 0, '') was dropped: pressing Enter just closed
the panel without selecting. Check value !== null && value !== undefined instead, so
a defined falsy value is committed while a missing active item still closes. Applies
to both BrnSelect and BrnSelectMultiple.

Co-authored-by: Benjamin <benjamin@amcbanking.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:47:28 +02:00
moosme 01aeb5a231 feat(navigation-menu): add style support #1408 (#1490)
* feat(navigation-menu): add style support #1408

* fix: review

* feat(navigation-menu): add align input to navigation-menu-trigger

* add align example

* feat(navigation-menu): add navOffset

* docs(navigation-menu): update example ids

* feat(navigation-menu): add guard in updateAlign

* feat(navigation-menu): remove group from trigger

* feat(navigation-menu): remove unused data-popup-open classes

* navigation-menu doesn't have data-popup-open attribute

---------

Co-authored-by: Merlin <merlin.moos@oldendorff.com>
Co-authored-by: Marc Stammerjohann <8985933+marcjulian@users.noreply.github.com>
2026-06-17 15:43:07 +02:00
Leonidas 9849f9cd72 chore: add new contributors to our 300 2026-06-17 10:58:34 +00:00
Ashley Hunter d2f40d3014 Merge pull request #1471 from PatrickLarocque/fix/overlay-lifecycle
refactor!: split dialog and overlay portal lifecycles
2026-06-17 10:16:35 +01:00
moosme 8cf3775943 Merge pull request #1489 from marcjulian/feat/remove-unused-styles 2026-06-17 08:07:19 +02:00
Leonidas b5e12f4140 chore: nightly release 2026-06-17 ⚡ 2026-06-17 04:12:35 +00:00
Ashley Hunter d4a0a31eb0 test(popover): cover animation-aware teardown and overlay behaviour
Panel stays mounted through the exit animation then disposes, reopen cancels a
pending teardown, no-animation disposes promptly; plus non-modal (no backdrop),
autoFocus opt-out, outside-pointer gating, unique overlay ids, and the
destroyed-output guard.
2026-06-16 23:56:56 +01:00
Ashley Hunter ecb098bb3d test: cover wait-for-element-animations helper
Active-animation collection (filtering finished, subtree, null-safety) and the
finish/fallback-timer behaviour that replaced the fixed close delay.
2026-06-16 23:56:56 +01:00
Ashley Hunter 82b6f756de test(drawer): cover open/close and directional positioning
Exercises the getPositionStrategy() override for bottom/top/left/right and the
modal backdrop, guarding the drawer's adaptation to the new dialog lifecycle.
2026-06-16 23:56:56 +01:00
Ashley Hunter ed9328f867 test(select): cover keyboard open, commit-and-close, and focus model
Guards the regression where committing with Enter re-opened the panel, plus
Escape-to-close and the trigger keeping focus while navigating.
2026-06-16 23:56:56 +01:00
Ashley Hunter 4140fc6d9a test(popover): cover autofocus, focus restore, and nested dismissal
Regression coverage for the overlay lifecycle work: autoFocus moves focus to
the first tabbable element on open, leaves focus on the trigger when the
content has none (the select/combobox keyboard model), restores focus to the
trigger on Escape, and a nested popover does not dismiss its parent while it is
the topmost overlay.
2026-06-16 23:41:50 +01:00
Ashley Hunter 35f1a92586 fix: avoid emitting on destroyed overlay/dialog outputs
Destroying a host while its overlay/dialog is open ran the onDestroy
forceClose(), which emits on closed$/stateChanged$. The subscriptions
forwarded those to the component outputs after the directive was destroyed,
logging NG0953 in dev mode. Set a destroyed flag (registered before the
forceClose teardown) and skip the emits once it is set.
2026-06-16 23:41:50 +01:00
Ashley Hunter 23f20bf4dd feat: restore overlay focus-into-content on open via opt-in autoFocus
Moving popover-backed controls off CDK Dialog dropped the dialog's
autoFocus: 'first-tabbable', so popovers no longer moved focus to their
content on open (form fields were left unfocused, comboboxes could not be
typed into immediately).

Add an opt-in autoFocus option to BrnOverlay that focuses the first tabbable
element once the content renders, and enable it in the popover defaults. The
select keeps focus on its trigger because its listbox has no tabbable element,
preserving the aria-activedescendant keyboard model. Re-expose the autoFocus
input on the helm popover wrapper and its CLI template, and refresh the docs
API snapshot.
2026-06-16 23:23:29 +01:00
Ashley Hunter cd932da378 fix(select): keep panel closed after committing a value with the keyboard
Address review feedback on the overlay lifecycle:

- the select trigger re-read its expanded state after selectActiveItem() had
  already closed the panel, so Enter/Tab fell through and re-opened the
  overlay via reopen(); capture the expansion state up-front so a commit no
  longer re-opens on the same keypress
- make the overlay id atomic (++overlaySequence) so the duplicate-id guard and
  the ref share the same counter, matching brn-dialog.service.ts
2026-06-16 23:23:29 +01:00
Ashley Hunter 2e14efcde5 fix(drawer): adapt drawer to the new dialog/overlay lifecycle
The drawer landed on main against the old BrnDialog API. Reconcile it with
this branch's refactor:

- override getPositionStrategy() for the directional position instead of the
  removed mutablePositionStrategy/positionBuilder members (matches BrnSheet)
- constrain BrnDrawerContent<T extends Record<string, unknown>> to satisfy
  BrnDialogContent's tightened generic
- drop the removed closeDelay-era 'delay' input from the drawer close wrapper
  and its CLI template
2026-06-16 23:23:29 +01:00
Ashley Hunter 0c3b653902 Merge origin/main into fix/overlay-lifecycle
Resolve brn-dialog.service.ts conflict: drop the deprecated injectBrnDialogCtx
alias (removed on main during the pre-1.0 audit) and keep the typed
injectBrnDialogContext with the unknown default.
2026-06-16 23:22:47 +01:00
moosme 263648ade1 feat(command): add style and rtl support #1399 (#1488)
* feat(command): add style and rtl support #1399

* fix: comments

* feat(command): remove custom data-hidden is built in

* remove important from rounded

* docs(command): fix typo

* fix(command): check has search input for separator

* otherwise shows multiple separator while searching in the scrollable example

---------

Co-authored-by: Merlin <merlin.moos@oldendorff.com>
Co-authored-by: Marc Stammerjohann <8985933+marcjulian@users.noreply.github.com>
2026-06-16 18:48:35 +02:00
Marc Stammerjohann 98ca3b7ae7 docs(popover): update basic example 2026-06-16 18:08:13 +02:00
Marc Stammerjohann 346c06eaab docs(popover): add align example 2026-06-16 17:26:33 +02:00
Marc Stammerjohann a0687ae64b feat(popover): add header, title and description 2026-06-16 17:21:28 +02:00
Marc Stammerjohann cc3a7578de chore: remove unused spartan-* classes 2026-06-16 17:09:52 +02:00
Marc Stammerjohann 27305c73c0 feat: dropdown and context menu styles, rtl example (#1486)
* feat(dropdown-menu): add style support, add sub trigger

* feat(dropdown-menu): update snapshot

* feat(context-menu): add rtl and more examples, enable styles

* remove spartan-context-* classes as it reuses dropdown-menu

* feat(menubar): remove unused spartan-menubar-* styles, update examples

* fix(dropdown-menu): remove duplicate styles which dropdown-menu-item already applies

* docs(context-menu): fix id

* docs: update examples

* feat(dropdown-menu): make checkbox/radio group scoped

* fix(dropdown-menu): fix rtl styles

* feat(dropdown-menu): add internal comment

* feat(dropdown-menu): add ng-icon styles for item-indicator

* docs(menubar): update preview
2026-06-16 16:33:33 +02:00
Marc Stammerjohann 05463a6955 fix: ignore copilot from contributors (#1487) 2026-06-16 16:13:34 +02:00
Leonidas 0475400815 chore: add new contributors to our 300 2026-06-16 11:12:27 +00:00
moosme 61a546f24a Merge pull request #1476 from spartan-ng/pre-1.0-audit
chore(repo): pre-1.0 audit - overlay leak fixes, data-slot, CLI drawer, naming
2026-06-16 11:43:11 +02:00
Leonidas bd321c9ab0 chore: nightly release 2026-06-16 ⚡ 2026-06-16 04:12:33 +00:00
Juan Valero 50c54ac29c docs: add tailwind configuration guide for Jetbrains-based IDEs (#1482) 2026-06-16 00:40:21 +02:00
moosme 457b7190cc feat(menubar): add style support (#1474)
* feat(menubar): add style support

* fix: review

---------

Co-authored-by: Merlin <merlin.moos@oldendorff.com>
2026-06-15 15:52:30 +02:00
Robin Goetz 70fb0e929f fix(cli): handle interrupts in healthcheck prompt and harden generators (#1479)
* fix(cli): handle interrupts in healthcheck prompt and harden generators

Replace the raw-stdin prompt in the healthcheck generator with the standard
enquirer confirm prompt so Ctrl+C correctly aborts the run instead of leaving
the generator running. Isolate each healthcheck so one throwing does not abort
the rest, and report registry fetch failures instead of throwing.

Make getImportAlias throw on a present-but-invalid config rather than silently
falling back to the default alias, guard against the coerce() NPE in
version-utils, and switch migrate-hlm to readJson. Add unit tests across these
paths and stub network access so the suite runs offline.

Closes #906

* fix(cli): guard version healthcheck fix against missing dependencies section

The fix writeback read packageJson.dependencies[dep] directly, which threw when
a package.json had no dependencies section and the dependency lived only in
devDependencies. Guard both sections with optional chaining so the writeback is
symmetrical and never touches an undefined section.
2026-06-15 15:16:42 +02:00