forty-cdk 0.2.0 → 0.3.0
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/accordion/README.md +122 -0
- package/aspect-ratio/README.md +76 -0
- package/avatar/README.md +100 -0
- package/breadcrumbs/README.md +49 -0
- package/breakpoints/README.md +81 -0
- package/button/README.md +49 -0
- package/calendar/README.md +458 -0
- package/carousel/README.md +358 -0
- package/checkbox/README.md +146 -0
- package/combobox/README.md +535 -0
- package/context-menu/README.md +139 -0
- package/date-field/README.md +184 -0
- package/date-picker/README.md +338 -0
- package/dialog/README.md +388 -0
- package/disclosure/README.md +114 -0
- package/drag-drop/README.md +359 -0
- package/drawer/README.md +560 -0
- package/dropdown-menu/README.md +176 -0
- package/fesm2022/forty-cdk-accordion.mjs +348 -0
- package/fesm2022/forty-cdk-accordion.mjs.map +1 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs +74 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs.map +1 -0
- package/fesm2022/forty-cdk-avatar.mjs +308 -0
- package/fesm2022/forty-cdk-avatar.mjs.map +1 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs +125 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs.map +1 -0
- package/fesm2022/forty-cdk-breakpoints.mjs +117 -0
- package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -0
- package/fesm2022/forty-cdk-button.mjs +134 -0
- package/fesm2022/forty-cdk-button.mjs.map +1 -0
- package/fesm2022/forty-cdk-calendar.mjs +2034 -0
- package/fesm2022/forty-cdk-calendar.mjs.map +1 -0
- package/fesm2022/forty-cdk-carousel.mjs +968 -0
- package/fesm2022/forty-cdk-carousel.mjs.map +1 -0
- package/fesm2022/forty-cdk-checkbox.mjs +226 -0
- package/fesm2022/forty-cdk-checkbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-combobox.mjs +2596 -0
- package/fesm2022/forty-cdk-combobox.mjs.map +1 -0
- package/fesm2022/forty-cdk-context-menu.mjs +413 -0
- package/fesm2022/forty-cdk-context-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-core.mjs +9022 -0
- package/fesm2022/forty-cdk-core.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-field.mjs +744 -0
- package/fesm2022/forty-cdk-date-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-picker.mjs +1011 -0
- package/fesm2022/forty-cdk-date-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-dialog.mjs +707 -0
- package/fesm2022/forty-cdk-dialog.mjs.map +1 -0
- package/fesm2022/forty-cdk-disclosure.mjs +190 -0
- package/fesm2022/forty-cdk-disclosure.mjs.map +1 -0
- package/fesm2022/forty-cdk-drag-drop.mjs +1180 -0
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/forty-cdk-drawer.mjs +1641 -0
- package/fesm2022/forty-cdk-drawer.mjs.map +1 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs +350 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-field.mjs +425 -0
- package/fesm2022/forty-cdk-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-fieldset.mjs +164 -0
- package/fesm2022/forty-cdk-fieldset.mjs.map +1 -0
- package/fesm2022/forty-cdk-file-upload.mjs +221 -0
- package/fesm2022/forty-cdk-file-upload.mjs.map +1 -0
- package/fesm2022/forty-cdk-hover-card.mjs +496 -0
- package/fesm2022/forty-cdk-hover-card.mjs.map +1 -0
- package/fesm2022/forty-cdk-input.mjs +274 -0
- package/fesm2022/forty-cdk-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-internationalized-date.mjs +1 -1
- package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +1279 -0
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-menu.mjs +1439 -0
- package/fesm2022/forty-cdk-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-menubar.mjs +787 -0
- package/fesm2022/forty-cdk-menubar.mjs.map +1 -0
- package/fesm2022/forty-cdk-meter.mjs +211 -0
- package/fesm2022/forty-cdk-meter.mjs.map +1 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs +1145 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-number-input.mjs +559 -0
- package/fesm2022/forty-cdk-number-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-otp-input.mjs +527 -0
- package/fesm2022/forty-cdk-otp-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-pagination.mjs +323 -0
- package/fesm2022/forty-cdk-pagination.mjs.map +1 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs +297 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -0
- package/fesm2022/forty-cdk-popover.mjs +698 -0
- package/fesm2022/forty-cdk-popover.mjs.map +1 -0
- package/fesm2022/forty-cdk-progress.mjs +226 -0
- package/fesm2022/forty-cdk-progress.mjs.map +1 -0
- package/fesm2022/forty-cdk-radio-group.mjs +378 -0
- package/fesm2022/forty-cdk-radio-group.mjs.map +1 -0
- package/fesm2022/forty-cdk-scroll-area.mjs +640 -0
- package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -0
- package/fesm2022/forty-cdk-search.mjs +205 -0
- package/fesm2022/forty-cdk-search.mjs.map +1 -0
- package/fesm2022/forty-cdk-select.mjs +1661 -0
- package/fesm2022/forty-cdk-select.mjs.map +1 -0
- package/fesm2022/forty-cdk-separator.mjs +82 -0
- package/fesm2022/forty-cdk-separator.mjs.map +1 -0
- package/fesm2022/forty-cdk-signal-forms.mjs +97 -0
- package/fesm2022/forty-cdk-signal-forms.mjs.map +1 -0
- package/fesm2022/forty-cdk-slider.mjs +803 -0
- package/fesm2022/forty-cdk-slider.mjs.map +1 -0
- package/fesm2022/forty-cdk-stepper.mjs +886 -0
- package/fesm2022/forty-cdk-stepper.mjs.map +1 -0
- package/fesm2022/forty-cdk-switch.mjs +137 -0
- package/fesm2022/forty-cdk-switch.mjs.map +1 -0
- package/fesm2022/forty-cdk-table.mjs +1518 -0
- package/fesm2022/forty-cdk-table.mjs.map +1 -0
- package/fesm2022/forty-cdk-tabs.mjs +400 -0
- package/fesm2022/forty-cdk-tabs.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-field.mjs +593 -0
- package/fesm2022/forty-cdk-time-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-picker.mjs +1013 -0
- package/fesm2022/forty-cdk-time-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-toast.mjs +1153 -0
- package/fesm2022/forty-cdk-toast.mjs.map +1 -0
- package/fesm2022/forty-cdk-toggle.mjs +516 -0
- package/fesm2022/forty-cdk-toggle.mjs.map +1 -0
- package/fesm2022/forty-cdk-toolbar.mjs +374 -0
- package/fesm2022/forty-cdk-toolbar.mjs.map +1 -0
- package/fesm2022/forty-cdk-tooltip.mjs +672 -0
- package/fesm2022/forty-cdk-tooltip.mjs.map +1 -0
- package/fesm2022/forty-cdk-tree.mjs +2007 -0
- package/fesm2022/forty-cdk-tree.mjs.map +1 -0
- package/fesm2022/forty-cdk-virtualization.mjs +1 -1
- package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
- package/fesm2022/forty-cdk.mjs +0 -43310
- package/fesm2022/forty-cdk.mjs.map +1 -1
- package/field/README.md +97 -0
- package/fieldset/README.md +86 -0
- package/file-upload/README.md +73 -0
- package/hover-card/README.md +171 -0
- package/input/README.md +156 -0
- package/listbox/README.md +424 -0
- package/menu/README.md +181 -0
- package/menubar/README.md +140 -0
- package/meter/README.md +128 -0
- package/navigation-menu/README.md +253 -0
- package/number-input/README.md +171 -0
- package/otp-input/README.md +198 -0
- package/package.json +213 -1
- package/pagination/README.md +61 -0
- package/pane-resizer/README.md +136 -0
- package/popover/README.md +262 -0
- package/progress/README.md +115 -0
- package/radio-group/README.md +129 -0
- package/scroll-area/README.md +184 -0
- package/search/README.md +42 -0
- package/select/README.md +488 -0
- package/separator/README.md +84 -0
- package/signal-forms/README.md +72 -0
- package/slider/README.md +152 -0
- package/stepper/README.md +292 -0
- package/switch/README.md +116 -0
- package/table/README.md +769 -0
- package/tabs/README.md +130 -0
- package/time-field/README.md +157 -0
- package/time-picker/README.md +172 -0
- package/toast/README.md +398 -0
- package/toggle/README.md +224 -0
- package/toolbar/README.md +109 -0
- package/tooltip/README.md +274 -0
- package/tree/README.md +708 -0
- package/types/forty-cdk-accordion.d.ts +242 -0
- package/types/forty-cdk-aspect-ratio.d.ts +59 -0
- package/types/forty-cdk-avatar.d.ts +133 -0
- package/types/forty-cdk-breadcrumbs.d.ts +92 -0
- package/types/forty-cdk-breakpoints.d.ts +141 -0
- package/types/forty-cdk-button.d.ts +80 -0
- package/types/forty-cdk-calendar.d.ts +914 -0
- package/types/forty-cdk-carousel.d.ts +530 -0
- package/types/forty-cdk-checkbox.d.ts +141 -0
- package/types/forty-cdk-combobox.d.ts +1259 -0
- package/types/forty-cdk-context-menu.d.ts +313 -0
- package/types/forty-cdk-core.d.ts +5774 -0
- package/types/forty-cdk-date-field.d.ts +307 -0
- package/types/forty-cdk-date-picker.d.ts +622 -0
- package/types/forty-cdk-dialog.d.ts +546 -0
- package/types/forty-cdk-disclosure.d.ts +127 -0
- package/types/forty-cdk-drag-drop.d.ts +456 -0
- package/types/forty-cdk-drawer.d.ts +871 -0
- package/types/forty-cdk-dropdown-menu.d.ts +242 -0
- package/types/forty-cdk-field.d.ts +236 -0
- package/types/forty-cdk-fieldset.d.ts +119 -0
- package/types/forty-cdk-file-upload.d.ts +124 -0
- package/types/forty-cdk-hover-card.d.ts +320 -0
- package/types/forty-cdk-input.d.ts +169 -0
- package/types/forty-cdk-internationalized-date.d.ts +1 -1
- package/types/forty-cdk-listbox.d.ts +513 -0
- package/types/forty-cdk-menu.d.ts +629 -0
- package/types/forty-cdk-menubar.d.ts +451 -0
- package/types/forty-cdk-meter.d.ts +122 -0
- package/types/forty-cdk-navigation-menu.d.ts +514 -0
- package/types/forty-cdk-number-input.d.ts +319 -0
- package/types/forty-cdk-otp-input.d.ts +248 -0
- package/types/forty-cdk-pagination.d.ts +214 -0
- package/types/forty-cdk-pane-resizer.d.ts +145 -0
- package/types/forty-cdk-popover.d.ts +509 -0
- package/types/forty-cdk-progress.d.ts +143 -0
- package/types/forty-cdk-radio-group.d.ts +222 -0
- package/types/forty-cdk-scroll-area.d.ts +258 -0
- package/types/forty-cdk-search.d.ts +142 -0
- package/types/forty-cdk-select.d.ts +899 -0
- package/types/forty-cdk-separator.d.ts +59 -0
- package/types/forty-cdk-signal-forms.d.ts +58 -0
- package/types/forty-cdk-slider.d.ts +379 -0
- package/types/forty-cdk-stepper.d.ts +650 -0
- package/types/forty-cdk-switch.d.ts +87 -0
- package/types/forty-cdk-table.d.ts +723 -0
- package/types/forty-cdk-tabs.d.ts +235 -0
- package/types/forty-cdk-time-field.d.ts +307 -0
- package/types/forty-cdk-time-picker.d.ts +578 -0
- package/types/forty-cdk-toast.d.ts +598 -0
- package/types/forty-cdk-toggle.d.ts +310 -0
- package/types/forty-cdk-toolbar.d.ts +217 -0
- package/types/forty-cdk-tooltip.d.ts +436 -0
- package/types/forty-cdk-tree.d.ts +688 -0
- package/types/forty-cdk.d.ts +1 -19743
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, model, input, numberAttribute, booleanAttribute, output, computed, Directive, ElementRef, effect } from '@angular/core';
|
|
3
|
+
import { createDefaults, MenuOverlayHost, MENU_POSITIONING_DEFAULTS, injectTextDirection, createMenuOverlay, FOR_MENU_CONTEXT, reflectDisabled } from 'forty-cdk/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Library fallback for dropdown menu defaults, read at the root injector when no
|
|
7
|
+
* consumer has called `provideForDropdownMenuDefaults`. Exported for the shared defaults
|
|
8
|
+
* contract spec; not re-exported from the primitive's public entry.
|
|
9
|
+
*/
|
|
10
|
+
const FOR_DROPDOWN_MENU_FALLBACK_DEFAULTS = {
|
|
11
|
+
sideOffset: 4,
|
|
12
|
+
collisionPadding: 8,
|
|
13
|
+
};
|
|
14
|
+
const { token, provideDefaults } = createDefaults('FOR_DROPDOWN_MENU_DEFAULTS', FOR_DROPDOWN_MENU_FALLBACK_DEFAULTS);
|
|
15
|
+
/** Token holding the resolved dropdown-menu defaults for the current scope. */
|
|
16
|
+
const FOR_DROPDOWN_MENU_DEFAULTS = token;
|
|
17
|
+
/**
|
|
18
|
+
* Configures forty-cdk dropdown-menu defaults for this injector scope.
|
|
19
|
+
* Partial overrides inherit unspecified keys from the parent scope (or
|
|
20
|
+
* library defaults at the root).
|
|
21
|
+
*/
|
|
22
|
+
function provideForDropdownMenuDefaults(defaults = {}) {
|
|
23
|
+
return provideDefaults(defaults);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Headless implementation of the [WAI-ARIA Menu Button pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/).
|
|
28
|
+
* Apply on a wrapper that contains the trigger and the `@if`-mounted
|
|
29
|
+
* `[forMenuContent]`. The directive owns open state, ids, and the registries
|
|
30
|
+
* that wire trigger / content / items together.
|
|
31
|
+
*
|
|
32
|
+
* Mount/unmount of the visible menu is the consumer's responsibility — wrap
|
|
33
|
+
* `[forMenuContent]` with `@if (open())` so `animate.enter` / `animate.leave`
|
|
34
|
+
* fire on the natural mount cycle:
|
|
35
|
+
*
|
|
36
|
+
* ```html
|
|
37
|
+
* <div forDropdownMenu [(open)]="open">
|
|
38
|
+
* <button forDropdownMenuTrigger>Options</button>
|
|
39
|
+
* @if (open()) {
|
|
40
|
+
* <div forMenuContent>…</div>
|
|
41
|
+
* }
|
|
42
|
+
* </div>
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* Selecting a `[forMenuItem]` closes the menu (call `event.preventDefault()`
|
|
46
|
+
* on the item's `(activate)` event to keep it open). Escape, pointer-down
|
|
47
|
+
* outside, and focus-outside also close — each emits a vetoable event.
|
|
48
|
+
*
|
|
49
|
+
* Most of the directive's body (id generation, item collection, typeahead,
|
|
50
|
+
* navigate / focus helpers, escape / outside-click veto plumbing) is owned
|
|
51
|
+
* by the shared `_internal/menu-overlay` helper. The directive contributes
|
|
52
|
+
* the inputs / outputs / model that make up the public surface, the
|
|
53
|
+
* trigger-anchored `anchor` and `dismissableExemptions`, and the
|
|
54
|
+
* `aria-haspopup="menu"` / return-focus semantics specific to the
|
|
55
|
+
* Menu Button pattern.
|
|
56
|
+
*/
|
|
57
|
+
class ForDropdownMenu extends MenuOverlayHost {
|
|
58
|
+
#defaults = inject(FOR_DROPDOWN_MENU_DEFAULTS);
|
|
59
|
+
/**
|
|
60
|
+
* Two-way bindable. Whether the menu is currently shown. The `model()`
|
|
61
|
+
* change emitter (`(openChange)`) fires only on internal transitions
|
|
62
|
+
* (trigger toggle, Escape, outside dismissal, item selection), never on
|
|
63
|
+
* consumer writes via `[(open)]`.
|
|
64
|
+
*/
|
|
65
|
+
open = model(false, /* @ts-ignore */
|
|
66
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
67
|
+
/**
|
|
68
|
+
* Side the menu is anchored to. Defaults to `'bottom'`. Pair with
|
|
69
|
+
* `align` for the full positioning API.
|
|
70
|
+
*
|
|
71
|
+
* One of the floating-ui positioning inputs shared verbatim across the
|
|
72
|
+
* three menu roots — their non-seed defaults come from the single
|
|
73
|
+
* `MENU_POSITIONING_DEFAULTS` source and `menu-positioning-inputs.spec.ts`
|
|
74
|
+
* guards the three roots against drift.
|
|
75
|
+
*/
|
|
76
|
+
side = input(MENU_POSITIONING_DEFAULTS.side, /* @ts-ignore */
|
|
77
|
+
...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
|
|
78
|
+
/** Alignment along the chosen `side`. Defaults to `'start'`. */
|
|
79
|
+
align = input(MENU_POSITIONING_DEFAULTS.align, /* @ts-ignore */
|
|
80
|
+
...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
81
|
+
/**
|
|
82
|
+
* Gap (px) between trigger and menu along the main axis. Default `4`.
|
|
83
|
+
* The default is read from
|
|
84
|
+
* `provideForDropdownMenuDefaults` for the surrounding scope.
|
|
85
|
+
*/
|
|
86
|
+
sideOffset = input(this.#defaults.sideOffset, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
87
|
+
/** Gap (px) along the cross axis. Default `0`. */
|
|
88
|
+
alignOffset = input(MENU_POSITIONING_DEFAULTS.alignOffset, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
89
|
+
/** When `true` (default), `flip` and `shift` keep the menu inside the viewport. */
|
|
90
|
+
avoidCollisions = input(MENU_POSITIONING_DEFAULTS.avoidCollisions, { ...(ngDevMode ? { debugName: "avoidCollisions" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
91
|
+
/**
|
|
92
|
+
* Padding (px) applied uniformly to flip / shift / size. Default `8`.
|
|
93
|
+
* The default is read from `provideForDropdownMenuDefaults` for the
|
|
94
|
+
* surrounding scope.
|
|
95
|
+
*/
|
|
96
|
+
collisionPadding = input(this.#defaults.collisionPadding, { ...(ngDevMode ? { debugName: "collisionPadding" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
97
|
+
/** Padding (px) for the `arrow` middleware. Default `0`. */
|
|
98
|
+
arrowPadding = input(MENU_POSITIONING_DEFAULTS.arrowPadding, { ...(ngDevMode ? { debugName: "arrowPadding" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
99
|
+
/** Stickiness behaviour for `shift`. Default `'partial'`. */
|
|
100
|
+
sticky = input(MENU_POSITIONING_DEFAULTS.sticky, /* @ts-ignore */
|
|
101
|
+
...(ngDevMode ? [{ debugName: "sticky" }] : /* istanbul ignore next */ []));
|
|
102
|
+
/** When `true`, sets `data-detached=""` while the trigger is scrolled off-screen. */
|
|
103
|
+
hideWhenDetached = input(MENU_POSITIONING_DEFAULTS.hideWhenDetached, { ...(ngDevMode ? { debugName: "hideWhenDetached" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
104
|
+
/**
|
|
105
|
+
* When `true` (default), the menu is clipped until floating-ui resolves
|
|
106
|
+
* its first position, preventing a flash at the viewport corner. Set to
|
|
107
|
+
* `false` so a dramatic `animate.enter` plays from its first frame.
|
|
108
|
+
*/
|
|
109
|
+
clipUntilPositioned = input(MENU_POSITIONING_DEFAULTS.clipUntilPositioned, { ...(ngDevMode ? { debugName: "clipUntilPositioned" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
110
|
+
/**
|
|
111
|
+
* When `true` (default), arrow-key navigation wraps from the last enabled
|
|
112
|
+
* item back to the first (and vice versa). When `false`, navigation stops
|
|
113
|
+
* at the ends.
|
|
114
|
+
*/
|
|
115
|
+
loop = input(true, { ...(ngDevMode ? { debugName: "loop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
116
|
+
/**
|
|
117
|
+
* Writing direction. Drives ArrowLeft / ArrowRight semantics on submenu
|
|
118
|
+
* triggers and items underneath this menu (in RTL, ArrowLeft opens a submenu
|
|
119
|
+
* and ArrowRight closes it back). When unset (default `null`), the inherited
|
|
120
|
+
* ambient direction is resolved from the nearest ancestor carrying a `dir`
|
|
121
|
+
* attribute (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]`
|
|
122
|
+
* always wins, the resolved value is reflected to the host `dir` attribute,
|
|
123
|
+
* and it is inherited by descendant submenus.
|
|
124
|
+
*/
|
|
125
|
+
_dirInput = input(null, { ...(ngDevMode ? { debugName: "_dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
|
|
126
|
+
dir = injectTextDirection(this._dirInput);
|
|
127
|
+
/**
|
|
128
|
+
* When true, trigger interaction is ignored and any open menu stays open
|
|
129
|
+
* until the consumer flips `open` themselves. The trigger reflects
|
|
130
|
+
* `data-disabled`; the items keep their per-item disabled semantics.
|
|
131
|
+
*/
|
|
132
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
133
|
+
/** When true (default), Escape, pointer-down outside, and focus outside close the menu. */
|
|
134
|
+
dismissible = input(true, { ...(ngDevMode ? { debugName: "dismissible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
135
|
+
/** When true (default), focus returns to the trigger on close. */
|
|
136
|
+
returnFocus = input(true, { ...(ngDevMode ? { debugName: "returnFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
137
|
+
/** Manual `aria-label` on `[forMenuContent]`. Use when the trigger isn't a meaningful name. */
|
|
138
|
+
ariaLabel = input(null, /* @ts-ignore */
|
|
139
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
140
|
+
/**
|
|
141
|
+
* Fires when Escape is pressed while the menu is open, just before it
|
|
142
|
+
* closes. Call `preventDefault()` on the emitted veto to keep the menu
|
|
143
|
+
* open and suppress the Escape-driven close.
|
|
144
|
+
*/
|
|
145
|
+
escapeKeyDown = output();
|
|
146
|
+
/**
|
|
147
|
+
* Fires on a pointer-down outside the menu (and outside the exempt
|
|
148
|
+
* trigger), just before it closes. Call `preventDefault()` on the veto to
|
|
149
|
+
* keep the menu open.
|
|
150
|
+
*/
|
|
151
|
+
pointerDownOutside = output();
|
|
152
|
+
/**
|
|
153
|
+
* Fires when focus moves outside the menu, just before it closes. Call
|
|
154
|
+
* `preventDefault()` on the veto to keep the menu open.
|
|
155
|
+
*/
|
|
156
|
+
focusOutside = output();
|
|
157
|
+
/**
|
|
158
|
+
* Composite outside-interaction channel: fires for either a
|
|
159
|
+
* pointer-down-outside or a focus-outside, just before the menu closes.
|
|
160
|
+
* Call `preventDefault()` on the veto to keep the menu open regardless of
|
|
161
|
+
* which interaction triggered it.
|
|
162
|
+
*/
|
|
163
|
+
interactOutside = output();
|
|
164
|
+
/**
|
|
165
|
+
* Fires just before the menu sends focus to its first / last enabled
|
|
166
|
+
* item on mount. Call `preventDefault()` on the emitted veto to skip
|
|
167
|
+
* the imperative focus move — useful when opening a menu from an
|
|
168
|
+
* input you want to keep focused.
|
|
169
|
+
*/
|
|
170
|
+
autoFocusOnOpen = output();
|
|
171
|
+
/**
|
|
172
|
+
* Fires just before focus returns to the trigger on unmount. Call
|
|
173
|
+
* `preventDefault()` on the veto to suppress the return-focus.
|
|
174
|
+
*/
|
|
175
|
+
autoFocusOnClose = output();
|
|
176
|
+
_overlay = createMenuOverlay('for-dropdown-menu', {
|
|
177
|
+
open: this.open,
|
|
178
|
+
disabled: this.disabled,
|
|
179
|
+
dismissible: this.dismissible,
|
|
180
|
+
loop: this.loop,
|
|
181
|
+
escapeKeyDown: this.escapeKeyDown,
|
|
182
|
+
pointerDownOutside: this.pointerDownOutside,
|
|
183
|
+
focusOutside: this.focusOutside,
|
|
184
|
+
interactOutside: this.interactOutside,
|
|
185
|
+
autoFocusOnOpen: this.autoFocusOnOpen,
|
|
186
|
+
autoFocusOnClose: this.autoFocusOnClose,
|
|
187
|
+
});
|
|
188
|
+
anchor = computed(() => this._overlay.trigger(), /* @ts-ignore */
|
|
189
|
+
...(ngDevMode ? [{ debugName: "anchor" }] : /* istanbul ignore next */ []));
|
|
190
|
+
dismissableExemptions = computed(() => {
|
|
191
|
+
const t = this._overlay.trigger();
|
|
192
|
+
return t ? [t] : [];
|
|
193
|
+
}, /* @ts-ignore */
|
|
194
|
+
...(ngDevMode ? [{ debugName: "dismissableExemptions" }] : /* istanbul ignore next */ []));
|
|
195
|
+
/** Top-level: no parent menu. */
|
|
196
|
+
parentMenu = null;
|
|
197
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForDropdownMenu, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
198
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForDropdownMenu, isStandalone: true, selector: "[forDropdownMenu]", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, alignOffset: { classPropertyName: "alignOffset", publicName: "alignOffset", isSignal: true, isRequired: false, transformFunction: null }, avoidCollisions: { classPropertyName: "avoidCollisions", publicName: "avoidCollisions", isSignal: true, isRequired: false, transformFunction: null }, collisionPadding: { classPropertyName: "collisionPadding", publicName: "collisionPadding", isSignal: true, isRequired: false, transformFunction: null }, arrowPadding: { classPropertyName: "arrowPadding", publicName: "arrowPadding", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, hideWhenDetached: { classPropertyName: "hideWhenDetached", publicName: "hideWhenDetached", isSignal: true, isRequired: false, transformFunction: null }, clipUntilPositioned: { classPropertyName: "clipUntilPositioned", publicName: "clipUntilPositioned", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, _dirInput: { classPropertyName: "_dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, returnFocus: { classPropertyName: "returnFocus", publicName: "returnFocus", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside", focusOutside: "focusOutside", interactOutside: "interactOutside", autoFocusOnOpen: "autoFocusOnOpen", autoFocusOnClose: "autoFocusOnClose" }, host: { properties: { "attr.data-state": "open() ? \"open\" : \"closed\"", "attr.data-disabled": "disabled() ? \"\" : null", "attr.dir": "dir()" } }, providers: [{ provide: FOR_MENU_CONTEXT, useExisting: ForDropdownMenu }], exportAs: ["forDropdownMenu"], usesInheritance: true, ngImport: i0 });
|
|
199
|
+
}
|
|
200
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForDropdownMenu, decorators: [{
|
|
201
|
+
type: Directive,
|
|
202
|
+
args: [{
|
|
203
|
+
selector: '[forDropdownMenu]',
|
|
204
|
+
exportAs: 'forDropdownMenu',
|
|
205
|
+
host: {
|
|
206
|
+
'[attr.data-state]': 'open() ? "open" : "closed"',
|
|
207
|
+
'[attr.data-disabled]': 'disabled() ? "" : null',
|
|
208
|
+
'[attr.dir]': 'dir()',
|
|
209
|
+
},
|
|
210
|
+
providers: [{ provide: FOR_MENU_CONTEXT, useExisting: ForDropdownMenu }],
|
|
211
|
+
}]
|
|
212
|
+
}], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], alignOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignOffset", required: false }] }], avoidCollisions: [{ type: i0.Input, args: [{ isSignal: true, alias: "avoidCollisions", required: false }] }], collisionPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "collisionPadding", required: false }] }], arrowPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowPadding", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], hideWhenDetached: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideWhenDetached", required: false }] }], clipUntilPositioned: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipUntilPositioned", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], _dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], returnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "returnFocus", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], escapeKeyDown: [{ type: i0.Output, args: ["escapeKeyDown"] }], pointerDownOutside: [{ type: i0.Output, args: ["pointerDownOutside"] }], focusOutside: [{ type: i0.Output, args: ["focusOutside"] }], interactOutside: [{ type: i0.Output, args: ["interactOutside"] }], autoFocusOnOpen: [{ type: i0.Output, args: ["autoFocusOnOpen"] }], autoFocusOnClose: [{ type: i0.Output, args: ["autoFocusOnClose"] }] } });
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Resolves the trigger's menu root: the explicit reference when the
|
|
216
|
+
* `[forDropdownMenuTrigger]` input carries one, the injected `FOR_MENU_CONTEXT`
|
|
217
|
+
* otherwise. The orphan error only fires when neither resolves, on first read
|
|
218
|
+
* of the returned signal. Must be called in an injection context.
|
|
219
|
+
*/
|
|
220
|
+
function injectDropdownMenuTriggerContext(explicitRoot) {
|
|
221
|
+
const injected = inject(FOR_MENU_CONTEXT, { optional: true });
|
|
222
|
+
return computed(() => {
|
|
223
|
+
const explicit = explicitRoot();
|
|
224
|
+
if (explicit !== '') {
|
|
225
|
+
return explicit;
|
|
226
|
+
}
|
|
227
|
+
if (injected) {
|
|
228
|
+
return injected;
|
|
229
|
+
}
|
|
230
|
+
throw new Error('[forty-cdk/dropdown-menu] ForDropdownMenuTrigger could not resolve its [forDropdownMenu] root: ' +
|
|
231
|
+
'no FOR_MENU_CONTEXT provider is visible and no explicit root reference was passed. ' +
|
|
232
|
+
"If this trigger is declared inside an ng-template, DI resolves at the template's declaration " +
|
|
233
|
+
'site — not where it is stamped — so either declare the template inside the root or pass the ' +
|
|
234
|
+
'root explicitly: [forDropdownMenuTrigger]="root" with #root="forDropdownMenu".');
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Button that toggles the dropdown menu when clicked, opens via ArrowDown
|
|
239
|
+
* (focus first item) or ArrowUp (focus last item).
|
|
240
|
+
*
|
|
241
|
+
* Apply on a `<button>` so Space / Enter dispatch native click events
|
|
242
|
+
* automatically — those open the menu via `(click)`. Wires `aria-haspopup`,
|
|
243
|
+
* `aria-expanded`, and `aria-controls` per the menu-button pattern.
|
|
244
|
+
*
|
|
245
|
+
* The trigger distinguishes pointer from keyboard activation (a `pointerdown`
|
|
246
|
+
* preceding the click marks it pointer-driven): both move focus to the first
|
|
247
|
+
* item, but only a keyboard open highlights it — a mouse-opened menu carries
|
|
248
|
+
* no `data-highlighted` until keyboard navigation.
|
|
249
|
+
*
|
|
250
|
+
* Disabling: the trigger merges its own `disabled` input OR the root's
|
|
251
|
+
* `disabled`. The native `disabled` attribute is reflected imperatively and
|
|
252
|
+
* non-destructively — the directive only removes the attribute when it set it
|
|
253
|
+
* itself, so a consumer-set `disabled` on the same button always survives an
|
|
254
|
+
* enabled menu context.
|
|
255
|
+
*
|
|
256
|
+
* The root is normally resolved via DI from the enclosing `[forDropdownMenu]`.
|
|
257
|
+
* When the trigger is declared inside an `ng-template` stamped into the root
|
|
258
|
+
* (e.g. via `ngTemplateOutlet`), DI resolves at the template's declaration
|
|
259
|
+
* site and misses the root — pass it explicitly through the selector input,
|
|
260
|
+
* `routerLink`-style: `[forDropdownMenuTrigger]="root"` with
|
|
261
|
+
* `#root="forDropdownMenu"`.
|
|
262
|
+
*/
|
|
263
|
+
class ForDropdownMenuTrigger {
|
|
264
|
+
#host = inject(ElementRef);
|
|
265
|
+
#pointerActivation = false;
|
|
266
|
+
/**
|
|
267
|
+
* Optional explicit reference to the `[forDropdownMenu]` root, named after
|
|
268
|
+
* the selector `routerLink`-style. The bare valueless attribute keeps
|
|
269
|
+
* resolving the enclosing root via DI; pass the root explicitly
|
|
270
|
+
* (`[forDropdownMenuTrigger]="root"`, with `#root="forDropdownMenu"`) when
|
|
271
|
+
* the trigger is declared in an `ng-template` stamped inside the root — DI
|
|
272
|
+
* resolves at the template's declaration site, so the enclosing root is
|
|
273
|
+
* invisible there. The empty string (what the valueless attribute yields)
|
|
274
|
+
* is treated as unset.
|
|
275
|
+
*/
|
|
276
|
+
forDropdownMenuTrigger = input('', /* @ts-ignore */
|
|
277
|
+
...(ngDevMode ? [{ debugName: "forDropdownMenuTrigger" }] : /* istanbul ignore next */ []));
|
|
278
|
+
ctx = injectDropdownMenuTriggerContext(this.forDropdownMenuTrigger);
|
|
279
|
+
/** Disables this trigger only, in addition to the root's `disabled`. */
|
|
280
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
281
|
+
/** Whether the trigger is disabled — its own `disabled` input OR the root's. */
|
|
282
|
+
effectiveDisabled = computed(() => this.disabled() || this.ctx().disabled(), /* @ts-ignore */
|
|
283
|
+
...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
284
|
+
constructor() {
|
|
285
|
+
const el = this.#host.nativeElement;
|
|
286
|
+
// Registration is an imperative call into the resolved root's registry,
|
|
287
|
+
// not state derivation — the effect only re-registers the element when the
|
|
288
|
+
// resolved root changes (explicit reference swapped at runtime).
|
|
289
|
+
effect((onCleanup) => {
|
|
290
|
+
const ctx = this.ctx();
|
|
291
|
+
ctx.registerTrigger(el);
|
|
292
|
+
onCleanup(() => ctx.unregisterTrigger(el));
|
|
293
|
+
});
|
|
294
|
+
reflectDisabled(this.effectiveDisabled);
|
|
295
|
+
}
|
|
296
|
+
onPointerDown() {
|
|
297
|
+
this.#pointerActivation = true;
|
|
298
|
+
}
|
|
299
|
+
onClick() {
|
|
300
|
+
const modality = this.#pointerActivation ? 'pointer' : 'keyboard';
|
|
301
|
+
this.#pointerActivation = false;
|
|
302
|
+
if (this.effectiveDisabled()) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
this.ctx().toggle('first', modality);
|
|
306
|
+
}
|
|
307
|
+
onKeyDown(event) {
|
|
308
|
+
this.#pointerActivation = false;
|
|
309
|
+
if (this.effectiveDisabled()) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (event.key === 'ArrowDown') {
|
|
313
|
+
event.preventDefault();
|
|
314
|
+
this.ctx().openMenu('first');
|
|
315
|
+
}
|
|
316
|
+
else if (event.key === 'ArrowUp') {
|
|
317
|
+
event.preventDefault();
|
|
318
|
+
this.ctx().openMenu('last');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForDropdownMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
322
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForDropdownMenuTrigger, isStandalone: true, selector: "[forDropdownMenuTrigger]", inputs: { forDropdownMenuTrigger: { classPropertyName: "forDropdownMenuTrigger", publicName: "forDropdownMenuTrigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, listeners: { "pointerdown": "onPointerDown()", "click": "onClick()", "keydown": "onKeyDown($event)" }, properties: { "id": "ctx().triggerId()", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "ctx().open() ? \"true\" : \"false\"", "attr.aria-controls": "ctx().open() ? ctx().contentId() : null", "attr.data-state": "ctx().open() ? \"open\" : \"closed\"", "attr.data-disabled": "effectiveDisabled() ? \"\" : null", "attr.aria-disabled": "effectiveDisabled() ? \"true\" : null" } }, exportAs: ["forDropdownMenuTrigger"], ngImport: i0 });
|
|
323
|
+
}
|
|
324
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForDropdownMenuTrigger, decorators: [{
|
|
325
|
+
type: Directive,
|
|
326
|
+
args: [{
|
|
327
|
+
selector: '[forDropdownMenuTrigger]',
|
|
328
|
+
exportAs: 'forDropdownMenuTrigger',
|
|
329
|
+
host: {
|
|
330
|
+
type: 'button',
|
|
331
|
+
'[id]': 'ctx().triggerId()',
|
|
332
|
+
'[attr.aria-haspopup]': '"menu"',
|
|
333
|
+
'[attr.aria-expanded]': 'ctx().open() ? "true" : "false"',
|
|
334
|
+
'[attr.aria-controls]': 'ctx().open() ? ctx().contentId() : null',
|
|
335
|
+
'[attr.data-state]': 'ctx().open() ? "open" : "closed"',
|
|
336
|
+
'[attr.data-disabled]': 'effectiveDisabled() ? "" : null',
|
|
337
|
+
'[attr.aria-disabled]': 'effectiveDisabled() ? "true" : null',
|
|
338
|
+
'(pointerdown)': 'onPointerDown()',
|
|
339
|
+
'(click)': 'onClick()',
|
|
340
|
+
'(keydown)': 'onKeyDown($event)',
|
|
341
|
+
},
|
|
342
|
+
}]
|
|
343
|
+
}], ctorParameters: () => [], propDecorators: { forDropdownMenuTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "forDropdownMenuTrigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Generated bundle index. Do not edit.
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
export { FOR_DROPDOWN_MENU_DEFAULTS, ForDropdownMenu, ForDropdownMenuTrigger, provideForDropdownMenuDefaults };
|
|
350
|
+
//# sourceMappingURL=forty-cdk-dropdown-menu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forty-cdk-dropdown-menu.mjs","sources":["../../../projects/forty-cdk/dropdown-menu/src/dropdown-menu-defaults.ts","../../../projects/forty-cdk/dropdown-menu/src/dropdown-menu.ts","../../../projects/forty-cdk/dropdown-menu/src/dropdown-menu-trigger.ts","../../../projects/forty-cdk/dropdown-menu/src/forty-cdk-dropdown-menu.ts"],"sourcesContent":["import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant dropdown menus in the surrounding\n * injector scope. Configure with `provideForDropdownMenuDefaults` either\n * at the application root or in any component's `providers` array; partial\n * overrides merge with the parent scope.\n */\nexport interface ForDropdownMenuDefaults {\n /**\n * Distance (px) between the dropdown trigger and the floating content\n * along the resolved `side` axis.\n */\n sideOffset: number;\n /**\n * Padding (px) added to the viewport edges for collision-aware\n * positioning. Higher values keep the floating content further from\n * the edge when `flip` / `shift` runs.\n */\n collisionPadding: number;\n}\n\n/**\n * Library fallback for dropdown menu defaults, read at the root injector when no\n * consumer has called `provideForDropdownMenuDefaults`. Exported for the shared defaults\n * contract spec; not re-exported from the primitive's public entry.\n */\nexport const FOR_DROPDOWN_MENU_FALLBACK_DEFAULTS: ForDropdownMenuDefaults = {\n sideOffset: 4,\n collisionPadding: 8,\n};\n\nconst { token, provideDefaults } = createDefaults<ForDropdownMenuDefaults>(\n 'FOR_DROPDOWN_MENU_DEFAULTS',\n FOR_DROPDOWN_MENU_FALLBACK_DEFAULTS,\n);\n\n/** Token holding the resolved dropdown-menu defaults for the current scope. */\nexport const FOR_DROPDOWN_MENU_DEFAULTS = token;\n\n/**\n * Configures forty-cdk dropdown-menu defaults for this injector scope.\n * Partial overrides inherit unspecified keys from the parent scope (or\n * library defaults at the root).\n */\nexport function provideForDropdownMenuDefaults(\n defaults: Partial<ForDropdownMenuDefaults> = {},\n): Provider[] {\n return provideDefaults(defaults);\n}\n","import {\n booleanAttribute,\n computed,\n Directive,\n inject,\n input,\n model,\n numberAttribute,\n output,\n} from '@angular/core';\nimport type { ReferenceElement } from '@floating-ui/dom';\n\nimport {\n type FloatingAlign,\n type FloatingSide,\n type WritingDirection,\n createMenuOverlay,\n MenuOverlayHost,\n MENU_POSITIONING_DEFAULTS,\n injectTextDirection,\n type VetoableEvent,\n type VetoableNativeEvent,\n FOR_MENU_CONTEXT,\n type ForMenuContext,\n} from 'forty-cdk/core';\nimport { FOR_DROPDOWN_MENU_DEFAULTS } from './dropdown-menu-defaults';\n\n/**\n * Headless implementation of the [WAI-ARIA Menu Button pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/).\n * Apply on a wrapper that contains the trigger and the `@if`-mounted\n * `[forMenuContent]`. The directive owns open state, ids, and the registries\n * that wire trigger / content / items together.\n *\n * Mount/unmount of the visible menu is the consumer's responsibility — wrap\n * `[forMenuContent]` with `@if (open())` so `animate.enter` / `animate.leave`\n * fire on the natural mount cycle:\n *\n * ```html\n * <div forDropdownMenu [(open)]=\"open\">\n * <button forDropdownMenuTrigger>Options</button>\n * @if (open()) {\n * <div forMenuContent>…</div>\n * }\n * </div>\n * ```\n *\n * Selecting a `[forMenuItem]` closes the menu (call `event.preventDefault()`\n * on the item's `(activate)` event to keep it open). Escape, pointer-down\n * outside, and focus-outside also close — each emits a vetoable event.\n *\n * Most of the directive's body (id generation, item collection, typeahead,\n * navigate / focus helpers, escape / outside-click veto plumbing) is owned\n * by the shared `_internal/menu-overlay` helper. The directive contributes\n * the inputs / outputs / model that make up the public surface, the\n * trigger-anchored `anchor` and `dismissableExemptions`, and the\n * `aria-haspopup=\"menu\"` / return-focus semantics specific to the\n * Menu Button pattern.\n */\n@Directive({\n selector: '[forDropdownMenu]',\n exportAs: 'forDropdownMenu',\n host: {\n '[attr.data-state]': 'open() ? \"open\" : \"closed\"',\n '[attr.data-disabled]': 'disabled() ? \"\" : null',\n '[attr.dir]': 'dir()',\n },\n providers: [{ provide: FOR_MENU_CONTEXT, useExisting: ForDropdownMenu }],\n})\nexport class ForDropdownMenu extends MenuOverlayHost implements ForMenuContext {\n readonly #defaults = inject(FOR_DROPDOWN_MENU_DEFAULTS);\n\n /**\n * Two-way bindable. Whether the menu is currently shown. The `model()`\n * change emitter (`(openChange)`) fires only on internal transitions\n * (trigger toggle, Escape, outside dismissal, item selection), never on\n * consumer writes via `[(open)]`.\n */\n readonly open = model<boolean>(false);\n\n /**\n * Side the menu is anchored to. Defaults to `'bottom'`. Pair with\n * `align` for the full positioning API.\n *\n * One of the floating-ui positioning inputs shared verbatim across the\n * three menu roots — their non-seed defaults come from the single\n * `MENU_POSITIONING_DEFAULTS` source and `menu-positioning-inputs.spec.ts`\n * guards the three roots against drift.\n */\n readonly side = input<FloatingSide | undefined>(MENU_POSITIONING_DEFAULTS.side);\n\n /** Alignment along the chosen `side`. Defaults to `'start'`. */\n readonly align = input<FloatingAlign | undefined>(MENU_POSITIONING_DEFAULTS.align);\n\n /**\n * Gap (px) between trigger and menu along the main axis. Default `4`.\n * The default is read from\n * `provideForDropdownMenuDefaults` for the surrounding scope.\n */\n readonly sideOffset = input(this.#defaults.sideOffset, { transform: numberAttribute });\n\n /** Gap (px) along the cross axis. Default `0`. */\n readonly alignOffset = input(MENU_POSITIONING_DEFAULTS.alignOffset, {\n transform: numberAttribute,\n });\n\n /** When `true` (default), `flip` and `shift` keep the menu inside the viewport. */\n readonly avoidCollisions = input(MENU_POSITIONING_DEFAULTS.avoidCollisions, {\n transform: booleanAttribute,\n });\n\n /**\n * Padding (px) applied uniformly to flip / shift / size. Default `8`.\n * The default is read from `provideForDropdownMenuDefaults` for the\n * surrounding scope.\n */\n readonly collisionPadding = input(this.#defaults.collisionPadding, {\n transform: numberAttribute,\n });\n\n /** Padding (px) for the `arrow` middleware. Default `0`. */\n readonly arrowPadding = input(MENU_POSITIONING_DEFAULTS.arrowPadding, {\n transform: numberAttribute,\n });\n\n /** Stickiness behaviour for `shift`. Default `'partial'`. */\n readonly sticky = input<'partial' | 'always' | false>(MENU_POSITIONING_DEFAULTS.sticky);\n\n /** When `true`, sets `data-detached=\"\"` while the trigger is scrolled off-screen. */\n readonly hideWhenDetached = input(MENU_POSITIONING_DEFAULTS.hideWhenDetached, {\n transform: booleanAttribute,\n });\n\n /**\n * When `true` (default), the menu is clipped until floating-ui resolves\n * its first position, preventing a flash at the viewport corner. Set to\n * `false` so a dramatic `animate.enter` plays from its first frame.\n */\n readonly clipUntilPositioned = input(MENU_POSITIONING_DEFAULTS.clipUntilPositioned, {\n transform: booleanAttribute,\n });\n\n /**\n * When `true` (default), arrow-key navigation wraps from the last enabled\n * item back to the first (and vice versa). When `false`, navigation stops\n * at the ends.\n */\n readonly loop = input(true, { transform: booleanAttribute });\n\n /**\n * Writing direction. Drives ArrowLeft / ArrowRight semantics on submenu\n * triggers and items underneath this menu (in RTL, ArrowLeft opens a submenu\n * and ArrowRight closes it back). When unset (default `null`), the inherited\n * ambient direction is resolved from the nearest ancestor carrying a `dir`\n * attribute (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]`\n * always wins, the resolved value is reflected to the host `dir` attribute,\n * and it is inherited by descendant submenus.\n */\n readonly _dirInput = input<WritingDirection | null>(null, { alias: 'dir' });\n readonly dir = injectTextDirection(this._dirInput);\n\n /**\n * When true, trigger interaction is ignored and any open menu stays open\n * until the consumer flips `open` themselves. The trigger reflects\n * `data-disabled`; the items keep their per-item disabled semantics.\n */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** When true (default), Escape, pointer-down outside, and focus outside close the menu. */\n readonly dismissible = input(true, { transform: booleanAttribute });\n\n /** When true (default), focus returns to the trigger on close. */\n readonly returnFocus = input(true, { transform: booleanAttribute });\n\n /** Manual `aria-label` on `[forMenuContent]`. Use when the trigger isn't a meaningful name. */\n readonly ariaLabel = input<string | null>(null);\n\n /**\n * Fires when Escape is pressed while the menu is open, just before it\n * closes. Call `preventDefault()` on the emitted veto to keep the menu\n * open and suppress the Escape-driven close.\n */\n readonly escapeKeyDown = output<VetoableNativeEvent<KeyboardEvent>>();\n\n /**\n * Fires on a pointer-down outside the menu (and outside the exempt\n * trigger), just before it closes. Call `preventDefault()` on the veto to\n * keep the menu open.\n */\n readonly pointerDownOutside = output<VetoableNativeEvent<PointerEvent>>();\n\n /**\n * Fires when focus moves outside the menu, just before it closes. Call\n * `preventDefault()` on the veto to keep the menu open.\n */\n readonly focusOutside = output<VetoableNativeEvent<FocusEvent>>();\n\n /**\n * Composite outside-interaction channel: fires for either a\n * pointer-down-outside or a focus-outside, just before the menu closes.\n * Call `preventDefault()` on the veto to keep the menu open regardless of\n * which interaction triggered it.\n */\n readonly interactOutside = output<VetoableNativeEvent<PointerEvent | FocusEvent>>();\n\n /**\n * Fires just before the menu sends focus to its first / last enabled\n * item on mount. Call `preventDefault()` on the emitted veto to skip\n * the imperative focus move — useful when opening a menu from an\n * input you want to keep focused.\n */\n readonly autoFocusOnOpen = output<VetoableEvent>();\n\n /**\n * Fires just before focus returns to the trigger on unmount. Call\n * `preventDefault()` on the veto to suppress the return-focus.\n */\n readonly autoFocusOnClose = output<VetoableEvent>();\n\n protected readonly _overlay = createMenuOverlay('for-dropdown-menu', {\n open: this.open,\n disabled: this.disabled,\n dismissible: this.dismissible,\n loop: this.loop,\n escapeKeyDown: this.escapeKeyDown,\n pointerDownOutside: this.pointerDownOutside,\n focusOutside: this.focusOutside,\n interactOutside: this.interactOutside,\n autoFocusOnOpen: this.autoFocusOnOpen,\n autoFocusOnClose: this.autoFocusOnClose,\n });\n\n readonly anchor = computed<ReferenceElement | null>(() => this._overlay.trigger());\n readonly dismissableExemptions = computed<readonly HTMLElement[]>(() => {\n const t = this._overlay.trigger();\n return t ? [t] : [];\n });\n\n /** Top-level: no parent menu. */\n readonly parentMenu = null;\n}\n","import {\n booleanAttribute,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n type Signal,\n} from '@angular/core';\n\nimport {\n reflectDisabled,\n type MenuActivationModality,\n FOR_MENU_CONTEXT,\n type ForMenuContext,\n} from 'forty-cdk/core';\n\n/**\n * Resolves the trigger's menu root: the explicit reference when the\n * `[forDropdownMenuTrigger]` input carries one, the injected `FOR_MENU_CONTEXT`\n * otherwise. The orphan error only fires when neither resolves, on first read\n * of the returned signal. Must be called in an injection context.\n */\nfunction injectDropdownMenuTriggerContext(\n explicitRoot: Signal<ForMenuContext | ''>,\n): Signal<ForMenuContext> {\n const injected = inject(FOR_MENU_CONTEXT, { optional: true });\n return computed(() => {\n const explicit = explicitRoot();\n if (explicit !== '') {\n return explicit;\n }\n if (injected) {\n return injected;\n }\n throw new Error(\n '[forty-cdk/dropdown-menu] ForDropdownMenuTrigger could not resolve its [forDropdownMenu] root: ' +\n 'no FOR_MENU_CONTEXT provider is visible and no explicit root reference was passed. ' +\n \"If this trigger is declared inside an ng-template, DI resolves at the template's declaration \" +\n 'site — not where it is stamped — so either declare the template inside the root or pass the ' +\n 'root explicitly: [forDropdownMenuTrigger]=\"root\" with #root=\"forDropdownMenu\".',\n );\n });\n}\n\n/**\n * Button that toggles the dropdown menu when clicked, opens via ArrowDown\n * (focus first item) or ArrowUp (focus last item).\n *\n * Apply on a `<button>` so Space / Enter dispatch native click events\n * automatically — those open the menu via `(click)`. Wires `aria-haspopup`,\n * `aria-expanded`, and `aria-controls` per the menu-button pattern.\n *\n * The trigger distinguishes pointer from keyboard activation (a `pointerdown`\n * preceding the click marks it pointer-driven): both move focus to the first\n * item, but only a keyboard open highlights it — a mouse-opened menu carries\n * no `data-highlighted` until keyboard navigation.\n *\n * Disabling: the trigger merges its own `disabled` input OR the root's\n * `disabled`. The native `disabled` attribute is reflected imperatively and\n * non-destructively — the directive only removes the attribute when it set it\n * itself, so a consumer-set `disabled` on the same button always survives an\n * enabled menu context.\n *\n * The root is normally resolved via DI from the enclosing `[forDropdownMenu]`.\n * When the trigger is declared inside an `ng-template` stamped into the root\n * (e.g. via `ngTemplateOutlet`), DI resolves at the template's declaration\n * site and misses the root — pass it explicitly through the selector input,\n * `routerLink`-style: `[forDropdownMenuTrigger]=\"root\"` with\n * `#root=\"forDropdownMenu\"`.\n */\n@Directive({\n selector: '[forDropdownMenuTrigger]',\n exportAs: 'forDropdownMenuTrigger',\n host: {\n type: 'button',\n '[id]': 'ctx().triggerId()',\n '[attr.aria-haspopup]': '\"menu\"',\n '[attr.aria-expanded]': 'ctx().open() ? \"true\" : \"false\"',\n '[attr.aria-controls]': 'ctx().open() ? ctx().contentId() : null',\n '[attr.data-state]': 'ctx().open() ? \"open\" : \"closed\"',\n '[attr.data-disabled]': 'effectiveDisabled() ? \"\" : null',\n '[attr.aria-disabled]': 'effectiveDisabled() ? \"true\" : null',\n '(pointerdown)': 'onPointerDown()',\n '(click)': 'onClick()',\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class ForDropdownMenuTrigger {\n readonly #host = inject<ElementRef<HTMLElement>>(ElementRef);\n #pointerActivation = false;\n\n /**\n * Optional explicit reference to the `[forDropdownMenu]` root, named after\n * the selector `routerLink`-style. The bare valueless attribute keeps\n * resolving the enclosing root via DI; pass the root explicitly\n * (`[forDropdownMenuTrigger]=\"root\"`, with `#root=\"forDropdownMenu\"`) when\n * the trigger is declared in an `ng-template` stamped inside the root — DI\n * resolves at the template's declaration site, so the enclosing root is\n * invisible there. The empty string (what the valueless attribute yields)\n * is treated as unset.\n */\n readonly forDropdownMenuTrigger = input<ForMenuContext | ''>('');\n\n protected readonly ctx = injectDropdownMenuTriggerContext(this.forDropdownMenuTrigger);\n\n /** Disables this trigger only, in addition to the root's `disabled`. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** Whether the trigger is disabled — its own `disabled` input OR the root's. */\n readonly effectiveDisabled = computed(() => this.disabled() || this.ctx().disabled());\n\n constructor() {\n const el = this.#host.nativeElement;\n // Registration is an imperative call into the resolved root's registry,\n // not state derivation — the effect only re-registers the element when the\n // resolved root changes (explicit reference swapped at runtime).\n effect((onCleanup) => {\n const ctx = this.ctx();\n ctx.registerTrigger(el);\n onCleanup(() => ctx.unregisterTrigger(el));\n });\n reflectDisabled(this.effectiveDisabled);\n }\n\n protected onPointerDown(): void {\n this.#pointerActivation = true;\n }\n\n protected onClick(): void {\n const modality: MenuActivationModality = this.#pointerActivation ? 'pointer' : 'keyboard';\n this.#pointerActivation = false;\n if (this.effectiveDisabled()) {\n return;\n }\n this.ctx().toggle('first', modality);\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n this.#pointerActivation = false;\n if (this.effectiveDisabled()) {\n return;\n }\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n this.ctx().openMenu('first');\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n this.ctx().openMenu('last');\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|