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.
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.
The generate-ui-docs snapshot captures each directive's exportAs, so the avatar exportAs rename
(avatarImage/avatarFallback -> brn*/hlm*) left it stale and failed the unit job. Diff is limited to
those four entries.
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.
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.
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.
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.
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.
* 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.
The collapsible component gained an exportAs on main but the generated
docs snapshot was not refreshed, leaving the generate-ui-docs stable
output test failing on every open branch. Regenerate the snapshot so it
matches the current component metadata.
The nx 22 / angular 21 upgrade (#1430) switched the cli tsconfig to
`module: preserve` with `moduleResolution: bundler`. With `preserve`,
TypeScript keeps the ESM import/export syntax in the emitted .js files,
but the published package declares `"type": "commonjs"`. Node then loads
the generator files (e.g. compat.js) as CommonJS and throws
"Cannot use import statement outside a module", breaking every
`ng g @spartan-ng/cli:*` command from alpha.708 onwards.
Restore `module: commonjs` (with `moduleResolution: node`) so the build
output matches the package type again. The same harmless mismatch is
corrected in libs/tools for consistency; tools runs from source and is
never published, so it was not affected at runtime.
Closes#1451
* feat(mcp): release and version mcp server alongside cli and brain
Wire the MCP server package into the release pipeline so it is published
and version-synced with the cli and brain packages. Add a
replace-mcp-version generator (invoked by auto-increment-version for
nightly and prepare-manual-release for manual), a release-mcp script,
and sync the package to the current alpha version.
Also drop the orphan scope:core tag from release-ui and list mcp in the
PR template's affected-packages section.
* refactor: document release schemas and harden version error handling
Fill in the empty titles and descriptions on the release generator and
executor schemas, and declare the newVersion option so the version
generators are self-documenting and CLI-invocable.
Make the version generators throw with actionable messages instead of
silently logging and returning, validate the brain version format in
auto-increment-version, and fix the misleading source-of-truth message
in replace-ui-version.
* fix: prevent shell injection in npm publish and correct version flag hints
Validate the TAG dist-tag and publish via execFileSync with an argument
array instead of interpolating it into a shell string, removing a
shell-injection vector in the npm-publish executor.
Correct the version generators' error messages to reference the actual
--newVersion / --new-version flag rather than the reserved --version.
Expose a size input ('default' | 'sm') on the brain and helm switch, bound to the
button's data-size attribute, so the size-keyed registry style rules resolve and
a smaller switch can be rendered. Replaces the previously hardcoded
data-size="default". Add brn-switch specs covering the data-size reflection and
the thumb data-state, and update the ui-docs snapshot for the new input.
* feat(date-picker): add date picker input
* feat(date-picker): add provideHlmDatePickerTrigger, add aria label inputs
* fix: language fix for datepicker rtl
* feat(date-picker): add generic to date picker base for updateDate
* feat(date-picker): clear the picker date for invalid parsing
* reveals form errors after a date picked and changed to invalid via input
* feat(date-picker): update snapshot
---------
Co-authored-by: Merlin <merlin.moos@oldendorff.com>
* feat(repo)!: upgrade nx to 22 and angular to 21
Upgrade the workspace to Nx 22.7.5 and Angular 21.2.16, and widen the
published peer dependency ranges to support Angular 21 and 22 while
dropping Angular 20.
- nx and @nx/* to 22.7.5; @angular/* to 21.2.16 (framework) and 21.2.14
(cli, build, devkit, cdk, ssr)
- brain, helm and trpc @angular/* peers to ">=21.0.0 <23.0.0"; the helm
embla-carousel-angular peer uses the same range
- @spartan-ng/cli minimums raised to >=21 and @schematics/angular to
21.2.14; the private tools lib aligned to nx 22 / angular 21
- analog 2.6.0, ng-packagr 21, angular-eslint 21, storybook 10, jest 30,
@testing-library/angular 19 and related tooling
- replace the calendar select host-listener $event with a typed output
subscription; constrain the ai-chat-link directive to anchors
- drive the menubar e2e arrow keys via native keydown and disable
Chromium throttling; hold cypress at 14 (15 breaks realPress specs)
BREAKING CHANGE: Angular 20 is no longer supported. spartan/ui now
supports Angular 21 and 22.
* ci: lower unit test parallelism to fit the runner memory
The docs app's vitest + Analog suite peaks at a few GB; running it
alongside two other test projects under --parallel=3 exhausted the
GitHub runner memory and the worker was OOM-killed with no output.
Run at most two test projects concurrently.
* fix(trpc): drop invalid environment providers from the test env module
The Nx 22 migration wrapped provideZoneChangeDetection() in an @NgModule,
but EnvironmentProviders are not valid in @NgModule providers and Angular
21 throws NG0207 at runtime. Restore the plain initTestEnvironment setup
(matching the docs app); the explicit zone provider is unnecessary.
* ci: run the docs app test suite in isolation
Bundling the docs app's vitest + Analog suite into the parallel test run
made it fail in CI while it passes on its own, and the interleaved output
hid the cause. Run the other projects in parallel, then the docs app as a
separate step.
* fix(nx): point test cache inputs at the real jest preset file
The test targets' cache inputs referenced jest.preset.js, but the
workspace preset is jest.preset.cjs, so the input never matched and a
preset change would not invalidate the cache. Fix both the
@nx/vitest:test target (added by the Nx 22 migration) and the existing
@nx/jest:jest target.
* ci: log exit code and retry the docs app test suite once
The docs app's vitest + Analog suite intermittently crashes in CI right
after loading Angular's testing modules, with no error output. Log the
exit code to classify the crash (128+signal indicates a native crash)
and retry once so a flaky crash does not fail the run while the root
cause is investigated.
* ci: clarify docs app test retry after pinpointing the flaky crash
The crash is in app.spec.ts: booting the full app shell (Header/Footer
and their deep import graph) intermittently crashes the vitest worker
during the Analog transform in CI (exit 1, no output, not reproducible
locally). It happens before any test runs, so a vitest per-test retry
cannot help; re-running the suite once does.
* chore(repo): hold analog at 2.1.3 and drop unit-test ci workarounds
Analog 2.6.0 intermittently crashed the docs app's vitest worker in CI
(a flaky transform of the app shell), so keep analog at the nx-migration's
tested 2.1.3, revert the marked bumps that 2.6.0 required, and restore the
ai-chat-link directive selector. Also restore the original unit test ci
step, dropping the parallel, isolation and retry workarounds added while
chasing that crash.
* feat(date-picker): add date-picker-trigger, use button styles, add forceInvalid
* fix(date-picker): lint issue and update snapshot
* fix(date-picker): add trigger to test
* fix(date-picker): cleanup imports
* docs(date-picker): add for to label
* docs(date-picker): use trigger in blocks
* docs(date-picker): add rtl example
* feat(date-picker): use trigger in story
* feat(date-picker): add header and footer slot for calendar, update block example
* add showTrigger input
Drop the duplicate m-risto entry that was also listed under the old MatznRisto
handle the account was renamed from, and ignore that handle in the
update-contributors generator so git history does not re-add it.
Restore the snyder-tech sponsor next to zerops; it had been removed after being
mistaken for the separate benpsnyder contributor account.
Adds a button on each runnable docs example that boots a real, runnable
Angular CLI project on StackBlitz, with helm source vendored from the existing
generated pipeline so it stays in sync.
- generate-hlm-component-preview captures the exact CLI output (libs/ui, deps,
tsconfig paths) and version/preset metadata; all @angular packages pinned to a
single consistent major; example-only deps (tanstack, luxon, ngx-scrollbar,
embla autoplay, extra ng-icon sets) added explicitly
- generate-primitive-snippets bundles sibling files of multi-file examples
(e.g. data-table) and rewrites back-references to the entry
- client-side builder assembles the project, drops mismatched Angular ranges,
rewrites /assets URLs to the live docs origin, and bundles siblings
- docs-internal examples (RTL) are excluded as not self-contained
- fix data-table flexRenderComponent calls that only failed under strict AOT
* feat(native-select): add style support, rtl example, add forceInvalid
* fix(native-select): center icon correctly considering the text-xs/relaxed for default size
* feat(sonner): add style support
* fix(select): trigger icon placement when no value/placeholder is available
* feat(field): add style support, add rtl example
* fix(field): rename to spartan-*
* docs(sonner): remove duration
* docs(field): fix translation value
* fix(sonner): merge toast options to keep the default styles
* feat(empty): add styles support
* feat(empty): add rtl and input group examples
* feat(label): support styles and add rtl example
* feat(input-otp): add styles support
* feat(input-otp): add rtl and other examples
* chore: copy hlm to cli
* feat(input-otp): update snapshot
* fix: class names
* docs(spinner): add rtl example and show theme toggle
* spinner doesn't have a different styles though, but allows displaying the examples in other styles
* feat(spinner): update icon text size styles
* feat(separator): add data-slot, add new examples including rtl
* feat(kbd): support styles, add rtl example
* feat(item): add style support, add rtl example
* docs: fix item usage
* fix(item): remove role list to fix e2e a11y test
* refactor(table): simplify table directive classes
* removes config and sets classes directly
* fixes issues where table spartan-* classes are not replace in the cli
* fix(table): update snapshot
* feat(skeleton): support styles, add more examples and rtl
* feat(table): support styles, update selectors, add more examples and rtl
* docs: cleanup key