@besaitech/ng-design-system 0.0.69 → 0.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy, ElementRef, TemplateRef, WritableSignal, OnInit, InjectionToken, Provider } from '@angular/core';
2
+ import { OnDestroy, ElementRef, TemplateRef, WritableSignal, OnInit, Signal, InjectionToken, Provider } from '@angular/core';
3
3
  import { SafeHtml } from '@angular/platform-browser';
4
4
  import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
5
5
  import * as _besaitech_ng_design_system from '@besaitech/ng-design-system';
@@ -4599,16 +4599,33 @@ type SdsSidebarAppearance = 'brand' | 'surface';
4599
4599
  * multiple independent sidebars, provide it at a component level instead.
4600
4600
  */
4601
4601
  declare class SidebarStore {
4602
- /** Desktop rail state: collapsed to icon-only width (applies at ≥ lg). */
4602
+ private readonly document;
4603
+ /**
4604
+ * The person's desktop preference: icon-only rail. It is a PREFERENCE, not the rendered state — use
4605
+ * {@link railCollapsed} to know whether the rail is actually icon-only right now.
4606
+ */
4603
4607
  readonly collapsed: _angular_core.WritableSignal<boolean>;
4608
+ /** True below `lg`, where the rail is the off-canvas drawer. */
4609
+ readonly belowLg: _angular_core.WritableSignal<boolean>;
4610
+ /**
4611
+ * Whether the rail is icon-only RIGHT NOW: the desktop collapse applies at ≥ lg only. The mobile drawer
4612
+ * is always full width — reading `collapsed` there hid every collapsible group's pages behind a header
4613
+ * that could no longer open them (collapse on desktop, then open the drawer on a narrow screen).
4614
+ */
4615
+ readonly railCollapsed: _angular_core.Signal<boolean>;
4604
4616
  /**
4605
4617
  * The rail's paint, published by <sds-sidebar> so projected <sds-nav-item>/<sds-nav-group> pick the
4606
4618
  * matching state and hover colours (white-on-dark for `brand`, ink-and-brand for `surface`) without
4607
4619
  * every item taking an input. One rail, one appearance — set by the sidebar, read by its children.
4608
4620
  */
4609
4621
  readonly appearance: _angular_core.WritableSignal<SdsSidebarAppearance>;
4622
+ /** Accordion mode, published by <sds-sidebar [accordion]>: opening one group closes the others. */
4623
+ readonly accordion: _angular_core.WritableSignal<boolean>;
4624
+ /** The collapsible group most recently opened by hand (accordion mode closes the rest). */
4625
+ readonly openedGroup: _angular_core.WritableSignal<number | null>;
4610
4626
  /** Mobile drawer state: whether the off-canvas sidebar is slid in (< lg). */
4611
4627
  readonly mobileOpen: _angular_core.WritableSignal<boolean>;
4628
+ constructor();
4612
4629
  /** Toggle the desktop icon-rail. */
4613
4630
  toggle(): void;
4614
4631
  setCollapsed(value: boolean): void;
@@ -4719,6 +4736,28 @@ declare class SdsShell {
4719
4736
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsShell, "sds-shell", never, { "background": { "alias": "background"; "required": false; "isSignal": true; }; "decorations": { "alias": "decorations"; "required": false; "isSignal": true; }; }, {}, never, ["[sdsTopbar]", "[sdsSidebar]", "*"], true, never>;
4720
4737
  }
4721
4738
 
4739
+ /**
4740
+ * What a <sds-nav-group> tells the <sds-nav-item>s projected into it. Internal to the library (not in
4741
+ * public-api.ts): it lets an item style itself as a nested sub-destination, or as a row of the
4742
+ * collapsed rail's flyout panel, without the app passing anything.
4743
+ */
4744
+ interface SdsNavGroupContext {
4745
+ /** The items are sub-destinations of a collapsible group (tree-guide styling, no icon needed). */
4746
+ readonly nested: Signal<boolean>;
4747
+ /** The items currently live in the collapsed rail's flyout panel (labels shown, no tooltips). */
4748
+ readonly inFlyout: Signal<boolean>;
4749
+ /** Close the flyout — called when an item inside it is chosen. */
4750
+ closeFlyout(restoreFocus?: boolean): void;
4751
+ }
4752
+ /**
4753
+ * What a <sds-sidebar> tells the groups and items projected into it. Its own appearance, read through
4754
+ * DI rather than the root store, so two rails on one page (an app rail and a demo, a light and a dark
4755
+ * one) each paint their own items.
4756
+ */
4757
+ interface SdsSidebarContext {
4758
+ readonly appearance: Signal<SdsSidebarAppearance>;
4759
+ }
4760
+
4722
4761
  /**
4723
4762
  * Collapsible navigation rail. Project <sds-nav-group>/<sds-nav-item> as the
4724
4763
  * default content, and pin a footer (e.g. search + version badge) via the
@@ -4731,18 +4770,24 @@ declare class SdsShell {
4731
4770
  *
4732
4771
  * Responsive: below `lg` it is a fixed off-canvas drawer opened by the top bar's hamburger; it is a
4733
4772
  * modal (scrim + trap), so while open Escape closes it, focus moves into it and is restored on close,
4734
- * and Tab is kept inside. While closed it is `inert`, so its off-screen items are out of the tab order.
4735
- * At `lg` and up it is the in-flow, collapsible rail.
4773
+ * Tab is kept inside, the page behind stops scrolling, and a swipe to the left closes it. While closed
4774
+ * it is `inert`, so its off-screen items are out of the tab order. The drawer is always full width —
4775
+ * the desktop collapse preference never applies to it. At `lg` and up it is the in-flow, collapsible
4776
+ * rail; collapsed to icons, its collapsible groups open as flyout panels and its items show tooltips.
4777
+ *
4778
+ * Project an `[sdsHeader]` element (typically the logo + app name) to brand the drawer's header row,
4779
+ * and set `[accordion]` to keep a single collapsible group open at a time.
4736
4780
  *
4737
4781
  * @example
4738
4782
  * <sds-sidebar appearance="surface" decorations>
4783
+ * <img sdsHeader class="h-7 lg:hidden" src="/logo.svg" alt="Saitech" />
4739
4784
  * <sds-nav-group label="Membres">
4740
4785
  * <sds-nav-item icon="user-plus" label="Add a member" link="/members/new" />
4741
4786
  * </sds-nav-group>
4742
4787
  * <div sdsFooter>…</div>
4743
4788
  * </sds-sidebar>
4744
4789
  */
4745
- declare class SdsSidebar {
4790
+ declare class SdsSidebar implements SdsSidebarContext {
4746
4791
  protected readonly store: SidebarStore;
4747
4792
  private readonly document;
4748
4793
  private readonly drawer;
@@ -4751,6 +4796,9 @@ declare class SdsSidebar {
4751
4796
  protected readonly belowLg: _angular_core.WritableSignal<boolean>;
4752
4797
  /** The element focused before the drawer opened, restored to it on close. */
4753
4798
  private restoreFocusTo;
4799
+ /** Live horizontal offset while a swipe drags the drawer closed (≤ 0). */
4800
+ protected readonly dragX: _angular_core.WritableSignal<number>;
4801
+ private touch;
4754
4802
  constructor();
4755
4803
  /**
4756
4804
  * Accessible names for the rail's three icon-only controls. English defaults; a multilingual app
@@ -4759,23 +4807,31 @@ declare class SdsSidebar {
4759
4807
  readonly collapseLabel: _angular_core.InputSignal<string>;
4760
4808
  readonly expandLabel: _angular_core.InputSignal<string>;
4761
4809
  readonly closeLabel: _angular_core.InputSignal<string>;
4810
+ /** Accessible name of the navigation landmark (e.g. "Main navigation"). */
4811
+ readonly navLabel: _angular_core.InputSignal<string>;
4762
4812
  /** `brand` (default) is the dark rail; `surface` is a light rail with brand accents. */
4763
4813
  readonly appearance: _angular_core.InputSignal<SdsSidebarAppearance>;
4814
+ /** Keep a single collapsible group open: opening one folds the others. */
4815
+ readonly accordion: _angular_core.InputSignalWithTransform<boolean, unknown>;
4764
4816
  /** Add slow-drifting brand-tinted blobs behind the rail (opt-in). */
4765
4817
  readonly decorations: _angular_core.InputSignalWithTransform<boolean, unknown>;
4766
- protected readonly collapsed: _angular_core.WritableSignal<boolean>;
4818
+ /** Icon-only right now (desktop preference, never in the mobile drawer). */
4819
+ protected readonly railCollapsed: _angular_core.Signal<boolean>;
4767
4820
  protected readonly mobileOpen: _angular_core.WritableSignal<boolean>;
4768
4821
  protected readonly asideClass: _angular_core.Signal<string>;
4769
4822
  /** The two header icon buttons, painted for the active rail. */
4770
4823
  protected readonly railBtnClass: _angular_core.Signal<"text-ink-soft hover:bg-muted hover:text-ink focus-visible:ring-brand-500/40" | "text-white/70 hover:bg-white/10 hover:text-white focus-visible:ring-white/40">;
4771
4824
  /** Desktop rail width (full vs. collapsed); mobile always uses full width. */
4772
4825
  protected readonly railWidth: _angular_core.Signal<"var(--sds-sidebar-w-collapsed)" | "var(--sds-sidebar-w)">;
4826
+ protected onTouchStart(event: TouchEvent): void;
4827
+ protected onTouchMove(event: TouchEvent): void;
4828
+ protected onTouchEnd(): void;
4773
4829
  protected onEscape(): void;
4774
4830
  /** Keep Tab inside the open mobile drawer (a modal must not leak focus to the page behind the scrim). */
4775
4831
  protected onDrawerKeydown(event: KeyboardEvent): void;
4776
4832
  private focusableEls;
4777
4833
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsSidebar, never>;
4778
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsSidebar, "sds-sidebar", never, { "collapseLabel": { "alias": "collapseLabel"; "required": false; "isSignal": true; }; "expandLabel": { "alias": "expandLabel"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "decorations": { "alias": "decorations"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[sdsFooter]"], true, never>;
4834
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsSidebar, "sds-sidebar", never, { "collapseLabel": { "alias": "collapseLabel"; "required": false; "isSignal": true; }; "expandLabel": { "alias": "expandLabel"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; "navLabel": { "alias": "navLabel"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "accordion": { "alias": "accordion"; "required": false; "isSignal": true; }; "decorations": { "alias": "decorations"; "required": false; "isSignal": true; }; }, {}, never, ["[sdsHeader]", "*", "[sdsFooter]"], true, never>;
4779
4835
  }
4780
4836
 
4781
4837
  type SdsNavItemBadgeTone = 'brand' | 'danger' | 'neutral';
@@ -4783,6 +4839,15 @@ type SdsNavItemBadgeTone = 'brand' | 'danger' | 'neutral';
4783
4839
  * A single sidebar navigation entry. Renders an anchor when [link] is set
4784
4840
  * (with automatic active state via routerLinkActive) or a button otherwise.
4785
4841
  *
4842
+ * It adapts to where it sits, with no input from the app:
4843
+ * - at the top level, an icon + label row with a pill and accent bar when active;
4844
+ * - inside a collapsible <sds-nav-group>, a nested sub-destination on the group's tree guide (no icon
4845
+ * needed), the active one marked on the guide line;
4846
+ * - inside the collapsed rail's flyout panel, a full row with its label;
4847
+ * - on the collapsed rail itself, its icon alone, with a tooltip naming it on hover and focus.
4848
+ *
4849
+ * Choosing an item closes the mobile drawer and any open flyout.
4850
+ *
4786
4851
  * Requires the host application to provide the Angular Router (`provideRouter`),
4787
4852
  * as it depends on RouterLink/RouterLinkActive even when used as a button.
4788
4853
  *
@@ -4792,6 +4857,7 @@ type SdsNavItemBadgeTone = 'brand' | 'danger' | 'neutral';
4792
4857
  */
4793
4858
  declare class SdsNavItem {
4794
4859
  protected readonly store: SidebarStore;
4860
+ private readonly group;
4795
4861
  readonly icon: _angular_core.InputSignal<"chart-column" | "chart-line" | "chart-bar" | "chart-area" | "chart-pie" | "chart-scatter" | "grid-3x3" | "activity" | "gauge" | "trending-up" | "trending-down" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "ticket" | "square" | "square-check" | "circle-dot" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "chevrons-up" | "chevrons-down" | "star" | "message-square" | "filter" | "table" | "qr-code" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "file-check" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "locate-fixed" | "locate-off" | "bug" | "scroll-text" | "moon" | "sun" | "search-x" | "command" | "sparkles" | "triangle-alert" | "octagon-x" | "ban" | "ellipsis" | "ellipsis-vertical" | "grip-vertical" | "upload" | "image" | "image-off" | "utensils" | "zoom-in" | "zoom-out" | "trash-2" | "clock" | "pencil" | "circle-help" | "stock" | "allergen-cereals-gluten" | "allergen-crustaceans" | "allergen-eggs" | "allergen-fish" | "allergen-peanuts" | "allergen-soybeans" | "allergen-milk" | "allergen-nuts" | "allergen-celery" | "allergen-mustard" | "allergen-sesame" | "allergen-sulphites" | "allergen-lupin" | "allergen-molluscs" | null>;
4796
4862
  readonly label: _angular_core.InputSignal<string>;
4797
4863
  /** Router link target; when null, the item behaves as a button. */
@@ -4811,7 +4877,20 @@ declare class SdsNavItem {
4811
4877
  /** Badge colour. `danger` for things that block, `brand` (default) for a neutral count. */
4812
4878
  readonly badgeTone: _angular_core.InputSignal<SdsNavItemBadgeTone>;
4813
4879
  readonly select: _angular_core.OutputEmitterRef<void>;
4814
- protected readonly collapsed: _angular_core.WritableSignal<boolean>;
4880
+ /** Inside a collapsible group: a nested sub-destination. */
4881
+ protected readonly nested: _angular_core.Signal<boolean>;
4882
+ /** A row of the collapsed rail's flyout panel. */
4883
+ private readonly inFlyout;
4884
+ /** Icon alone: on the collapsed desktop rail, unless it is listed in a flyout. */
4885
+ protected readonly iconOnly: _angular_core.Signal<boolean>;
4886
+ /** Tooltip anchor (viewport coordinates) while hovered/focused on the icon rail. */
4887
+ protected readonly tip: _angular_core.WritableSignal<{
4888
+ top: number;
4889
+ left: number;
4890
+ } | null>;
4891
+ private readonly rail;
4892
+ /** Paint of the rail this item sits in (its own sidebar's, else the store's for a free-standing item). */
4893
+ private readonly surface;
4815
4894
  /** The badge's spoken text, or null when there is nothing to show. */
4816
4895
  protected readonly badgeText: _angular_core.Signal<string | null>;
4817
4896
  protected readonly badgeDisplay: _angular_core.Signal<string>;
@@ -4820,45 +4899,60 @@ declare class SdsNavItem {
4820
4899
  protected readonly badgeClass: _angular_core.Signal<string>;
4821
4900
  protected itemClass(isActive: boolean): string;
4822
4901
  /**
4823
- * The left accent bar on an active item — the strongest "selected" cue, and the one that survives a
4824
- * grayscale brand where a tinted pill alone is nearly invisible. brand-600 on the light rail, white on
4825
- * the dark one; on a coloured brand it is the brand colour, matching the certicheck accent bar.
4902
+ * The active marker — the strongest "selected" cue, and the one that survives a grayscale brand where a
4903
+ * tinted pill alone is nearly invisible. A top-level (or flyout) item carries it inside its pill; a
4904
+ * nested item draws it ON the group's tree guide (12 px to its left), so the line itself points at the
4905
+ * current page.
4826
4906
  */
4827
4907
  protected readonly accentBarClass: _angular_core.Signal<string>;
4908
+ protected showTip(event: Event): void;
4909
+ protected chosen(): void;
4828
4910
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsNavItem, never>;
4829
4911
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsNavItem, "sds-nav-item", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "link": { "alias": "link"; "required": false; "isSignal": true; }; "exact": { "alias": "exact"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeLabel": { "alias": "badgeLabel"; "required": false; "isSignal": true; }; "badgeMax": { "alias": "badgeMax"; "required": false; "isSignal": true; }; "badgeTone": { "alias": "badgeTone"; "required": false; "isSignal": true; }; }, { "select": "select"; }, never, never, true, never>;
4830
4912
  }
4831
4913
 
4832
4914
  /**
4833
- * Groups nav items under an optional uppercase section label.
4915
+ * Groups nav items under an optional section label.
4834
4916
  *
4835
4917
  * Two modes:
4836
- * - **Section** (default) — a static label over its items. The label is replaced by a divider when
4837
- * the rail is collapsed.
4838
- * - **Collapsible** (`[collapsible]`) — the label becomes a button that expands and collapses the
4839
- * group. Set `[basePath]` and the group opens itself whenever the active route is inside it, so a
4840
- * deep link or a browser Back lands with the right section already open instead of the person
4841
- * having to find and re-open it. A group whose pages live under several prefixes (a business area
4842
- * grouping `/people`, `/customers`, `/drivers`) lists them all in `[basePaths]`.
4918
+ * - **Section** (default) — a static uppercase caption over its items. On the collapsed rail the caption
4919
+ * becomes a divider and the items (which carry their own icons) stay visible.
4920
+ * - **Collapsible** (`[collapsible]`) — the label becomes a row-height header that opens and closes the
4921
+ * group with a short height animation. Its items render as nested sub-destinations on a tree guide
4922
+ * line, the active one marked on the line itself. Set `[basePath]` (or several `[basePaths]`) and the
4923
+ * group opens itself whenever the active route is inside it, so a deep link or a browser Back lands
4924
+ * with the right section already open; while closed it still shows that it holds the current page
4925
+ * (a highlighted header with a dot).
4926
+ *
4927
+ * On the collapsed desktop rail a collapsible group is its icon alone, and its pages open in a FLYOUT
4928
+ * panel beside the rail — on hover, on click/tap (which pins it), or from the keyboard (Enter, Space or
4929
+ * → opens it and focuses the first page; ↑/↓ move, Esc or ← closes back to the header). So every
4930
+ * destination stays reachable on the icon rail, without navigating anywhere just to see what a section
4931
+ * holds.
4843
4932
  *
4844
4933
  * A collapsible group can carry a `[badge]` of its own — typically the sum of its children's. It is
4845
4934
  * drawn on the header only while the children are hidden, so a closed section still says that
4846
4935
  * something inside it is waiting, and an open one does not show the same count twice.
4847
4936
  *
4848
- * Collapsible mode exists because a flat rail stops scaling somewhere around a dozen destinations,
4849
- * and the alternative — showing every child of every section at once — buries the ones in use.
4850
- *
4851
- * On the collapsed desktop rail there is nowhere to put a header, so a collapsible group renders
4852
- * exactly like a section: divider, children visible. Hiding them there would leave the rail with
4853
- * unreachable destinations and no affordance to reveal them.
4937
+ * Inside the mobile drawer the rail is always full width, whatever the desktop collapse preference.
4854
4938
  */
4855
- declare class SdsNavGroup {
4939
+ declare class SdsNavGroup implements SdsNavGroupContext {
4856
4940
  private readonly store;
4857
4941
  private readonly router;
4942
+ private readonly document;
4943
+ private readonly host;
4944
+ private readonly injector;
4945
+ private readonly id;
4946
+ protected readonly headerId: string;
4947
+ protected readonly panelId: string;
4948
+ private readonly header;
4949
+ private readonly panel;
4858
4950
  readonly label: _angular_core.InputSignal<string>;
4859
4951
  /** Turn the label into an expand/collapse control. */
4860
4952
  readonly collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
4861
- /** Icon for a collapsible header, so it reads at the same weight as the items it sits among. */
4953
+ /** Start open (until the person toggles it), even when the route is not inside the group. */
4954
+ readonly defaultOpen: _angular_core.InputSignalWithTransform<boolean, unknown>;
4955
+ /** Icon for a collapsible header — and the group's only representation on the collapsed rail. */
4862
4956
  readonly icon: _angular_core.InputSignal<"chart-column" | "chart-line" | "chart-bar" | "chart-area" | "chart-pie" | "chart-scatter" | "grid-3x3" | "activity" | "gauge" | "trending-up" | "trending-down" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "ticket" | "square" | "square-check" | "circle-dot" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "chevrons-up" | "chevrons-down" | "star" | "message-square" | "filter" | "table" | "qr-code" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "file-check" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "locate-fixed" | "locate-off" | "bug" | "scroll-text" | "moon" | "sun" | "search-x" | "command" | "sparkles" | "triangle-alert" | "octagon-x" | "ban" | "ellipsis" | "ellipsis-vertical" | "grip-vertical" | "upload" | "image" | "image-off" | "utensils" | "zoom-in" | "zoom-out" | "trash-2" | "clock" | "pencil" | "circle-help" | "stock" | "allergen-cereals-gluten" | "allergen-crustaceans" | "allergen-eggs" | "allergen-fish" | "allergen-peanuts" | "allergen-soybeans" | "allergen-milk" | "allergen-nuts" | "allergen-celery" | "allergen-mustard" | "allergen-sesame" | "allergen-sulphites" | "allergen-lupin" | "allergen-molluscs" | null>;
4863
4957
  /**
4864
4958
  * URL prefix owned by this group, e.g. `/payments`. While the active route starts with it the
@@ -4881,7 +4975,10 @@ declare class SdsNavGroup {
4881
4975
  readonly badgeMax: _angular_core.InputSignal<number>;
4882
4976
  /** Badge colour, as on {@link SdsNavItem}. */
4883
4977
  readonly badgeTone: _angular_core.InputSignal<SdsNavItemBadgeTone>;
4884
- /** Emits the new state on every manual toggle. Not emitted for route-driven auto-expansion. */
4978
+ /**
4979
+ * Emits the new state on every manual inline toggle. Not emitted for route-driven auto-expansion, nor
4980
+ * for the collapsed rail's flyout (which shows the pages instead — no need to navigate to see them).
4981
+ */
4885
4982
  readonly expandedChange: _angular_core.OutputEmitterRef<boolean>;
4886
4983
  /** Explicit user choice; null means "follow the route". */
4887
4984
  private readonly manual;
@@ -4893,42 +4990,74 @@ declare class SdsNavGroup {
4893
4990
  */
4894
4991
  protected readonly routeActive: _angular_core.Signal<boolean>;
4895
4992
  protected readonly expanded: _angular_core.Signal<boolean>;
4896
- protected readonly collapsed: _angular_core.WritableSignal<boolean>;
4993
+ /** Icon-only desktop rail right now (never inside the mobile drawer). */
4994
+ protected readonly railCollapsed: _angular_core.Signal<boolean>;
4995
+ protected readonly flyoutOpen: _angular_core.WritableSignal<boolean>;
4996
+ /** Opened by click / keyboard: stays open when the pointer leaves, until a choice, Esc or outside click. */
4997
+ private pinned;
4998
+ protected readonly pos: _angular_core.WritableSignal<{
4999
+ top: number;
5000
+ left: number;
5001
+ maxHeight: number;
5002
+ }>;
5003
+ private openTimer;
5004
+ private closeTimer;
5005
+ protected readonly flyoutShown: _angular_core.Signal<boolean>;
5006
+ readonly nested: _angular_core.Signal<boolean>;
5007
+ readonly inFlyout: _angular_core.Signal<boolean>;
5008
+ constructor();
4897
5009
  /** The header badge's spoken text — only while the children (which show their own) are hidden. */
4898
5010
  protected readonly headerBadgeText: _angular_core.Signal<string | null>;
4899
5011
  protected readonly badgeDisplay: _angular_core.Signal<string>;
4900
- /** The same pill as {@link SdsNavItem}'s, pinned to the icon's corner on the collapsed rail. */
4901
- protected readonly badgeClass: _angular_core.Signal<string>;
5012
+ /** Accessible name of the icon-only header: "Money, 3 pending". */
5013
+ protected readonly collapsedName: _angular_core.Signal<string>;
4902
5014
  /** Rail paint, shared via the store — see SidebarStore.appearance. Drives the header/caption tones. */
5015
+ private readonly rail;
4903
5016
  private readonly surface;
5017
+ private badgeTone$;
5018
+ protected readonly badgeClass: _angular_core.Signal<string>;
5019
+ /** The badge as a small pill on the icon's corner (collapsed rail). */
5020
+ protected readonly pipClass: _angular_core.Signal<string>;
5021
+ protected readonly activeDotClass: _angular_core.Signal<string>;
5022
+ protected readonly wrapClass: _angular_core.Signal<"mt-1 first:mt-2" | "mt-5 first:mt-3">;
4904
5023
  /** Collapsible header, painted for the active rail (ink+brand on `surface`, white on `brand`). */
4905
5024
  protected readonly headerClass: _angular_core.Signal<string>;
4906
5025
  protected readonly chevronClass: _angular_core.Signal<string>;
4907
5026
  protected readonly dividerClass: _angular_core.Signal<string>;
4908
5027
  protected readonly captionClass: _angular_core.Signal<string>;
5028
+ protected readonly flyoutTitleClass: _angular_core.Signal<string>;
4909
5029
  /**
4910
- * A plain section always shows its items — they carry their own icons, so they survive the collapsed
4911
- * rail. A collapsible group hides its children there instead: its children are sub-destinations and
4912
- * typically have no icon, which on an icon-only rail is a row with nothing in it.
5030
+ * Whether the items are on screen: a plain section always; a collapsible group when open on the full
5031
+ * rail (its items have no icon of their own, so on the icon rail they live in the flyout instead).
4913
5032
  */
4914
5033
  protected readonly childrenVisible: _angular_core.Signal<boolean>;
5034
+ /** Closed panels are `inert`, so their (visually hidden) links leave the tab order. */
5035
+ protected readonly childrenInteractive: _angular_core.Signal<boolean>;
5036
+ protected readonly panelClass: _angular_core.Signal<string>;
5037
+ protected readonly innerClass: _angular_core.Signal<"" | "min-h-0 overflow-y-auto overscroll-contain" | "min-h-0 overflow-hidden">;
4915
5038
  /**
4916
- * One binding rather than `[class]` alongside `[class.hidden]` — mixing a whole-list binding with a
4917
- * single-class toggle on the same element depends on Angular's styling precedence to resolve, which
4918
- * is a subtlety no template should rest on.
4919
- *
4920
- * The indent rule appears only on an expanded collapsible group on the full-width rail: it is what
4921
- * shows the children belong to the header above them.
4922
- */
4923
- protected readonly childrenClass: _angular_core.Signal<string>;
4924
- /**
4925
- * On the collapsed rail there is nothing to expand into, so the toggle always reports "opening" —
4926
- * the app's handler takes that as the cue to navigate into the section, which is the only useful
4927
- * meaning the control can have there.
5039
+ * The tree guide: a hairline under the header's icon (22 px = the header's 12 px padding + half its
5040
+ * 20 px icon), with the items indented beside it. The active item marks its own stretch of the line.
4928
5041
  */
5042
+ protected readonly listClass: _angular_core.Signal<string>;
5043
+ /** Header click: toggle inline; on the collapsed rail, open (and pin) or close the flyout. */
4929
5044
  protected toggle(): void;
5045
+ protected onHeaderKeydown(event: KeyboardEvent): void;
5046
+ protected onHeaderEnter(): void;
5047
+ protected scheduleClose(): void;
5048
+ protected cancelClose(): void;
5049
+ private openFlyout;
5050
+ /** {@link SdsNavGroupContext} — also called by an item chosen inside the flyout. */
5051
+ closeFlyout(restoreFocus?: boolean): void;
5052
+ protected onEscape(): void;
5053
+ /** Focus leaving the header + flyout altogether closes the flyout (Tab past the last page). */
5054
+ protected onFocusOut(event: FocusEvent): void;
5055
+ /** ↑/↓ (and Home/End) move between the flyout's pages; ← closes back to the header. */
5056
+ protected onPanelKeydown(event: KeyboardEvent): void;
5057
+ private items;
5058
+ private clearTimers;
4930
5059
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsNavGroup, never>;
4931
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsNavGroup, "sds-nav-group", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "basePath": { "alias": "basePath"; "required": false; "isSignal": true; }; "basePaths": { "alias": "basePaths"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeLabel": { "alias": "badgeLabel"; "required": false; "isSignal": true; }; "badgeMax": { "alias": "badgeMax"; "required": false; "isSignal": true; }; "badgeTone": { "alias": "badgeTone"; "required": false; "isSignal": true; }; }, { "expandedChange": "expandedChange"; }, never, ["*"], true, never>;
5060
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsNavGroup, "sds-nav-group", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "defaultOpen": { "alias": "defaultOpen"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "basePath": { "alias": "basePath"; "required": false; "isSignal": true; }; "basePaths": { "alias": "basePaths"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeLabel": { "alias": "badgeLabel"; "required": false; "isSignal": true; }; "badgeMax": { "alias": "badgeMax"; "required": false; "isSignal": true; }; "badgeTone": { "alias": "badgeTone"; "required": false; "isSignal": true; }; }, { "expandedChange": "expandedChange"; }, never, ["*"], true, never>;
4932
5061
  }
4933
5062
 
4934
5063
  type SdsUserMenuAppearance = 'surface' | 'on-brand';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@besaitech/ng-design-system",
3
- "version": "0.0.69",
3
+ "version": "0.0.71",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"