Commit Graph

232 Commits

Author SHA1 Message Date
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
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
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 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
Marc Stammerjohann a0687ae64b feat(popover): add header, title and description 2026-06-16 17:21:28 +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
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 90d06b2f1b feat(native-select): update option and optgroup selector 2026-06-15 11:23:37 +02:00
Ashley Hunter 85bc4b74a2 test(repo): refresh ui-docs API snapshot for prefixed avatar exportAs
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.
2026-06-15 00:05:00 +01:00
Ashley Hunter f94c1377a2 test(drawer): regenerate ui-docs snapshot after HlmDrawerHandle removal 2026-06-14 21:42:43 +01:00
mehrabix 94a57f4eee Merge remote-tracking branch 'origin/main' into feat/drawer-component 2026-06-14 18:49:54 +03:30
Patrick 803614a7bb test: update overlay api snapshots 2026-06-13 14:48:23 -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
mehrabix ff7a32df01 fix(cli): update generate-ui-docs snapshot for drawer component 2026-06-13 21:31:31 +03:30
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 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
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 a7e225c1fd feat(alert-dialog): add style support, rtl and more examples, add BrnDialogClose to hlmAlertDialogCancel (#1450)
* feat(alert-dialog): add style support, add BrnDialogClose to hlmAlertDialogCancel

* feat(alert-dialog): add rtl and more examples

* docs(alert-dialog): fix text

* feat(alert-dialog): align dialog width

* feat(alert-dialog): update snapshot

* chore: update snapshot comment
2026-06-11 12:01:07 +02:00
Ashley Hunter 447bc8afc1 test: regenerate ui docs snapshot for collapsible exportAs
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.
2026-06-10 18:24:28 +01:00
Ashley Hunter 63bf4fe4f1 fix(cli): emit CommonJS so generators load in compat mode
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
2026-06-10 12:59:38 +01:00
Robin Goetz fc8c037add feat(mcp): release and version mcp server alongside cli and brain (#1448)
* 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.
2026-06-10 09:58:55 +02:00
Marc Stammerjohann 34e835e843 feat: update duplicate outputs, replace ngModel (#1428)
* feat: migrate duplicate output from model + output to input + linkedSignal + output, closes #1385

# Conflicts:
#	libs/helm/switch/src/lib/hlm-switch.ts

* feat(pagination): replace ngModel

* fix(toggle-group): select fires twice onChange and change.emit

* feat: rename value/checked input and linkedSignal
2026-06-09 18:51:22 +02:00
Ashley Hunter d872c74580 feat(switch): add size input
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.
2026-06-09 08:35:41 +01:00
Marc Stammerjohann 0691967e14 feat(date-picker): add date picker input (#1427)
* 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>
2026-06-08 22:24:10 +02:00
Ashley Hunter d4da582d40 feat(repo)!: upgrade nx to 22 and angular to 21 (#1430)
* 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.
2026-06-08 22:23:45 +02:00
Marc Stammerjohann 9a1d9baf3b feat(date-picker): add date-picker-trigger, use button styles (#1390)
* 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
2026-06-08 09:58:17 +02:00
goetzrobin dc32440b21 chore: fix stale and misattributed entries in the 300
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.
2026-06-04 14:45:32 +02:00
moosme 7bd4482127 Merge pull request #1379 from marcjulian/feat/style-support
feat: add style support, update combobox empty, clear button autocomplete/combobox
2026-06-03 15:43:34 +02:00
Ashley Hunter ef2342aae2 feat: add "Open in StackBlitz" to component examples (#1381)
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
2026-06-03 12:03:09 +02:00
Marc Stammerjohann 7e9393aa1d feat(select): add style support, add forceInvalid, add rtl and invalid example 2026-06-03 11:28:45 +02:00
Marc Stammerjohann 3d0ee7f634 feat(combobox): add forceInvalid and invalid example 2026-06-02 13:42:40 +02:00
Marc Stammerjohann 9e527ee1a2 feat: add style support to native-select, sonner, field (#1375)
* 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
2026-06-01 14:09:41 +02:00
Marc Stammerjohann 0c34b49ec1 feat(combobox): update snapshot 2026-05-28 14:42:26 +02:00
Merlin 766a85d5ad fix: snapshot 2026-05-20 13:28:39 +02:00
Marc Stammerjohann ae85c62f14 feat: support styles for input, input-group and textarea (#1352)
* feat(textarea): support styles, remove error variants, update examples

* feat(input): support styles, remove error variants, more examples

* update sidebar-input

* feat(input-group): support styles, update examples

* feat: update snaphot

* feat(input-group): remove invalid state as css selector check for descendant

* fix(input): test

* chore: update hlm files

* fix(input): lint issues

* fix(input): update tests, classes are now applied via spartan-input and in cli copied
2026-05-07 15:56:38 +02:00
Marc Stammerjohann 8b3232638d feat: add style support for empty, label and input-otp (#1350)
* 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
2026-05-05 17:04:01 +02:00
Marc Stammerjohann f585b9e2e5 feat: track autocomplete/combox/select input/trigger width (#1336)
* feat(select): track trigger width changes

* feat(combobox): track input width changes

* feat(autocomplete): track input width changes

* feat: update snapshot

* feat: use injectElementSize to track input/trigger width changes

* feat: add getBoundingClientRect() as fallback for potential offsetWidth = 0 in safari

* feat: update snapshot
2026-04-30 15:00:36 +02:00
Phuong Tran Dong 4f80f29ccf fix(pagination): redundant spacing of pagination element (#1339)
* fix(pagination): redundant spacing of pagination element

* fix(pagination): template

* fix(pagination): update executor snapshot
2026-04-30 14:29:21 +02:00
Dafnik c74a13a55a fix: align components with input ids (#1312)
* fix: align components with input ids

related to #1286

* feat: add hlm input id rename generator
2026-04-28 14:25:10 +02:00
moosme 28fb0fbb0c feat: add hlm card token (#1332)
* feat: add hlm card token

* fix: move type to token file

* fix: update snap

---------

Co-authored-by: Merlin <merlin.moos@oldendorff.com>
2026-04-27 17:27:10 +02:00
Marc Stammerjohann 6feff236bc feat: add rtl example and style support (#1331)
* 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
2026-04-27 16:03:06 +02:00
Marc Stammerjohann d14aff5d9a feat(toggle): add style support, update and add rtl example (#1327)
* feat(toggle): add style support, update and add rtl example

* docs(toggle): update examples, cleanup vega styles and update snapshot

* docs(toggle): remove unused code snippets

* chore: copy hlm to cli
2026-04-23 16:06:34 +02:00
Marc Stammerjohann 22d5635f5c refactor(table): simplify table directive classes (#1325)
* 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
2026-04-21 16:52:40 +02:00
Marc Stammerjohann 76de8e4f7a chore: ignore dependabot from contributors 2026-04-14 13:01:06 +02:00
Marc Stammerjohann d1eea0ca29 feat: skeleton and table style support and examples (#1315)
* feat(skeleton): support styles, add more examples and rtl

* feat(table): support styles, update selectors, add more examples and rtl

* docs: cleanup key
2026-04-14 09:51:11 +02:00
Marc Stammerjohann 761949c989 docs: update accordion trigger usage 2026-04-08 10:44:35 +02:00