Commit Graph

710 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
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
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 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 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 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
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
Leonidas b5e12f4140 chore: nightly release 2026-06-17 ⚡ 2026-06-17 04:12:35 +00: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 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 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
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
copilot-swe-agent[bot] aaf29b4e05 chore(repo): merge main into pre-1.0-audit (resolve drawer brain version conflict) 2026-06-15 11:47:09 +00:00
Marc Stammerjohann 9e825894d1 feat(native-select): generate to cli 2026-06-15 11:24:11 +02:00
Leonidas 7da9d3e4c3 chore: nightly release 2026-06-15 ⚡ 2026-06-15 04:22:11 +00:00
Ashley Hunter e1b26056ec refactor(breadcrumb): drop deprecated HlmBreadCrumbImports alias
Remove the mis-cased `HlmBreadCrumbImports` alias in favour of the canonical
`HlmBreadcrumbImports`, dropping it before 1.0 rather than carrying it on the stable line. The
NgModule migration map is repointed to the canonical name so `nx g @spartan-ng/cli:migrate-module-
imports` still rewrites `HlmBreadCrumbModule` to an export that exists.
2026-06-14 23:40:36 +01:00
Ashley Hunter 935e4c2404 fix(avatar): give image/fallback distinct prefixed exportAs names
BrnAvatarImage/BrnAvatarFallback and their helm wrappers all used the same
unprefixed exportAs ('avatarImage'/'avatarFallback'). Since the helm directive
host-applies the brain one on the same <img>, a template ref was ambiguous, and
the names broke the brn*/hlm* convention every other exportAs follows. Rename to
brnAvatarImage/brnAvatarFallback and hlmAvatarImage/hlmAvatarFallback before the
exportAs surface is locked at 1.0. Regenerated the CLI avatar templates to match.
2026-06-14 22:26:34 +01:00
Ashley Hunter bf758cfac0 feat(cli): add drawer to the ui generator
Drawer shipped as a helm lib with docs but was missing from the CLI, so
`nx g @spartan-ng/cli:ui drawer` failed. Register it in the Primitive union and
dependency map, generate its templates + supported-ui-libraries entry, and add a
drift-guard spec asserting the CLI primitive set equals the installable helm
components (with a generator template each) so this cannot recur.
2026-06-14 22:24:06 +01:00
Leonidas f377723a53 chore: nightly release 2026-06-14 ⚡ 2026-06-14 04:09:37 +00:00
Patrick c7fb7469d6 fix: restore overlay dismissal semantics 2026-06-13 14:32:40 -04:00
Patrick ba74c53c97 refactor: split dialog and overlay primitives 2026-06-13 14:32:40 -04:00
Patrick 179ec6af8f fix: coordinate overlay lifecycle with animations
Replace fixed close delays with lifecycle-driven disposal so overlays remain responsive.
Wait only for exit animations that actually start and centralize Escape, backdrop, and
outside-pointer dismissal.

BREAKING CHANGE: remove the closeDelay input and configuration option. Remove explicit delay
values; closed-state exit animations are now detected automatically.
2026-06-13 14:32:40 -04:00
Ashley Hunter b296a3613b test: silence nx-generator console noise in cli and tools specs
The cli generator specs drive real nx generators, which log copiously
("Couldn't find .gitignore", "NX workspace root does not exist", etc.) - ~3k
lines across 142 specs, enough to truncate the CI log and bury the run summary,
making a passing suite look like it failed. tools has the same class of chatter.

Add `onConsoleLog: () => false` to both configs so that intercepted console
output is dropped (the specs assert on the generated tree and on console spies,
not on this logging; test failures are still reported by the reporter). cli's
output drops from ~3160 to ~530 lines and the summary is visible again.
2026-06-13 19:15:39 +01:00
Ashley Hunter 16ecd13eab test: surface vitest test counts in CI logs for the node projects
Add reporters: ['default'] to the mcp, cli, tools, registry and cli-smoke vite
configs (brain and helm already had it). Without a default reporter the @nx/vitest
NxReporter is the only one attached, so these projects printed no summary in CI -
which is how mcp's silently-undiscovered specs stayed invisible. The counts are
now shown so test execution is verifiable at a glance.
2026-06-13 17:35:00 +01:00
Ashley Hunter e0f236ba47 fix: run mcp tests and stop passWithNoTests masking missing test discovery
The mcp vite config lacked `root: __dirname`, so the @nx/vitest executor (which
runs from the workspace root) resolved `src/**/*.spec.ts` against the workspace
root, found nothing, and `passWithNoTests` passed it silently - mcp's 19 tests
never ran.

Pin mcp's root, and drop `passWithNoTests` from every project that has specs
(mcp, cli, tools, brain, helm) so a future test-discovery break fails loudly
instead of going green. registry keeps the flag - it genuinely has no specs.
2026-06-13 17:16:45 +01:00
Ashley Hunter 656225e78b test: address review feedback in cli generator specs
- base spec: replace hoisted vi.unmock + require with test-scoped vi.importActual
  to load the real @nx/angular/generators for that one test without leaking mock
  state across the file
- migrate-brain-accordion-trigger spec: remove a stray debug console.log
- refresh a stale jest-era comment on the @angular/core stub
2026-06-13 15:46:30 +01:00
Ashley Hunter 1b743f8019 test: migrate from jest to vitest with browser testing for brain/helm
Replace Jest with Vitest across the workspace. The brain and helm Angular suites
now run in a real browser (Playwright/Chromium via Vitest browser mode) so they
exercise real layout, focus, pointer events and computed styles that jsdom could
not. The cli, tools, mcp, registry and cli-smoke suites run on Vitest's node
environment.

- Add per-project vite configs and switch test targets to @nx/vitest:test
- Convert jest APIs to vi.* and jest module mocks to vi.mock with importOriginal
- Replace jest-axe with a browser-native axe-core helper and toHaveNoViolations
- Regenerate snapshots in vitest format (content unchanged, format-only)
- Remove all jest packages, configs, the preset and the @nx/jest target default
- Install Playwright Chromium in the CI unit job for the browser suites

Also fixes a brain avatar test that asserted inside a fire-and-forget setTimeout,
which passed vacuously under jsdom and only surfaced once a real browser loaded
the image.
2026-06-13 15:16:45 +01:00
Leonidas f29b10bb68 chore: nightly release 2026-06-13 ⚡ 2026-06-13 03:47:26 +00:00
Ashley Hunter f870b0b8e7 fix(cli): avoid @nx/workspace barrel import in migrate-helm-libraries (#1464)
* fix(cli): avoid @nx/workspace barrel import in migrate-helm-libraries

Import removeGenerator from its module directly instead of the @nx/workspace
barrel. The barrel eagerly evaluates convert-to-nx-project, whose output.js
crashes on nx 22 ("Cannot read properties of undefined (reading 'inverse')"),
so the generator threw before doing any work.

Add a regression test that runs the generator and asserts it does not throw.

* test(cli): tidy migrate-helm-libraries regression test

Assert the generator resolves to undefined instead of using the
resolves.not.toThrow matcher, which does not fit a Promise<void>, and
restore mocks after each test to keep the suite hermetic.

* test(sidebar): update generate-ui-docs snapshot for HlmSidebarTrigger

The HlmSidebarTrigger gained an `srOnlyText` input, but the generate-ui-docs
stable-output snapshot was never regenerated, so `tools:test` failed whenever
it ran uncached. Regenerate the snapshot to match the current component API.
2026-06-12 19:35:54 +02:00
Marc Stammerjohann 90773f3b3c fix(tooltip): spartan-tooltip-content to be replaced for styles 2026-06-12 09:56:08 +02:00
Leonidas 1d4b389e6e chore: nightly release 2026-06-12 ⚡ 2026-06-12 04:02:56 +00:00
Ashley Hunter 859676a41a feat!: drop Tailwind CSS v3 support (#1460)
spartan/ui is now Tailwind CSS v4 only. The v3 compatibility layer added
complexity across the brain preset, the CLI generators and the docs, all of
which is removed here.

Brain:
- Delete the v3 JavaScript preset (hlm-tailwind-preset.js) and its package
  export; the v4 CSS preset (hlm-tailwind-preset.css) is now the only preset.
- Bump the tailwindcss peer dependency to >=4.0.0 and declare tw-animate-css
  as a peer, since it is imported by the CSS preset.

CLI:
- Remove Tailwind version detection and the v3 confirmation prompt; the theme
  generator always emits the v4 stylesheet (preset import plus OKLCH theme).
- Drop the legacy HSL theme table, the v3-only CDK overlay import branch, the
  vestigial addCdkStyles option and the unused registryItemTailwindSchema.

Docs and tooling:
- Remove the Tailwind v3 installation and theming sections and snippets.
- Drop autoprefixer; Tailwind v4 handles vendor prefixing via @tailwindcss/postcss.

BREAKING CHANGE: Tailwind CSS v3 is no longer supported. The
@spartan-ng/brain/hlm-tailwind-preset (JS) package export has been removed; use
the @spartan-ng/brain/hlm-tailwind-preset.css preset with Tailwind CSS v4. The
tailwindcss peer dependency now requires >=4.0.0.
2026-06-12 00:39:14 +02:00
Ashley Hunter f52f1ea6c6 chore(cli): apply review feedback on the smoke harness
- Remove the acceptTailwindV3 flag from the theme and init generators. It was a leftover from
  when the matrix covered Tailwind v3; the suite is v4-only and v3 support is being dropped.
- Publish packages via execFileSync with an argument array so the registry and npmrc values
  are never interpreted by a shell.
- Drop the explanatory embla-carousel import comments from the carousel template and helm source.
2026-06-11 18:07:11 +01:00
Ashley Hunter 7cbb144cdf Merge remote-tracking branch 'origin/main' into feat/cli-smoke-harness
# Conflicts:
#	libs/cli/src/generators/ui/supported-ui-libraries.json
2026-06-11 18:06:49 +01:00
Leonidas a3607e71d7 chore: nightly release 2026-06-11 ⚡ 2026-06-11 04:03:48 +00:00
Ashley Hunter 9769b58fd5 chore(cli): address review feedback on the cli-smoke harness
- await the local-registry stop in global-teardown and the global-setup error
  path, so verdaccio is fully stopped before the process exits
- restore the dist package.json byte-for-byte after publishing, so a local
  `pnpm smoke` leaves the build artifacts untouched
- pass the nx affected args via execFileSync (no shell) so NX_BASE/NX_HEAD are
  never shell-interpreted
- note that setupTailwindCss is an internal-only theme option
2026-06-10 23:35:27 +01:00
Ashley Hunter a60bbfbd5a fix(scroll-area): declare ngx-scrollbar as a generator peer dependency
The generated scroll-area directive imports provideScrollbarOptions from
ngx-scrollbar, but the ui generator did not install it, so a fresh scroll-area
failed to compile (TS2307). Add it to the scroll-area peer dependencies.
2026-06-10 22:55:49 +01:00
Ashley Hunter 2b2e3b21a9 fix(carousel): import embla types from the base embla-carousel package
embla-carousel-angular v22 no longer re-exports EmblaOptionsType,
EmblaEventType and EmblaPluginType, so a fresh carousel failed to compile
(TS2459). Import them from the base embla-carousel package, which exports them
in both v21 and v22, and add it as a peer dependency.
2026-06-10 22:51:43 +01:00
Ashley Hunter a60be560a7 fix(cli): resolve the workspace root tsconfig in the nx generators
The generators assumed a tsconfig.base.json, so they failed on a standalone nx
workspace (single app, no base tsconfig) with "File not found:
tsconfig.base.json". Resolve the root tsconfig with getRootTsConfigPathInTree
instead, and stop tying the eslint-editing ts-morph Project to an on-disk
tsconfig that may not exist yet during generation.
2026-06-10 22:51:43 +01:00
Ashley Hunter 390c38dcb7 feat(cli): support non-interactive init and ui-theme generators
Passing --theme opts the init and ui-theme generators into non-interactive
mode: the project is auto-selected when there is a single app, the styles
entry point is auto-detected, and the Tailwind v3 warning is skipped. This
lets the CLI be scripted in CI. Prompts are unchanged when no theme is passed.
Adds unit tests for the non-interactive paths.
2026-06-10 22:51:43 +01:00
moosme e8fb6b0cfb Merge pull request #1441 from spartan-ng/wt/resizable-1412 2026-06-10 22:44:24 +02:00
Ashley Hunter 99b05147d1 fix(scroll-area): implement per-style support and match shadcn
Address review feedback on the PR. Wire the directive to ngx-scrollbar's
real CSS variables at shadcn's values (transparent 10px track, 7px
bg-border thumb) and default visibility to hover so the thumb only shows
on hover, scroll or focus like shadcn.

Move the container radius into the registry per style now that the demo
no longer hardcodes it: rounded-md for vega/nova/mira, square for lyra
via --radius 0, and rounded-2xl for maia/luma. Replace the dead
radix-era marker rules with a single spartan-scroll-area rule.

Declare ngx-scrollbar as a helm peer dependency since the directive now
imports from it, and mirror the changes in the CLI template.
2026-06-10 18:24:28 +01:00