@nordhealth/components 4.24.2 → 4.25.1

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 (56) hide show
  1. package/custom-elements.json +13747 -12710
  2. package/lib/Banner.js +1 -1
  3. package/lib/Banner.js.map +1 -1
  4. package/lib/Button.js +1 -1
  5. package/lib/Card.js +1 -1
  6. package/lib/Card.js.map +1 -1
  7. package/lib/DatePicker.js +1 -1
  8. package/lib/Dropdown.js +1 -1
  9. package/lib/DropdownItem-Cb-7cHMg.js +2 -0
  10. package/lib/DropdownItem-Cb-7cHMg.js.map +1 -0
  11. package/lib/DropdownItem.js +1 -1
  12. package/lib/DropdownItem.js.map +1 -1
  13. package/lib/DropdownSubmenu.js +1 -1
  14. package/lib/IconManager.js +1 -1
  15. package/lib/Layout.js +1 -1
  16. package/lib/Layout.js.map +1 -1
  17. package/lib/Message.js +1 -1
  18. package/lib/NavGroup.js +1 -1
  19. package/lib/NavGroup.js.map +1 -1
  20. package/lib/NavItem.js +1 -1
  21. package/lib/NavItem.js.map +1 -1
  22. package/lib/NavToggle-BQxuLW2X.js +2 -0
  23. package/lib/NavToggle-BQxuLW2X.js.map +1 -0
  24. package/lib/NavToggle.js +1 -1
  25. package/lib/Navigation.js +1 -1
  26. package/lib/Navigation.js.map +1 -1
  27. package/lib/Popout-DtEL0HZ0.js +2 -0
  28. package/lib/Popout-DtEL0HZ0.js.map +1 -0
  29. package/lib/Popout.js +1 -1
  30. package/lib/Tooltip.js +1 -1
  31. package/lib/Tooltip.js.map +1 -1
  32. package/lib/Truncate.js +2 -0
  33. package/lib/Truncate.js.map +1 -0
  34. package/lib/bundle.js +17 -17
  35. package/lib/bundle.js.map +1 -1
  36. package/lib/index.js +1 -1
  37. package/lib/react.d.ts +5 -0
  38. package/lib/src/card/Card.d.ts +2 -0
  39. package/lib/src/dropdown-item/DropdownItem.d.ts +2 -0
  40. package/lib/src/index.d.ts +1 -0
  41. package/lib/src/layout/Layout.d.ts +42 -1
  42. package/lib/src/nav-group/NavGroup.d.ts +10 -0
  43. package/lib/src/nav-item/NavItem.d.ts +49 -1
  44. package/lib/src/nav-toggle/NavToggle.d.ts +15 -0
  45. package/lib/src/navigation/Navigation.d.ts +6 -0
  46. package/lib/src/popout/Popout.d.ts +3 -0
  47. package/lib/src/tooltip/Tooltip.d.ts +11 -0
  48. package/lib/src/truncate/Truncate.d.ts +81 -0
  49. package/lib/vue.d.ts +2 -0
  50. package/package.json +6 -5
  51. package/lib/DropdownItem-Cp-z3XA9.js +0 -2
  52. package/lib/DropdownItem-Cp-z3XA9.js.map +0 -1
  53. package/lib/NavToggle-QzUt-7lX.js +0 -2
  54. package/lib/NavToggle-QzUt-7lX.js.map +0 -1
  55. package/lib/Popout-vR6LxNS9.js +0 -2
  56. package/lib/Popout-vR6LxNS9.js.map +0 -1
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-QzUt-7lX.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-vR6LxNS9.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 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-Cp-z3XA9.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 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";
2
2
  //# sourceMappingURL=index.js.map
package/lib/react.d.ts CHANGED
@@ -583,6 +583,11 @@ declare module "react" {
583
583
  React.HTMLAttributes<HTMLElement> &
584
584
  React.Attributes & {};
585
585
 
586
+ "nord-truncate": WCProps<Components.Truncate> &
587
+ React.RefAttributes<Components.Truncate> &
588
+ React.HTMLAttributes<HTMLElement> &
589
+ React.Attributes & {};
590
+
586
591
  "nord-visually-hidden": WCProps<Components.VisuallyHidden> &
587
592
  React.RefAttributes<Components.VisuallyHidden> &
588
593
  React.HTMLAttributes<HTMLElement> &
@@ -21,6 +21,8 @@ import { LitElement } from 'lit';
21
21
  * @cssprop [--n-card-header-padding-block=var(--n-space-m)] - Controls the block (top and bottom) padding of the card header.
22
22
  * @cssprop [--n-card-header-padding-inline=var(--n-card-slot-padding)] - Controls the inline (left and right) padding of the card header.
23
23
  * @cssprop [--n-card-header-slot-flex-grow=0] - Controls the flex-grow value of the header slot.
24
+ * @cssprop [--n-card-header-end-margin-block-start=calc(var(--n-space-xs) * -1)] - Block-start margin of content slotted into `header-end`. The negative default lets buttons and similar controls sit within the header without inflating its height. Override (e.g. `0`) when slotting tall content that should occupy the full header height.
25
+ * @cssprop [--n-card-header-end-margin-block-end=calc(var(--n-space-xs) * -1)] - Block-end margin of content slotted into `header-end`. The negative default lets buttons and similar controls sit within the header without inflating its height. Override (e.g. `0`) when slotting tall content that should occupy the full header height.
24
26
  */
25
27
  export default class Card extends LitElement {
26
28
  static styles: import("lit").CSSResult[];
@@ -14,6 +14,8 @@ declare const DropdownItem_base: (new (...args: any[]) => import("../common/mixi
14
14
  *
15
15
  * @cssprop [--n-dropdown-item-background-color=transparent] - Controls the background color of the item, using our [color tokens](/tokens/#color).
16
16
  * @cssprop [--n-dropdown-item-color=var(--n-color-text)] - Controls the color of the text within the item, using our [color tokens](/tokens/#color).
17
+ * @cssprop [--n-dropdown-item-white-space=nowrap] - Controls how the item's label handles whitespace. Set to `normal` to allow long labels to wrap across multiple lines instead of truncating with an ellipsis.
18
+ * @cssprop [--n-dropdown-item-align-items=center] - Controls how the item's contents (start slot, label, end slot) align on the cross axis. Useful with multi-line wrapping: set to `flex-start` so icons/avatars sit on the first line instead of the vertical middle.
17
19
  */
18
20
  export default class DropdownItem extends DropdownItem_base {
19
21
  static styles: import("lit").CSSResult[];
@@ -58,4 +58,5 @@ export { default as Toast } from './toast/Toast.js';
58
58
  export { default as Toggle } from './toggle/Toggle.js';
59
59
  export { default as Tooltip } from './tooltip/Tooltip.js';
60
60
  export { default as TopBar } from './top-bar/TopBar.js';
61
+ export { default as Truncate } from './truncate/Truncate.js';
61
62
  export { default as VisuallyHidden } from './visually-hidden/VisuallyHidden.js';
@@ -1,8 +1,9 @@
1
1
  import type { States } from '../common/fsm.js';
2
2
  import { LitElement } from 'lit';
3
3
  import '../nav-toggle/NavToggle.js';
4
+ import '../tooltip/Tooltip.js';
4
5
  declare const navMachine: {
5
- transition(currentState: "closed" | "opened" | "peek" | "unpeek" | "wait" | "blocked", event: "click" | "close" | "focusin" | "focusout" | "pointerenter" | "pointerleave" | "toggle" | "transitionend" | "open" | "dropdownOpen" | "dropdownClose" | "timeout"): "closed" | "opened" | "peek" | "unpeek" | "wait" | "blocked";
6
+ transition(currentState: "closed" | "opened" | "peek" | "unpeek" | "wait" | "blocked", event: "click" | "close" | "focusin" | "focusout" | "pointerenter" | "pointerleave" | "toggle" | "transitionend" | "open" | "timeout" | "dropdownOpen" | "dropdownClose"): "closed" | "opened" | "peek" | "unpeek" | "wait" | "blocked";
6
7
  };
7
8
  type NavState = States<typeof navMachine>;
8
9
  /**
@@ -26,20 +27,32 @@ type NavState = States<typeof navMachine>;
26
27
  * @cssprop [--n-layout-drawer-inline-size=320px] - Controls the width of the drawer area, when used.
27
28
  * @cssprop [--n-layout-background-color=var(--n-color-background)] - Controls the background color of the layout, using [color tokens](/tokens/#color).
28
29
  * @cssprop [--n-layout-nav-border-color=var(--n-color-border)] - Controls the color of the border between the navigation and the main content area when the nav is open on wide screens.
30
+ * @cssprop [--n-layout-resize-color=var(--n-color-accent)] - Controls the colour of the resize handle's accent bar (shown on hover, focus, and while dragging).
31
+ * @cssprop [--n-layout-resize-block-size=100%] - Controls the block-axis (vertical) size of the resize handle. Set to a fixed length (e.g. `200px`) to constrain the handle so it doesn't span the full nav height.
32
+ * @cssprop [--n-layout-resize-inset-inline-end=5px] - Controls the inline-end offset of the resize handle's accent bar (the visible vertical line shown on hover/focus/drag).
33
+ * @cssprop [--n-layout-nav-rail-width=48px] - Controls the width of the navigation column when `collapse-mode="rail"` is active and the nav is closed.
34
+ * @cssprop [--n-layout-header-size=var(--n-space-xxl)] - Controls the block-axis (height) of the layout's header area. Also drives the size of the nav-toggle container and sticky-positioning offsets.
35
+ * @cssprop [--n-layout-drawer-box-shadow=var(--n-box-shadow-nav)] - Controls the box-shadow applied to the drawer (aside) on narrow viewports.
36
+ * @cssprop [--n-layout-drawer-box-shadow-wide=var(--n-box-shadow-header)] - Controls the box-shadow applied to the drawer (aside) on wide viewports (≥1240px).
37
+ * @cssprop [--n-layout-drawer-border-inline-start-width=1px] - Controls the inline-start border width of the drawer on wide viewports.
38
+ * @cssprop [--n-layout-drawer-border-inline-start-color=var(--n-color-border)] - Controls the inline-start border color of the drawer on wide viewports.
29
39
  */
30
40
  export default class Layout extends LitElement {
31
41
  static styles: import("lit").CSSResult[];
32
42
  private peekTimeoutId?;
43
+ private readonly resizeTooltipId;
33
44
  private navSlot;
34
45
  private drawerSlot;
35
46
  private topBarSlot;
36
47
  private headerSlot;
37
48
  private footerSlot;
49
+ private dividerTooltipSlot;
38
50
  private direction;
39
51
  private events;
40
52
  private lightDismiss;
41
53
  private broadcast;
42
54
  private navEl;
55
+ private resizeTooltipEl?;
43
56
  private navWidth;
44
57
  private isDragging;
45
58
  private navState;
@@ -93,6 +106,30 @@ export default class Layout extends LitElement {
93
106
  * `<nord-header>`) and want the layout's default one hidden.
94
107
  */
95
108
  hideDefaultNavToggle: boolean;
109
+ /**
110
+ * Suppresses the built-in collapse button rendered inside the nav (the
111
+ * lock-icon button that toggles the sidebar between opened and the
112
+ * collapsed state defined by `collapse-mode`). Set this when you've
113
+ * placed your own collapse control elsewhere.
114
+ */
115
+ hideCollapseButton: boolean;
116
+ /**
117
+ * When set, clicking the resize handle (without dragging) toggles the
118
+ * nav between opened and the collapsed state defined by `collapse-mode`.
119
+ * Dragging the handle still resizes the sidebar as usual; the click
120
+ * behaviour only fires when the pointer barely moves between down and up.
121
+ */
122
+ toggleOnResizeClick: boolean;
123
+ /**
124
+ * Controls how the navigation renders when closed on wide viewports.
125
+ * `hide` (default) slides the nav off-screen entirely. `rail` keeps a
126
+ * narrow icon-only column visible, with tooltips for labels and flyout
127
+ * popovers for items that have a `subnav` slot.
128
+ *
129
+ * Narrow viewports always use the off-screen behaviour regardless of
130
+ * this setting.
131
+ */
132
+ collapseMode: 'hide' | 'rail';
96
133
  /**
97
134
  * A getter whose values reflects whether the layout component considers the viewport to be narrow or not.
98
135
  * A narrow viewport is considered to be less than 768px wide.
@@ -124,8 +161,12 @@ export default class Layout extends LitElement {
124
161
  private handleTransitionEnd;
125
162
  private handleKeyboardResize;
126
163
  private setNavWidth;
164
+ private dragStartX;
165
+ private hasDragged;
127
166
  private startDragging;
128
167
  private stopDragging;
168
+ private handleResizeHoverMove;
169
+ private handleResizePointerLeave;
129
170
  private handleDrag;
130
171
  }
131
172
  declare global {
@@ -10,13 +10,23 @@ import '../icon/Icon.js';
10
10
  *
11
11
  * @fires {NordEvent} toggle - Dispatched whenever a nav item's state changes between open and closed.
12
12
  * @fires {NordEvent} activate - Dispatched whenever a nav item has been marked as active
13
+ *
14
+ * @cssprop [--n-nav-group-heading-display=block] - Controls the `display` of the group's heading. Set to `none` to hide it — useful for a `slot="subnav"` group whose heading repeats the parent item's label inline; the heading is still shown in the rail flyout where it titles the projected list.
13
15
  */
14
16
  export default class NavGroup extends LitElement {
15
17
  static styles: import("lit").CSSResult[];
18
+ private layoutObserver?;
19
+ private observedLayout?;
16
20
  /**
17
21
  * Heading and accessible label for the nav group
18
22
  */
19
23
  heading?: string;
24
+ connectedCallback(): void;
25
+ disconnectedCallback(): void;
26
+ private handleViewportChange;
27
+ private startObservingLayout;
28
+ private stopObservingLayout;
29
+ private updateRailState;
20
30
  render(): import("lit").TemplateResult<1>;
21
31
  }
22
32
  declare global {
@@ -1,5 +1,7 @@
1
1
  import type { TemplateResult } from 'lit';
2
2
  import { LitElement } from 'lit';
3
+ import '../popout/Popout.js';
4
+ import '../tooltip/Tooltip.js';
3
5
  declare const NavItem_base: (new (...args: any[]) => import("../common/mixins/FocusableMixin.js").FocusableMixinInterface) & typeof LitElement;
4
6
  /**
5
7
  * Navigation item populates sidebar navigation with links.
@@ -8,7 +10,10 @@ declare const NavItem_base: (new (...args: any[]) => import("../common/mixins/Fo
8
10
  * @status ready
9
11
  * @category navigation
10
12
  * @slot - The default slot used for the nav item's text.
13
+ * @slot icon - Slot for a custom leading icon element. Use when the `icon` attribute isn't enough — for example, an icon wrapped in a styled badge or circular frame. When set, it takes priority over the `icon` attribute and is shown in both the expanded nav and the collapsed rail.
14
+ * @slot end - Trailing content rendered after the label inside the item's flex row. The slotted element flows naturally — it claims its real width and the label flex-shrinks to make room. Use for a custom badge, count pill, action icon, etc. when the `badge` attribute's plain text isn't enough.
11
15
  * @slot subnav - Used for nesting navigation. When used the nav-item becomes a button to collapse the subnav, rather than a link.
16
+ * @slot rail-tooltip - Full content of the rail-mode tooltip. When provided, it replaces the default label projection — write the tooltip's content directly (label + count + keyboard shortcut etc., bound to whatever reactive state you like). When absent, the tooltip falls back to the item's default-slot label. Only rendered in rail mode.
12
17
  *
13
18
  * @fires toggle - Dispatched whenever a nav item's state changes between open and closed.
14
19
  * @fires activate - Dispatched whenever a nav item has been marked as active
@@ -19,6 +24,7 @@ declare const NavItem_base: (new (...args: any[]) => import("../common/mixins/Fo
19
24
  * @cssprop [--n-nav-item-padding-block=var(--n-space-s)] - Block-axis (top/bottom) padding.
20
25
  * @cssprop [--n-nav-item-padding-inline=var(--n-space-s)] - Inline-axis (start/end) padding.
21
26
  * @cssprop [--n-nav-item-line-height=var(--n-line-height-tight)] - Line height of the item's text.
27
+ * @cssprop [--n-nav-item-icon-gap=calc(var(--n-space-s) * 1.4)] - Inline gap between the leading icon (the `icon` attribute or `icon` slot) and the item's text.
22
28
  * @cssprop [--n-nav-item-color-hover=var(--n-color-text)] - Text color on hover.
23
29
  * @cssprop [--n-nav-item-background-hover=var(--n-color-nav-hover)] - Background color on hover.
24
30
  * @cssprop [--n-nav-item-color-active=var(--n-color-text-on-accent)] - Text color when the item is `active`.
@@ -27,11 +33,43 @@ declare const NavItem_base: (new (...args: any[]) => import("../common/mixins/Fo
27
33
  * @cssprop [--n-nav-item-background-expanded=var(--n-color-accent)] - Background color of the overlay drawn behind an active-parent item.
28
34
  * @cssprop [--n-nav-item-expanded-overlay-opacity=0.12] - Opacity of the active-parent overlay. Set to `1` for a solid background.
29
35
  * @cssprop [--n-nav-item-expanded-overlay-filter=brightness(150%)] - Filter applied to the active-parent overlay. Set to `none` to disable.
36
+ * @cssprop [--n-rail-flyout-background=var(--n-color-surface)] - Background colour of the rail-mode subnav flyout container.
37
+ * @cssprop [--n-rail-flyout-box-shadow=var(--n-box-shadow-popout)] - Box-shadow of the rail-mode subnav flyout container.
38
+ * @cssprop [--n-rail-flyout-min-inline-size=220px] - Minimum inline size (width in LTR) of the rail-mode subnav flyout body.
39
+ * @cssprop [--n-rail-flyout-padding=var(--n-space-s)] - Padding of the rail-mode subnav flyout body.
40
+ * @cssprop [--n-rail-flyout-offset-inline=0] - Extra inline-axis offset applied to the rail flyout (positive values push it away from the rail in LTR; mirrored in RTL).
41
+ * @cssprop [--n-rail-flyout-offset-block=0] - Extra block-axis offset applied to the rail flyout (positive values push it downward).
42
+ * @cssprop [--n-rail-subnav-indicator-color=var(--n-color-border-strong)] - Colour of the small triangle indicator drawn in the bottom-inline-end corner of rail items that have a subnav (default + hover state).
43
+ * @cssprop [--n-rail-subnav-indicator-color-active=var(--n-color-border-hover)] - Colour of the triangle indicator while the item's flyout popout is open.
44
+ * @cssprop [--n-nav-badge-background=var(--n-color-status-notification)] - Background colour of the built-in `badge` attribute pill (`.n-nav-badge`).
45
+ * @cssprop [--n-nav-badge-color=#fff] - Text colour of the built-in `badge` attribute pill.
46
+ * @cssprop [--n-nav-badge-font-size=var(--n-font-size-xs)] - Font size of the built-in `badge` attribute pill.
47
+ * @cssprop [--n-nav-badge-font-weight=var(--n-font-weight)] - Font weight of the built-in `badge` attribute pill.
48
+ * @cssprop [--n-nav-badge-line-height=1] - Line height of the built-in `badge` attribute pill. Combined with `--n-nav-badge-padding-block` this controls the pill's effective block size.
49
+ * @cssprop [--n-nav-badge-padding-block=var(--n-space-xs)] - Block-axis padding of the built-in `badge` attribute pill.
50
+ * @cssprop [--n-nav-badge-padding-inline=calc(var(--n-space-s) / 2)] - Inline-axis padding of the built-in `badge` attribute pill.
51
+ * @cssprop [--n-nav-badge-border-radius=var(--n-border-radius-pill)] - Border radius of the built-in `badge` attribute pill.
52
+ * @cssprop [--n-nav-badge-min-inline-size=20px] - Minimum inline size (width in LTR) of the built-in `badge` attribute pill — sets a visual floor for single-digit counts.
53
+ * @cssprop [--n-nav-badge-margin-inline-start=var(--n-space-xs)] - Inline-start margin separating the badge from the preceding label inside the nav-item's flex row.
54
+ * @cssprop [--n-rail-badge-size=5px] - Diameter of the rail-mode dot the badge collapses into when the layout is in `collapse-mode="rail"` and not `nav-open`.
30
55
  */
31
56
  export default class NavItem extends NavItem_base {
32
57
  static styles: import("lit").CSSResult[];
33
58
  private subnavSlot;
59
+ private iconSlot;
60
+ private railTooltipSlot;
34
61
  private direction;
62
+ private layoutObserver?;
63
+ private observedLayout?;
64
+ private readonly tooltipId;
65
+ private readonly popoutId;
66
+ private popoutEl?;
67
+ /**
68
+ * Reflects whether the ancestor layout is in rail-collapsed state
69
+ * (i.e. `collapse-mode="rail"` and `nav-open` is absent).
70
+ * @internal
71
+ */
72
+ private railCollapsed;
35
73
  /**
36
74
  * Used for indicating the current page. This gives a prominent background to the nav item,
37
75
  * and marks the item as the current page for assistive technology.
@@ -59,7 +97,17 @@ export default class NavItem extends NavItem_base {
59
97
  * @internal
60
98
  */
61
99
  get hasSubNav(): boolean;
62
- render(): TemplateResult<1>;
100
+ connectedCallback(): void;
101
+ disconnectedCallback(): void;
102
+ private handleViewportChange;
103
+ private startObservingLayout;
104
+ private stopObservingLayout;
105
+ private updateRailState;
106
+ render(): TemplateResult;
107
+ private renderLeadingIcon;
108
+ private renderRail;
109
+ private renderRailFlyout;
110
+ private get textInitial();
63
111
  private renderLink;
64
112
  private renderToggle;
65
113
  private renderButton;
@@ -47,6 +47,21 @@ export default class NavToggle extends NavToggle_base {
47
47
  * placing the toggle outside the `nav-toggle` slot.
48
48
  */
49
49
  autoHide: boolean;
50
+ /**
51
+ * Forwards the `square` attribute to the underlying `<nord-button>`,
52
+ * giving the toggle a fixed square footprint instead of the default
53
+ * pill shape.
54
+ */
55
+ square: boolean;
56
+ /**
57
+ * Size of the underlying `<nord-button>`. Defaults to `m`.
58
+ */
59
+ size: 's' | 'm';
60
+ /**
61
+ * Size of the inner `<nord-icon>` elements. Accepts the same values
62
+ * as `<nord-icon>`'s `size`. Defaults to `m`.
63
+ */
64
+ iconSize: 'xxs' | 'xs' | 's' | 'm' | 'l';
50
65
  /**
51
66
  * Reflects whether `auto-hide` is engaged (i.e. the ancestor layout
52
67
  * currently has `nav-open`). The CSS hides the host based on this.
@@ -27,6 +27,8 @@ export default class Navigation extends LitElement {
27
27
  private headerSlot;
28
28
  private events;
29
29
  private footerObserver;
30
+ private layoutObserver?;
31
+ private observedLayout?;
30
32
  private allowItemsToRemainOpen;
31
33
  /**
32
34
  * Controls whether the navigations's footer has sticky positioning.
@@ -34,6 +36,10 @@ export default class Navigation extends LitElement {
34
36
  stickyFooter: boolean;
35
37
  connectedCallback(): void;
36
38
  disconnectedCallback(): void;
39
+ private handleViewportChange;
40
+ private startObservingLayout;
41
+ private stopObservingLayout;
42
+ private updateRailState;
37
43
  /**
38
44
  * Observe the footer slot element for visibility changes.
39
45
  * Watches style and class attributes on the footer element itself, and
@@ -6,6 +6,9 @@ declare const Popout_base: (new (...args: any[]) => import("../common/mixins/Flo
6
6
  * @status ready
7
7
  * @category overlay
8
8
  * @slot - The popout content.
9
+ *
10
+ * @cssprop [--n-popout-offset-inline=0] - Extra inline-axis offset applied to the popout's computed position. Positive values shift the popout toward the inline-end (right in LTR).
11
+ * @cssprop [--n-popout-offset-block=0] - Extra block-axis offset applied to the popout's computed position. Positive values shift the popout downward.
9
12
  */
10
13
  export default class Popout extends Popout_base {
11
14
  static styles: import("lit").CSSResult[];
@@ -48,6 +48,10 @@ export default class Tooltip extends LitElement {
48
48
  * The delay in milliseconds before the tooltip is opened.
49
49
  */
50
50
  delay: number;
51
+ /**
52
+ * Indicates whether the tooltip is currently open.
53
+ */
54
+ open: boolean;
51
55
  /**
52
56
  * Apply all event listeners
53
57
  */
@@ -66,6 +70,13 @@ export default class Tooltip extends LitElement {
66
70
  private handleHide;
67
71
  private hideOnEscape;
68
72
  private addDescribedBy;
73
+ /**
74
+ * Place the element in the top layer via the Popover API so that
75
+ * position: fixed works relative to the viewport regardless of
76
+ * `overflow: hidden|auto` or `contain` on any ancestor.
77
+ */
78
+ private enterTopLayer;
79
+ private leaveTopLayer;
69
80
  private removeDescribedBy;
70
81
  }
71
82
  declare global {
@@ -0,0 +1,81 @@
1
+ import type { PropertyValues } from 'lit';
2
+ import { LitElement } from 'lit';
3
+ import '../tooltip/Tooltip.js';
4
+ /**
5
+ * Truncate is a text wrapper that applies single-line or multi-line ellipsis
6
+ * truncation and automatically reveals a tooltip with the full text when the
7
+ * content actually overflows its container.
8
+ *
9
+ * Truncation is performed in JS (the DOM text node is replaced with a
10
+ * pre-truncated string + ellipsis), matching the approach used by Ant Design
11
+ * Pro's `Ellipsis` component. This avoids the well-known CSS
12
+ * `text-overflow: ellipsis` quirk where clicking inside the clipped text
13
+ * shifts the line and loses the ellipsis — there is no overflow to scroll
14
+ * because the visible text fits exactly.
15
+ *
16
+ * @status ready
17
+ * @category text
18
+ * @slot - The full text content. Plain text is recommended; rich markup is
19
+ * not supported (only `textContent` is read for truncation).
20
+ */
21
+ export default class Truncate extends LitElement {
22
+ static styles: import("lit").CSSResult;
23
+ private spanRef;
24
+ private observer?;
25
+ private contentObserver?;
26
+ private tooltipId;
27
+ private tooltipElement?;
28
+ private currentTrigger;
29
+ private isTruncated;
30
+ private text;
31
+ /**
32
+ * Position of the tooltip relative to the truncated text. Mirrors `nord-tooltip`.
33
+ */
34
+ position: 'block-end' | 'block-start' | 'inline-start' | 'inline-end';
35
+ /**
36
+ * Delay in milliseconds before the tooltip opens.
37
+ */
38
+ delay: number;
39
+ /**
40
+ * Maximum number of lines before truncating. Defaults to `1` (single line).
41
+ * Values `>= 2` allow the text to wrap up to that many lines before the
42
+ * ellipsis kicks in.
43
+ */
44
+ lineClamp: number;
45
+ /**
46
+ * When set, the component still truncates the text but does not render
47
+ * a hover tooltip with the full content. The `truncated` attribute is
48
+ * still reflected so consumers can style it.
49
+ */
50
+ noTooltip: boolean;
51
+ connectedCallback(): void;
52
+ protected firstUpdated(): void;
53
+ protected updated(): void;
54
+ disconnectedCallback(): void;
55
+ private captureText;
56
+ /**
57
+ * Measure overflow and, if needed, binary-search the longest prefix of the
58
+ * full text that fits in the available space, then commit `<prefix>…` as
59
+ * the visible text. Same algorithm as Ant Design Pro's `Ellipsis`.
60
+ */
61
+ private measure;
62
+ private fits;
63
+ /**
64
+ * Walk up the DOM until we find an ancestor that actually receives pointer
65
+ * events. Needed because `nord-button` (and similar) set
66
+ * `::slotted(*) { pointer-events: none }`, so this host can never see hover.
67
+ * Falls back to this host if no such ancestor is found.
68
+ */
69
+ private findTriggerElement;
70
+ private addDescribedById;
71
+ private removeDescribedById;
72
+ private clearTrigger;
73
+ private syncTooltip;
74
+ protected willUpdate(changed: PropertyValues): void;
75
+ render(): import("lit").TemplateResult<1>;
76
+ }
77
+ declare global {
78
+ interface HTMLElementTagNameMap {
79
+ 'nord-truncate': Truncate;
80
+ }
81
+ }
package/lib/vue.d.ts CHANGED
@@ -477,6 +477,8 @@ interface NordComponents {
477
477
 
478
478
  "nord-top-bar": DefineComponent<WCProps<Components.TopBar> & {}>;
479
479
 
480
+ "nord-truncate": DefineComponent<WCProps<Components.Truncate> & {}>;
481
+
480
482
  "nord-visually-hidden": DefineComponent<
481
483
  WCProps<Components.VisuallyHidden> & {}
482
484
  >;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nordhealth/components",
3
3
  "type": "module",
4
- "version": "4.24.2",
4
+ "version": "4.25.1",
5
5
  "description": "This package includes Nord Design System Web Components",
6
6
  "author": "Nordhealth <support@nordhealth.design>",
7
7
  "license": "SEE LICENSE IN LICENSE.md",
@@ -20,6 +20,7 @@
20
20
  "start": "concurrently -k -n TSC,SB -c blue.bold,magenta.bold \"tsc -w --noEmit\" \"storybook dev -p 6006\"",
21
21
  "prebuild": "pnpm clean",
22
22
  "build": "rollup -c",
23
+ "build:watch": "rollup -c -w",
23
24
  "postbuild": "pnpm analyze && pnpm build:react-types && pnpm build:vue-types",
24
25
  "clean": "rm -rf lib/",
25
26
  "test": "vitest run --project=components",
@@ -37,7 +38,7 @@
37
38
  },
38
39
  "dependencies": {
39
40
  "@floating-ui/dom": "^1.7.5",
40
- "@nordhealth/icons": "^3.16.2",
41
+ "@nordhealth/icons": "^3.17.0",
41
42
  "lit": "^3.3.2",
42
43
  "qr": "^0.4.2",
43
44
  "tinykeys": "^1.4.0"
@@ -46,8 +47,8 @@
46
47
  "@custom-elements-manifest/analyzer": "^0.10.10",
47
48
  "@nordhealth/css": "^4.4.1",
48
49
  "@nordhealth/fonts": "^3.0.4",
49
- "@nordhealth/themes": "^9.0.8",
50
- "@nordhealth/tokens": "^8.0.5",
50
+ "@nordhealth/themes": "^9.0.9",
51
+ "@nordhealth/tokens": "^8.1.0",
51
52
  "@open-wc/eslint-config": "^12.0.3",
52
53
  "@open-wc/testing-helpers": "^3.0.1",
53
54
  "@playwright/test": "1.58.0",
@@ -90,5 +91,5 @@
90
91
  "rollup": "~4.21.3"
91
92
  }
92
93
  },
93
- "gitHead": "2f4f8b80d8e638f92882ebd067da9c6ae327b0a6"
94
+ "gitHead": "3a3dfd051cce0bf870a4de967069d3e8b48f2294"
94
95
  }
@@ -1,2 +0,0 @@
1
- import{css as o}from"lit";const n=o`:host{--_n-dropdown-item-background-color:var(--n-dropdown-item-background-color, transparent);--_n-dropdown-item-color:var(--n-dropdown-item-color, var(--n-color-text));display:flex;line-height:var(--n-line-height-tight)}.n-dropdown-item{appearance:none;cursor:pointer;display:flex;flex:1;gap:var(--n-space-s);align-items:center;font-family:inherit;font-size:inherit;font-weight:var(--n-font-weight);text-decoration:none;border:0;color:var(--_n-dropdown-item-color);padding:var(--n-space-s);border-radius:var(--n-border-radius-s);background:var(--_n-dropdown-item-background-color);text-align:start;box-shadow:var(--n-dropdown-item-box-shadow,none);min-inline-size:0}.n-dropdown-item ::slotted(nord-icon){color:var(--n-color-icon)}@media (hover:hover){.n-dropdown-item:hover{--_n-dropdown-item-background-color:var(--n-dropdown-item-background-color, var(--n-color-active));--_n-dropdown-item-color:var(--n-dropdown-item-color, var(--n-color-text))}.n-dropdown-item:hover ::slotted(*){color:var(--n-dropdown-item-color,var(--n-color-text))!important}.n-dropdown-item:hover ::slotted(nord-icon){color:currentColor}}:host([aria-expanded=true]) .n-dropdown-item{--_n-dropdown-item-background-color:var(--n-dropdown-item-background-color, var(--n-color-active));--_n-dropdown-item-color:var(--n-dropdown-item-color, var(--n-color-text))}:host([aria-expanded=true]) .n-dropdown-item ::slotted(nord-icon){color:currentColor}.n-dropdown-item:active{opacity:.7}.n-dropdown-item:focus{--n-dropdown-item-box-shadow:0 0 0 2px var(--n-color-accent);outline:0;position:relative;z-index:var(--n-index-masked)}@supports selector(:focus-visible){.n-dropdown-item:focus{--n-dropdown-item-box-shadow:none}.n-dropdown-item:focus-visible{--n-dropdown-item-box-shadow:0 0 0 2px var(--n-color-accent)}}@media (max-width:35.9375em){.n-dropdown-item{gap:var(--n-space-m);padding:calc(var(--n-space-m)/ 1.5) var(--n-space-m)}.n-dropdown-item ::slotted(nord-icon){block-size:var(--n-size-icon-m);inline-size:var(--n-size-icon-m)}}slot[name=end],slot[name=start]{flex:0 0 auto}slot[name=end]{display:flex;margin-inline-start:auto}.n-content{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host([disabled]){--_n-dropdown-item-background-color:var(--n-dropdown-item-background-color, transparent);--_n-dropdown-item-color:var(--n-dropdown-item-color, var(--n-color-text-weakest));pointer-events:none}:host([disabled]) .n-button::after{display:none}::slotted(nord-icon:not([size])){--_n-icon-size:var(--n-size-icon-s)}`;export{n as s};
2
- //# sourceMappingURL=DropdownItem-Cp-z3XA9.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DropdownItem-Cp-z3XA9.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{css as o,html as i,LitElement as e}from"lit";import{property as r,state as n,customElement as s}from"lit/decorators.js";import{classMap as a}from"lit/directives/class-map.js";import{ref as l}from"lit/directives/ref.js";import{D as d}from"./DirectionController-ChvNGESZ.js";import{F as c}from"./FocusableMixin-BlQLNPdJ.js";import{s as u}from"./Component-DSU3Qp0O.js";import h from"./Icon.js";import{LocalizeController as v}from"./LocalizeController.js";import"./Button.js";import"./VisuallyHidden.js";const p="navigation-toggle-lock";var m=Object.freeze({__proto__:null,default:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m19.7188 10.71-8 8-1.41-1.41 7.29-7.29-7.3-7.29996 1.41-1.41 8 8c.39.39.39 1.01996 0 1.40996zm-8-1.40996-7.99997-8.01-1.41 1.41 7.29 7.29-7.3 7.29996 1.41 1.41 8.00997-7.99c.39-.39.39-1.01996 0-1.40996z" fill="currentColor"/></svg>',tags:"nordicon navigation hamburger menu toggle navigation arrow right double lock triangle chevron",title:p});const g="navigation-toggle";var b=Object.freeze({__proto__:null,default:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m18.9988 3v2h-16.00002v-2zm-16.00002 8h16.00002v-2h-16.00002zm0 6h16.00002v-2h-16.00002z" fill="currentColor"/></svg>',tags:"nordicon navigation hamburger menu toggle navigation three lines",title:g});const f=o`:host{color:var(--n-color-icon);display:inline-flex}@media (min-width:768px){:host([data-auto-hidden]){display:none}}nord-button{--n-button-color:currentColor}nord-icon{display:block;transform:translateX(-1px);color:currentColor}.icon-active{display:none}.is-rtl .icon-active{transform:rotate(180deg)}@media (min-width:768px){:host(:is(:hover,:focus-within)) .icon-active{display:block}:host(:is(:hover,:focus-within)) .icon-default{display:none}}`;h.registerIcon(b),h.registerIcon(m);let y=class extends(c(e)){constructor(){super(...arguments),this.direction=new d(this),this.localization=new v(this),this.icon=g,this.iconActive=p,this.autoHide=!1,this.autoHidden=!1}connectedCallback(){super.connectedCallback(),this.startAutoHide()}disconnectedCallback(){super.disconnectedCallback(),this.stopAutoHide()}updated(t){var o;null===(o=super.updated)||void 0===o||o.call(this,t),t.has("autoHide")&&(this.stopAutoHide(),this.startAutoHide()),t.has("autoHidden")&&this.toggleAttribute("data-auto-hidden",this.autoHidden)}startAutoHide(){if(!this.autoHide)return;const t=this.closest("nord-layout");t&&(this.observedLayout=t,this.autoHidden=t.hasAttribute("nav-open"),this.layoutObserver=new MutationObserver((()=>{this.autoHidden=t.hasAttribute("nav-open")})),this.layoutObserver.observe(t,{attributes:!0,attributeFilter:["nav-open"]}))}stopAutoHide(){var t;null===(t=this.layoutObserver)||void 0===t||t.disconnect(),this.layoutObserver=void 0,this.observedLayout=void 0,this.autoHidden=!1}render(){return i`<nord-button variant="plain" ${l(this.focusableRef)} class="${a({"is-rtl":this.direction.isRTL})}"><nord-visually-hidden>${this.localization.term("label")}</nord-visually-hidden><nord-icon size="m" class="icon-default" name="${this.icon}"></nord-icon><nord-icon size="m" class="icon-active" name="${this.iconActive}"></nord-icon></nord-button>`}};y.styles=[u,f],t([r({reflect:!0})],y.prototype,"icon",void 0),t([r({reflect:!0,attribute:"icon-active"})],y.prototype,"iconActive",void 0),t([r({type:Boolean,reflect:!0,attribute:"auto-hide"})],y.prototype,"autoHide",void 0),t([n()],y.prototype,"autoHidden",void 0),y=t([s("nord-nav-toggle")],y);var w=y;export{w as N,m as l};
2
- //# sourceMappingURL=NavToggle-QzUt-7lX.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavToggle-QzUt-7lX.js","sources":["../../icons/lib/assets/navigation-toggle-lock.js","../../icons/lib/assets/navigation-toggle.js","../src/nav-toggle/NavToggle.ts"],"sourcesContent":["export default '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m19.7188 10.71-8 8-1.41-1.41 7.29-7.29-7.3-7.29996 1.41-1.41 8 8c.39.39.39 1.01996 0 1.40996zm-8-1.40996-7.99997-8.01-1.41 1.41 7.29 7.29-7.3 7.29996 1.41 1.41 8.00997-7.99c.39-.39.39-1.01996 0-1.40996z\" fill=\"currentColor\"/></svg>';\nexport const title = \"navigation-toggle-lock\";\nexport const tags =\n \"nordicon navigation hamburger menu toggle navigation arrow right double lock triangle chevron\";\n","export default '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m18.9988 3v2h-16.00002v-2zm-16.00002 8h16.00002v-2h-16.00002zm0 6h16.00002v-2h-16.00002z\" fill=\"currentColor\"/></svg>';\nexport const title = \"navigation-toggle\";\nexport const tags =\n \"nordicon navigation hamburger menu toggle navigation three lines\";\n","import * as lockIcon from '@nordhealth/icons/lib/assets/navigation-toggle-lock.js'\nimport * as unlockIcon from '@nordhealth/icons/lib/assets/navigation-toggle.js'\nimport { html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ref } from 'lit/directives/ref.js'\n\nimport { DirectionController } from '../common/controllers/DirectionController.js'\nimport { FocusableMixin } from '../common/mixins/FocusableMixin.js'\nimport componentStyle from '../common/styles/Component.css'\n\nimport Icon from '../icon/Icon.js'\nimport { LocalizeController } from '../localization/LocalizeController.js'\nimport style from './NavToggle.css'\n\nimport '../button/Button.js'\nimport '../visually-hidden/VisuallyHidden.js'\n\nIcon.registerIcon(unlockIcon)\nIcon.registerIcon(lockIcon)\n\n/**\n * Nav toggle is meant for hiding and showing the primary navigation.\n *\n * Used internally by `<nord-layout>` as the default contents of its\n * `nav-toggle` slot. Can also be placed **anywhere inside `<nord-layout>`**\n * (e.g. inside a `<nord-header>` next to the page title) — the layout\n * listens for clicks on any descendant `<nord-nav-toggle>` and toggles the\n * navigation accordingly. Outside of a `<nord-layout>` it renders as a\n * presentational button with no behaviour.\n *\n * The two displayed icons can be customised via the `icon` and\n * `icon-active` attributes. The first is shown in the resting state; the\n * second replaces it on hover/focus (≥ 768px).\n *\n * Set `auto-hide` to have the toggle disappear automatically when the\n * ancestor `<nord-layout>`'s nav is open (on wide viewports), mirroring\n * the built-in fallback toggle's behaviour.\n *\n * @status ready\n * @category action\n *\n * @localization label - Accessible label for the nav toggle button.\n */\n@customElement('nord-nav-toggle')\nexport default class NavToggle extends FocusableMixin(LitElement) {\n static styles = [componentStyle, style]\n\n private direction = new DirectionController(this)\n private localization = new LocalizeController<'nord-nav-toggle'>(this)\n private layoutObserver?: MutationObserver\n private observedLayout?: HTMLElement\n\n /**\n * Icon shown in the resting state. Accepts any registered icon name.\n * Defaults to `navigation-toggle`.\n */\n @property({ reflect: true }) icon: string = unlockIcon.title\n\n /**\n * Icon shown on hover/focus (≥ 768px), swapping in for `icon`.\n * Defaults to `navigation-toggle-lock`.\n */\n @property({ reflect: true, attribute: 'icon-active' }) iconActive: string = lockIcon.title\n\n /**\n * When set, the toggle finds its ancestor `<nord-layout>` and hides\n * itself on wide viewports while the layout's nav is open. Useful when\n * placing the toggle outside the `nav-toggle` slot.\n */\n @property({ type: Boolean, reflect: true, attribute: 'auto-hide' }) autoHide: boolean = false\n\n /**\n * Reflects whether `auto-hide` is engaged (i.e. the ancestor layout\n * currently has `nav-open`). The CSS hides the host based on this.\n */\n @state() private autoHidden: boolean = false\n\n connectedCallback() {\n super.connectedCallback()\n this.startAutoHide()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.stopAutoHide()\n }\n\n protected updated(changed: Map<string, unknown>) {\n super.updated?.(changed)\n if (changed.has('autoHide')) {\n this.stopAutoHide()\n this.startAutoHide()\n }\n if (changed.has('autoHidden')) {\n this.toggleAttribute('data-auto-hidden', this.autoHidden)\n }\n }\n\n private startAutoHide() {\n if (!this.autoHide) {\n return\n }\n const layout = this.closest<HTMLElement>('nord-layout')\n if (!layout) {\n return\n }\n this.observedLayout = layout\n this.autoHidden = layout.hasAttribute('nav-open')\n this.layoutObserver = new MutationObserver(() => {\n this.autoHidden = layout.hasAttribute('nav-open')\n })\n this.layoutObserver.observe(layout, {\n attributes: true,\n attributeFilter: ['nav-open'],\n })\n }\n\n private stopAutoHide() {\n this.layoutObserver?.disconnect()\n this.layoutObserver = undefined\n this.observedLayout = undefined\n this.autoHidden = false\n }\n\n render() {\n return html`\n <nord-button variant=\"plain\" ${ref(this.focusableRef)} class=${classMap({ 'is-rtl': this.direction.isRTL })}>\n <nord-visually-hidden>${this.localization.term('label')}</nord-visually-hidden>\n <nord-icon size=\"m\" class=\"icon-default\" name=${this.icon}></nord-icon>\n <nord-icon size=\"m\" class=\"icon-active\" name=${this.iconActive}></nord-icon>\n </nord-button>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-nav-toggle': NavToggle\n }\n}\n"],"names":["title","Icon","registerIcon","unlockIcon","lockIcon","NavToggle","FocusableMixin","LitElement","constructor","this","direction","DirectionController","localization","LocalizeController","icon","unlockIcon.title","iconActive","lockIcon.title","autoHide","autoHidden","connectedCallback","super","startAutoHide","disconnectedCallback","stopAutoHide","updated","changed","_a","call","has","toggleAttribute","layout","closest","observedLayout","hasAttribute","layoutObserver","MutationObserver","observe","attributes","attributeFilter","disconnect","undefined","render","html","ref","focusableRef","classMap","isRTL","term","styles","componentStyle","style","__decorate","property","reflect","prototype","attribute","type","Boolean","state","customElement"],"mappings":"uiBACO,MAAMA,EAAQ,qEADN,oTAGb,0GCFK,MAAMA,EAAQ,gEADN,kMAGb,whBCeFC,EAAKC,aAAaC,GAClBF,EAAKC,aAAaE,GA0BH,IAAMC,EAAN,cAAwBC,EAAeC,IAAvC,WAAAC,uBAGLC,KAAAC,UAAY,IAAIC,EAAoBF,MACpCA,KAAAG,aAAe,IAAIC,EAAsCJ,MAQpCA,KAAAK,KAAeC,EAMWN,KAAAO,WAAqBC,EAORR,KAAQS,UAAY,EAMvET,KAAUU,YAAY,CA0DxC,CAxDC,iBAAAC,GACEC,MAAMD,oBACNX,KAAKa,eACN,CAED,oBAAAC,GACEF,MAAME,uBACNd,KAAKe,cACN,CAES,OAAAC,CAAQC,SACA,QAAhBC,EAAAN,MAAMI,eAAU,IAAAE,GAAAA,EAAAC,KAAAnB,KAAAiB,GACZA,EAAQG,IAAI,cACdpB,KAAKe,eACLf,KAAKa,iBAEHI,EAAQG,IAAI,eACdpB,KAAKqB,gBAAgB,mBAAoBrB,KAAKU,WAEjD,CAEO,aAAAG,GACN,IAAKb,KAAKS,SACR,OAEF,MAAMa,EAAStB,KAAKuB,QAAqB,eACpCD,IAGLtB,KAAKwB,eAAiBF,EACtBtB,KAAKU,WAAaY,EAAOG,aAAa,YACtCzB,KAAK0B,eAAiB,IAAIC,kBAAiB,KACzC3B,KAAKU,WAAaY,EAAOG,aAAa,WAAW,IAEnDzB,KAAK0B,eAAeE,QAAQN,EAAQ,CAClCO,YAAY,EACZC,gBAAiB,CAAC,cAErB,CAEO,YAAAf,SACe,QAArBG,EAAAlB,KAAK0B,sBAAgB,IAAAR,GAAAA,EAAAa,aACrB/B,KAAK0B,oBAAiBM,EACtBhC,KAAKwB,oBAAiBQ,EACtBhC,KAAKU,YAAa,CACnB,CAED,MAAAuB,GACE,OAAOC,CAAI,gCACsBC,EAAInC,KAAKoC,wBAAuBC,EAAS,CAAE,SAAUrC,KAAKC,UAAUqC,kCACzEtC,KAAKG,aAAaoC,KAAK,iFACCvC,KAAKK,mEACNL,KAAKO,wCAGzD,GAvFMX,EAAA4C,OAAS,CAACC,EAAgBC,GAWJC,EAAA,CAA5BC,EAAS,CAAEC,SAAS,KAAuCjD,EAAAkD,UAAA,YAAA,GAMLH,EAAA,CAAtDC,EAAS,CAAEC,SAAS,EAAME,UAAW,iBAAoDnD,EAAAkD,UAAA,kBAAA,GAOtBH,EAAA,CAAnEC,EAAS,CAAEI,KAAMC,QAASJ,SAAS,EAAME,UAAW,eAAwCnD,EAAAkD,UAAA,gBAAA,GAM5EH,EAAA,CAAhBO,KAA2CtD,EAAAkD,UAAA,kBAAA,GA/BzBlD,EAAS+C,EAAA,CAD7BQ,EAAc,oBACMvD,SAAAA"}
@@ -1,2 +0,0 @@
1
- import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{o as e,a as o,s as i,h as s,l as n,c as a,b as r,f as l}from"./positioning-D-K8Mueq.js";import{css as h,html as p,LitElement as d}from"lit";import{property as c,query as m,state as u,customElement as v}from"lit/decorators.js";import{D as g}from"./DirectionController-ChvNGESZ.js";import{E as f}from"./EventController-BBOmvfLa.js";import{L as y}from"./LightDismissController-4pH8cdko.js";import{S as b}from"./ScrollbarController-BFC67Y2x.js";import{o as w}from"./observe-D0n0zOfU.js";import{N as E,t as x}from"./events-Bv6wNHwJ.js";import{s as A}from"./Component-DSU3Qp0O.js";function k(e){class o extends e{constructor(){super(...arguments),this.open=!1,this.align="start",this.position="block-end"}}return t([c({type:Boolean,reflect:!0})],o.prototype,"open",void 0),t([c({reflect:!0})],o.prototype,"align",void 0),t([c({reflect:!0})],o.prototype,"position",void 0),o}const C=h`:host{position:fixed;pointer-events:none;z-index:var(--n-index-popout);color:var(--n-color-text);opacity:0;transition:opacity var(--n-transition-slowly);inset:auto;inline-size:auto;block-size:auto;margin:0;padding:0;border:none;background:0 0;overflow:visible;left:var(--_n-popout-position-x);top:var(--_n-popout-position-y)}.n-popout{pointer-events:none;transform:translateY(-10px) scale(.97);visibility:hidden;transition:transform var(--n-transition-slowly),visibility var(--n-transition-slowly);transform-origin:top left;will-change:transform,opacity,visibility;background:var(--n-color-surface);box-shadow:var(--n-box-shadow-popout);border-radius:var(--n-border-radius-s)}:host([open]){opacity:1}:host([open]) .n-popout{transition-property:transform;visibility:visible;pointer-events:auto;transform:translateY(0) translateX(0) scale(1)}@media (max-width:35.9375em){:host(:not([always-floating])){position:fixed;inset:0;overflow-y:auto;opacity:1;background:0 0;transition:background var(--n-transition-mobile)}:host([open]:not([always-floating])){pointer-events:auto;background:var(--n-color-overlay)}:host([open]:not([always-floating])) .n-popout{transform:translateY(0)}:host(:not([always-floating])) .n-popout{position:fixed;inset:0;inset-block-start:auto;transform:translateY(100%);transition:transform var(--n-transition-mobile),visibility var(--n-transition-mobile);transform-origin:bottom center;border-radius:0}}.top-end,.top-start{transform:translateY(10px) scale(.97)}.left-end,.left-start{transform:translateX(10px) scale(.97)}.right-end,.right-start{transform:translateX(-10px) scale(.97)}.bottom-start.is-rtl,.left-end,.top-end{transform-origin:bottom right}.bottom-end,.left-start,.top-start.is-rtl{transform-origin:top right}.bottom-end.is-rtl,.right-end,.right-start{transform-origin:bottom left}.right-start,.top-end.is-rtl{transform-origin:top left}`,P="undefined"==typeof matchMedia?{matches:!1,addEventListener(){}}:matchMedia("(max-width: 35.9375em)");let S=class extends(k(d)){constructor(){super(...arguments),this.scrollBar=new b(this),this.dismiss=new y(this,{isOpen:()=>this.open,onDismiss:t=>this.hide("click"!==t.type),isDismissible:t=>t!==this.popout&&t!==this.targetElement}),this.events=new f(this),this.direction=new g(this),this.smallViewport=P.matches,this.id="",this.alwaysFloating=!1,this.enableScroll=()=>{this.open||(this.scrollBar.unlockScroll(),this.leaveTopLayer())},this.updatePosition=async()=>{var t;if(!this.anchorElement)return;const r={strategy:"fixed"};"auto"===this.position?r.middleware=[e(8),o({alignment:this.align,padding:8}),i({padding:8}),s()]:(r.placement=n(this.position,this.align,this.direction.dir),r.middleware=[e(8),l(),i({padding:8}),s()]);const{x:h,y:p,placement:d,middlewareData:c}=await a(this.anchorElement,this,r);this.computedPosition=d,this.style.setProperty("--_n-popout-position-x",`${h}px`),this.style.setProperty("--_n-popout-position-y",`${p}px`),(null===(t=c.hide)||void 0===t?void 0:t.referenceHidden)&&this.hide()},this.toggleOpen=t=>{t.preventDefault(),this.open?this.hide(!1):!this.smallViewport||this.alwaysFloating?(this.enterTopLayer(),this.updatePosition().then((()=>this.show()))):this.show()},this.handleMediaQueryChange=()=>{var t;this.smallViewport=P.matches,null===(t=this.cleanupAutoUpdate)||void 0===t||t.call(this),(!this.smallViewport||this.alwaysFloating)&&this.open&&this.anchorElement?(this.cleanupAutoUpdate=r(this.anchorElement,this,this.updatePosition),this.scrollBar.unlockScroll()):this.open&&this.scrollBar.lockScroll()}}async show(){return this.open?Promise.resolve():(this.enterTopLayer(),this.open=!0,await this.updateComplete,this.dispatchEvent(new E("open")),x(this.popout))}async hide(t=!0){var e,o;if(!this.open)return Promise.resolve();this.open=!1,null===(e=this.cleanupAutoUpdate)||void 0===e||e.call(this),this.dispatchEvent(new E("close")),t&&(null===(o=this.targetElement)||void 0===o||o.focus({preventScroll:!0}));const i=await x(this.popout);return this.leaveTopLayer(),i}firstUpdated(){this.smallViewport&&!this.alwaysFloating||this.updatePosition()}connectedCallback(){super.connectedCallback(),this.events.listen(P,"change",this.handleMediaQueryChange),this.initializeElements()}disconnectedCallback(){var t,e;super.disconnectedCallback(),null===(t=this.cleanupAutoUpdate)||void 0===t||t.call(this),null===(e=this.targetElement)||void 0===e||e.removeAttribute("aria-expanded")}render(){return p`<div class="n-popout ${this.computedPosition} is-${this.direction.dir}" aria-hidden="${this.open?"false":"true"}" @transitionend="${this.enableScroll}"><slot></slot></div>`}handleIdChange(){var t;null===(t=this.targetElement)||void 0===t||t.removeEventListener("click",this.toggleOpen),this.id?this.initializeElements():console.warn("NORD: popout requires an id attribute and value")}initializeElements(){this.targetElement=this.getToggle(),this.anchorElement=this.getAnchor(),this.events.listen(this.targetElement,"click",this.toggleOpen)}handleOpenChange(){var t,e;null===(t=this.targetElement)||void 0===t||t.setAttribute("aria-expanded",`${this.open}`),this.open?(this.enterTopLayer(),this.smallViewport&&!this.alwaysFloating?this.scrollBar.lockScroll():this.anchorElement&&(this.cleanupAutoUpdate=r(this.anchorElement,this,this.updatePosition))):null===(e=this.cleanupAutoUpdate)||void 0===e||e.call(this)}handleAnchorChange(){var t;null===(t=this.cleanupAutoUpdate)||void 0===t||t.call(this),this.anchorElement=this.getAnchor(),this.open&&(!this.smallViewport||this.alwaysFloating)&&this.anchorElement&&(this.cleanupAutoUpdate=r(this.anchorElement,this,this.updatePosition))}enterTopLayer(){if("function"==typeof this.showPopover)try{this.setAttribute("popover","manual"),this.showPopover()}catch(t){this.removeAttribute("popover")}}leaveTopLayer(){this.removeAttribute("popover")}getToggle(){const t=this.getRootNode(),e=t.querySelectorAll(`[aria-controls='${this.id}']`);let o=e[0];if(e.length>1){const i=[...t.querySelectorAll(`[id='${this.id}']`)].indexOf(this);i>=0&&i<e.length&&(o=e[i])}return o instanceof HTMLSlotElement?o.assignedElements()[0]:o}getAnchor(){if(!this.anchor)return this.targetElement;const t=this.getRootNode().querySelector(`#${this.anchor}`);return t instanceof HTMLSlotElement?t.assignedElements()[0]:t}};S.styles=[A,C],t([m(".n-popout",!0)],S.prototype,"popout",void 0),t([u()],S.prototype,"computedPosition",void 0),t([u()],S.prototype,"smallViewport",void 0),t([c({reflect:!0})],S.prototype,"id",void 0),t([c({reflect:!0})],S.prototype,"anchor",void 0),t([c({reflect:!0,type:Boolean,attribute:"always-floating"})],S.prototype,"alwaysFloating",void 0),t([w("id")],S.prototype,"handleIdChange",null),t([w("open")],S.prototype,"handleOpenChange",null),t([w("anchor")],S.prototype,"handleAnchorChange",null),S=t([v("nord-popout")],S);var L=S;export{k as F,L as P};
2
- //# sourceMappingURL=Popout-vR6LxNS9.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Popout-vR6LxNS9.js","sources":["../src/common/mixins/FloatingComponentMixin.ts","../src/popout/Popout.ts"],"sourcesContent":["import type { Alignment } from '@floating-ui/dom'\nimport type { LitElement } from 'lit'\nimport type { LogicalSide } from '../positioning.js'\nimport { property } from 'lit/decorators.js'\n\ntype Constructor<T = Record<string, unknown>> = new (...args: any[]) => T\n\nexport declare class FloatingMixinInterface {\n open: boolean\n align: Alignment\n position: LogicalSide | 'auto'\n}\n\nexport function FloatingMixin<T extends Constructor<LitElement>>(\n superClass: T,\n): Constructor<FloatingMixinInterface> & T {\n class FloatingElement extends superClass {\n /**\n * Controls whether the component is open or not.\n */\n @property({ type: Boolean, reflect: true }) open = false\n\n /**\n * Set the alignment in relation to the toggle (or anchor) depending on the position.\n * `start` will align it to the left of the toggle (or anchor).\n * `end` will align it to the right of the toggle (or anchor).\n * Setting the `position` to `inline-start` or `inline-end` will switch\n * `start` and `end` to the top and bottom respectively.\n */\n @property({ reflect: true }) align: 'start' | 'end' = 'start'\n\n /**\n * Set the position in relation to the toggle (or anchor).\n * Options follow logical properties.\n * `block-start` and `block-end` referring to top and bottom respectively,\n * `inline-start` and `inline-end` referring to left and right respectively.\n * You can also set it to `auto` for automatic positioning depending on\n * which side has the most space available.\n */\n @property({ reflect: true }) position: 'block-end' | 'block-start' | 'inline-start' | 'inline-end' | 'auto'\n = 'block-end'\n }\n\n return FloatingElement\n}\n","import type {\n ComputePositionConfig,\n Placement,\n} from '@floating-ui/dom'\nimport {\n autoPlacement,\n autoUpdate,\n computePosition,\n flip,\n hide,\n offset,\n shift,\n} from '@floating-ui/dom'\nimport { html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { DirectionController } from '../common/controllers/DirectionController.js'\nimport { EventController } from '../common/controllers/EventController.js'\nimport { LightDismissController } from '../common/controllers/LightDismissController.js'\nimport { ScrollbarController } from '../common/controllers/ScrollbarController.js'\n\nimport { observe } from '../common/decorators/observe.js'\nimport { NordEvent, transition } from '../common/events.js'\nimport { FloatingMixin } from '../common/mixins/FloatingComponentMixin.js'\nimport { logicalToPhysical } from '../common/positioning.js'\nimport componentStyle from '../common/styles/Component.css'\nimport style from './Popout.css'\n\n/*\n * The breakpoint width to switch between \"sheet\" design and floating design\n */\nconst mediaQuery\n = typeof matchMedia === 'undefined'\n ? ({\n matches: false,\n addEventListener() {\n /* noop */\n },\n } as unknown as MediaQueryList)\n : matchMedia('(max-width: 35.9375em)')\n\n/**\n * Popouts are small overlays that open on demand. They let users access additional content and actions without cluttering the page.\n *\n * @status ready\n * @category overlay\n * @slot - The popout content.\n */\n@customElement('nord-popout')\nexport default class Popout extends FloatingMixin(LitElement) {\n static styles = [componentStyle, style]\n\n private targetElement?: HTMLElement\n private anchorElement?: HTMLElement\n private cleanupAutoUpdate?: ReturnType<typeof autoUpdate>\n\n @query('.n-popout', true) private popout!: HTMLDivElement\n\n private scrollBar = new ScrollbarController(this)\n\n /**\n * Handle dismissal of the popout, clicking outside the target button and popout.\n */\n private dismiss = new LightDismissController(this, {\n isOpen: () => this.open,\n onDismiss: e => this.hide(e.type !== 'click'),\n isDismissible: node => node !== this.popout && node !== this.targetElement,\n })\n\n private events = new EventController(this)\n private direction = new DirectionController(this)\n\n @state() private computedPosition?: Placement\n\n @state() private smallViewport = mediaQuery.matches\n\n /**\n * The id for the active element to reference via aria-controls.\n */\n\n @property({ reflect: true }) id: string = ''\n\n /**\n * Set an optional anchor element to align against, replacing the triggering element.\n */\n @property({ reflect: true }) anchor?: string\n\n /**\n * Set to true to always display the popout as a floating overlay, even on smaller viewports.\n */\n @property({ reflect: true, type: Boolean, attribute: 'always-floating' }) alwaysFloating: boolean = false\n\n /**\n * Show the popout.\n * A promise that resolves to a `TransitionEvent` when the popout's show animation ends or is cancelled.\n * If the popout is already open, the promise resolves immediately with `undefined`.\n */\n async show(): Promise<TransitionEvent | void> {\n if (this.open) {\n return Promise.resolve()\n }\n\n this.enterTopLayer()\n this.open = true\n\n // we should only focus once the popout is visible after render is complete\n await this.updateComplete\n\n /**\n * Dispatched when the popout is opened.\n */\n this.dispatchEvent(new NordEvent('open'))\n\n return transition(this.popout)\n }\n\n /**\n * Hide the popout.\n * Returns a promise that resolves to a `TransitionEvent` when the popout's hide animation ends or is cancelled.\n * If the popout is already closed, the promise resolves immediately with `undefined`.\n * @param {boolean} moveFocusToButton prevent focus returning to the target button. Default is true.\n */\n async hide(moveFocusToButton: boolean = true): Promise<TransitionEvent | void> {\n if (!this.open) {\n return Promise.resolve()\n }\n\n this.open = false\n\n this.cleanupAutoUpdate?.()\n\n /**\n * Dispatched when the popout is closed.\n */\n this.dispatchEvent(new NordEvent('close'))\n\n if (moveFocusToButton) {\n this.targetElement?.focus({ preventScroll: true })\n }\n\n const result = await transition(this.popout)\n this.leaveTopLayer()\n return result\n }\n\n /**\n * Position the popout on load.\n */\n firstUpdated() {\n if (!this.smallViewport || this.alwaysFloating) {\n this.updatePosition()\n }\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n this.events.listen(mediaQuery, 'change', this.handleMediaQueryChange)\n\n this.initializeElements()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.cleanupAutoUpdate?.()\n this.targetElement?.removeAttribute('aria-expanded')\n }\n\n render() {\n return html`\n <div\n class=\"n-popout ${this.computedPosition} is-${this.direction.dir}\"\n aria-hidden=${this.open ? 'false' : 'true'}\n @transitionend=${this.enableScroll}\n >\n <slot></slot>\n </div>\n `\n }\n\n @observe('id')\n protected handleIdChange() {\n // clean up any old listeners\n this.targetElement?.removeEventListener('click', this.toggleOpen)\n\n if (!this.id) {\n console.warn('NORD: popout requires an id attribute and value')\n }\n else {\n this.initializeElements()\n }\n }\n\n private initializeElements() {\n this.targetElement = this.getToggle()\n this.anchorElement = this.getAnchor()\n\n this.events.listen(this.targetElement, 'click', this.toggleOpen)\n }\n\n @observe('open')\n protected handleOpenChange() {\n this.targetElement?.setAttribute('aria-expanded', `${this.open}`)\n\n if (this.open) {\n this.enterTopLayer()\n\n if (this.smallViewport && !this.alwaysFloating) {\n // hide scrollbar and prevent scroll on body\n this.scrollBar.lockScroll()\n }\n else if (this.anchorElement) {\n this.cleanupAutoUpdate = autoUpdate(this.anchorElement, this, this.updatePosition)\n }\n }\n else {\n this.cleanupAutoUpdate?.()\n }\n }\n\n @observe('anchor')\n protected handleAnchorChange() {\n this.cleanupAutoUpdate?.()\n this.anchorElement = this.getAnchor()\n\n // if the popout is already open when the anchor changes, we should update its position\n if (this.open && (!this.smallViewport || this.alwaysFloating) && this.anchorElement) {\n this.cleanupAutoUpdate = autoUpdate(this.anchorElement, this, this.updatePosition)\n }\n }\n\n private enableScroll = () => {\n // scrollbar should only be restored when the backdrop has transitioned\n // that way we avoid awkward double scrollbars.\n if (!this.open) {\n this.scrollBar.unlockScroll()\n this.leaveTopLayer()\n }\n }\n\n /**\n * Place the element in the top layer via the Popover API so that\n * position: fixed works relative to the viewport regardless of\n * container queries or other containing block ancestors.\n */\n private enterTopLayer() {\n if (typeof this.showPopover !== 'function')\n return\n\n try {\n this.setAttribute('popover', 'manual')\n this.showPopover()\n }\n catch {\n this.removeAttribute('popover')\n }\n }\n\n private leaveTopLayer() {\n this.removeAttribute('popover')\n }\n\n /**\n * Get the position of the element toggling the popout\n * and position the popout underneath it, taking into account the optional placement.\n */\n private updatePosition = async () => {\n if (!this.anchorElement) {\n return\n }\n\n const computePositionConfig: ComputePositionConfig = {\n strategy: 'fixed',\n }\n\n if (this.position === 'auto') {\n computePositionConfig.middleware = [\n offset(8),\n autoPlacement({ alignment: this.align, padding: 8 }),\n shift({\n padding: 8,\n }),\n hide(),\n ]\n }\n else {\n computePositionConfig.placement = logicalToPhysical(this.position, this.align, this.direction.dir)\n computePositionConfig.middleware = [\n offset(8),\n flip(),\n shift({\n padding: 8,\n }),\n hide(),\n ]\n }\n\n const { x, y, placement, middlewareData } = await computePosition(this.anchorElement, this, computePositionConfig)\n\n this.computedPosition = placement\n\n // use physical properties here since floating-ui\n // works exclusively in physical dimensions\n // we do all the mapping in logicalToPhysical\n this.style.setProperty('--_n-popout-position-x', `${x}px`)\n this.style.setProperty('--_n-popout-position-y', `${y}px`)\n\n if (middlewareData.hide?.referenceHidden) {\n this.hide()\n }\n }\n\n /**\n * Toggle the popout open or closed using state.\n * Updating the position to underneath the target button before the popout is opened.\n */\n private toggleOpen = (e: Event) => {\n e.preventDefault()\n if (this.open) {\n this.hide(false)\n }\n else if (!this.smallViewport || this.alwaysFloating) {\n this.enterTopLayer()\n this.updatePosition().then(() => this.show())\n }\n else {\n this.show()\n }\n }\n\n private getToggle() {\n const rootNode = this.getRootNode() as Document | ShadowRoot\n const allToggles = rootNode.querySelectorAll<HTMLElement>(`[aria-controls='${this.id}']`)\n\n let toggle = allToggles[0]\n\n // When multiple toggles share the same aria-controls (duplicate IDs on page),\n // pair each toggle with its corresponding popout by document order.\n if (allToggles.length > 1) {\n const index = [...rootNode.querySelectorAll<HTMLElement>(`[id='${this.id}']`)].indexOf(this)\n if (index >= 0 && index < allToggles.length) {\n toggle = allToggles[index]\n }\n }\n\n if (toggle instanceof HTMLSlotElement) {\n return toggle.assignedElements()[0] as HTMLElement\n }\n\n return toggle\n }\n\n private getAnchor() {\n if (!this.anchor) {\n return this.targetElement\n }\n\n const rootNode = this.getRootNode() as Document | ShadowRoot\n const anchor = <HTMLElement>rootNode.querySelector(`#${this.anchor}`)\n\n if (anchor instanceof HTMLSlotElement) {\n return anchor.assignedElements()[0] as HTMLElement\n }\n\n return anchor\n }\n\n /**\n * Update the smallViewport flag to switch between \"sheet\" and \"floating\".\n * autoUpdate is needed when a viewport gets larger and the popout is open.\n */\n private handleMediaQueryChange = () => {\n this.smallViewport = mediaQuery.matches\n\n this.cleanupAutoUpdate?.()\n\n if ((!this.smallViewport || this.alwaysFloating) && this.open && this.anchorElement) {\n this.cleanupAutoUpdate = autoUpdate(this.anchorElement, this, this.updatePosition)\n this.scrollBar.unlockScroll()\n }\n else if (this.open) {\n this.scrollBar.lockScroll()\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-popout': Popout\n }\n}\n"],"names":["FloatingMixin","superClass","FloatingElement","constructor","this","open","align","position","__decorate","property","type","Boolean","reflect","prototype","mediaQuery","matchMedia","matches","addEventListener","Popout","LitElement","scrollBar","ScrollbarController","dismiss","LightDismissController","isOpen","onDismiss","e","hide","isDismissible","node","popout","targetElement","events","EventController","direction","DirectionController","smallViewport","id","alwaysFloating","enableScroll","unlockScroll","leaveTopLayer","updatePosition","async","anchorElement","computePositionConfig","strategy","middleware","offset","autoPlacement","alignment","padding","shift","placement","logicalToPhysical","dir","flip","x","y","middlewareData","computePosition","computedPosition","style","setProperty","_a","referenceHidden","toggleOpen","preventDefault","enterTopLayer","then","show","handleMediaQueryChange","cleanupAutoUpdate","call","autoUpdate","lockScroll","Promise","resolve","updateComplete","dispatchEvent","NordEvent","transition","moveFocusToButton","_b","focus","preventScroll","result","firstUpdated","connectedCallback","super","listen","initializeElements","disconnectedCallback","removeAttribute","render","html","handleIdChange","removeEventListener","console","warn","getToggle","getAnchor","handleOpenChange","setAttribute","handleAnchorChange","showPopover","rootNode","getRootNode","allToggles","querySelectorAll","toggle","length","index","indexOf","HTMLSlotElement","assignedElements","anchor","querySelector","styles","componentStyle","query","state","attribute","observe","customElement"],"mappings":"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"}