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.
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
* feat: better form control integration
- general a11y described by service
- hint and error stories
- datepicker value type
- mock resizeObserver causing select failure
- form desciption test failures
* feat: autocomplete and combobox
- re-implemented form integration based on latest implementation
* fix: error state
* fix: formatting
* chore: update snapshot
* fix: format
* fix: update snapshot
* fix: autocomplete stories
* fix: test
* fix: remove not needed effects
* fix: call onTouched when autocomplete focus out
* fix: evaluate only error state in field
* fix: fix slider classes and field integration
* fix: set correct error styles to input group
* feat: add native select field control support
* fix: implement field control
* fix: emit touched when blurred for combobox
* fix: add invalid support for combobox multiple
* fix: fix autcomplete search and input styles
* feat: improve control state data attributes and hlm-error
- render hlm-error if error presetn
- add touched, dirty and matches-spartan-invalid attributes
* feat: apply field control as host directive
* test: fix some control error stories WIP
* fix: lint issues w/ type imports and sort order
* chore: remove form-field package as it is replaced by field
* chore: update snapshot
* fix: fix autocomplete providers array and error story
* fix: fix select, field error and input group
* docs: fix reactive forms examples WIP
* feat: add healthcheck and migration for hlm-form-field to hlm-field
* fix: add value accessor to date-picker multi
* docs: update field for/id
* fix: fix checkbox and rename CVA providers
* fix: add and fix tests
* docs(field): update headings
* feat(autocomplete): add inputId
* feat(combobox): add input/button id
* chore: update snapshot
* docs(date-picker): use hlm field
* docs(field): add native-select example, simplify selectId
* docs: use hlm-field for date-picker blocks
* feat: update form field usage in autocomplete story
* fix(input): unit test and remove unused ngControl
* fix: comment out missing errorState in select
* feat: remove ng-* classes
* feat: remove unused code
* fix: comment out error in unit tests
* feat: set label for attribute automatically
* refactor: rename variable
* docs: add brain input and textarea docs
* fix: apply button styles in storybook
* fix: fix select test and add missing attributes
* feat: add attributes to switch
* fix: fix field e2e tests and lint errors
* chore: fix format
* fix: add optional chain
* feat(select): add controls and aria labels to brn-select-trigger
* fix: update default value for select demo
* docs(select): add form example
* chore: update snapshot
* fix(select): add optional chain for aria-invalid
* feat(select): update e2e test form attributes
* fix(input): form unit test
* fix(select): update unit test template, add HlmFieldControlDescribedBy to select trigger button
* fix(combobox): use new combobox template for unit test
* add hlmFieldControlDescribedBy to combobox trigger button
* chore: remove console log from unit test
* fix(checkbox): use buttonName instead of id
* fix: lint issue w/ import
* test: fix unit tests
* docs: add field date picker preview
* docs: fix blocks and reactive forms
* docs: improve control, field and forms docs
* feat: add provider for error matcher
* chore: rename var
* fix: replace aria-invalid in registry styles
* feat: move state to brn, add to combo tigger
* chore: format
* feat(combobox): apply form attributes on brnComboboxTrigger
* remove need for applyControlState
* chore: update snapshot
* docs: update container width for the responsive select demo
* fix: remove aria invalid and fix chips focus styles
* feat(field): move HlmFieldControlDescribedBy and HlmFieldA11yService into brain package
* chore: update snapshot
* feat(field): update id input handling, update styles
* docs: update form examples to required
* feat: add forceInvalid to brn-field and brn-checkbox
* allow overrides to data-invalid and data-matches-spartan-invalid
* fix: add error if ngControl.control is not defined
---------
Co-authored-by: Merlin <merlin.moos@oldendorff.com>
Co-authored-by: Toni Škobić <toni.skobic@gmail.com>
Co-authored-by: Marc Stammerjohann <8985933+marcjulian@users.noreply.github.com>
* feat(combobox): open on enter and select active with tab
* feat(combobox): open popup with arrow down/up
* refactor(autocomplete): update isExpanded check for keydown
* feat(combobox): apply data-disabled for item for correct styles
* feat(autocomplete): apply data-disabled for item for correct styles
* feat(combobox): add custom placeholder and value template
* add placeholder to combobox-value
* add buttonId to the combobox trigger
* improve combobox trigger a11y
* feat(select): refactor select brain/helm
* refactor(select): comment out select
* feat(select): add more examples
* feat(select): add placeholder input to hlmSelectValue
* feat(select): add placeholder text for select value and custom placeholder
* feat(select): add select values
* feat(select): add select-value-template
* feat(select): handle scroll up/down elements
* feat(pagination): use hlm-select
* feat: update snapshot
* fix: lint
* fix(select): update hidden access
* feat(select): update on ai review
* feat(select): add migration and healthcheck
* feat(select): set active item on open, either first or the selected value
* for multiple the last value
* feat(select): make scroll up/down smoother and add showScroll to select content
* feat(calendar): change selectof for month/year select
* feat(select): remove unused importAlias from select migration
* feat(select): dogfeed migration
* fix(select): use placeholder from brn-select
* feat(select): improve keyboard navigations
* open on enter
* select active item on tab
* feat(select): more dogfeeding of the migration, fix placeholder replacement
* fix(select): healthcheck test, as BrnSelectImports is removed w/ brnSelect migration
* fix: lint
* feat(select): improve a11y and update tests
* feat(select): update snapshot
* fix(select): allow empty string to be resolved