@vadem/ui 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +88 -8
- package/fesm2022/vadem-ui-menu.mjs +21 -1
- package/fesm2022/vadem-ui-menu.mjs.map +1 -1
- package/fesm2022/vadem-ui-select.mjs +10 -13
- package/fesm2022/vadem-ui-select.mjs.map +1 -1
- package/fesm2022/vadem-ui.mjs +1 -1
- package/fesm2022/vadem-ui.mjs.map +1 -1
- package/package.json +25 -1
- package/styles/components/file-preview.css +5 -0
- package/types/vadem-ui-menu.d.ts +2 -0
- package/types/vadem-ui-select.d.ts +1 -2
- package/types/vadem-ui.d.ts +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vasyl Demchuk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,20 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Vadem UI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@vadem/ui)
|
|
4
|
+
[](https://github.com/Demchuk12/vadem-ui-angular/actions/workflows/ci.yml)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
A modern Angular component library for forms, dashboards, and data-rich applications.
|
|
7
|
+
Vadem combines a consistent visual language with native HTML semantics, reusable CSS
|
|
8
|
+
design tokens, and components built with standalone APIs, signals, and OnPush change detection.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Components for everyday product UI:** buttons, form controls, selects, calendars,
|
|
13
|
+
dialogs, notifications, navigation, tables, charts, and file interactions.
|
|
14
|
+
- **Dark and light themes:** a shared token system for colors, typography, spacing,
|
|
15
|
+
shape, and motion, customizable through CSS custom properties.
|
|
16
|
+
- **Accessibility-focused interactions:** keyboard navigation, focus management,
|
|
17
|
+
ARIA semantics, and support for reduced motion and forced colors where applicable.
|
|
18
|
+
- **Localization:** English and Ukrainian locale packs, with RTL-aware layouts and controls.
|
|
19
|
+
- **Angular forms:** native controls and custom value accessors where appropriate,
|
|
20
|
+
with Reactive Forms and Signal Forms examples in the gallery.
|
|
21
|
+
- **Plain CSS:** no Tailwind or third-party UI framework; shared styles are independent
|
|
22
|
+
of Angular view encapsulation.
|
|
23
|
+
- **Bundled assets:** self-hosted Manrope and JetBrains Mono fonts, plus a vendored Lucide
|
|
24
|
+
icon subset. No runtime font or icon CDN is required.
|
|
25
|
+
- **Separate entry points:** import the components you need from `@vadem/ui/button`,
|
|
26
|
+
`@vadem/ui/dialog`, and other component-specific paths.
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
Angular **22.2 or later within major version 22**, matching the package's peer dependencies.
|
|
31
|
+
Browser targets: the last two Chrome, Edge, and Firefox versions, and Safari 26+.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npm install @vadem/ui
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Add the shared stylesheet to your application's global CSS:
|
|
7
40
|
|
|
8
41
|
```css
|
|
9
42
|
@import '@vadem/ui/styles.css';
|
|
10
43
|
```
|
|
11
44
|
|
|
12
|
-
|
|
45
|
+
## Quick start
|
|
13
46
|
|
|
14
47
|
```ts
|
|
48
|
+
import { Component } from '@angular/core';
|
|
15
49
|
import { VdButton } from '@vadem/ui/button';
|
|
50
|
+
|
|
51
|
+
@Component({
|
|
52
|
+
selector: 'app-root',
|
|
53
|
+
imports: [VdButton],
|
|
54
|
+
template: `<button vdButton variant="primary">Save changes</button>`,
|
|
55
|
+
})
|
|
56
|
+
export class App {}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Themes and customization
|
|
60
|
+
|
|
61
|
+
Apply a theme to the document or a section of your application:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<html data-theme="dark"></html>
|
|
16
65
|
```
|
|
17
66
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
67
|
+
Use `data-theme="light"` for light mode or `data-theme="auto"` to follow the system preference.
|
|
68
|
+
Customize the accent through the shared token:
|
|
69
|
+
|
|
70
|
+
```css
|
|
71
|
+
:root {
|
|
72
|
+
--vd-hue-accent: 270;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Documentation and examples
|
|
77
|
+
|
|
78
|
+
- [Source repository](https://github.com/Demchuk12/vadem-ui-angular)
|
|
79
|
+
- [Component contracts](https://github.com/Demchuk12/vadem-ui-angular/tree/main/specs)
|
|
80
|
+
- [Demo gallery source](https://github.com/Demchuk12/vadem-ui-angular/tree/main/projects/demo)
|
|
81
|
+
- [Issues](https://github.com/Demchuk12/vadem-ui-angular/issues)
|
|
82
|
+
|
|
83
|
+
To explore the gallery locally, clone the repository, run `npm ci`, then `npm start`.
|
|
84
|
+
|
|
85
|
+
## Release status
|
|
86
|
+
|
|
87
|
+
Vadem UI is in early development. APIs may change between releases before version 1.0.
|
|
88
|
+
|
|
89
|
+
## Third-party assets
|
|
90
|
+
|
|
91
|
+
Manrope and JetBrains Mono are distributed under SIL OFL 1.1; their notices are included
|
|
92
|
+
in `fonts/`. Lucide icon geometry is distributed under ISC; see `LICENSE-lucide.txt`.
|
|
93
|
+
|
|
94
|
+
Getting started and copyable application examples: [usage guide](https://github.com/Demchuk12/vadem-ui-angular/blob/main/docs/GETTING_STARTED.md).
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
Vadem's own code is licensed under the MIT License; see `LICENSE` in the package.
|
|
99
|
+
Third-party fonts, icon geometry, and vendored design skills retain their respective licenses
|
|
100
|
+
and notices; they are not relicensed by the Vadem license.
|
|
@@ -479,18 +479,38 @@ var VdContextMenu = class VdContextMenu {
|
|
|
479
479
|
el = inject(ElementRef).nativeElement;
|
|
480
480
|
doc = inject(DOCUMENT);
|
|
481
481
|
entry = null;
|
|
482
|
+
pendingPointerOpen = null;
|
|
482
483
|
pressTimer;
|
|
483
484
|
constructor() {
|
|
484
485
|
inject(DestroyRef).onDestroy(() => {
|
|
485
486
|
clearTimeout(this.pressTimer);
|
|
487
|
+
this.cancelPointerOpen();
|
|
486
488
|
if (this.entry) release(this.vdContextMenu());
|
|
487
489
|
});
|
|
488
490
|
}
|
|
489
491
|
onContextMenu(event) {
|
|
490
492
|
if (event.shiftKey && event.button === 2) return;
|
|
491
493
|
event.preventDefault();
|
|
492
|
-
this.
|
|
494
|
+
this.cancelPointerOpen();
|
|
495
|
+
const { clientX: x, clientY: y } = event;
|
|
496
|
+
const origin = event.target;
|
|
497
|
+
if (event.buttons & 2) {
|
|
498
|
+
this.pendingPointerOpen = (release) => {
|
|
499
|
+
if (release.button !== 2) return;
|
|
500
|
+
this.cancelPointerOpen();
|
|
501
|
+
if (origin.isConnected) this.openAt(x, y, origin);
|
|
502
|
+
};
|
|
503
|
+
this.doc.addEventListener("pointerup", this.pendingPointerOpen);
|
|
504
|
+
this.doc.addEventListener("pointercancel", this.cancelPointerOpen);
|
|
505
|
+
} else this.openAt(x, y, origin);
|
|
493
506
|
}
|
|
507
|
+
cancelPointerOpen = () => {
|
|
508
|
+
if (this.pendingPointerOpen) {
|
|
509
|
+
this.doc.removeEventListener("pointerup", this.pendingPointerOpen);
|
|
510
|
+
this.pendingPointerOpen = null;
|
|
511
|
+
}
|
|
512
|
+
this.doc.removeEventListener("pointercancel", this.cancelPointerOpen);
|
|
513
|
+
};
|
|
494
514
|
onKeydown(event) {
|
|
495
515
|
if (!(event.key === "ContextMenu" || event.shiftKey && event.key === "F10")) return;
|
|
496
516
|
event.preventDefault();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui-menu.mjs","names":[],"sources":["../../../projects/ui/menu/src/core/menu-controller.ts","../../../projects/ui/menu/src/menu.ts","../../../projects/ui/menu/src/context-menu.ts"],"sourcesContent":["/**\n * Framework-agnostic menu button (APG): trigger + `popover=\"auto\"` menu. Focus moves into the\n * menu (roving focus over items), arrows loop, typeahead jumps, activation or Escape closes and\n * returns focus to the trigger, Tab closes and lets focus move on.\n */\nimport { VdTypeahead, vdListTarget } from '@vadem/ui/keyboard';\n\nexport interface VdMenuControllerOptions {\n /** Items in DOM order (role=\"menuitem\", including disabled ones). */\n items(): HTMLElement[];\n onOpenChange?(open: boolean): void;\n /** Where focus returns on close; defaults to the trigger (context menus return to the opener). */\n returnFocusTo?(): HTMLElement | null;\n}\n\nconst ITEM = '[role=\"menuitem\"]';\n\nfunction isDisabled(el: HTMLElement): boolean {\n return el.getAttribute('aria-disabled') === 'true' || (el as HTMLButtonElement).disabled;\n}\n\nexport class VdMenuController {\n private readonly typeahead = new VdTypeahead();\n private returnFocus = false;\n /** Light dismiss closes on pointerdown over the trigger; the click must not reopen. */\n private wasOpen = false;\n\n constructor(\n private readonly trigger: HTMLElement,\n private readonly menu: HTMLElement,\n private readonly options: VdMenuControllerOptions,\n ) {\n trigger.addEventListener('pointerdown', this.onTriggerPointerDown);\n trigger.addEventListener('click', this.onTriggerClick);\n trigger.addEventListener('keydown', this.onTriggerKeydown);\n menu.addEventListener('keydown', this.onMenuKeydown);\n menu.addEventListener('click', this.onMenuClick);\n menu.addEventListener('pointermove', this.onPointerMove);\n menu.addEventListener('toggle', this.onToggle);\n }\n\n get isOpen(): boolean {\n return this.menu.matches(':popover-open');\n }\n\n open(focus: 'first' | 'last' = 'first'): void {\n if (!this.isOpen) {\n this.menu.showPopover({ source: this.trigger } as ShowPopoverOptions);\n this.options.onOpenChange?.(true);\n }\n const items = this.enabledItems();\n (focus === 'first' ? items[0] : items[items.length - 1])?.focus();\n }\n\n close(returnFocus: boolean): void {\n this.returnFocus = returnFocus;\n if (this.isOpen) this.menu.hidePopover();\n }\n\n destroy(): void {\n this.trigger.removeEventListener('pointerdown', this.onTriggerPointerDown);\n this.trigger.removeEventListener('click', this.onTriggerClick);\n this.trigger.removeEventListener('keydown', this.onTriggerKeydown);\n this.menu.removeEventListener('keydown', this.onMenuKeydown);\n this.menu.removeEventListener('click', this.onMenuClick);\n this.menu.removeEventListener('pointermove', this.onPointerMove);\n this.menu.removeEventListener('toggle', this.onToggle);\n }\n\n private enabledItems(): HTMLElement[] {\n return this.options.items().filter((i) => !isDisabled(i));\n }\n\n private readonly onTriggerPointerDown = () => {\n this.wasOpen = this.isOpen;\n };\n\n private readonly onTriggerClick = (event: MouseEvent) => {\n if (this.wasOpen || this.isOpen) {\n this.wasOpen = false;\n this.close(false);\n return;\n }\n // Enter/Space are handled in keydown (and prevented), so this is a pointer click.\n this.open('first');\n event.preventDefault();\n };\n\n private readonly onTriggerKeydown = (event: KeyboardEvent) => {\n const { key } = event;\n if (key === 'ArrowDown' || key === 'Enter' || key === ' ') {\n event.preventDefault();\n this.open('first');\n } else if (key === 'ArrowUp') {\n event.preventDefault();\n this.open('last');\n }\n };\n\n private readonly onMenuKeydown = (event: KeyboardEvent) => {\n const items = this.options.items();\n const current = items.indexOf(event.target as HTMLElement);\n const { key } = event;\n\n if (key === 'Escape') {\n event.preventDefault();\n this.close(true);\n return;\n }\n if (key === 'Tab') {\n this.close(false);\n return;\n }\n const target = vdListTarget(key, current, items.map(isDisabled), { loop: true, pageSize: 10 });\n if (target !== null) {\n event.preventDefault();\n items[target]?.focus();\n return;\n }\n if (VdTypeahead.accepts(event)) {\n const idx = this.typeahead.match(\n key,\n items.map((i) => i.textContent?.trim() ?? ''),\n items.map(isDisabled),\n current,\n );\n if (idx !== null) items[idx]?.focus();\n }\n };\n\n private readonly onMenuClick = (event: MouseEvent) => {\n const item = (event.target as Element).closest<HTMLElement>(ITEM);\n if (!item || !this.menu.contains(item)) return;\n if (isDisabled(item)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return;\n }\n // Item handlers already ran (bubbling reached the menu): close and restore focus.\n this.close(true);\n };\n\n /** Pointer and keyboard share one \"current\" item: hovering focuses it. */\n private readonly onPointerMove = (event: PointerEvent) => {\n if (event.pointerType === 'touch') return;\n const item = (event.target as Element).closest<HTMLElement>(ITEM);\n if (item && !isDisabled(item) && item !== this.menu.ownerDocument.activeElement) item.focus();\n };\n\n private readonly onToggle = (event: Event) => {\n if ((event as ToggleEvent).newState !== 'closed') return;\n this.typeahead.reset();\n this.options.onOpenChange?.(false);\n if (this.returnFocus) (this.options.returnFocusTo?.() ?? this.trigger).focus();\n this.returnFocus = false;\n };\n}\n","import {\n DestroyRef,\n Directive,\n ElementRef,\n afterNextRender,\n booleanAttribute,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdMenuController } from './core/menu-controller';\n\n/** Menu panel: a `popover=\"auto\"` with `role=\"menu\"`. Open it with `vdMenuTrigger`. */\n@Directive({\n selector: '[vdMenu]',\n exportAs: 'vdMenu',\n host: {\n class: 'vd-menu',\n role: 'menu',\n popover: 'auto',\n tabindex: '-1',\n '[id]': 'id',\n '[attr.aria-labelledby]': 'labelledBy()',\n },\n})\nexport class VdMenu {\n readonly id = vdUniqueId('vd-menu');\n readonly el: HTMLElement = inject(ElementRef).nativeElement;\n readonly labelledBy = signal<string | null>(null);\n\n items(): HTMLElement[] {\n return Array.from(this.el.querySelectorAll<HTMLElement>('[role=\"menuitem\"]'));\n }\n}\n\n/** Opens a `vdMenu`. Use on a button (works with `vdButton`). Spec: specs/menu.md */\n@Directive({\n selector: 'button[vdMenuTrigger]',\n host: {\n 'aria-haspopup': 'menu',\n '[attr.aria-expanded]': 'open()',\n '[attr.aria-controls]': 'vdMenuTrigger().id',\n '[attr.data-state]': 'open() ? \"open\" : \"closed\"',\n },\n})\nexport class VdMenuTrigger {\n readonly vdMenuTrigger = input.required<VdMenu>();\n protected readonly open = signal(false);\n private readonly el: HTMLButtonElement = inject(ElementRef).nativeElement;\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n afterNextRender(() => {\n const menu = this.vdMenuTrigger();\n if (!this.el.id) this.el.id = vdUniqueId('vd-menu-trigger');\n menu.labelledBy.set(this.el.id);\n const name = `--${menu.id}`;\n this.el.style.setProperty('anchor-name', name);\n menu.el.style.setProperty('position-anchor', name);\n const controller = new VdMenuController(this.el, menu.el, {\n items: () => menu.items(),\n onOpenChange: (open) => this.open.set(open),\n });\n destroyRef.onDestroy(() => controller.destroy());\n });\n }\n}\n\nexport type VdMenuItemVariant = 'default' | 'danger';\n\n@Directive({\n selector: 'button[vdMenuItem], a[vdMenuItem]',\n host: {\n class: 'vd-menu__item',\n role: 'menuitem',\n tabindex: '-1',\n '[attr.type]': 'isButton ? \"button\" : null',\n '[attr.data-variant]': 'variant()',\n '[attr.aria-disabled]': 'disabled() || null',\n },\n})\nexport class VdMenuItem {\n readonly variant = input<VdMenuItemVariant>('default');\n /** Disabled items stay in the menu (discoverable) but are skipped and inert. */\n readonly disabled = input(false, { transform: booleanAttribute });\n protected readonly isButton =\n (inject(ElementRef).nativeElement as HTMLElement).tagName === 'BUTTON';\n}\n\n@Directive({\n selector: '[vdMenuSeparator]',\n host: { class: 'vd-menu__separator', role: 'separator' },\n})\nexport class VdMenuSeparator {}\n\n/** Group heading inside a menu (mono eyebrow). Presentational. */\n@Directive({\n selector: '[vdMenuLabel]',\n host: { class: 'vd-menu__label', role: 'presentation' },\n})\nexport class VdMenuLabel {}\n\nexport const VD_MENU = [VdMenu, VdMenuTrigger, VdMenuItem, VdMenuSeparator, VdMenuLabel] as const;\n","import { DOCUMENT } from '@angular/common';\nimport { DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { vdTexts } from '@vadem/ui/locale';\nimport { VdMenuController } from './core/menu-controller';\nimport type { VdMenu } from './menu';\n\n/** Touch hold that opens the menu where `contextmenu` does not fire (iOS Safari). */\nconst LONG_PRESS_MS = 500;\nconst LONG_PRESS_SLOP = 10;\n\n/** One controller and one virtual anchor per menu, shared by every region that opens it. */\ninterface Shared {\n anchor: HTMLElement;\n controller: VdMenuController;\n opener: HTMLElement | null;\n users: number;\n}\nconst shared = new WeakMap<HTMLElement, Shared>();\n\nfunction acquire(menu: VdMenu, doc: Document): Shared {\n let entry = shared.get(menu.el);\n if (!entry) {\n const anchor = doc.createElement('span');\n anchor.className = 'vd-context-menu__anchor';\n anchor.setAttribute('aria-hidden', 'true');\n const name = `--${vdUniqueId('vd-context-anchor')}`;\n anchor.style.setProperty('anchor-name', name);\n menu.el.style.setProperty('position-anchor', name);\n // Next to the menu, so it shares any dialog's top layer and inert state.\n (menu.el.parentElement ?? doc.body).appendChild(anchor);\n const created: Shared = {\n anchor,\n opener: null,\n users: 0,\n controller: new VdMenuController(anchor, menu.el, {\n items: () => menu.items(),\n returnFocusTo: () => created.opener,\n }),\n };\n entry = created;\n shared.set(menu.el, entry);\n }\n entry.users++;\n return entry;\n}\n\nfunction release(menu: VdMenu): void {\n const entry = shared.get(menu.el);\n if (!entry || --entry.users > 0) return;\n entry.controller.destroy();\n entry.anchor.remove();\n shared.delete(menu.el);\n}\n\n/**\n * Opens a `vdMenu` at the pointer on right-click / long-press, or at the focused element on\n * the ContextMenu key and Shift+F10. Spec: specs/menu.md\n */\n@Directive({\n selector: '[vdContextMenu]',\n host: {\n class: 'vd-context-menu-target',\n '(contextmenu)': 'onContextMenu($event)',\n '(keydown)': 'onKeydown($event)',\n '(pointerdown)': 'onPointerDown($event)',\n },\n})\nexport class VdContextMenu {\n readonly vdContextMenu = input.required<VdMenu>();\n /** Accessible name of the menu while this region opened it. */\n readonly label = input<string>();\n /** Fires before the menu opens, so the consumer can point it at this region's item. */\n readonly opened = output<void>();\n\n protected readonly t = vdTexts('contextMenu', { label: this.label });\n private readonly el: HTMLElement = inject(ElementRef).nativeElement;\n private readonly doc = inject(DOCUMENT);\n private entry: Shared | null = null;\n private pressTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.pressTimer);\n if (this.entry) release(this.vdContextMenu());\n });\n }\n\n protected onContextMenu(event: MouseEvent): void {\n // Shift+right-click keeps the browser's own menu (copy, inspect) available.\n if (event.shiftKey && event.button === 2) return;\n event.preventDefault();\n this.openAt(event.clientX, event.clientY, event.target as HTMLElement);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const keyboardMenu = event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10');\n if (!keyboardMenu) return;\n event.preventDefault();\n const target = (event.target as HTMLElement) ?? this.el;\n const rect = target.getBoundingClientRect();\n const rtl = this.doc.defaultView?.getComputedStyle(target).direction === 'rtl';\n this.openAt(rtl ? rect.right : rect.left, rect.bottom, target);\n }\n\n protected onPointerDown(event: PointerEvent): void {\n if (event.pointerType !== 'touch') return;\n const { clientX: x, clientY: y } = event;\n const target = event.target as HTMLElement;\n const cancel = (e?: PointerEvent) => {\n if (\n e &&\n e.type === 'pointermove' &&\n Math.hypot(e.clientX - x, e.clientY - y) < LONG_PRESS_SLOP\n )\n return;\n clearTimeout(this.pressTimer);\n this.el.removeEventListener('pointermove', cancel);\n this.el.removeEventListener('pointerup', cancel);\n this.el.removeEventListener('pointercancel', cancel);\n };\n this.el.addEventListener('pointermove', cancel);\n this.el.addEventListener('pointerup', cancel);\n this.el.addEventListener('pointercancel', cancel);\n clearTimeout(this.pressTimer);\n this.pressTimer = setTimeout(() => {\n cancel();\n this.openAt(x, y, target);\n }, LONG_PRESS_MS);\n }\n\n private openAt(x: number, y: number, origin: HTMLElement): void {\n const menu = this.vdContextMenu();\n this.entry ??= acquire(menu, this.doc);\n // Android also fires contextmenu after a long press; one opening is enough.\n if (this.entry.controller.isOpen && this.entry.opener === this.focusable(origin)) return;\n this.opened.emit();\n this.entry.opener = this.focusable(origin);\n this.place(this.entry.anchor, x, y);\n menu.el.setAttribute('aria-label', this.t().label);\n menu.labelledBy.set(null);\n this.entry.controller.close(false);\n this.entry.controller.open('first');\n }\n\n /**\n * Puts the zero-size anchor at viewport point (x, y). An ancestor with a transform, filter or\n * container query becomes the fixed containing block, so the first guess is measured and\n * corrected by the difference. Insets stay logical: in RTL inline-start grows leftwards.\n */\n private place(anchor: HTMLElement, x: number, y: number): void {\n const rtl = this.doc.defaultView?.getComputedStyle(anchor).direction === 'rtl';\n let inline = rtl ? this.doc.documentElement.clientWidth - x : x;\n let block = y;\n const set = () => {\n anchor.style.setProperty('--vd-context-x', `${inline}px`);\n anchor.style.setProperty('--vd-context-y', `${block}px`);\n };\n set();\n const rect = anchor.getBoundingClientRect();\n inline += rtl ? rect.left - x : x - rect.left;\n block += y - rect.top;\n set();\n }\n\n /** Focus returns to the nearest focusable element of this region, or the region itself. */\n private focusable(origin: HTMLElement): HTMLElement {\n const candidate = origin.closest<HTMLElement>(\n 'a[href], button, input, select, textarea, [tabindex]',\n );\n return candidate && this.el.contains(candidate) ? candidate : this.el;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vadem-ui-menu.mjs","names":[],"sources":["../../../projects/ui/menu/src/core/menu-controller.ts","../../../projects/ui/menu/src/menu.ts","../../../projects/ui/menu/src/context-menu.ts"],"sourcesContent":["/**\n * Framework-agnostic menu button (APG): trigger + `popover=\"auto\"` menu. Focus moves into the\n * menu (roving focus over items), arrows loop, typeahead jumps, activation or Escape closes and\n * returns focus to the trigger, Tab closes and lets focus move on.\n */\nimport { VdTypeahead, vdListTarget } from '@vadem/ui/keyboard';\n\nexport interface VdMenuControllerOptions {\n /** Items in DOM order (role=\"menuitem\", including disabled ones). */\n items(): HTMLElement[];\n onOpenChange?(open: boolean): void;\n /** Where focus returns on close; defaults to the trigger (context menus return to the opener). */\n returnFocusTo?(): HTMLElement | null;\n}\n\nconst ITEM = '[role=\"menuitem\"]';\n\nfunction isDisabled(el: HTMLElement): boolean {\n return el.getAttribute('aria-disabled') === 'true' || (el as HTMLButtonElement).disabled;\n}\n\nexport class VdMenuController {\n private readonly typeahead = new VdTypeahead();\n private returnFocus = false;\n /** Light dismiss closes on pointerdown over the trigger; the click must not reopen. */\n private wasOpen = false;\n\n constructor(\n private readonly trigger: HTMLElement,\n private readonly menu: HTMLElement,\n private readonly options: VdMenuControllerOptions,\n ) {\n trigger.addEventListener('pointerdown', this.onTriggerPointerDown);\n trigger.addEventListener('click', this.onTriggerClick);\n trigger.addEventListener('keydown', this.onTriggerKeydown);\n menu.addEventListener('keydown', this.onMenuKeydown);\n menu.addEventListener('click', this.onMenuClick);\n menu.addEventListener('pointermove', this.onPointerMove);\n menu.addEventListener('toggle', this.onToggle);\n }\n\n get isOpen(): boolean {\n return this.menu.matches(':popover-open');\n }\n\n open(focus: 'first' | 'last' = 'first'): void {\n if (!this.isOpen) {\n this.menu.showPopover({ source: this.trigger } as ShowPopoverOptions);\n this.options.onOpenChange?.(true);\n }\n const items = this.enabledItems();\n (focus === 'first' ? items[0] : items[items.length - 1])?.focus();\n }\n\n close(returnFocus: boolean): void {\n this.returnFocus = returnFocus;\n if (this.isOpen) this.menu.hidePopover();\n }\n\n destroy(): void {\n this.trigger.removeEventListener('pointerdown', this.onTriggerPointerDown);\n this.trigger.removeEventListener('click', this.onTriggerClick);\n this.trigger.removeEventListener('keydown', this.onTriggerKeydown);\n this.menu.removeEventListener('keydown', this.onMenuKeydown);\n this.menu.removeEventListener('click', this.onMenuClick);\n this.menu.removeEventListener('pointermove', this.onPointerMove);\n this.menu.removeEventListener('toggle', this.onToggle);\n }\n\n private enabledItems(): HTMLElement[] {\n return this.options.items().filter((i) => !isDisabled(i));\n }\n\n private readonly onTriggerPointerDown = () => {\n this.wasOpen = this.isOpen;\n };\n\n private readonly onTriggerClick = (event: MouseEvent) => {\n if (this.wasOpen || this.isOpen) {\n this.wasOpen = false;\n this.close(false);\n return;\n }\n // Enter/Space are handled in keydown (and prevented), so this is a pointer click.\n this.open('first');\n event.preventDefault();\n };\n\n private readonly onTriggerKeydown = (event: KeyboardEvent) => {\n const { key } = event;\n if (key === 'ArrowDown' || key === 'Enter' || key === ' ') {\n event.preventDefault();\n this.open('first');\n } else if (key === 'ArrowUp') {\n event.preventDefault();\n this.open('last');\n }\n };\n\n private readonly onMenuKeydown = (event: KeyboardEvent) => {\n const items = this.options.items();\n const current = items.indexOf(event.target as HTMLElement);\n const { key } = event;\n\n if (key === 'Escape') {\n event.preventDefault();\n this.close(true);\n return;\n }\n if (key === 'Tab') {\n this.close(false);\n return;\n }\n const target = vdListTarget(key, current, items.map(isDisabled), { loop: true, pageSize: 10 });\n if (target !== null) {\n event.preventDefault();\n items[target]?.focus();\n return;\n }\n if (VdTypeahead.accepts(event)) {\n const idx = this.typeahead.match(\n key,\n items.map((i) => i.textContent?.trim() ?? ''),\n items.map(isDisabled),\n current,\n );\n if (idx !== null) items[idx]?.focus();\n }\n };\n\n private readonly onMenuClick = (event: MouseEvent) => {\n const item = (event.target as Element).closest<HTMLElement>(ITEM);\n if (!item || !this.menu.contains(item)) return;\n if (isDisabled(item)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return;\n }\n // Item handlers already ran (bubbling reached the menu): close and restore focus.\n this.close(true);\n };\n\n /** Pointer and keyboard share one \"current\" item: hovering focuses it. */\n private readonly onPointerMove = (event: PointerEvent) => {\n if (event.pointerType === 'touch') return;\n const item = (event.target as Element).closest<HTMLElement>(ITEM);\n if (item && !isDisabled(item) && item !== this.menu.ownerDocument.activeElement) item.focus();\n };\n\n private readonly onToggle = (event: Event) => {\n if ((event as ToggleEvent).newState !== 'closed') return;\n this.typeahead.reset();\n this.options.onOpenChange?.(false);\n if (this.returnFocus) (this.options.returnFocusTo?.() ?? this.trigger).focus();\n this.returnFocus = false;\n };\n}\n","import {\n DestroyRef,\n Directive,\n ElementRef,\n afterNextRender,\n booleanAttribute,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdMenuController } from './core/menu-controller';\n\n/** Menu panel: a `popover=\"auto\"` with `role=\"menu\"`. Open it with `vdMenuTrigger`. */\n@Directive({\n selector: '[vdMenu]',\n exportAs: 'vdMenu',\n host: {\n class: 'vd-menu',\n role: 'menu',\n popover: 'auto',\n tabindex: '-1',\n '[id]': 'id',\n '[attr.aria-labelledby]': 'labelledBy()',\n },\n})\nexport class VdMenu {\n readonly id = vdUniqueId('vd-menu');\n readonly el: HTMLElement = inject(ElementRef).nativeElement;\n readonly labelledBy = signal<string | null>(null);\n\n items(): HTMLElement[] {\n return Array.from(this.el.querySelectorAll<HTMLElement>('[role=\"menuitem\"]'));\n }\n}\n\n/** Opens a `vdMenu`. Use on a button (works with `vdButton`). Spec: specs/menu.md */\n@Directive({\n selector: 'button[vdMenuTrigger]',\n host: {\n 'aria-haspopup': 'menu',\n '[attr.aria-expanded]': 'open()',\n '[attr.aria-controls]': 'vdMenuTrigger().id',\n '[attr.data-state]': 'open() ? \"open\" : \"closed\"',\n },\n})\nexport class VdMenuTrigger {\n readonly vdMenuTrigger = input.required<VdMenu>();\n protected readonly open = signal(false);\n private readonly el: HTMLButtonElement = inject(ElementRef).nativeElement;\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n afterNextRender(() => {\n const menu = this.vdMenuTrigger();\n if (!this.el.id) this.el.id = vdUniqueId('vd-menu-trigger');\n menu.labelledBy.set(this.el.id);\n const name = `--${menu.id}`;\n this.el.style.setProperty('anchor-name', name);\n menu.el.style.setProperty('position-anchor', name);\n const controller = new VdMenuController(this.el, menu.el, {\n items: () => menu.items(),\n onOpenChange: (open) => this.open.set(open),\n });\n destroyRef.onDestroy(() => controller.destroy());\n });\n }\n}\n\nexport type VdMenuItemVariant = 'default' | 'danger';\n\n@Directive({\n selector: 'button[vdMenuItem], a[vdMenuItem]',\n host: {\n class: 'vd-menu__item',\n role: 'menuitem',\n tabindex: '-1',\n '[attr.type]': 'isButton ? \"button\" : null',\n '[attr.data-variant]': 'variant()',\n '[attr.aria-disabled]': 'disabled() || null',\n },\n})\nexport class VdMenuItem {\n readonly variant = input<VdMenuItemVariant>('default');\n /** Disabled items stay in the menu (discoverable) but are skipped and inert. */\n readonly disabled = input(false, { transform: booleanAttribute });\n protected readonly isButton =\n (inject(ElementRef).nativeElement as HTMLElement).tagName === 'BUTTON';\n}\n\n@Directive({\n selector: '[vdMenuSeparator]',\n host: { class: 'vd-menu__separator', role: 'separator' },\n})\nexport class VdMenuSeparator {}\n\n/** Group heading inside a menu (mono eyebrow). Presentational. */\n@Directive({\n selector: '[vdMenuLabel]',\n host: { class: 'vd-menu__label', role: 'presentation' },\n})\nexport class VdMenuLabel {}\n\nexport const VD_MENU = [VdMenu, VdMenuTrigger, VdMenuItem, VdMenuSeparator, VdMenuLabel] as const;\n","import { DOCUMENT } from '@angular/common';\nimport { DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { vdTexts } from '@vadem/ui/locale';\nimport { VdMenuController } from './core/menu-controller';\nimport type { VdMenu } from './menu';\n\n/** Touch hold that opens the menu where `contextmenu` does not fire (iOS Safari). */\nconst LONG_PRESS_MS = 500;\nconst LONG_PRESS_SLOP = 10;\n\n/** One controller and one virtual anchor per menu, shared by every region that opens it. */\ninterface Shared {\n anchor: HTMLElement;\n controller: VdMenuController;\n opener: HTMLElement | null;\n users: number;\n}\nconst shared = new WeakMap<HTMLElement, Shared>();\n\nfunction acquire(menu: VdMenu, doc: Document): Shared {\n let entry = shared.get(menu.el);\n if (!entry) {\n const anchor = doc.createElement('span');\n anchor.className = 'vd-context-menu__anchor';\n anchor.setAttribute('aria-hidden', 'true');\n const name = `--${vdUniqueId('vd-context-anchor')}`;\n anchor.style.setProperty('anchor-name', name);\n menu.el.style.setProperty('position-anchor', name);\n // Next to the menu, so it shares any dialog's top layer and inert state.\n (menu.el.parentElement ?? doc.body).appendChild(anchor);\n const created: Shared = {\n anchor,\n opener: null,\n users: 0,\n controller: new VdMenuController(anchor, menu.el, {\n items: () => menu.items(),\n returnFocusTo: () => created.opener,\n }),\n };\n entry = created;\n shared.set(menu.el, entry);\n }\n entry.users++;\n return entry;\n}\n\nfunction release(menu: VdMenu): void {\n const entry = shared.get(menu.el);\n if (!entry || --entry.users > 0) return;\n entry.controller.destroy();\n entry.anchor.remove();\n shared.delete(menu.el);\n}\n\n/**\n * Opens a `vdMenu` at the pointer on right-click / long-press, or at the focused element on\n * the ContextMenu key and Shift+F10. Spec: specs/menu.md\n */\n@Directive({\n selector: '[vdContextMenu]',\n host: {\n class: 'vd-context-menu-target',\n '(contextmenu)': 'onContextMenu($event)',\n '(keydown)': 'onKeydown($event)',\n '(pointerdown)': 'onPointerDown($event)',\n },\n})\nexport class VdContextMenu {\n readonly vdContextMenu = input.required<VdMenu>();\n /** Accessible name of the menu while this region opened it. */\n readonly label = input<string>();\n /** Fires before the menu opens, so the consumer can point it at this region's item. */\n readonly opened = output<void>();\n\n protected readonly t = vdTexts('contextMenu', { label: this.label });\n private readonly el: HTMLElement = inject(ElementRef).nativeElement;\n private readonly doc = inject(DOCUMENT);\n private entry: Shared | null = null;\n private pendingPointerOpen: ((event: PointerEvent) => void) | null = null;\n private pressTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.pressTimer);\n this.cancelPointerOpen();\n if (this.entry) release(this.vdContextMenu());\n });\n }\n\n protected onContextMenu(event: MouseEvent): void {\n // Shift+right-click keeps the browser's own menu (copy, inspect) available.\n if (event.shiftKey && event.button === 2) return;\n event.preventDefault();\n this.cancelPointerOpen();\n const { clientX: x, clientY: y } = event;\n const origin = event.target as HTMLElement;\n // Some engines dispatch contextmenu before right-button release. Opening an\n // auto popover then lets that same pointerup immediately light-dismiss it.\n if (event.buttons & 2) {\n this.pendingPointerOpen = (release) => {\n if (release.button !== 2) return;\n this.cancelPointerOpen();\n if (origin.isConnected) this.openAt(x, y, origin);\n };\n this.doc.addEventListener('pointerup', this.pendingPointerOpen);\n this.doc.addEventListener('pointercancel', this.cancelPointerOpen);\n } else {\n this.openAt(x, y, origin);\n }\n }\n\n private readonly cancelPointerOpen = (): void => {\n if (this.pendingPointerOpen) {\n this.doc.removeEventListener('pointerup', this.pendingPointerOpen);\n this.pendingPointerOpen = null;\n }\n this.doc.removeEventListener('pointercancel', this.cancelPointerOpen);\n };\n\n protected onKeydown(event: KeyboardEvent): void {\n const keyboardMenu = event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10');\n if (!keyboardMenu) return;\n event.preventDefault();\n const target = (event.target as HTMLElement) ?? this.el;\n const rect = target.getBoundingClientRect();\n const rtl = this.doc.defaultView?.getComputedStyle(target).direction === 'rtl';\n this.openAt(rtl ? rect.right : rect.left, rect.bottom, target);\n }\n\n protected onPointerDown(event: PointerEvent): void {\n if (event.pointerType !== 'touch') return;\n const { clientX: x, clientY: y } = event;\n const target = event.target as HTMLElement;\n const cancel = (e?: PointerEvent) => {\n if (\n e &&\n e.type === 'pointermove' &&\n Math.hypot(e.clientX - x, e.clientY - y) < LONG_PRESS_SLOP\n )\n return;\n clearTimeout(this.pressTimer);\n this.el.removeEventListener('pointermove', cancel);\n this.el.removeEventListener('pointerup', cancel);\n this.el.removeEventListener('pointercancel', cancel);\n };\n this.el.addEventListener('pointermove', cancel);\n this.el.addEventListener('pointerup', cancel);\n this.el.addEventListener('pointercancel', cancel);\n clearTimeout(this.pressTimer);\n this.pressTimer = setTimeout(() => {\n cancel();\n this.openAt(x, y, target);\n }, LONG_PRESS_MS);\n }\n\n private openAt(x: number, y: number, origin: HTMLElement): void {\n const menu = this.vdContextMenu();\n this.entry ??= acquire(menu, this.doc);\n // Android also fires contextmenu after a long press; one opening is enough.\n if (this.entry.controller.isOpen && this.entry.opener === this.focusable(origin)) return;\n this.opened.emit();\n this.entry.opener = this.focusable(origin);\n this.place(this.entry.anchor, x, y);\n menu.el.setAttribute('aria-label', this.t().label);\n menu.labelledBy.set(null);\n this.entry.controller.close(false);\n this.entry.controller.open('first');\n }\n\n /**\n * Puts the zero-size anchor at viewport point (x, y). An ancestor with a transform, filter or\n * container query becomes the fixed containing block, so the first guess is measured and\n * corrected by the difference. Insets stay logical: in RTL inline-start grows leftwards.\n */\n private place(anchor: HTMLElement, x: number, y: number): void {\n const rtl = this.doc.defaultView?.getComputedStyle(anchor).direction === 'rtl';\n let inline = rtl ? this.doc.documentElement.clientWidth - x : x;\n let block = y;\n const set = () => {\n anchor.style.setProperty('--vd-context-x', `${inline}px`);\n anchor.style.setProperty('--vd-context-y', `${block}px`);\n };\n set();\n const rect = anchor.getBoundingClientRect();\n inline += rtl ? rect.left - x : x - rect.left;\n block += y - rect.top;\n set();\n }\n\n /** Focus returns to the nearest focusable element of this region, or the region itself. */\n private focusable(origin: HTMLElement): HTMLElement {\n const candidate = origin.closest<HTMLElement>(\n 'a[href], button, input, select, textarea, [tabindex]',\n );\n return candidate && this.el.contains(candidate) ? candidate : this.el;\n }\n}\n"],"mappings":"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"}
|
|
@@ -86,6 +86,13 @@ var VdListboxBase = class VdListboxBase {
|
|
|
86
86
|
list.addEventListener("toggle", onToggle);
|
|
87
87
|
this.destroyRef.onDestroy(() => list.removeEventListener("toggle", onToggle));
|
|
88
88
|
});
|
|
89
|
+
afterRenderEffect(() => {
|
|
90
|
+
if (this.isDisabled()) this.closeList();
|
|
91
|
+
else if (this.open()) {
|
|
92
|
+
const active = this.activeOption();
|
|
93
|
+
if (!active || active.disabled()) this.activate("first");
|
|
94
|
+
}
|
|
95
|
+
});
|
|
89
96
|
afterRenderEffect(() => {
|
|
90
97
|
const id = this.activeId();
|
|
91
98
|
if (!this.open() || !id) return;
|
|
@@ -129,7 +136,7 @@ var VdListboxBase = class VdListboxBase {
|
|
|
129
136
|
this.onChange(value);
|
|
130
137
|
}
|
|
131
138
|
markTouched() {
|
|
132
|
-
this.onTouched();
|
|
139
|
+
if (!this.isDisabled()) this.onTouched();
|
|
133
140
|
}
|
|
134
141
|
openList(start = "selected") {
|
|
135
142
|
if (this.isDisabled() || this.open()) return;
|
|
@@ -349,6 +356,7 @@ var VdCombobox = class VdCombobox extends VdListboxBase {
|
|
|
349
356
|
}
|
|
350
357
|
writeValue(value) {
|
|
351
358
|
this.value.set(value ?? null);
|
|
359
|
+
this.query.set(null);
|
|
352
360
|
}
|
|
353
361
|
choose(option) {
|
|
354
362
|
if (option.disabled() || this.isDisabled()) return;
|
|
@@ -670,16 +678,6 @@ var VdMultiSelect = class VdMultiSelect extends VdListboxBase {
|
|
|
670
678
|
disabled: option?.disabled() ?? false
|
|
671
679
|
};
|
|
672
680
|
}), ...ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []);
|
|
673
|
-
constructor() {
|
|
674
|
-
super();
|
|
675
|
-
afterRenderEffect(() => {
|
|
676
|
-
if (this.isDisabled()) this.closeList();
|
|
677
|
-
else if (this.open()) {
|
|
678
|
-
const active = this.activeOption();
|
|
679
|
-
if (!active || active.disabled()) this.activate("first");
|
|
680
|
-
}
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
681
|
listEl() {
|
|
684
682
|
return this.list()?.nativeElement;
|
|
685
683
|
}
|
|
@@ -762,7 +760,7 @@ var VdMultiSelect = class VdMultiSelect extends VdListboxBase {
|
|
|
762
760
|
version: "22.2.1",
|
|
763
761
|
ngImport: i0,
|
|
764
762
|
type: VdMultiSelect,
|
|
765
|
-
deps:
|
|
763
|
+
deps: null,
|
|
766
764
|
target: i0.ɵɵFactoryTarget.Component
|
|
767
765
|
});
|
|
768
766
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
@@ -1005,7 +1003,6 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1005
1003
|
encapsulation: ViewEncapsulation.None
|
|
1006
1004
|
}]
|
|
1007
1005
|
}],
|
|
1008
|
-
ctorParameters: () => [],
|
|
1009
1006
|
propDecorators: {
|
|
1010
1007
|
value: [{
|
|
1011
1008
|
type: i0.Input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui-select.mjs","names":[],"sources":["../../../projects/ui/select/src/listbox-base.ts","../../../projects/ui/select/src/listbox-host.ts","../../../projects/ui/select/src/combobox.ts","../../../projects/ui/select/src/core/multi-selection.ts","../../../projects/ui/select/src/multi-select.ts","../../../projects/ui/select/src/option.ts","../../../projects/ui/select/src/select.ts"],"sourcesContent":["import {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n ModelSignal,\n OnInit,\n Signal,\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NgControl } from '@angular/forms';\nimport {\n VD_FIELD,\n VdFieldControl,\n VdNgControlState,\n vdNgControlState,\n vdUniqueId,\n} from '@vadem/ui/field';\nimport { VdTypeahead, vdListTarget } from '@vadem/ui/keyboard';\nimport { VdListboxHost } from './listbox-host';\nimport type { VdOption } from './option';\nimport { vdTexts } from '@vadem/ui/locale';\n\nexport type VdSelectSize = 'sm' | 'md' | 'lg';\n\nconst NO_NG_STATE: VdNgControlState = {\n invalid: false,\n touched: false,\n disabled: false,\n required: false,\n};\n\n/**\n * Shared behavior of select, combobox, and multi-select: option registry, active option\n * (aria-activedescendant - focus stays on the combobox element), popover listbox anchored to\n * the field, value + ControlValueAccessor, and `vd-field` wiring.\n */\n@Directive()\nexport abstract class VdListboxBase<T = string | null>\n implements VdListboxHost, ControlValueAccessor, OnInit\n{\n /** Concrete controls define a single-value or array-valued selection model. */\n abstract readonly value: ModelSignal<T>;\n readonly placeholder = input('');\n readonly size = input<VdSelectSize>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Invalid state (e.g. server error); form validity is detected after touch. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Gate for `invalid`; Signal Forms binds it (FormUiControl contract). */\n readonly touched = input<boolean | undefined>(undefined);\n readonly required = input(false, { transform: booleanAttribute });\n /** Shown when no option is visible (e.g. nothing matches the filter). */\n readonly emptyText = input<string>();\n /** Text inputs resolved against the active VD_LOCALE. */\n protected readonly t = vdTexts('select', { emptyText: this.emptyText });\n /** Accessible name when there's no `vd-field` label; applied to the inner combobox element. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n readonly listboxId = vdUniqueId('vd-listbox');\n readonly controlId = vdUniqueId('vd-combobox');\n\n protected readonly field = inject(VD_FIELD, { optional: true });\n protected readonly hostEl: HTMLElement = inject(ElementRef).nativeElement;\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly options = signal<readonly VdOption[]>([]);\n protected readonly open = signal(false);\n protected readonly activeId = signal<string | null>(null);\n private readonly formDisabled = signal(false);\n private readonly ngSource = signal<Signal<VdNgControlState> | null>(null);\n private readonly typeahead = new VdTypeahead();\n\n /** The popover listbox element. */\n protected abstract listEl(): HTMLElement | undefined;\n /** What the listbox is anchored to (the visible field). */\n protected abstract anchorEl(): HTMLElement | undefined;\n\n protected readonly ordered = computed(() =>\n [...this.options()].sort((a, b) =>\n a.el.compareDocumentPosition(b.el) & a.el.DOCUMENT_POSITION_FOLLOWING ? -1 : 1,\n ),\n );\n protected readonly visibleOptions = computed(() =>\n this.ordered().filter((o) => this.isVisible(o)),\n );\n protected readonly selectedOption = computed(() =>\n this.ordered().find((o) => this.isSelected(o)),\n );\n protected readonly selectedLabel = computed(() => this.selectedOption()?.textLabel() ?? '');\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n private readonly ngState = computed(() => this.ngSource()?.() ?? NO_NG_STATE);\n\n protected readonly showInvalid = computed(() => {\n if (this.invalid() && this.touched() !== false) return true;\n const ng = this.ngState();\n return ng.invalid && ng.touched;\n });\n protected readonly isRequired = computed(() => this.required() || this.ngState().required);\n protected readonly describedBy = computed(() => this.field?.describedBy() ?? null);\n\n private onChange: (value: T) => void = () => undefined;\n private onTouched: () => void = () => undefined;\n\n constructor() {\n const fieldControl: VdFieldControl = {\n id: signal(this.controlId),\n invalid: this.showInvalid,\n required: this.isRequired,\n disabled: this.isDisabled,\n };\n this.field?.register(fieldControl);\n this.destroyRef.onDestroy(() => this.field?.unregister(fieldControl));\n\n // Browser-only: anchor the listbox and keep `open` in sync with light dismiss / Escape.\n afterNextRender(() => {\n const list = this.listEl();\n const anchor = this.anchorEl();\n if (!list || !anchor) return;\n const name = `--${this.listboxId}`;\n anchor.style.setProperty('anchor-name', name);\n list.style.setProperty('position-anchor', name);\n const onToggle = (e: Event) => {\n if ((e as ToggleEvent).newState === 'closed') this.afterClose();\n };\n list.addEventListener('toggle', onToggle);\n this.destroyRef.onDestroy(() => list.removeEventListener('toggle', onToggle));\n });\n\n // Keep the active option visible while navigating.\n afterRenderEffect(() => {\n const id = this.activeId();\n if (!this.open() || !id) return;\n this.ordered()\n .find((o) => o.id === id)\n ?.el.scrollIntoView({ block: 'nearest' });\n });\n }\n\n ngOnInit(): void {\n // Can't inject NgControl in the constructor: it depends on this value accessor.\n const ngControl = this.injector.get(NgControl, null, { self: true, optional: true });\n this.ngSource.set(vdNgControlState(ngControl, this.destroyRef));\n }\n\n // ------------------------------------------------------------- VdListboxHost\n\n abstract isSelected(option: VdOption): boolean;\n\n isActive(option: VdOption): boolean {\n return option.id === this.activeId();\n }\n\n isVisible(_option: VdOption): boolean {\n return true;\n }\n\n abstract choose(option: VdOption): void;\n\n hover(option: VdOption): void {\n if (!option.disabled()) this.activeId.set(option.id);\n }\n\n register(option: VdOption): () => void {\n this.options.update((list) => [...list, option]);\n return () => this.options.update((list) => list.filter((o) => o !== option));\n }\n\n // --------------------------------------------------------- ControlValueAccessor\n\n abstract writeValue(value: T | null): void;\n\n registerOnChange(fn: (value: T) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.formDisabled.set(disabled);\n }\n\n // ------------------------------------------------------------------ internals\n\n /** Hook for subclasses after an option was chosen. */\n protected onChosen(_option: VdOption): void {\n /* default: nothing */\n }\n\n /** Hook for subclasses after the list closed (any reason). */\n protected onClosed(): void {\n /* default: nothing */\n }\n\n protected setValue(value: T): void {\n if (value === this.value()) return;\n this.value.set(value);\n this.onChange(value);\n }\n\n protected markTouched(): void {\n this.onTouched();\n }\n\n protected openList(start: 'selected' | 'first' | 'last' = 'selected'): void {\n if (this.isDisabled() || this.open()) return;\n const list = this.listEl();\n if (!list) return;\n this.open.set(true);\n // `source` ties the popover to its field: clicks on the field don't light-dismiss it.\n // Engines without the option ignore it.\n list.showPopover({ source: this.anchorEl() } as ShowPopoverOptions);\n this.activate(start);\n }\n\n protected closeList(): void {\n const list = this.listEl();\n if (list?.matches(':popover-open')) list.hidePopover();\n else this.afterClose();\n }\n\n protected activate(start: 'selected' | 'first' | 'last'): void {\n const visible = this.visibleOptions();\n const enabled = visible.filter((o) => !o.disabled());\n const pick =\n start === 'selected'\n ? (enabled.find((o) => this.isSelected(o)) ?? enabled[0])\n : start === 'first'\n ? enabled[0]\n : enabled[enabled.length - 1];\n this.activeId.set(pick?.id ?? null);\n }\n\n /** Handles list navigation keys. Returns true when the key was used. */\n protected navigate(event: KeyboardEvent): boolean {\n const visible = this.visibleOptions();\n const current = visible.findIndex((o) => o.id === this.activeId());\n const target = vdListTarget(\n event.key,\n current,\n visible.map((o) => o.disabled()),\n { loop: false, pageSize: 10 },\n );\n if (target === null) return false;\n event.preventDefault();\n this.activeId.set(visible[target]?.id ?? null);\n return true;\n }\n\n /** Feeds a printable key to typeahead. Returns the matched option, if any. */\n protected typeaheadMatch(event: KeyboardEvent): VdOption | undefined {\n if (!VdTypeahead.accepts(event)) return undefined;\n const visible = this.visibleOptions();\n const current = visible.findIndex(\n (o) => o.id === (this.activeId() ?? this.selectedOption()?.id),\n );\n const idx = this.typeahead.match(\n event.key,\n visible.map((o) => o.textLabel()),\n visible.map((o) => o.disabled()),\n current,\n );\n return idx === null ? undefined : visible[idx];\n }\n\n protected activeOption(): VdOption | undefined {\n return this.visibleOptions().find((o) => o.id === this.activeId());\n }\n\n private afterClose(): void {\n if (!this.open()) return;\n this.open.set(false);\n this.activeId.set(null);\n this.typeahead.reset();\n this.onClosed();\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport type { VdOption } from './option';\n\n/** What an option needs from the select, combobox, or multi-select that owns it. */\nexport interface VdListboxHost {\n isSelected(option: VdOption): boolean;\n isActive(option: VdOption): boolean;\n isVisible(option: VdOption): boolean;\n choose(option: VdOption): void;\n hover(option: VdOption): void;\n register(option: VdOption): () => void;\n}\n\nexport const VD_LISTBOX = new InjectionToken<VdListboxHost>('VD_LISTBOX');\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n forwardRef,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { vdMatchesQuery } from '@vadem/ui/keyboard';\nimport { VdListboxBase } from './listbox-base';\nimport { VD_LISTBOX } from './listbox-host';\nimport type { VdOption } from './option';\n\n/**\n * Editable combobox with list autocomplete (APG): type to filter, pick with arrows + Enter or\n * click. The value is always one of the options; free text reverts on blur. Spec: specs/select.md\n */\n@Component({\n selector: 'vd-combobox',\n imports: [VdIcon],\n template: `\n <!-- Pointer convenience only: the input inside handles every key. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n #field\n class=\"vd-combobox__field\"\n (pointerdown)=\"onFieldPointerDown($event)\"\n (click)=\"onFieldClick($event)\"\n >\n <vd-icon name=\"search\" class=\"vd-combobox__icon\" />\n <input\n #input\n class=\"vd-combobox__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n [id]=\"controlId\"\n [value]=\"inputText()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n <vd-icon name=\"chevron-down\" class=\"vd-select__chevron\" />\n </div>\n <div #list class=\"vd-listbox\" popover=\"auto\" role=\"listbox\" [id]=\"listboxId\" tabindex=\"-1\">\n <ng-content />\n @if (visibleOptions().length === 0) {\n <p class=\"vd-listbox__empty\">{{ t().emptyText }}</p>\n }\n </div>\n `,\n host: {\n class: 'vd-combobox',\n '[attr.data-size]': 'size()',\n '[attr.data-open]': 'open() ? \"\" : null',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n // Naming attributes move to the inner combobox element.\n '[attr.aria-label]': 'null',\n '[attr.aria-labelledby]': 'null',\n },\n providers: [\n { provide: VD_LISTBOX, useExisting: forwardRef(() => VdCombobox) },\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => VdCombobox), multi: true },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdCombobox extends VdListboxBase {\n readonly value = model<string | null>(null);\n\n isSelected(option: VdOption): boolean {\n return option.value() === this.value();\n }\n\n writeValue(value: string | null): void {\n this.value.set(value ?? null);\n }\n\n choose(option: VdOption): void {\n if (option.disabled() || this.isDisabled()) return;\n this.setValue(option.value());\n this.onChosen();\n this.closeList();\n }\n\n private readonly fieldRef = viewChild.required<ElementRef<HTMLElement>>('field');\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('input');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n\n /** Text being typed; `null` when not filtering (the input shows the selected label). */\n private readonly query = signal<string | null>(null);\n protected readonly inputText = computed(() => this.query() ?? this.selectedLabel());\n\n protected listEl(): HTMLElement | undefined {\n return this.list()?.nativeElement;\n }\n\n protected anchorEl(): HTMLElement | undefined {\n return this.fieldRef()?.nativeElement;\n }\n\n focus(): void {\n this.inputRef().nativeElement.focus();\n }\n\n override isVisible(option: VdOption): boolean {\n const q = this.query();\n return q === null || vdMatchesQuery(option.textLabel(), q);\n }\n\n protected override onChosen(): void {\n this.query.set(null);\n }\n\n protected override onClosed(): void {\n this.query.set(null);\n if (this.hostEl.ownerDocument.activeElement !== this.inputRef().nativeElement)\n this.markTouched();\n }\n\n /** Whether the list was open when the press started (light dismiss may close it first). */\n private wasOpen = false;\n\n protected onFieldPointerDown(event: PointerEvent): void {\n this.wasOpen = this.open();\n const input = this.inputRef().nativeElement;\n // Icons and padding focus the input instead of stealing focus.\n if (event.target !== input && !this.isDisabled()) {\n event.preventDefault();\n input.focus();\n }\n }\n\n protected onFieldClick(event: MouseEvent): void {\n if (this.isDisabled()) return;\n const onInput = event.target === this.inputRef().nativeElement;\n if (this.open() && !onInput) this.closeList();\n else if (!this.open() && !(this.wasOpen && !onInput)) this.openList('selected');\n this.wasOpen = false;\n }\n\n protected onInput(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n if (!this.open()) this.openList('first');\n else this.activate('first');\n }\n\n protected onBlur(): void {\n this.query.set(null);\n if (!this.open()) this.markTouched();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const { key, altKey } = event;\n\n if (!this.open()) {\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n event.preventDefault();\n this.openList(key === 'ArrowUp' ? 'last' : 'selected');\n }\n return;\n }\n\n if (key === 'Escape') {\n event.preventDefault();\n this.closeList();\n } else if (key === 'Enter' || (altKey && key === 'ArrowUp')) {\n event.preventDefault();\n const active = this.activeOption();\n if (active) this.choose(active);\n else this.closeList();\n } else if (key === 'Tab') {\n this.closeList();\n } else if (key !== 'Home' && key !== 'End') {\n // Home/End keep moving the caret in the text field.\n this.navigate(event);\n }\n }\n}\n","/** Immutable, unique selection values. Unknown values remain until the consumer removes them. */\nexport function vdUniqueSelection(values: readonly string[] | null): string[] {\n return [...new Set(values ?? [])];\n}\n\nexport function vdToggleSelection(values: readonly string[], value: string): string[] {\n return values.includes(value)\n ? values.filter((item) => item !== value)\n : [...new Set([...values, value])];\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n afterRenderEffect,\n computed,\n forwardRef,\n input,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { vdMatchesQuery } from '@vadem/ui/keyboard';\nimport { vdToggleSelection, vdUniqueSelection } from './core/multi-selection';\nimport { VdListboxBase } from './listbox-base';\nimport { VD_LISTBOX } from './listbox-host';\nimport type { VdOption } from './option';\nimport { vdTexts } from '@vadem/ui/locale';\n\n/** Searchable multiple selection. Spec: specs/multi-select.md. */\n@Component({\n selector: 'vd-multi-select',\n imports: [VdIcon],\n template: `\n <div #field class=\"vd-multi-select__field\" (pointerdown)=\"onFieldPointerDown($event)\">\n @for (item of selectedItems(); track item.value) {\n <span class=\"vd-multi-select__chip\">\n <span class=\"vd-multi-select__label\" [title]=\"item.label\">{{ item.label }}</span>\n <button\n type=\"button\"\n class=\"vd-multi-select__remove\"\n [disabled]=\"isDisabled() || item.disabled\"\n [attr.aria-label]=\"multiTexts().removeLabel(item.label)\"\n (click)=\"remove(item.value)\"\n >\n <vd-icon name=\"x\" />\n </button>\n </span>\n }\n <input\n #input\n class=\"vd-multi-select__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n autocomplete=\"off\"\n [id]=\"controlId\"\n [value]=\"query()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-describedby]=\"descriptionIds()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (click)=\"openList()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (compositionend)=\"onInput($event)\"\n />\n <vd-icon name=\"chevron-down\" class=\"vd-select__chevron\" />\n </div>\n <span class=\"vd-visually-hidden\" [id]=\"summaryId\" role=\"status\" aria-atomic=\"true\">\n {{ multiTexts().selectionLabel(selectedItems().length) }}\n </span>\n <div\n #list\n class=\"vd-listbox vd-multi-select__list\"\n popover=\"auto\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [id]=\"listboxId\"\n tabindex=\"-1\"\n >\n <ng-content />\n @if (visibleOptions().length === 0) {\n <p class=\"vd-listbox__empty\">{{ t().emptyText }}</p>\n }\n </div>\n `,\n host: {\n class: 'vd-multi-select',\n '[attr.data-size]': 'size()',\n '[attr.data-open]': 'open() ? \"\" : null',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-label]': 'null',\n '[attr.aria-labelledby]': 'null',\n '(focusout)': 'onFocusOut($event)',\n },\n providers: [\n { provide: VD_LISTBOX, useExisting: forwardRef(() => VdMultiSelect) },\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => VdMultiSelect), multi: true },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdMultiSelect extends VdListboxBase<string[]> {\n readonly value = model<string[]>([]);\n readonly removeLabel = input<(label: string) => string>();\n readonly selectionLabel = input<(count: number) => string>();\n /** Text inputs resolved against the active VD_LOCALE. */\n protected readonly multiTexts = vdTexts('multiSelect', {\n removeLabel: this.removeLabel,\n selectionLabel: this.selectionLabel,\n });\n\n private readonly fieldRef = viewChild.required<ElementRef<HTMLElement>>('field');\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('input');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n protected readonly query = signal('');\n protected readonly summaryId = vdUniqueId('vd-selection');\n protected readonly descriptionIds = computed(() =>\n [this.describedBy(), this.summaryId].filter(Boolean).join(' '),\n );\n protected readonly selectedItems = computed(() =>\n vdUniqueSelection(this.value()).map((value) => {\n const option = this.ordered().find((item) => item.value() === value);\n return { value, label: option?.textLabel() || value, disabled: option?.disabled() ?? false };\n }),\n );\n\n constructor() {\n super();\n afterRenderEffect(() => {\n if (this.isDisabled()) this.closeList();\n else if (this.open()) {\n // A query, dynamic option removal, or disabled change must never leave a dangling id.\n const active = this.activeOption();\n if (!active || active.disabled()) this.activate('first');\n }\n });\n }\n\n protected listEl(): HTMLElement | undefined {\n return this.list()?.nativeElement;\n }\n\n protected anchorEl(): HTMLElement | undefined {\n return this.fieldRef()?.nativeElement;\n }\n\n focus(): void {\n this.inputRef().nativeElement.focus();\n }\n\n isSelected(option: VdOption): boolean {\n return this.value().includes(option.value());\n }\n\n override isVisible(option: VdOption): boolean {\n return vdMatchesQuery(option.textLabel(), this.query());\n }\n\n choose(option: VdOption): void {\n if (this.isDisabled() || option.disabled()) return;\n this.setValue(vdToggleSelection(this.value(), option.value()));\n this.focus();\n }\n\n writeValue(value: string[] | null): void {\n this.value.set(vdUniqueSelection(value));\n }\n\n protected remove(value: string): void {\n const item = this.selectedItems().find((item) => item.value === value);\n if (this.isDisabled() || item?.disabled) return;\n this.setValue(this.value().filter((item) => item !== value));\n this.focus();\n }\n\n protected onInput(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n if ((event as InputEvent).isComposing) return;\n this.openList('first');\n this.activate('first');\n }\n\n protected onFocusOut(event: FocusEvent): void {\n const next = event.relatedTarget as Node | null;\n if (next && this.hostEl.contains(next)) return;\n this.markTouched();\n this.closeList();\n }\n\n protected onFieldPointerDown(event: PointerEvent): void {\n const target = event.target as HTMLElement;\n if (this.isDisabled() || target.closest('button') || target === this.inputRef().nativeElement)\n return;\n event.preventDefault();\n this.focus();\n this.openList();\n }\n\n protected override onClosed(): void {\n this.query.set('');\n if (!this.hostEl.contains(this.hostEl.ownerDocument.activeElement)) this.markTouched();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.isComposing || this.isDisabled()) return;\n const { key, altKey } = event;\n if (key === 'Backspace' && this.query() === '') {\n const last = this.selectedItems().at(-1);\n if (last && !last.disabled) {\n event.preventDefault();\n this.remove(last.value);\n }\n } else if (!this.open()) {\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n event.preventDefault();\n this.openList(key === 'ArrowUp' ? 'last' : 'selected');\n }\n } else if (key === 'Escape' || (altKey && key === 'ArrowUp')) {\n event.preventDefault();\n event.stopPropagation();\n this.closeList();\n } else if (key === 'Enter') {\n event.preventDefault();\n const active = this.activeOption();\n if (active) this.choose(active);\n } else if (key === 'Tab') {\n this.closeList();\n } else if (key !== 'Home' && key !== 'End') {\n this.navigate(event);\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n OnInit,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_LISTBOX } from './listbox-host';\n\n/** One option of select, combobox, or multi-select. Specs: select.md, multi-select.md. */\n@Component({\n selector: 'vd-option',\n imports: [VdIcon],\n template: `\n <span class=\"vd-option__label\"><ng-content /></span>\n <vd-icon name=\"check\" class=\"vd-option__check\" />\n `,\n host: {\n class: 'vd-option',\n role: 'option',\n '[id]': 'id',\n '[attr.aria-selected]': 'selected()',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.data-active]': 'active() ? \"\" : null',\n '[hidden]': '!visible()',\n '(click)': 'host.choose(this)',\n '(pointermove)': 'host.hover(this)',\n // Keep focus on the combobox element while clicking options.\n '(mousedown)': '$event.preventDefault()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdOption implements OnInit {\n readonly value = input.required<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Text for the trigger, typeahead and filtering. Defaults to the option's text content. */\n readonly label = input<string>();\n\n protected readonly host = inject(VD_LISTBOX);\n readonly el: HTMLElement = inject(ElementRef).nativeElement;\n readonly id = vdUniqueId('vd-option');\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly selected = computed(() => this.host.isSelected(this));\n protected readonly active = computed(() => this.host.isActive(this));\n protected readonly visible = computed(() => this.host.isVisible(this));\n\n textLabel(): string {\n return this.label() ?? this.el.querySelector('.vd-option__label')?.textContent?.trim() ?? '';\n }\n\n ngOnInit(): void {\n this.destroyRef.onDestroy(this.host.register(this));\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n forwardRef,\n model,\n viewChild,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VdListboxBase } from './listbox-base';\nimport { VD_LISTBOX } from './listbox-host';\nimport type { VdOption } from './option';\n\n/**\n * Select-only combobox (APG): a button that opens a listbox; focus stays on the button and the\n * active option is exposed with aria-activedescendant. Spec: specs/select.md\n */\n@Component({\n selector: 'vd-select',\n imports: [VdIcon],\n template: `\n <button\n #trigger\n type=\"button\"\n class=\"vd-select__trigger\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"controlId\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (pointerdown)=\"wasOpen = open()\"\n (click)=\"onClick()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n >\n <span class=\"vd-select__value\" [attr.data-placeholder]=\"selectedLabel() ? null : ''\">\n {{ selectedLabel() || placeholder() }}\n </span>\n <vd-icon name=\"chevron-down\" class=\"vd-select__chevron\" />\n </button>\n <div #list class=\"vd-listbox\" popover=\"auto\" role=\"listbox\" [id]=\"listboxId\" tabindex=\"-1\">\n <ng-content />\n @if (visibleOptions().length === 0) {\n <p class=\"vd-listbox__empty\">{{ t().emptyText }}</p>\n }\n </div>\n `,\n host: {\n class: 'vd-select',\n '[attr.data-size]': 'size()',\n '[attr.data-open]': 'open() ? \"\" : null',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n // Naming attributes move to the inner combobox element.\n '[attr.aria-label]': 'null',\n '[attr.aria-labelledby]': 'null',\n },\n providers: [\n { provide: VD_LISTBOX, useExisting: forwardRef(() => VdSelect) },\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => VdSelect), multi: true },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdSelect extends VdListboxBase {\n readonly value = model<string | null>(null);\n\n isSelected(option: VdOption): boolean {\n return option.value() === this.value();\n }\n\n writeValue(value: string | null): void {\n this.value.set(value ?? null);\n }\n\n choose(option: VdOption): void {\n if (option.disabled() || this.isDisabled()) return;\n this.setValue(option.value());\n this.onChosen(option);\n this.closeList();\n }\n\n private readonly trigger = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n /** Light dismiss closes the list on pointerdown; the following click must not reopen it. */\n protected wasOpen = false;\n\n protected listEl(): HTMLElement | undefined {\n return this.list()?.nativeElement;\n }\n\n protected anchorEl(): HTMLElement | undefined {\n return this.trigger()?.nativeElement;\n }\n\n focus(): void {\n this.trigger().nativeElement.focus();\n }\n\n protected onClick(): void {\n if (this.wasOpen || this.open()) {\n this.wasOpen = false;\n this.closeList();\n return;\n }\n this.openList('selected');\n }\n\n protected onBlur(): void {\n if (!this.open()) this.markTouched();\n }\n\n protected override onClosed(): void {\n // Light dismiss moved focus elsewhere: the user has left the field.\n if (this.hostEl.ownerDocument.activeElement !== this.trigger().nativeElement)\n this.markTouched();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const { key, altKey } = event;\n\n if (!this.open()) {\n if (key === 'ArrowDown' || key === 'ArrowUp' || key === 'Enter' || key === ' ') {\n event.preventDefault();\n this.openList('selected');\n } else if (key === 'Home' || key === 'End') {\n event.preventDefault();\n this.openList(key === 'Home' ? 'first' : 'last');\n } else {\n const match = this.typeaheadMatch(event);\n if (match) {\n // APG: typing on a closed select opens it on the match.\n this.openList('selected');\n this.activeId.set(match.id);\n }\n }\n return;\n }\n\n if (key === 'Escape') {\n event.preventDefault();\n this.closeList();\n } else if (key === 'Enter' || key === ' ' || (altKey && key === 'ArrowUp')) {\n event.preventDefault();\n const active = this.activeOption();\n if (active) this.choose(active);\n else this.closeList();\n } else if (key === 'Tab') {\n const active = this.activeOption();\n if (active) this.choose(active);\n else this.closeList();\n } else if (!this.navigate(event)) {\n const match = this.typeaheadMatch(event);\n if (match) this.activeId.set(match.id);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vadem-ui-select.mjs","names":[],"sources":["../../../projects/ui/select/src/listbox-base.ts","../../../projects/ui/select/src/listbox-host.ts","../../../projects/ui/select/src/combobox.ts","../../../projects/ui/select/src/core/multi-selection.ts","../../../projects/ui/select/src/multi-select.ts","../../../projects/ui/select/src/option.ts","../../../projects/ui/select/src/select.ts"],"sourcesContent":["import {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n ModelSignal,\n OnInit,\n Signal,\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NgControl } from '@angular/forms';\nimport {\n VD_FIELD,\n VdFieldControl,\n VdNgControlState,\n vdNgControlState,\n vdUniqueId,\n} from '@vadem/ui/field';\nimport { VdTypeahead, vdListTarget } from '@vadem/ui/keyboard';\nimport { VdListboxHost } from './listbox-host';\nimport type { VdOption } from './option';\nimport { vdTexts } from '@vadem/ui/locale';\n\nexport type VdSelectSize = 'sm' | 'md' | 'lg';\n\nconst NO_NG_STATE: VdNgControlState = {\n invalid: false,\n touched: false,\n disabled: false,\n required: false,\n};\n\n/**\n * Shared behavior of select, combobox, and multi-select: option registry, active option\n * (aria-activedescendant - focus stays on the combobox element), popover listbox anchored to\n * the field, value + ControlValueAccessor, and `vd-field` wiring.\n */\n@Directive()\nexport abstract class VdListboxBase<T = string | null>\n implements VdListboxHost, ControlValueAccessor, OnInit\n{\n /** Concrete controls define a single-value or array-valued selection model. */\n abstract readonly value: ModelSignal<T>;\n readonly placeholder = input('');\n readonly size = input<VdSelectSize>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Invalid state (e.g. server error); form validity is detected after touch. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Gate for `invalid`; Signal Forms binds it (FormUiControl contract). */\n readonly touched = input<boolean | undefined>(undefined);\n readonly required = input(false, { transform: booleanAttribute });\n /** Shown when no option is visible (e.g. nothing matches the filter). */\n readonly emptyText = input<string>();\n /** Text inputs resolved against the active VD_LOCALE. */\n protected readonly t = vdTexts('select', { emptyText: this.emptyText });\n /** Accessible name when there's no `vd-field` label; applied to the inner combobox element. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n readonly listboxId = vdUniqueId('vd-listbox');\n readonly controlId = vdUniqueId('vd-combobox');\n\n protected readonly field = inject(VD_FIELD, { optional: true });\n protected readonly hostEl: HTMLElement = inject(ElementRef).nativeElement;\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly options = signal<readonly VdOption[]>([]);\n protected readonly open = signal(false);\n protected readonly activeId = signal<string | null>(null);\n private readonly formDisabled = signal(false);\n private readonly ngSource = signal<Signal<VdNgControlState> | null>(null);\n private readonly typeahead = new VdTypeahead();\n\n /** The popover listbox element. */\n protected abstract listEl(): HTMLElement | undefined;\n /** What the listbox is anchored to (the visible field). */\n protected abstract anchorEl(): HTMLElement | undefined;\n\n protected readonly ordered = computed(() =>\n [...this.options()].sort((a, b) =>\n a.el.compareDocumentPosition(b.el) & a.el.DOCUMENT_POSITION_FOLLOWING ? -1 : 1,\n ),\n );\n protected readonly visibleOptions = computed(() =>\n this.ordered().filter((o) => this.isVisible(o)),\n );\n protected readonly selectedOption = computed(() =>\n this.ordered().find((o) => this.isSelected(o)),\n );\n protected readonly selectedLabel = computed(() => this.selectedOption()?.textLabel() ?? '');\n protected readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n private readonly ngState = computed(() => this.ngSource()?.() ?? NO_NG_STATE);\n\n protected readonly showInvalid = computed(() => {\n if (this.invalid() && this.touched() !== false) return true;\n const ng = this.ngState();\n return ng.invalid && ng.touched;\n });\n protected readonly isRequired = computed(() => this.required() || this.ngState().required);\n protected readonly describedBy = computed(() => this.field?.describedBy() ?? null);\n\n private onChange: (value: T) => void = () => undefined;\n private onTouched: () => void = () => undefined;\n\n constructor() {\n const fieldControl: VdFieldControl = {\n id: signal(this.controlId),\n invalid: this.showInvalid,\n required: this.isRequired,\n disabled: this.isDisabled,\n };\n this.field?.register(fieldControl);\n this.destroyRef.onDestroy(() => this.field?.unregister(fieldControl));\n\n // Browser-only: anchor the listbox and keep `open` in sync with light dismiss / Escape.\n afterNextRender(() => {\n const list = this.listEl();\n const anchor = this.anchorEl();\n if (!list || !anchor) return;\n const name = `--${this.listboxId}`;\n anchor.style.setProperty('anchor-name', name);\n list.style.setProperty('position-anchor', name);\n const onToggle = (e: Event) => {\n if ((e as ToggleEvent).newState === 'closed') this.afterClose();\n };\n list.addEventListener('toggle', onToggle);\n this.destroyRef.onDestroy(() => list.removeEventListener('toggle', onToggle));\n });\n\n // Dynamic options and disabled state must not leave an inaccessible open list.\n afterRenderEffect(() => {\n if (this.isDisabled()) this.closeList();\n else if (this.open()) {\n const active = this.activeOption();\n if (!active || active.disabled()) this.activate('first');\n }\n });\n\n // Keep the active option visible while navigating.\n afterRenderEffect(() => {\n const id = this.activeId();\n if (!this.open() || !id) return;\n this.ordered()\n .find((o) => o.id === id)\n ?.el.scrollIntoView({ block: 'nearest' });\n });\n }\n\n ngOnInit(): void {\n // Can't inject NgControl in the constructor: it depends on this value accessor.\n const ngControl = this.injector.get(NgControl, null, { self: true, optional: true });\n this.ngSource.set(vdNgControlState(ngControl, this.destroyRef));\n }\n\n // ------------------------------------------------------------- VdListboxHost\n\n abstract isSelected(option: VdOption): boolean;\n\n isActive(option: VdOption): boolean {\n return option.id === this.activeId();\n }\n\n isVisible(_option: VdOption): boolean {\n return true;\n }\n\n abstract choose(option: VdOption): void;\n\n hover(option: VdOption): void {\n if (!option.disabled()) this.activeId.set(option.id);\n }\n\n register(option: VdOption): () => void {\n this.options.update((list) => [...list, option]);\n return () => this.options.update((list) => list.filter((o) => o !== option));\n }\n\n // --------------------------------------------------------- ControlValueAccessor\n\n abstract writeValue(value: T | null): void;\n\n registerOnChange(fn: (value: T) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.formDisabled.set(disabled);\n }\n\n // ------------------------------------------------------------------ internals\n\n /** Hook for subclasses after an option was chosen. */\n protected onChosen(_option: VdOption): void {\n /* default: nothing */\n }\n\n /** Hook for subclasses after the list closed (any reason). */\n protected onClosed(): void {\n /* default: nothing */\n }\n\n protected setValue(value: T): void {\n if (value === this.value()) return;\n this.value.set(value);\n this.onChange(value);\n }\n\n protected markTouched(): void {\n if (!this.isDisabled()) this.onTouched();\n }\n\n protected openList(start: 'selected' | 'first' | 'last' = 'selected'): void {\n if (this.isDisabled() || this.open()) return;\n const list = this.listEl();\n if (!list) return;\n this.open.set(true);\n // `source` ties the popover to its field: clicks on the field don't light-dismiss it.\n // Engines without the option ignore it.\n list.showPopover({ source: this.anchorEl() } as ShowPopoverOptions);\n this.activate(start);\n }\n\n protected closeList(): void {\n const list = this.listEl();\n if (list?.matches(':popover-open')) list.hidePopover();\n else this.afterClose();\n }\n\n protected activate(start: 'selected' | 'first' | 'last'): void {\n const visible = this.visibleOptions();\n const enabled = visible.filter((o) => !o.disabled());\n const pick =\n start === 'selected'\n ? (enabled.find((o) => this.isSelected(o)) ?? enabled[0])\n : start === 'first'\n ? enabled[0]\n : enabled[enabled.length - 1];\n this.activeId.set(pick?.id ?? null);\n }\n\n /** Handles list navigation keys. Returns true when the key was used. */\n protected navigate(event: KeyboardEvent): boolean {\n const visible = this.visibleOptions();\n const current = visible.findIndex((o) => o.id === this.activeId());\n const target = vdListTarget(\n event.key,\n current,\n visible.map((o) => o.disabled()),\n { loop: false, pageSize: 10 },\n );\n if (target === null) return false;\n event.preventDefault();\n this.activeId.set(visible[target]?.id ?? null);\n return true;\n }\n\n /** Feeds a printable key to typeahead. Returns the matched option, if any. */\n protected typeaheadMatch(event: KeyboardEvent): VdOption | undefined {\n if (!VdTypeahead.accepts(event)) return undefined;\n const visible = this.visibleOptions();\n const current = visible.findIndex(\n (o) => o.id === (this.activeId() ?? this.selectedOption()?.id),\n );\n const idx = this.typeahead.match(\n event.key,\n visible.map((o) => o.textLabel()),\n visible.map((o) => o.disabled()),\n current,\n );\n return idx === null ? undefined : visible[idx];\n }\n\n protected activeOption(): VdOption | undefined {\n return this.visibleOptions().find((o) => o.id === this.activeId());\n }\n\n private afterClose(): void {\n if (!this.open()) return;\n this.open.set(false);\n this.activeId.set(null);\n this.typeahead.reset();\n this.onClosed();\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport type { VdOption } from './option';\n\n/** What an option needs from the select, combobox, or multi-select that owns it. */\nexport interface VdListboxHost {\n isSelected(option: VdOption): boolean;\n isActive(option: VdOption): boolean;\n isVisible(option: VdOption): boolean;\n choose(option: VdOption): void;\n hover(option: VdOption): void;\n register(option: VdOption): () => void;\n}\n\nexport const VD_LISTBOX = new InjectionToken<VdListboxHost>('VD_LISTBOX');\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n forwardRef,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { vdMatchesQuery } from '@vadem/ui/keyboard';\nimport { VdListboxBase } from './listbox-base';\nimport { VD_LISTBOX } from './listbox-host';\nimport type { VdOption } from './option';\n\n/**\n * Editable combobox with list autocomplete (APG): type to filter, pick with arrows + Enter or\n * click. User choices come from the options; free text reverts on blur. Spec: specs/select.md\n */\n@Component({\n selector: 'vd-combobox',\n imports: [VdIcon],\n template: `\n <!-- Pointer convenience only: the input inside handles every key. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n #field\n class=\"vd-combobox__field\"\n (pointerdown)=\"onFieldPointerDown($event)\"\n (click)=\"onFieldClick($event)\"\n >\n <vd-icon name=\"search\" class=\"vd-combobox__icon\" />\n <input\n #input\n class=\"vd-combobox__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n [id]=\"controlId\"\n [value]=\"inputText()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n <vd-icon name=\"chevron-down\" class=\"vd-select__chevron\" />\n </div>\n <div #list class=\"vd-listbox\" popover=\"auto\" role=\"listbox\" [id]=\"listboxId\" tabindex=\"-1\">\n <ng-content />\n @if (visibleOptions().length === 0) {\n <p class=\"vd-listbox__empty\">{{ t().emptyText }}</p>\n }\n </div>\n `,\n host: {\n class: 'vd-combobox',\n '[attr.data-size]': 'size()',\n '[attr.data-open]': 'open() ? \"\" : null',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n // Naming attributes move to the inner combobox element.\n '[attr.aria-label]': 'null',\n '[attr.aria-labelledby]': 'null',\n },\n providers: [\n { provide: VD_LISTBOX, useExisting: forwardRef(() => VdCombobox) },\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => VdCombobox), multi: true },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdCombobox extends VdListboxBase {\n readonly value = model<string | null>(null);\n\n isSelected(option: VdOption): boolean {\n return option.value() === this.value();\n }\n\n writeValue(value: string | null): void {\n this.value.set(value ?? null);\n this.query.set(null);\n }\n\n choose(option: VdOption): void {\n if (option.disabled() || this.isDisabled()) return;\n this.setValue(option.value());\n this.onChosen();\n this.closeList();\n }\n\n private readonly fieldRef = viewChild.required<ElementRef<HTMLElement>>('field');\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('input');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n\n /** Text being typed; `null` when not filtering (the input shows the selected label). */\n private readonly query = signal<string | null>(null);\n protected readonly inputText = computed(() => this.query() ?? this.selectedLabel());\n\n protected listEl(): HTMLElement | undefined {\n return this.list()?.nativeElement;\n }\n\n protected anchorEl(): HTMLElement | undefined {\n return this.fieldRef()?.nativeElement;\n }\n\n focus(): void {\n this.inputRef().nativeElement.focus();\n }\n\n override isVisible(option: VdOption): boolean {\n const q = this.query();\n return q === null || vdMatchesQuery(option.textLabel(), q);\n }\n\n protected override onChosen(): void {\n this.query.set(null);\n }\n\n protected override onClosed(): void {\n this.query.set(null);\n if (this.hostEl.ownerDocument.activeElement !== this.inputRef().nativeElement)\n this.markTouched();\n }\n\n /** Whether the list was open when the press started (light dismiss may close it first). */\n private wasOpen = false;\n\n protected onFieldPointerDown(event: PointerEvent): void {\n this.wasOpen = this.open();\n const input = this.inputRef().nativeElement;\n // Icons and padding focus the input instead of stealing focus.\n if (event.target !== input && !this.isDisabled()) {\n event.preventDefault();\n input.focus();\n }\n }\n\n protected onFieldClick(event: MouseEvent): void {\n if (this.isDisabled()) return;\n const onInput = event.target === this.inputRef().nativeElement;\n if (this.open() && !onInput) this.closeList();\n else if (!this.open() && !(this.wasOpen && !onInput)) this.openList('selected');\n this.wasOpen = false;\n }\n\n protected onInput(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n if (!this.open()) this.openList('first');\n else this.activate('first');\n }\n\n protected onBlur(): void {\n this.query.set(null);\n if (!this.open()) this.markTouched();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const { key, altKey } = event;\n\n if (!this.open()) {\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n event.preventDefault();\n this.openList(key === 'ArrowUp' ? 'last' : 'selected');\n }\n return;\n }\n\n if (key === 'Escape') {\n event.preventDefault();\n this.closeList();\n } else if (key === 'Enter' || (altKey && key === 'ArrowUp')) {\n event.preventDefault();\n const active = this.activeOption();\n if (active) this.choose(active);\n else this.closeList();\n } else if (key === 'Tab') {\n this.closeList();\n } else if (key !== 'Home' && key !== 'End') {\n // Home/End keep moving the caret in the text field.\n this.navigate(event);\n }\n }\n}\n","/** Immutable, unique selection values. Unknown values remain until the consumer removes them. */\nexport function vdUniqueSelection(values: readonly string[] | null): string[] {\n return [...new Set(values ?? [])];\n}\n\nexport function vdToggleSelection(values: readonly string[], value: string): string[] {\n return values.includes(value)\n ? values.filter((item) => item !== value)\n : [...new Set([...values, value])];\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n forwardRef,\n input,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { vdMatchesQuery } from '@vadem/ui/keyboard';\nimport { vdToggleSelection, vdUniqueSelection } from './core/multi-selection';\nimport { VdListboxBase } from './listbox-base';\nimport { VD_LISTBOX } from './listbox-host';\nimport type { VdOption } from './option';\nimport { vdTexts } from '@vadem/ui/locale';\n\n/** Searchable multiple selection. Spec: specs/multi-select.md. */\n@Component({\n selector: 'vd-multi-select',\n imports: [VdIcon],\n template: `\n <div #field class=\"vd-multi-select__field\" (pointerdown)=\"onFieldPointerDown($event)\">\n @for (item of selectedItems(); track item.value) {\n <span class=\"vd-multi-select__chip\">\n <span class=\"vd-multi-select__label\" [title]=\"item.label\">{{ item.label }}</span>\n <button\n type=\"button\"\n class=\"vd-multi-select__remove\"\n [disabled]=\"isDisabled() || item.disabled\"\n [attr.aria-label]=\"multiTexts().removeLabel(item.label)\"\n (click)=\"remove(item.value)\"\n >\n <vd-icon name=\"x\" />\n </button>\n </span>\n }\n <input\n #input\n class=\"vd-multi-select__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n autocomplete=\"off\"\n [id]=\"controlId\"\n [value]=\"query()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-describedby]=\"descriptionIds()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (click)=\"openList()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (compositionend)=\"onInput($event)\"\n />\n <vd-icon name=\"chevron-down\" class=\"vd-select__chevron\" />\n </div>\n <span class=\"vd-visually-hidden\" [id]=\"summaryId\" role=\"status\" aria-atomic=\"true\">\n {{ multiTexts().selectionLabel(selectedItems().length) }}\n </span>\n <div\n #list\n class=\"vd-listbox vd-multi-select__list\"\n popover=\"auto\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [id]=\"listboxId\"\n tabindex=\"-1\"\n >\n <ng-content />\n @if (visibleOptions().length === 0) {\n <p class=\"vd-listbox__empty\">{{ t().emptyText }}</p>\n }\n </div>\n `,\n host: {\n class: 'vd-multi-select',\n '[attr.data-size]': 'size()',\n '[attr.data-open]': 'open() ? \"\" : null',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-label]': 'null',\n '[attr.aria-labelledby]': 'null',\n '(focusout)': 'onFocusOut($event)',\n },\n providers: [\n { provide: VD_LISTBOX, useExisting: forwardRef(() => VdMultiSelect) },\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => VdMultiSelect), multi: true },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdMultiSelect extends VdListboxBase<string[]> {\n readonly value = model<string[]>([]);\n readonly removeLabel = input<(label: string) => string>();\n readonly selectionLabel = input<(count: number) => string>();\n /** Text inputs resolved against the active VD_LOCALE. */\n protected readonly multiTexts = vdTexts('multiSelect', {\n removeLabel: this.removeLabel,\n selectionLabel: this.selectionLabel,\n });\n\n private readonly fieldRef = viewChild.required<ElementRef<HTMLElement>>('field');\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('input');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n protected readonly query = signal('');\n protected readonly summaryId = vdUniqueId('vd-selection');\n protected readonly descriptionIds = computed(() =>\n [this.describedBy(), this.summaryId].filter(Boolean).join(' '),\n );\n protected readonly selectedItems = computed(() =>\n vdUniqueSelection(this.value()).map((value) => {\n const option = this.ordered().find((item) => item.value() === value);\n return { value, label: option?.textLabel() || value, disabled: option?.disabled() ?? false };\n }),\n );\n\n protected listEl(): HTMLElement | undefined {\n return this.list()?.nativeElement;\n }\n\n protected anchorEl(): HTMLElement | undefined {\n return this.fieldRef()?.nativeElement;\n }\n\n focus(): void {\n this.inputRef().nativeElement.focus();\n }\n\n isSelected(option: VdOption): boolean {\n return this.value().includes(option.value());\n }\n\n override isVisible(option: VdOption): boolean {\n return vdMatchesQuery(option.textLabel(), this.query());\n }\n\n choose(option: VdOption): void {\n if (this.isDisabled() || option.disabled()) return;\n this.setValue(vdToggleSelection(this.value(), option.value()));\n this.focus();\n }\n\n writeValue(value: string[] | null): void {\n this.value.set(vdUniqueSelection(value));\n }\n\n protected remove(value: string): void {\n const item = this.selectedItems().find((item) => item.value === value);\n if (this.isDisabled() || item?.disabled) return;\n this.setValue(this.value().filter((item) => item !== value));\n this.focus();\n }\n\n protected onInput(event: Event): void {\n this.query.set((event.target as HTMLInputElement).value);\n if ((event as InputEvent).isComposing) return;\n this.openList('first');\n this.activate('first');\n }\n\n protected onFocusOut(event: FocusEvent): void {\n const next = event.relatedTarget as Node | null;\n if (next && this.hostEl.contains(next)) return;\n this.markTouched();\n this.closeList();\n }\n\n protected onFieldPointerDown(event: PointerEvent): void {\n const target = event.target as HTMLElement;\n if (this.isDisabled() || target.closest('button') || target === this.inputRef().nativeElement)\n return;\n event.preventDefault();\n this.focus();\n this.openList();\n }\n\n protected override onClosed(): void {\n this.query.set('');\n if (!this.hostEl.contains(this.hostEl.ownerDocument.activeElement)) this.markTouched();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.isComposing || this.isDisabled()) return;\n const { key, altKey } = event;\n if (key === 'Backspace' && this.query() === '') {\n const last = this.selectedItems().at(-1);\n if (last && !last.disabled) {\n event.preventDefault();\n this.remove(last.value);\n }\n } else if (!this.open()) {\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n event.preventDefault();\n this.openList(key === 'ArrowUp' ? 'last' : 'selected');\n }\n } else if (key === 'Escape' || (altKey && key === 'ArrowUp')) {\n event.preventDefault();\n event.stopPropagation();\n this.closeList();\n } else if (key === 'Enter') {\n event.preventDefault();\n const active = this.activeOption();\n if (active) this.choose(active);\n } else if (key === 'Tab') {\n this.closeList();\n } else if (key !== 'Home' && key !== 'End') {\n this.navigate(event);\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n OnInit,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_LISTBOX } from './listbox-host';\n\n/** One option of select, combobox, or multi-select. Specs: select.md, multi-select.md. */\n@Component({\n selector: 'vd-option',\n imports: [VdIcon],\n template: `\n <span class=\"vd-option__label\"><ng-content /></span>\n <vd-icon name=\"check\" class=\"vd-option__check\" />\n `,\n host: {\n class: 'vd-option',\n role: 'option',\n '[id]': 'id',\n '[attr.aria-selected]': 'selected()',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.data-active]': 'active() ? \"\" : null',\n '[hidden]': '!visible()',\n '(click)': 'host.choose(this)',\n '(pointermove)': 'host.hover(this)',\n // Keep focus on the combobox element while clicking options.\n '(mousedown)': '$event.preventDefault()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdOption implements OnInit {\n readonly value = input.required<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Text for the trigger, typeahead and filtering. Defaults to the option's text content. */\n readonly label = input<string>();\n\n protected readonly host = inject(VD_LISTBOX);\n readonly el: HTMLElement = inject(ElementRef).nativeElement;\n readonly id = vdUniqueId('vd-option');\n private readonly destroyRef = inject(DestroyRef);\n\n protected readonly selected = computed(() => this.host.isSelected(this));\n protected readonly active = computed(() => this.host.isActive(this));\n protected readonly visible = computed(() => this.host.isVisible(this));\n\n textLabel(): string {\n return this.label() ?? this.el.querySelector('.vd-option__label')?.textContent?.trim() ?? '';\n }\n\n ngOnInit(): void {\n this.destroyRef.onDestroy(this.host.register(this));\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n forwardRef,\n model,\n viewChild,\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VdListboxBase } from './listbox-base';\nimport { VD_LISTBOX } from './listbox-host';\nimport type { VdOption } from './option';\n\n/**\n * Select-only combobox (APG): a button that opens a listbox; focus stays on the button and the\n * active option is exposed with aria-activedescendant. Spec: specs/select.md\n */\n@Component({\n selector: 'vd-select',\n imports: [VdIcon],\n template: `\n <button\n #trigger\n type=\"button\"\n class=\"vd-select__trigger\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [id]=\"controlId\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"listboxId\"\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\n [attr.aria-invalid]=\"showInvalid() || null\"\n [attr.aria-required]=\"isRequired() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (pointerdown)=\"wasOpen = open()\"\n (click)=\"onClick()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n >\n <span class=\"vd-select__value\" [attr.data-placeholder]=\"selectedLabel() ? null : ''\">\n {{ selectedLabel() || placeholder() }}\n </span>\n <vd-icon name=\"chevron-down\" class=\"vd-select__chevron\" />\n </button>\n <div #list class=\"vd-listbox\" popover=\"auto\" role=\"listbox\" [id]=\"listboxId\" tabindex=\"-1\">\n <ng-content />\n @if (visibleOptions().length === 0) {\n <p class=\"vd-listbox__empty\">{{ t().emptyText }}</p>\n }\n </div>\n `,\n host: {\n class: 'vd-select',\n '[attr.data-size]': 'size()',\n '[attr.data-open]': 'open() ? \"\" : null',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : null',\n // Naming attributes move to the inner combobox element.\n '[attr.aria-label]': 'null',\n '[attr.aria-labelledby]': 'null',\n },\n providers: [\n { provide: VD_LISTBOX, useExisting: forwardRef(() => VdSelect) },\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => VdSelect), multi: true },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdSelect extends VdListboxBase {\n readonly value = model<string | null>(null);\n\n isSelected(option: VdOption): boolean {\n return option.value() === this.value();\n }\n\n writeValue(value: string | null): void {\n this.value.set(value ?? null);\n }\n\n choose(option: VdOption): void {\n if (option.disabled() || this.isDisabled()) return;\n this.setValue(option.value());\n this.onChosen(option);\n this.closeList();\n }\n\n private readonly trigger = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n /** Light dismiss closes the list on pointerdown; the following click must not reopen it. */\n protected wasOpen = false;\n\n protected listEl(): HTMLElement | undefined {\n return this.list()?.nativeElement;\n }\n\n protected anchorEl(): HTMLElement | undefined {\n return this.trigger()?.nativeElement;\n }\n\n focus(): void {\n this.trigger().nativeElement.focus();\n }\n\n protected onClick(): void {\n if (this.wasOpen || this.open()) {\n this.wasOpen = false;\n this.closeList();\n return;\n }\n this.openList('selected');\n }\n\n protected onBlur(): void {\n if (!this.open()) this.markTouched();\n }\n\n protected override onClosed(): void {\n // Light dismiss moved focus elsewhere: the user has left the field.\n if (this.hostEl.ownerDocument.activeElement !== this.trigger().nativeElement)\n this.markTouched();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const { key, altKey } = event;\n\n if (!this.open()) {\n if (key === 'ArrowDown' || key === 'ArrowUp' || key === 'Enter' || key === ' ') {\n event.preventDefault();\n this.openList('selected');\n } else if (key === 'Home' || key === 'End') {\n event.preventDefault();\n this.openList(key === 'Home' ? 'first' : 'last');\n } else {\n const match = this.typeaheadMatch(event);\n if (match) {\n // APG: typing on a closed select opens it on the match.\n this.openList('selected');\n this.activeId.set(match.id);\n }\n }\n return;\n }\n\n if (key === 'Escape') {\n event.preventDefault();\n this.closeList();\n } else if (key === 'Enter' || key === ' ' || (altKey && key === 'ArrowUp')) {\n event.preventDefault();\n const active = this.activeOption();\n if (active) this.choose(active);\n else this.closeList();\n } else if (key === 'Tab') {\n const active = this.activeOption();\n if (active) this.choose(active);\n else this.closeList();\n } else if (!this.navigate(event)) {\n const match = this.typeaheadMatch(event);\n if (match) this.activeId.set(match.id);\n }\n }\n}\n"],"mappings":"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"}
|
package/fesm2022/vadem-ui.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui.mjs","names":[],"sources":["../../../projects/ui/src/public-api.ts"],"sourcesContent":["/*\n * Public API surface of @vadem/ui (primary entry point).\n * Components live in secondary entry points: @vadem/ui/button, @vadem/ui/card, ...\n */\nexport const VD_VERSION = '0.0.
|
|
1
|
+
{"version":3,"file":"vadem-ui.mjs","names":[],"sources":["../../../projects/ui/src/public-api.ts"],"sourcesContent":["/*\n * Public API surface of @vadem/ui (primary entry point).\n * Components live in secondary entry points: @vadem/ui/button, @vadem/ui/card, ...\n */\nexport const VD_VERSION = '0.0.3';\n"],"mappings":"AAIA,MAAa,aAAa"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vadem/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": "^22.2.0",
|
|
6
6
|
"@angular/core": "^22.2.0",
|
|
@@ -303,6 +303,30 @@
|
|
|
303
303
|
"default": "./fesm2022/vadem-ui-upload-list.mjs"
|
|
304
304
|
}
|
|
305
305
|
},
|
|
306
|
+
"description": "Modern Angular UI components with dark and light themes, CSS design tokens, keyboard interactions, and English/Ukrainian localization.",
|
|
307
|
+
"keywords": [
|
|
308
|
+
"angular",
|
|
309
|
+
"ui",
|
|
310
|
+
"components",
|
|
311
|
+
"design-system",
|
|
312
|
+
"signals",
|
|
313
|
+
"theming",
|
|
314
|
+
"accessibility"
|
|
315
|
+
],
|
|
316
|
+
"repository": {
|
|
317
|
+
"type": "git",
|
|
318
|
+
"url": "git+https://github.com/Demchuk12/vadem-ui-angular.git",
|
|
319
|
+
"directory": "projects/ui"
|
|
320
|
+
},
|
|
321
|
+
"homepage": "https://demchuk12.github.io/vadem-ui-angular/",
|
|
322
|
+
"bugs": {
|
|
323
|
+
"url": "https://github.com/Demchuk12/vadem-ui-angular/issues"
|
|
324
|
+
},
|
|
325
|
+
"publishConfig": {
|
|
326
|
+
"access": "public",
|
|
327
|
+
"registry": "https://registry.npmjs.org/"
|
|
328
|
+
},
|
|
329
|
+
"license": "MIT",
|
|
306
330
|
"module": "fesm2022/vadem-ui.mjs",
|
|
307
331
|
"typings": "types/vadem-ui.d.ts",
|
|
308
332
|
"type": "module"
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
align-items: start;
|
|
11
11
|
justify-content: space-between;
|
|
12
12
|
gap: var(--vd-file-preview-gap);
|
|
13
|
+
padding-block-end: var(--vd-dialog-gap);
|
|
13
14
|
}
|
|
14
15
|
.vd-file-preview__heading {
|
|
15
16
|
min-inline-size: 0;
|
|
@@ -32,6 +33,10 @@
|
|
|
32
33
|
display: grid;
|
|
33
34
|
gap: var(--vd-file-preview-gap);
|
|
34
35
|
min-inline-size: 0;
|
|
36
|
+
margin-inline: var(--vd-dialog-padding);
|
|
37
|
+
margin-block-end: var(--vd-dialog-gap);
|
|
38
|
+
padding: var(--vd-space-5);
|
|
39
|
+
border-radius: var(--vd-radius-md);
|
|
35
40
|
background: var(--vd-file-preview-bg);
|
|
36
41
|
}
|
|
37
42
|
.vd-file-preview__body:focus-visible {
|
package/types/vadem-ui-menu.d.ts
CHANGED
|
@@ -99,9 +99,11 @@ export declare class VdContextMenu {
|
|
|
99
99
|
private readonly el;
|
|
100
100
|
private readonly doc;
|
|
101
101
|
private entry;
|
|
102
|
+
private pendingPointerOpen;
|
|
102
103
|
private pressTimer;
|
|
103
104
|
constructor();
|
|
104
105
|
protected onContextMenu(event: MouseEvent): void;
|
|
106
|
+
private readonly cancelPointerOpen;
|
|
105
107
|
protected onKeydown(event: KeyboardEvent): void;
|
|
106
108
|
protected onPointerDown(event: PointerEvent): void;
|
|
107
109
|
private openAt;
|
|
@@ -176,7 +176,7 @@ declare abstract class VdListboxBase<T = string | null> implements VdListboxHost
|
|
|
176
176
|
}
|
|
177
177
|
/**
|
|
178
178
|
* Editable combobox with list autocomplete (APG): type to filter, pick with arrows + Enter or
|
|
179
|
-
* click.
|
|
179
|
+
* click. User choices come from the options; free text reverts on blur. Spec: specs/select.md
|
|
180
180
|
*/
|
|
181
181
|
export declare class VdCombobox extends VdListboxBase {
|
|
182
182
|
readonly value: import("@angular/core").ModelSignal<string | null>;
|
|
@@ -234,7 +234,6 @@ export declare class VdMultiSelect extends VdListboxBase<string[]> {
|
|
|
234
234
|
label: string;
|
|
235
235
|
disabled: boolean;
|
|
236
236
|
}[]>;
|
|
237
|
-
constructor();
|
|
238
237
|
protected listEl(): HTMLElement | undefined;
|
|
239
238
|
protected anchorEl(): HTMLElement | undefined;
|
|
240
239
|
focus(): void;
|
package/types/vadem-ui.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VD_VERSION = "0.0.
|
|
1
|
+
export declare const VD_VERSION = "0.0.3";
|