@nordhealth/components 4.25.1 → 4.26.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.
Files changed (57) hide show
  1. package/custom-elements.json +6502 -4577
  2. package/lib/Aside.js +8 -0
  3. package/lib/Aside.js.map +1 -0
  4. package/lib/AsideDrawer.js +14 -0
  5. package/lib/AsideDrawer.js.map +1 -0
  6. package/lib/AsideTrigger.js +5 -0
  7. package/lib/AsideTrigger.js.map +1 -0
  8. package/lib/{Calendar-B5X2WKNb.js → Calendar-ChNZdVRO.js} +2 -2
  9. package/lib/{Calendar-B5X2WKNb.js.map → Calendar-ChNZdVRO.js.map} +1 -1
  10. package/lib/Calendar.js +1 -1
  11. package/lib/Checkbox.js +1 -1
  12. package/lib/CommandMenu.js +1 -1
  13. package/lib/CommandMenu.js.map +1 -1
  14. package/lib/DatePicker.js +1 -1
  15. package/lib/Drawer.js +1 -1
  16. package/lib/Drawer.js.map +1 -1
  17. package/lib/DropdownItem.js +1 -1
  18. package/lib/DropdownSubmenu.js.map +1 -1
  19. package/lib/Footer.js +1 -1
  20. package/lib/Footer.js.map +1 -1
  21. package/lib/Header.js +1 -1
  22. package/lib/Header.js.map +1 -1
  23. package/lib/Icon.js +1 -1
  24. package/lib/Input.js +1 -1
  25. package/lib/Layout.js +3 -1
  26. package/lib/Layout.js.map +1 -1
  27. package/lib/Modal.js +1 -1
  28. package/lib/NavToggle-DzKbd-El.js +2 -0
  29. package/lib/NavToggle-DzKbd-El.js.map +1 -0
  30. package/lib/NavToggle.js +1 -1
  31. package/lib/Select.js +1 -1
  32. package/lib/TagGroup.js +1 -1
  33. package/lib/Toggle.js +1 -1
  34. package/lib/Truncate.js.map +1 -1
  35. package/lib/bundle.js +56 -38
  36. package/lib/bundle.js.map +1 -1
  37. package/lib/focus-D8oSvIcN.js +2 -0
  38. package/lib/focus-D8oSvIcN.js.map +1 -0
  39. package/lib/index.js +1 -1
  40. package/lib/react.d.ts +45 -20
  41. package/lib/src/aside/Aside.d.ts +388 -0
  42. package/lib/src/aside-drawer/AsideDrawer.d.ts +153 -0
  43. package/lib/src/aside-trigger/AsideTrigger.d.ts +84 -0
  44. package/lib/src/common/body-scroll-lock.d.ts +20 -0
  45. package/lib/src/drawer/Drawer.d.ts +2 -1
  46. package/lib/src/dropdown-submenu/DropdownSubmenu.d.ts +0 -6
  47. package/lib/src/header/Header.d.ts +1 -1
  48. package/lib/src/index.d.ts +3 -0
  49. package/lib/src/layout/Layout.d.ts +17 -2
  50. package/lib/src/nav-toggle/NavToggle.d.ts +1 -16
  51. package/lib/src/truncate/Truncate.d.ts +1 -10
  52. package/lib/storage-CGZ-YX4-.js +2 -0
  53. package/lib/storage-CGZ-YX4-.js.map +1 -0
  54. package/lib/vue.d.ts +40 -20
  55. package/package.json +7 -7
  56. package/lib/NavToggle-BQxuLW2X.js +0 -2
  57. package/lib/NavToggle-BQxuLW2X.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ function e(o){var t;return(null===(t=o.activeElement)||void 0===t?void 0:t.shadowRoot)?e(o.activeElement.shadowRoot):o.activeElement||void 0}export{e as g};
2
+ //# sourceMappingURL=focus-D8oSvIcN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-D8oSvIcN.js","sources":["../src/common/focus.ts"],"sourcesContent":["/**\n * Gets the currently focused element, taking shadow roots into account.\n */\nexport function getFocusedElement(root: Document | ShadowRoot): Element | undefined {\n if (root.activeElement?.shadowRoot) {\n return getFocusedElement(root.activeElement.shadowRoot)\n }\n\n return root.activeElement || undefined\n}\n"],"names":["getFocusedElement","root","activeElement","_a","shadowRoot","undefined"],"mappings":"AAGM,SAAUA,EAAkBC,SAChC,OAAwB,UAApBA,EAAKC,qBAAe,IAAAC,OAAA,EAAAA,EAAAC,YACfJ,EAAkBC,EAAKC,cAAcE,YAGvCH,EAAKC,oBAAiBG,CAC/B"}
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export{default as Avatar}from"./Avatar.js";export{default as Badge}from"./Badge.js";export{default as Banner}from"./Banner.js";export{default as ButtonGroup}from"./ButtonGroup.js";export{default as Button}from"./Button.js";export{C as Calendar}from"./Calendar-B5X2WKNb.js";export{default as Card}from"./Card.js";export{default as Checkbox}from"./Checkbox.js";export{default as CommandMenu}from"./CommandMenu.js";export{default as CommandMenuAction}from"./CommandMenuAction.js";export{default as DatePicker}from"./DatePicker.js";export{default as Divider}from"./Divider.js";export{default as Drawer}from"./Drawer.js";export{default as DropdownGroup}from"./DropdownGroup.js";export{default as DropdownItem}from"./DropdownItem.js";export{default as DropdownSubmenu}from"./DropdownSubmenu.js";export{default as Dropdown}from"./Dropdown.js";export{default as EmptyState}from"./EmptyState.js";export{default as Fieldset}from"./Fieldset.js";export{default as Footer}from"./Footer.js";export{default as Header}from"./Header.js";export{default as Icon}from"./Icon.js";export{default as Input}from"./Input.js";export{default as Layout}from"./Layout.js";export{NavOpenChangeEvent}from"./NavOpenChangeEvent.js";export{NavResizeEvent}from"./NavResizeEvent.js";export{isTranslationRegistered,registerTranslation}from"./translation.js";export{default as Message}from"./Message.js";export{default as Modal,ModalCancelEvent,ModalCloseEvent}from"./Modal.js";export{default as NavGroup}from"./NavGroup.js";export{default as NavItem}from"./NavItem.js";export{N as NavToggle}from"./NavToggle-BQxuLW2X.js";export{default as Navigation}from"./Navigation.js";export{default as NotificationGroup}from"./NotificationGroup.js";export{default as Notification}from"./Notification.js";export{P as Popout}from"./Popout-DtEL0HZ0.js";export{default as ProgressBar}from"./ProgressBar.js";export{default as Progress}from"./Progress.js";export{default as Qrcode}from"./Qrcode.js";export{default as Radio}from"./Radio.js";export{default as Range}from"./Range.js";export{default as SegmentedControlItem}from"./SegmentedControlItem.js";export{default as SegmentedControl}from"./SegmentedControl.js";export{default as Select}from"./Select.js";export{default as Skeleton}from"./Skeleton.js";export{default as Spinner}from"./Spinner.js";export{default as Stack}from"./Stack.js";export{default as TabGroup}from"./TabGroup.js";export{default as TabPanel}from"./TabPanel.js";export{default as Tab}from"./Tab.js";export{default as Table}from"./Table.js";export{default as TagGroup}from"./TagGroup.js";export{default as Tag}from"./Tag.js";export{default as Textarea}from"./Textarea.js";export{default as ToastGroup}from"./ToastGroup.js";export{default as Toast}from"./Toast.js";export{default as Toggle}from"./Toggle.js";export{default as Tooltip}from"./Tooltip.js";export{default as TopBar}from"./TopBar.js";export{default as Truncate}from"./Truncate.js";export{default as VisuallyHidden}from"./VisuallyHidden.js";import"./tslib.es6-CmLYFWVC.js";import"lit";import"lit/decorators.js";import"./observe-D0n0zOfU.js";import"./fsm-Bq5jMQrK.js";import"./Component-DSU3Qp0O.js";import"lit/directives/class-map.js";import"./DirectionController-ChvNGESZ.js";import"./SlotController-Z6eG7LSZ.js";import"./EventController-BBOmvfLa.js";import"lit/directives/ref.js";import"./LightDomController-DIwtVelV.js";import"./cond-CI1KbneT.js";import"./FocusableMixin-BlQLNPdJ.js";import"./InputMixin-LetXsCyv.js";import"lit/directives/repeat.js";import"./tinykeys.module-_6MZt7MP.js";import"./collection-Dvg2XbxV.js";import"./dates-CAAlPKZi.js";import"./number-Dg2vCfGd.js";import"./LocalizeController.js";import"./en-us.js";import"./localization.js";import"./localization2.js";import"./localization3.js";import"./localization4.js";import"./localization5.js";import"./localization6.js";import"./localization7.js";import"./localization8.js";import"./localization9.js";import"./DateSelectEvent.js";import"./events-Bv6wNHwJ.js";import"./interface-checked-small-BQmkNgCI.js";import"lit/directives/if-defined.js";import"./FormAssociatedMixin-B4Qj-CQN.js";import"./FormDataController-OUt5L5uC.js";import"./SizeMixin-CU9cLbLC.js";import"./FormField-BFaVzUjk.js";import"./LightDismissController-4pH8cdko.js";import"./ShortcutController-BIb3WGzH.js";import"./KeyboardController.js";import"./SelectEvent.js";import"./interface-close-small-CnpAFMO3.js";import"./TextField-B955GOhe.js";import"./date-adapter.js";import"./DropdownItem-Cb-7cHMg.js";import"lit/directives/unsafe-html.js";import"./IconManager.js";import"lit/directives/style-map.js";import"./AutocompleteMixin-D8eiOxvO.js";import"./TextSelectableMixin-Cfv__lHS.js";import"./Sticky-DqnqENYN.js";import"./ModalController.js";import"./ScrollbarController-BFC67Y2x.js";import"./NotificationMixin-DOUQsx7N.js";import"./positioning-D-K8Mueq.js";import"./LightSlotController-Coyy4nqS.js";
1
+ export{default as AsideDrawer,AsideDrawerWidthChangeEvent}from"./AsideDrawer.js";export{default as AsideTrigger}from"./AsideTrigger.js";export{default as Aside,AsideActiveDrawerChangeEvent,AsideDrawerCloseEvent,AsideDrawerOpenEvent,AsideDrawerResizeEvent,AsideHandleModeChangeEvent}from"./Aside.js";export{default as Avatar}from"./Avatar.js";export{default as Badge}from"./Badge.js";export{default as Banner}from"./Banner.js";export{default as ButtonGroup}from"./ButtonGroup.js";export{default as Button}from"./Button.js";export{C as Calendar}from"./Calendar-ChNZdVRO.js";export{default as Card}from"./Card.js";export{default as Checkbox}from"./Checkbox.js";export{default as CommandMenu}from"./CommandMenu.js";export{default as CommandMenuAction}from"./CommandMenuAction.js";export{default as DatePicker}from"./DatePicker.js";export{default as Divider}from"./Divider.js";export{default as Drawer}from"./Drawer.js";export{default as DropdownGroup}from"./DropdownGroup.js";export{default as DropdownItem}from"./DropdownItem.js";export{default as DropdownSubmenu}from"./DropdownSubmenu.js";export{default as Dropdown}from"./Dropdown.js";export{default as EmptyState}from"./EmptyState.js";export{default as Fieldset}from"./Fieldset.js";export{default as Footer}from"./Footer.js";export{default as Header}from"./Header.js";export{default as Icon}from"./Icon.js";export{default as Input}from"./Input.js";export{default as Layout}from"./Layout.js";export{NavOpenChangeEvent}from"./NavOpenChangeEvent.js";export{NavResizeEvent}from"./NavResizeEvent.js";export{isTranslationRegistered,registerTranslation}from"./translation.js";export{default as Message}from"./Message.js";export{default as Modal,ModalCancelEvent,ModalCloseEvent}from"./Modal.js";export{default as NavGroup}from"./NavGroup.js";export{default as NavItem}from"./NavItem.js";export{N as NavToggle}from"./NavToggle-DzKbd-El.js";export{default as Navigation}from"./Navigation.js";export{default as NotificationGroup}from"./NotificationGroup.js";export{default as Notification}from"./Notification.js";export{P as Popout}from"./Popout-DtEL0HZ0.js";export{default as ProgressBar}from"./ProgressBar.js";export{default as Progress}from"./Progress.js";export{default as Qrcode}from"./Qrcode.js";export{default as Radio}from"./Radio.js";export{default as Range}from"./Range.js";export{default as SegmentedControlItem}from"./SegmentedControlItem.js";export{default as SegmentedControl}from"./SegmentedControl.js";export{default as Select}from"./Select.js";export{default as Skeleton}from"./Skeleton.js";export{default as Spinner}from"./Spinner.js";export{default as Stack}from"./Stack.js";export{default as TabGroup}from"./TabGroup.js";export{default as TabPanel}from"./TabPanel.js";export{default as Tab}from"./Tab.js";export{default as Table}from"./Table.js";export{default as TagGroup}from"./TagGroup.js";export{default as Tag}from"./Tag.js";export{default as Textarea}from"./Textarea.js";export{default as ToastGroup}from"./ToastGroup.js";export{default as Toast}from"./Toast.js";export{default as Toggle}from"./Toggle.js";export{default as Tooltip}from"./Tooltip.js";export{default as TopBar}from"./TopBar.js";export{default as Truncate}from"./Truncate.js";export{default as VisuallyHidden}from"./VisuallyHidden.js";import"./tslib.es6-CmLYFWVC.js";import"lit";import"lit/decorators.js";import"./observe-D0n0zOfU.js";import"./events-Bv6wNHwJ.js";import"./number-Dg2vCfGd.js";import"./storage-CGZ-YX4-.js";import"./Component-DSU3Qp0O.js";import"./SlotController-Z6eG7LSZ.js";import"./EventController-BBOmvfLa.js";import"lit/directives/class-map.js";import"./focus-D8oSvIcN.js";import"./fsm-Bq5jMQrK.js";import"./DirectionController-ChvNGESZ.js";import"lit/directives/ref.js";import"./LightDomController-DIwtVelV.js";import"./cond-CI1KbneT.js";import"./FocusableMixin-BlQLNPdJ.js";import"./InputMixin-LetXsCyv.js";import"lit/directives/repeat.js";import"./tinykeys.module-_6MZt7MP.js";import"./collection-Dvg2XbxV.js";import"./dates-CAAlPKZi.js";import"./LocalizeController.js";import"./en-us.js";import"./localization.js";import"./localization2.js";import"./localization3.js";import"./localization4.js";import"./localization5.js";import"./localization6.js";import"./localization7.js";import"./localization8.js";import"./localization9.js";import"./DateSelectEvent.js";import"./interface-checked-small-BQmkNgCI.js";import"lit/directives/if-defined.js";import"./FormAssociatedMixin-B4Qj-CQN.js";import"./FormDataController-OUt5L5uC.js";import"./SizeMixin-CU9cLbLC.js";import"./FormField-BFaVzUjk.js";import"./LightDismissController-4pH8cdko.js";import"./ShortcutController-BIb3WGzH.js";import"./KeyboardController.js";import"./SelectEvent.js";import"./interface-close-small-CnpAFMO3.js";import"./TextField-B955GOhe.js";import"./date-adapter.js";import"./DropdownItem-Cb-7cHMg.js";import"lit/directives/unsafe-html.js";import"./IconManager.js";import"lit/directives/style-map.js";import"./AutocompleteMixin-D8eiOxvO.js";import"./TextSelectableMixin-Cfv__lHS.js";import"./Sticky-DqnqENYN.js";import"./ModalController.js";import"./ScrollbarController-BFC67Y2x.js";import"./NotificationMixin-DOUQsx7N.js";import"./positioning-D-K8Mueq.js";import"./LightSlotController-Coyy4nqS.js";
2
2
  //# sourceMappingURL=index.js.map
package/lib/react.d.ts CHANGED
@@ -13,6 +13,51 @@ type MapEvents<T> = {
13
13
  declare module "react" {
14
14
  namespace JSX {
15
15
  interface IntrinsicElements {
16
+ "nord-aside": WCProps<Components.Aside> &
17
+ React.RefAttributes<Components.Aside> &
18
+ React.HTMLAttributes<HTMLElement> &
19
+ React.Attributes & {
20
+ /**
21
+ * Dispatched when `active-drawer` changes, with `activeDrawer` / `previousDrawer` properties. Fires on every transition including open, switch, and close.
22
+ */
23
+ "onactive-drawer-change"?: (event: Event) => void;
24
+
25
+ /**
26
+ * Dispatched when all drawers close (active-drawer went from a non-empty value to empty). Has a `previousDrawer` property.
27
+ */
28
+ "ondrawer-close"?: (event: Event) => void;
29
+
30
+ /**
31
+ * Dispatched when transitioning from no active drawer to an active one (i.e. a drawer opened from the closed state). Has an `activeDrawer` property.
32
+ */
33
+ "ondrawer-open"?: (event: Event) => void;
34
+
35
+ /**
36
+ * Dispatched when the active drawer's width changes, with `drawerId` (the specific drawer that changed) and `width` properties. Unlike active-drawer-change, this names a single drawer by id rather than describing a transition between drawers.
37
+ */
38
+ "ondrawer-resize"?: (event: Event) => void;
39
+
40
+ /**
41
+ * Dispatched when the resize handle's mode changes (`col-resize` / `pointer` / `default`). Mirrors the current value to the host's `data-handle-mode` attribute so consumers can also read it synchronously. Has `mode` / `previous` properties.
42
+ */
43
+ "onhandle-mode-change"?: (event: Event) => void;
44
+ };
45
+
46
+ "nord-aside-drawer": WCProps<Components.AsideDrawer> &
47
+ React.RefAttributes<Components.AsideDrawer> &
48
+ React.HTMLAttributes<HTMLElement> &
49
+ React.Attributes & {
50
+ /**
51
+ * Dispatched when the drawer's width changes. The event exposes `width` (the new applied inline-size in px) and `source` (`'drag' | 'keyboard' | 'attribute' | 'storage'`).
52
+ */
53
+ "onwidth-change"?: (event: Event) => void;
54
+ };
55
+
56
+ "nord-aside-trigger": WCProps<Components.AsideTrigger> &
57
+ React.RefAttributes<Components.AsideTrigger> &
58
+ React.HTMLAttributes<HTMLElement> &
59
+ React.Attributes & {};
60
+
16
61
  "nord-avatar": WCProps<Components.Avatar> &
17
62
  React.RefAttributes<Components.Avatar> &
18
63
  React.HTMLAttributes<HTMLElement> &
@@ -241,16 +286,6 @@ declare module "react" {
241
286
  * Dispatched when the navigation sidebar width changes. The event's `width` property contains the new width in pixels.
242
287
  */
243
288
  "onnav-resize"?: (event: Event) => void;
244
-
245
- /**
246
- * undefined
247
- */
248
- onnavopen?: (event: Event) => void;
249
-
250
- /**
251
- * undefined
252
- */
253
- onnavwidth?: (event: Event) => void;
254
289
  };
255
290
 
256
291
  "nord-message": WCProps<Components.Message> &
@@ -271,16 +306,6 @@ declare module "react" {
271
306
  * Dispatched when a modal is closed for any reason. The event includes an optional trigger property containing the original event that caused the close, if the modal was closed by a user action.
272
307
  */
273
308
  onclose?: (event: Event) => void;
274
-
275
- /**
276
- * undefined
277
- */
278
- onclosetrigger?: (event: Event) => void;
279
-
280
- /**
281
- * undefined
282
- */
283
- ontrigger?: (event: Event) => void;
284
309
  };
285
310
 
286
311
  "nord-nav-group": WCProps<Components.NavGroup> &
@@ -0,0 +1,388 @@
1
+ import { LitElement } from 'lit';
2
+ import { NordEvent } from '../common/events.js';
3
+ import '../tooltip/Tooltip.js';
4
+ export type AsideHandleClick = 'toggle' | 'close' | 'none';
5
+ export type AsideHandleMode = 'col-resize' | 'pointer' | 'default';
6
+ /**
7
+ * Event dispatched when the aside's active drawer changes — on open,
8
+ * switch, and close. `activeDrawer` is the new active drawer id (empty
9
+ * string when all drawers closed); `previousDrawer` is the prior one.
10
+ */
11
+ export declare class AsideActiveDrawerChangeEvent extends NordEvent {
12
+ activeDrawer: string;
13
+ previousDrawer: string;
14
+ constructor(activeDrawer: string, previousDrawer: string);
15
+ }
16
+ /**
17
+ * Event dispatched when a drawer opens from the fully-closed state.
18
+ * `activeDrawer` is the id of the drawer that opened.
19
+ */
20
+ export declare class AsideDrawerOpenEvent extends NordEvent {
21
+ activeDrawer: string;
22
+ constructor(activeDrawer: string);
23
+ }
24
+ /**
25
+ * Event dispatched when all drawers close. `previousDrawer` is the id of
26
+ * the drawer that was open before closing.
27
+ */
28
+ export declare class AsideDrawerCloseEvent extends NordEvent {
29
+ previousDrawer: string;
30
+ constructor(previousDrawer: string);
31
+ }
32
+ /**
33
+ * Event dispatched when the active drawer's width changes. `drawerId`
34
+ * names the specific drawer whose width changed (unlike the
35
+ * active-drawer-change event, which describes a transition between
36
+ * drawers); `width` is the new width in px.
37
+ */
38
+ export declare class AsideDrawerResizeEvent extends NordEvent {
39
+ drawerId: string;
40
+ width: number;
41
+ constructor(drawerId: string, width: number);
42
+ }
43
+ /**
44
+ * Event dispatched when the resize handle's interaction mode changes.
45
+ * `mode` is the new mode; `previous` is the prior mode.
46
+ */
47
+ export declare class AsideHandleModeChangeEvent extends NordEvent {
48
+ mode: AsideHandleMode;
49
+ previous: AsideHandleMode;
50
+ constructor(mode: AsideHandleMode, previous: AsideHandleMode);
51
+ }
52
+ /**
53
+ * Container for the right-side rail + drawer pattern in the app shell.
54
+ *
55
+ * @status new
56
+ * @category structure
57
+ * @slot rail - Free-form content placed in the rail column.
58
+ * @slot tooltip-divider - Tooltip anchored to the resize handle on hover.
59
+ * @slot - Default slot for `<nord-aside-drawer>` panels.
60
+ *
61
+ * @fires {AsideActiveDrawerChangeEvent} active-drawer-change - Dispatched
62
+ * when `active-drawer` changes, with `activeDrawer` / `previousDrawer`
63
+ * properties. Fires on every transition including open, switch, and close.
64
+ * @fires {AsideDrawerOpenEvent} drawer-open - Dispatched when transitioning
65
+ * from no active drawer to an active one (i.e. a drawer opened from the
66
+ * closed state). Has an `activeDrawer` property.
67
+ * @fires {AsideDrawerCloseEvent} drawer-close - Dispatched when all drawers
68
+ * close (active-drawer went from a non-empty value to empty). Has a
69
+ * `previousDrawer` property.
70
+ * @fires {AsideDrawerResizeEvent} drawer-resize - Dispatched when the active
71
+ * drawer's width changes, with `drawerId` (the specific drawer that changed)
72
+ * and `width` properties. Unlike active-drawer-change, this names a single
73
+ * drawer by id rather than describing a transition between drawers.
74
+ * @fires {AsideHandleModeChangeEvent} handle-mode-change - Dispatched when
75
+ * the resize handle's mode changes (`col-resize` / `pointer` / `default`).
76
+ * Mirrors the current value to the host's `data-handle-mode` attribute so
77
+ * consumers can also read it synchronously. Has `mode` / `previous` properties.
78
+ *
79
+ * @cssprop [--n-aside-rail-width=48px] - Controls the inline-size of the rail column.
80
+ * @cssprop [--n-aside-rail-gap=var(--n-space-s)] - Controls the gap between the rail and the active drawer.
81
+ * @cssprop [--n-aside-rail-background-color=var(--n-color-surface)] - Controls the background color of the rail column.
82
+ * @cssprop [--n-aside-background-color=var(--n-color-background)] - Controls the background color of the aside container (matches the layout's main area by default).
83
+ * @cssprop [--n-aside-drawers-margin-inline-start=0] - Inline-start margin of the drawers wrapper — creates a gap between the layout's main area and the active drawer card. The resize handle follows this margin so it stays at the drawer's edge.
84
+ * @cssprop [--n-aside-rail-narrow-block-size=56px] - Block-size of the rail when it renders as a bottom bar at <768px.
85
+ * @cssprop [--n-aside-rail-narrow-padding-inline=var(--n-space-m)] - Inline padding inside the bottom rail at <768px.
86
+ * @cssprop [--n-aside-rail-narrow-padding-block=var(--n-space-s)] - Block padding inside the bottom rail at <768px.
87
+ * @cssprop [--n-aside-rail-narrow-border-block-start-width=1px] - Top border width of the bottom rail at <768px. Set to 0 to remove.
88
+ * @cssprop [--n-aside-rail-narrow-border-color=var(--n-aside-rail-border-color)] - Top border color of the bottom rail at <768px.
89
+ * @cssprop [--n-aside-drawer-floating-inset-block-start=var(--n-layout-header-size, 60px)] - Distance from the viewport top to the floating drawer at <768px (clears the layout header).
90
+ * @cssprop [--n-aside-drawer-floating-inset-inline=0px] - Inline gap between the floating drawer and each viewport edge at <768px. Default 0 = full viewport width.
91
+ * @cssprop [--n-aside-drawer-slide-duration=300ms] - Duration of the slide-up animation when a drawer opens at <768px.
92
+ * @cssprop [--n-aside-drawer-slide-easing=cubic-bezier(0.4, 0, 0.2, 1)] - Easing of the slide-up animation when a drawer opens at <768px.
93
+ * @cssprop [--n-aside-drawer-floating-inset-block-end=calc(rail-size - bottom-offset)] - Distance from the viewport bottom to the floating drawer at <768px. By default the drawer's bottom edge meets the rail's top edge.
94
+ * @cssprop [--n-aside-drawer-floating-bottom-offset=0] - Subtracts from the floating drawer's `inset-block-end` to let the drawer extend past the rail's top edge (visual overlap). Default 0.
95
+ * @cssprop [--n-aside-backdrop-background=rgb(0 0 0 / 0.4)] - Background color of the backdrop behind the floating drawer at <768px.
96
+ * @cssprop [--n-aside-z-backdrop=calc(var(--n-index-top-bar) + 2)] - z-index of the backdrop at <768px (above the sticky footer so it dims the footer too).
97
+ * @cssprop [--n-aside-z-drawer-floating=calc(var(--n-index-top-bar) + 3)] - z-index of the floating drawer overlay at <768px (above the backdrop).
98
+ * @cssprop [--n-aside-z-rail-narrow=calc(var(--n-index-top-bar) + 4)] - z-index of the bottom rail at <768px (above the drawer so it remains tappable).
99
+ */
100
+ export default class Aside extends LitElement {
101
+ static styles: import("lit").CSSResult[];
102
+ /**
103
+ * The id of the currently-active `<nord-aside-drawer>`. Empty string
104
+ * means no drawer is open. Setting to an unknown / disabled id is a
105
+ * silent no-op.
106
+ */
107
+ activeDrawer: string;
108
+ /**
109
+ * Width of the rail column in px.
110
+ */
111
+ railWidth: number;
112
+ /**
113
+ * Gap between rail and the active drawer panel in px.
114
+ */
115
+ railGap: number;
116
+ /**
117
+ * Controls what clicking (no-drag) the resize handle does.
118
+ * Drag-for-resize is independent of this attribute.
119
+ */
120
+ handleClick: AsideHandleClick;
121
+ /**
122
+ * Session-only memory of the most-recent non-empty `active-drawer`.
123
+ * Does not persist across page reload. Used by the resize-handle
124
+ * click in `toggle` mode to reopen the last drawer.
125
+ * @internal
126
+ */
127
+ private lastDrawer;
128
+ private isDragging;
129
+ private wideScreen;
130
+ private hasRailItems;
131
+ private handleEl?;
132
+ private resizeTooltipEl?;
133
+ private tooltipSlot;
134
+ private readonly resizeTooltipId;
135
+ private childObserver?;
136
+ private dragStartX;
137
+ private hasDragged;
138
+ render(): import("lit").TemplateResult<1>;
139
+ private handleRailSlotChange;
140
+ private handleBackdropClick;
141
+ connectedCallback(): void;
142
+ disconnectedCallback(): void;
143
+ private handleMediaChange;
144
+ /**
145
+ * Esc closes the active drawer when it's floating (narrow + open).
146
+ * Wide-screen handling is unchanged — Esc has no effect at desktop.
147
+ */
148
+ private handleHostKeyDown;
149
+ /**
150
+ * Compute narrow-mode state from viewport + slot + layout context, and
151
+ * reflect two attributes on the aside host AND its containing layout:
152
+ *
153
+ * - `data-narrow-rail-bottom`: rail is a bottom-fixed bar.
154
+ * Active when narrow + rail has slotted items.
155
+ * - `data-narrow-floating-drawer`: drawer is a floating overlay.
156
+ * Active when narrow + a drawer is active (regardless of collapse-mode
157
+ * or fullscreen — fullscreen is neutralized at narrow).
158
+ *
159
+ * Also writes `--n-aside-rail-narrow-inset-block-end` on the host so
160
+ * the rail lifts above the layout's sticky-footer when one is present.
161
+ * Suspends `--n-layout-drawer-inline-size` (sets to 0) at narrow so
162
+ * the layout's main area doesn't reserve drawer space.
163
+ */
164
+ /**
165
+ * Tracks whether THIS aside currently holds a body-scroll lock so we
166
+ * don't double-lock or leak a lock across disconnect. The lock helper
167
+ * itself is ref-counted globally; this flag is per-instance bookkeeping.
168
+ */
169
+ private holdsBodyScrollLock;
170
+ private syncNarrowState;
171
+ /**
172
+ * Tracks whether the narrow floating-drawer focus trap is currently
173
+ * engaged, so `syncNarrowState` only enters / exits on a real
174
+ * transition (mirrors `holdsBodyScrollLock`).
175
+ */
176
+ private floatingFocusActive;
177
+ /**
178
+ * The element that was focused when the floating drawer opened (the
179
+ * activating trigger). Focus is returned here on close if it's still
180
+ * connected.
181
+ */
182
+ private floatingFocusReturnElement;
183
+ /**
184
+ * The drawer currently held in the floating focus trap. Cached so
185
+ * `exitFloatingFocus` can clear the contract `floating` flag and the
186
+ * fallback `tabindex` even after `activeDrawer` has already changed.
187
+ */
188
+ private trappedDrawer;
189
+ /**
190
+ * Engage the floating-drawer focus trap. SSR-safe: only runs when a
191
+ * document is available (it's only ever called from `syncNarrowState`,
192
+ * which runs in client lifecycle, but guard anyway).
193
+ */
194
+ private enterFloatingFocus;
195
+ /**
196
+ * Release the floating-drawer focus trap and restore focus to the
197
+ * captured trigger if it's still connected.
198
+ */
199
+ private exitFloatingFocus;
200
+ /**
201
+ * Trap Tab / Shift+Tab within the floating drawer. Focusable elements
202
+ * are queried live each keystroke because the drawer's content lives in
203
+ * slotted light DOM and can change. Wraps from last to first and back.
204
+ */
205
+ private handleFloatingFocusKeydown;
206
+ /**
207
+ * Whether the currently-focused element lives inside the drawer's
208
+ * subtree (light DOM or nested shadow roots). Used to redirect focus
209
+ * back into the trap when Tab would otherwise escape it.
210
+ */
211
+ private drawerContainsFocus;
212
+ /**
213
+ * Query the drawer's currently-focusable descendants in DOM order.
214
+ * Slotted light DOM, so a live `querySelectorAll` reflects the latest
215
+ * content. Filters out disabled / hidden / non-tabbable elements.
216
+ */
217
+ private focusableElementsInDrawer;
218
+ private firstFocusableInDrawer;
219
+ private isFocusable;
220
+ private clearNarrowState;
221
+ /**
222
+ * Re-broadcast a drawer's local `width-change` as the aside's
223
+ * `drawer-resize` so consumers only need one listener.
224
+ */
225
+ private handleDrawerWidthChange;
226
+ /**
227
+ * Cached references to the listened-to layout. Cleared on disconnect.
228
+ */
229
+ private syncedLayout?;
230
+ private get hostLayout();
231
+ /**
232
+ * When slotted into `<nord-layout slot="drawer">`, push the aside's
233
+ * outer width into `--n-layout-drawer-inline-size` so the layout's
234
+ * drawer slot grows/shrinks to fit. No-op when the aside isn't slotted
235
+ * into a layout.
236
+ */
237
+ private attachLayoutSync;
238
+ private detachLayoutSync;
239
+ /**
240
+ * Push the aside's intended outer width (rail + active drawer + margins
241
+ * + gap) into `--n-layout-drawer-inline-size` so the layout's drawer
242
+ * slot wrapper grows/shrinks to fit. Also pins
243
+ * `--n-layout-drawer-min-inline-size` to the rail's outer width so
244
+ * narrow viewports (where the layout would otherwise drop the content
245
+ * margin and overlay the rail) still reserve room for the rail.
246
+ */
247
+ private syncLayoutDrawerSize;
248
+ /**
249
+ * Surface `rail-width` / `rail-gap` as custom properties so the slotted
250
+ * rail content can react without the host needing a re-render.
251
+ */
252
+ protected applyRailVars(): void;
253
+ protected handleActiveDrawerChange(previousDrawer: string, activeDrawer: string): void;
254
+ private findDrawer;
255
+ private get activeDrawerEl();
256
+ private updateDrawerVisibility;
257
+ private observeChildren;
258
+ /**
259
+ * Reflect a `data-fullscreen` attribute on the host whenever any
260
+ * direct `<nord-aside-drawer>` child is currently fullscreen OR
261
+ * transitioning into/out of fullscreen. CSS selectors target this
262
+ * attribute to bump the rail above the fullscreen drawer's z-index.
263
+ */
264
+ private syncFullscreenAttr;
265
+ private startDragging;
266
+ /**
267
+ * Aside geometry captured at `startDragging` and reused for every
268
+ * pointermove until `stopDragging`. Cleared on drag end.
269
+ */
270
+ private dragGeometry?;
271
+ private stopDragging;
272
+ private handlePointerLeave;
273
+ /**
274
+ * Follow the pointer vertically so the tooltip floats next to the cursor
275
+ * along the handle's full height instead of staying anchored to its
276
+ * midpoint. Mirrors `<nord-layout>`'s handleResizeHoverMove.
277
+ */
278
+ private handleResizeHoverMove;
279
+ private handleDrag;
280
+ /**
281
+ * Viewport-x where the drawer's inline-start edge must stop. Unified
282
+ * rule that drives drag, keyboard, and fullscreen sizing:
283
+ *
284
+ * - `collapse-mode="rail"` → `max(0, nav.right)`. Nav stays visible
285
+ * as a rail, so the cap is the nav's right edge regardless of
286
+ * open/closed state (rail width vs expanded width).
287
+ * - otherwise → `max(nav.right, DRAWER_VIEWPORT_LEFT_OFFSET)`. The
288
+ * nav can translate fully off-screen; the 54px viewport floor only
289
+ * kicks in when the nav is actually off-screen — when the nav is
290
+ * on-screen and wider than 54, its right edge wins.
291
+ *
292
+ * Returns `undefined` when no host layout is present.
293
+ */
294
+ private getLeftCapViewportX;
295
+ /**
296
+ * Derive the drawer's maximum inline-size from {@link getLeftCapViewportX}
297
+ * WITHOUT reserving the layout's main-panel floor — the drawer grows
298
+ * all the way to the layout's main-panel edge. Used by fullscreen sizing.
299
+ *
300
+ * Returns `undefined` when no host layout is present.
301
+ */
302
+ private drawerWidthAtCap;
303
+ /**
304
+ * Derive the drawer's maximum inline-size from {@link getLeftCapViewportX}
305
+ * WITH the layout's main-panel floor reserved — drag / keyboard resize
306
+ * can never push the main body below `--n-layout-main-min-inline-size`
307
+ * (default `0` below 1240px, `600px` above). Used by drag, keyboard, and
308
+ * the drag-cap reconcile.
309
+ *
310
+ * Returns `undefined` when no host layout is present.
311
+ */
312
+ private drawerWidthAtCapWithMainFloor;
313
+ /**
314
+ * Shared core for {@link drawerWidthAtCap} /
315
+ * {@link drawerWidthAtCapWithMainFloor}. Subtracts:
316
+ * - `--n-layout-main-min-inline-size` when `reserveMainMin === true`.
317
+ *
318
+ * Reads the aside's geometry (bounding rect + computed style) once;
319
+ * callers in the same coalesced frame may pass a precomputed
320
+ * {@link AsideGeometry} to avoid redundant layout reads.
321
+ *
322
+ * Returns `undefined` when no host layout is present.
323
+ */
324
+ private computeDrawerWidthAtCap;
325
+ private parseLengthVar;
326
+ /**
327
+ * Publishes the layout's left-cap (the maximum the fullscreen drawer
328
+ * can grow to without overlapping the nav) as
329
+ * `--_n-aside-drawer-fullscreen-available` on the active drawer.
330
+ *
331
+ * The drawer's `:host([fullscreen])` rule uses CSS `min()` to clamp
332
+ * its own ceiling (`--_n-aside-drawer-fullscreen-max`) by this
333
+ * available value — so a consumer who sets `max-fullscreen-width`
334
+ * higher than the layout cap can never overflow past the main-panel
335
+ * edge. Pure-CSS resolution; this method just publishes the input.
336
+ *
337
+ * Coalesced via rAF so a flurry of nav/viewport/slot events collapses
338
+ * to one write per frame. The host's geometry (bounding rect + computed
339
+ * style) is read once per frame and threaded into both flushes so a
340
+ * single frame never re-reads layout.
341
+ */
342
+ private scheduleLeftCapReconcile;
343
+ private leftCapReconcileScheduled;
344
+ private flushFullscreenAvailable;
345
+ /**
346
+ * If the active drawer's docked width now exceeds the drag cap (e.g.
347
+ * the nav just expanded and the cap tightened), shrink the drawer
348
+ * down to the new cap. Skipped while a drag is in flight so the
349
+ * user's interaction stays unbroken; skipped for fullscreen drawers
350
+ * since fullscreen has its own cap path. Reconciles the same events
351
+ * `flushFullscreenAvailable` listens to.
352
+ */
353
+ private flushDragCap;
354
+ /**
355
+ * Remove the published `--_n-aside-drawer-fullscreen-available` var
356
+ * so the drawer's CSS `min()` rule falls back to `100vw` and the
357
+ * drawer's own `--_n-aside-drawer-fullscreen-max` becomes the
358
+ * effective cap. Called when the drawer leaves fullscreen.
359
+ */
360
+ private clearFullscreenSizeOverride;
361
+ private handleLayoutNavChange;
362
+ private handleViewportResize;
363
+ private navResizeObserver?;
364
+ /**
365
+ * Apply the `handle-click` matrix. Called by `stopDragging` when the
366
+ * pointer hasn't moved past the drag threshold.
367
+ */
368
+ private handleHandleClick;
369
+ private findFirstTriggerDrawer;
370
+ private handleKeyboardResize;
371
+ /**
372
+ * "Is the handle interactive right now?" — single computation that
373
+ * drives cursor, tooltip-divider visibility, and `aria-disabled`.
374
+ * @internal
375
+ */
376
+ get handleInteractive(): {
377
+ enabled: boolean;
378
+ dragOk: boolean;
379
+ clickOk: boolean;
380
+ cursor: 'col-resize' | 'pointer' | 'default';
381
+ tooltip: boolean;
382
+ };
383
+ }
384
+ declare global {
385
+ interface HTMLElementTagNameMap {
386
+ 'nord-aside': Aside;
387
+ }
388
+ }
@@ -0,0 +1,153 @@
1
+ import { LitElement } from 'lit';
2
+ import { NordEvent } from '../common/events.js';
3
+ export type AsideDrawerWidthSource = 'drag' | 'keyboard' | 'attribute' | 'storage';
4
+ /**
5
+ * Event dispatched when the drawer's width changes. The `width` property is
6
+ * the new applied inline-size in px, and `source` is the cause of the change.
7
+ */
8
+ export declare class AsideDrawerWidthChangeEvent extends NordEvent {
9
+ width: number;
10
+ source: AsideDrawerWidthSource;
11
+ constructor(width: number, source: AsideDrawerWidthSource);
12
+ }
13
+ /**
14
+ * A drawer panel inside `<nord-aside>`.
15
+ *
16
+ * @status new
17
+ * @category structure
18
+ * @slot - Default slot. Place arbitrary drawer content here.
19
+ *
20
+ * @fires {AsideDrawerWidthChangeEvent} width-change - Dispatched when the
21
+ * drawer's width changes. The event exposes `width` (the new applied
22
+ * inline-size in px) and `source` (`'drag' | 'keyboard' | 'attribute' | 'storage'`).
23
+ */
24
+ export default class AsideDrawer extends LitElement {
25
+ static styles: import("lit").CSSResult[];
26
+ /**
27
+ * Initial width in px. The persisted value overrides this on load; if
28
+ * `default-width` changes between sessions, the persisted value is
29
+ * re-seeded to the new default.
30
+ */
31
+ defaultWidth: number;
32
+ /**
33
+ * Resize clamp lower bound in px.
34
+ */
35
+ minWidth: number;
36
+ /**
37
+ * Resize clamp upper bound in px. Defaults to `Number.MAX_SAFE_INTEGER`
38
+ * so an unset `max-width` doesn't constrain the drawer — the consumer's
39
+ * layout (or the rail / nav anchoring) determines the practical ceiling.
40
+ * Set an explicit value to clamp.
41
+ *
42
+ * Not reflected: an unset cap is the `Number.MAX_SAFE_INTEGER` sentinel,
43
+ * which must never render into the DOM as `max-width="9007199254740991"`.
44
+ */
45
+ maxWidth: number;
46
+ /**
47
+ * Maximum inline-size in px the drawer can reach when `[fullscreen]`
48
+ * is active. Independent of `max-width` (which only caps the docked
49
+ * drag / keyboard resize) — fullscreen typically wants to grow
50
+ * larger than the docked maximum. Defaults to `Number.MAX_SAFE_INTEGER`
51
+ * so an unset value lets fullscreen fill all available room (bounded
52
+ * by the layout's left-cap rule in `<nord-aside>`).
53
+ *
54
+ * Not reflected: an unset cap is the `Number.MAX_SAFE_INTEGER` sentinel,
55
+ * which must never render into the DOM.
56
+ */
57
+ maxFullscreenWidth: number;
58
+ /**
59
+ * When set, the drawer cannot be opened. Programmatic opens are silently
60
+ * ignored; if the drawer is already open and this flips on, the drawer
61
+ * stays open until closed normally.
62
+ */
63
+ disabled: boolean;
64
+ /**
65
+ * Reflected. Phase 3 wires the overlay sizing internally.
66
+ */
67
+ fullscreen: boolean;
68
+ /**
69
+ * Set by the parent `<nord-aside>` when the drawer renders as a narrow
70
+ * floating overlay (rather than a docked region). When `true` the host
71
+ * becomes an accessible modal dialog (`role="dialog"` + `aria-modal`);
72
+ * when `false` the host is a `role="region"` landmark. Drive this only
73
+ * through the parent — it owns the floating-vs-docked decision.
74
+ */
75
+ floating: boolean;
76
+ /**
77
+ * Currently-applied width in px. Public read-only-ish; use `setWidth()`
78
+ * (or drive via `default-width` + min/max attrs) rather than poking
79
+ * this directly.
80
+ * @internal
81
+ */
82
+ width: number;
83
+ private widthSeeded;
84
+ private fullscreenSeeded;
85
+ private fullscreenAnimationCleanup?;
86
+ private fullscreenAnimation?;
87
+ private observedWidth;
88
+ private fullscreenResizeObserver?;
89
+ render(): import("lit").TemplateResult<1>;
90
+ connectedCallback(): void;
91
+ disconnectedCallback(): void;
92
+ willUpdate(): void;
93
+ /**
94
+ * Animate the fullscreen toggle ONLY when the user flips the attribute.
95
+ * Not on initial mount, not on drag-resize, not on show/hide, not on
96
+ * nav-state-driven size changes.
97
+ *
98
+ * Uses Web Animations API with explicit `from`/`to` keyframes because
99
+ * the drawer's `position` flips between `relative` (docked, in flex
100
+ * flow) and `fixed` (fullscreen, overlay). CSS transitions don't
101
+ * reliably interpolate `inline-size` across a position-type change.
102
+ *
103
+ * `fromWidth` comes from `observedWidth` — the last size painted by
104
+ * the browser, captured by ResizeObserver BEFORE the consumer flipped
105
+ * the attribute. Reading `getBoundingClientRect()` here would return
106
+ * the post-toggle size (Lit has already reflected the attribute), so
107
+ * the cached value is the only reliable pre-toggle width.
108
+ *
109
+ * `toWidth` is measured inside rAF, after Lit has committed the new
110
+ * attribute and Aside has updated `--_n-aside-drawer-fullscreen-size`.
111
+ *
112
+ * Exiting also resets the drawer's docked width to its declared
113
+ * `default-width` so the user lands at a predictable size after
114
+ * collapsing.
115
+ */
116
+ protected handleFullscreenChange(_oldValue: boolean | undefined, newValue: boolean): void;
117
+ protected handleBoundsChange(): void;
118
+ protected handleFloatingChange(): void;
119
+ /**
120
+ * Single writer for the host's landmark/dialog role. A floating overlay
121
+ * is an accessible modal (`role="dialog"` + `aria-modal="true"`); a docked
122
+ * drawer is a `role="region"` landmark with no aria-modal.
123
+ */
124
+ private applyFloatingRole;
125
+ protected applyWidthVars(): void;
126
+ /**
127
+ * Update the drawer width, clamped to `[min-width, max-width]`. Persists
128
+ * to localStorage and dispatches `width-change` with the given source.
129
+ */
130
+ setWidth(width: number, source: AsideDrawerWidthSource): void;
131
+ /**
132
+ * Whether the drawer is pinned — `min === max === default`. A pinned
133
+ * drawer's resize handle is a drag no-op.
134
+ */
135
+ get isPinned(): boolean;
136
+ /**
137
+ * Lift Layout.ts's re-seed pattern: if the consumer-provided
138
+ * `default-width` differs from the last default we wrote for this id,
139
+ * the persisted width is reset to the new default.
140
+ */
141
+ private seedWidth;
142
+ /**
143
+ * Resolve the matching `<nord-aside-trigger drawer="<this.id>">` inside
144
+ * the ancestor `<nord-aside>` and use it as the drawer's aria-labelledby
145
+ * target. Falls back to no label when no matching trigger exists.
146
+ */
147
+ private applyAriaLabelledby;
148
+ }
149
+ declare global {
150
+ interface HTMLElementTagNameMap {
151
+ 'nord-aside-drawer': AsideDrawer;
152
+ }
153
+ }