@aurora-ds/components 1.4.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import { ComponentType, SVGProps, ButtonHTMLAttributes, Ref, FC, AnchorHTMLAttributes, HTMLAttributes, ReactNode, CSSProperties, FormEvent, InputHTMLAttributes, MouseEvent, AriaRole, AriaAttributes } from 'react';
1
+ import * as react from 'react';
2
+ import { ComponentType, SVGProps, ButtonHTMLAttributes, Ref, FC, AnchorHTMLAttributes, ReactNode, HTMLAttributes, CSSProperties, TdHTMLAttributes, ThHTMLAttributes, AriaAttributes, ErrorInfo, Component, FormEvent, InputHTMLAttributes, MouseEvent, AriaRole, RefObject, RefCallback } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
4
 
3
5
  declare const lightPalette: {
4
6
  surfaceBackground: string;
@@ -28,6 +30,7 @@ declare const lightPalette: {
28
30
  borderSubtle: string;
29
31
  borderMain: string;
30
32
  borderStrong: string;
33
+ focusRing: string;
31
34
  disabledMain: string;
32
35
  disabledText: string;
33
36
  successMain: string;
@@ -302,6 +305,63 @@ type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
302
305
  */
303
306
  declare const Button: FC<ButtonProps>;
304
307
 
308
+ /** Semantic color intent of the FAB. */
309
+ type FabColor = ButtonColor;
310
+ /** SVG icon component used by the FAB. */
311
+ type FabIcon = ButtonIcon;
312
+ /** Size token controlling dimensions of the FAB. */
313
+ type FabSize = 'sm' | 'md' | 'lg';
314
+ /** Screen corner where the FAB is anchored when `position` is fixed. */
315
+ type FabPlacement = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
316
+
317
+ type FabProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'aria-label'> & {
318
+ /** Ref forwarded to the underlying button element. */
319
+ ref?: Ref<HTMLButtonElement>;
320
+ /**
321
+ * Accessible label — required since the FAB may contain only an icon.
322
+ * @a11y Required — the button's only accessible name when no label is visible. Describe the action (e.g. "Add item").
323
+ */
324
+ ariaLabel: string;
325
+ /** SVG icon component rendered inside the FAB. */
326
+ icon: FabIcon;
327
+ /**
328
+ * Optional text label displayed next to the icon (extended FAB).
329
+ * When provided the FAB adopts a pill shape.
330
+ */
331
+ label?: string;
332
+ /** Semantic color intent. @default 'primary' */
333
+ color?: FabColor;
334
+ /** Size token controlling width, height and icon scale. @default 'md' */
335
+ size?: FabSize;
336
+ /**
337
+ * Screen corner where the FAB is anchored with `position: fixed`.
338
+ * Set to `undefined` to opt out of fixed positioning (useful for inline placement).
339
+ * @default 'bottom-right'
340
+ */
341
+ placement?: FabPlacement | null;
342
+ /** Horizontal offset from the placement edge. @default '1.5rem' */
343
+ offsetX?: string;
344
+ /** Vertical offset from the placement edge. @default '1.5rem' */
345
+ offsetY?: string;
346
+ /** Show a spinner and disable interaction. */
347
+ isLoading?: boolean;
348
+ /** Native button type. @default 'button' */
349
+ type?: 'button' | 'submit' | 'reset';
350
+ };
351
+
352
+ /**
353
+ * Floating Action Button (FAB).
354
+ *
355
+ * A circular elevated button intended for the primary action of a screen.
356
+ * Pass a `label` to get an extended (pill-shaped) FAB.
357
+ *
358
+ * @example <Fab icon={AddIcon} ariaLabel="Add item" />
359
+ * @example <Fab icon={AddIcon} ariaLabel="Add item" label="Add" color="success" />
360
+ * @example <Fab icon={EditIcon} ariaLabel="Edit" placement="bottom-left" />
361
+ * @example <Fab icon={AddIcon} ariaLabel="Add" placement={null} /> // inline, no fixed positioning
362
+ */
363
+ declare const Fab: FC<FabProps>;
364
+
305
365
  type IconButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'aria-label'> & {
306
366
  /** Ref forwarded to the underlying button element. */
307
367
  ref?: Ref<HTMLButtonElement>;
@@ -395,6 +455,371 @@ type LinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
395
455
  */
396
456
  declare const Link: FC<LinkProps>;
397
457
 
458
+ /** Visual style available for toggle buttons. Intentionally restricted to 2 variants. */
459
+ type ToggleButtonVariant = 'outlined' | 'text';
460
+
461
+ type ToggleButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & {
462
+ /** Ref forwarded to the underlying button element. */
463
+ ref?: Ref<HTMLButtonElement>;
464
+ /**
465
+ * Text label displayed inside the button.
466
+ * @a11y Recommended — provides the button's accessible name.
467
+ */
468
+ label?: string;
469
+ /** Visual style. @default 'outlined' */
470
+ variant?: ToggleButtonVariant;
471
+ /** Semantic color. @default 'primary' */
472
+ color?: ButtonColor;
473
+ /** Size token controlling height, padding and font size. @default 'md' */
474
+ size?: ButtonSize;
475
+ /** Explicit width for the button. Accepts numbers (px) or any CSS width value. */
476
+ width?: number | string;
477
+ /** Flex grow factor applied to the button container. */
478
+ flexGrow?: number;
479
+ /** Flex shrink factor applied to the button container. */
480
+ flexShrink?: number;
481
+ /**
482
+ * Controlled active (pressed) state.
483
+ * When provided the component is in controlled mode.
484
+ */
485
+ active?: boolean;
486
+ /**
487
+ * Initial active state for uncontrolled mode.
488
+ * @default false
489
+ */
490
+ defaultActive?: boolean;
491
+ /** Called when the active state changes. */
492
+ onActiveChange?: (active: boolean) => void;
493
+ /**
494
+ * Identifier used by `ToggleGroup` to track which toggle is selected.
495
+ * Required when used inside a `ToggleGroup`.
496
+ */
497
+ value?: string;
498
+ /** SVG icon component rendered before the label. */
499
+ startIcon?: ButtonIcon;
500
+ /** SVG icon component rendered after the label. */
501
+ endIcon?: ButtonIcon;
502
+ /** Show a spinner and disable interaction. */
503
+ isLoading?: boolean;
504
+ /** Native button type. @default 'button' */
505
+ type?: 'button' | 'submit' | 'reset';
506
+ };
507
+
508
+ /**
509
+ * A toggle button that can be pressed/unpressed (`aria-pressed`).
510
+ * Supports both **controlled** (`active` + `onActiveChange`) and **uncontrolled**
511
+ * (`defaultActive`) modes.
512
+ *
513
+ * When placed inside a `ToggleGroup`, the group manages mutual exclusivity:
514
+ * the `value` prop identifies this button within the group.
515
+ *
516
+ * @example
517
+ * // Standalone, uncontrolled
518
+ * <ToggleButton label="Bold" defaultActive={false} onActiveChange={setBold} />
519
+ *
520
+ * @example
521
+ * // Standalone, controlled
522
+ * <ToggleButton label="Bold" active={isBold} onActiveChange={setIsBold} />
523
+ *
524
+ * @example
525
+ * // Inside a ToggleGroup
526
+ * <ToggleGroup defaultValue="md" ariaLabel="Text size">
527
+ * <ToggleButton value="sm" label="Small" />
528
+ * <ToggleButton value="md" label="Medium" />
529
+ * </ToggleGroup>
530
+ */
531
+ declare const ToggleButton: FC<ToggleButtonProps>;
532
+
533
+ type ToggleIconButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'aria-label'> & {
534
+ /** Ref forwarded to the underlying button element. */
535
+ ref?: Ref<HTMLButtonElement>;
536
+ /** SVG icon component to render inside the button. */
537
+ icon: ButtonIcon;
538
+ /**
539
+ * Accessible label — required since there is no visible text.
540
+ * @a11y Required — the button's only accessible name. Describe the action, not the icon.
541
+ */
542
+ ariaLabel: string;
543
+ /** Visual style. @default 'outlined' */
544
+ variant?: ToggleButtonVariant;
545
+ /** Semantic color. @default 'primary' */
546
+ color?: ButtonColor;
547
+ /** Size token controlling width, height and padding. @default 'md' */
548
+ size?: ButtonSize;
549
+ /** Show a spinner and disable interaction. */
550
+ isLoading?: boolean;
551
+ /** Native button type. @default 'button' */
552
+ type?: 'button' | 'submit' | 'reset';
553
+ /**
554
+ * Controlled active (pressed) state.
555
+ * When provided the component is in controlled mode.
556
+ */
557
+ active?: boolean;
558
+ /**
559
+ * Initial active state for uncontrolled mode.
560
+ * @default false
561
+ */
562
+ defaultActive?: boolean;
563
+ /** Called when the active state changes. */
564
+ onActiveChange?: (active: boolean) => void;
565
+ /**
566
+ * Identifier used by `ToggleGroup` to track which toggle is selected.
567
+ * Required when used inside a `ToggleGroup`.
568
+ */
569
+ value?: string;
570
+ };
571
+
572
+ /**
573
+ * A square icon-only toggle button that can be pressed/unpressed (`aria-pressed`).
574
+ * `ariaLabel` is mandatory since there is no visible text.
575
+ *
576
+ * Supports both **controlled** (`active` + `onActiveChange`) and **uncontrolled**
577
+ * (`defaultActive`) modes.
578
+ *
579
+ * When placed inside a `ToggleGroup`, the group manages mutual exclusivity:
580
+ * the `value` prop identifies this button within the group.
581
+ *
582
+ * @example
583
+ * // Standalone, controlled
584
+ * <ToggleIconButton icon={BoldIcon} ariaLabel="Toggle bold" active={isBold} onActiveChange={setIsBold} />
585
+ *
586
+ * @example
587
+ * // Inside a ToggleGroup (alignment segmented control)
588
+ * <ToggleGroup value={align} onChange={setAlign} ariaLabel="Text alignment" joined>
589
+ * <ToggleIconButton value="left" icon={AlignLeftIcon} ariaLabel="Align left" />
590
+ * <ToggleIconButton value="center" icon={AlignCenterIcon} ariaLabel="Align center" />
591
+ * <ToggleIconButton value="right" icon={AlignRightIcon} ariaLabel="Align right" />
592
+ * </ToggleGroup>
593
+ */
594
+ declare const ToggleIconButton: FC<ToggleIconButtonProps>;
595
+
596
+ type ToggleGroupProps = {
597
+ /** Toggle buttons to render inside the group. */
598
+ children: ReactNode;
599
+ /**
600
+ * Controlled selected value.
601
+ * When provided the component is in controlled mode.
602
+ * Pass `null` to express "nothing selected".
603
+ */
604
+ value?: string | null;
605
+ /**
606
+ * Initial selected value for uncontrolled mode.
607
+ * @default null
608
+ */
609
+ defaultValue?: string | null;
610
+ /** Called when the selected value changes. */
611
+ onChange?: (value: string | null) => void;
612
+ /**
613
+ * Accessible label for the group.
614
+ * @a11y Either `ariaLabel` or `ariaLabelledBy` is required.
615
+ */
616
+ ariaLabel?: string;
617
+ /**
618
+ * ID of an element that labels this group.
619
+ * @a11y Alternative to `ariaLabel`.
620
+ */
621
+ ariaLabelledBy?: string;
622
+ /**
623
+ * Layout direction.
624
+ * @default 'horizontal'
625
+ */
626
+ orientation?: 'horizontal' | 'vertical';
627
+ /**
628
+ * Visually join the toggle buttons into a single segmented control
629
+ * (shared borders, no gap, rounded ends only).
630
+ * @default false
631
+ */
632
+ joined?: boolean;
633
+ /**
634
+ * Variant applied to all child toggles (overrides their own `variant` prop).
635
+ */
636
+ variant?: ToggleButtonVariant;
637
+ /**
638
+ * Color applied to all child toggles (overrides their own `color` prop).
639
+ */
640
+ color?: ButtonColor;
641
+ /**
642
+ * Size applied to all child toggles (overrides their own `size` prop).
643
+ */
644
+ size?: ButtonSize;
645
+ /**
646
+ * Whether clicking the currently active toggle deselects it (value becomes null).
647
+ * @default true
648
+ */
649
+ allowDeselect?: boolean;
650
+ };
651
+
652
+ /**
653
+ * Groups multiple `ToggleButton` or `ToggleIconButton` components so that only
654
+ * one can be active at a time (mutual exclusivity).
655
+ *
656
+ * Supports both **controlled** (`value` + `onChange`) and **uncontrolled**
657
+ * (`defaultValue`) modes. Set `allowDeselect={false}` to always keep one
658
+ * option selected.
659
+ *
660
+ * @example
661
+ * // Uncontrolled
662
+ * <ToggleGroup defaultValue="md" ariaLabel="Text size">
663
+ * <ToggleButton value="sm" label="Small" />
664
+ * <ToggleButton value="md" label="Medium" />
665
+ * <ToggleButton value="lg" label="Large" />
666
+ * </ToggleGroup>
667
+ *
668
+ * @example
669
+ * // Controlled
670
+ * const [align, setAlign] = useState<string | null>('left')
671
+ * <ToggleGroup value={align} onChange={setAlign} ariaLabel="Text alignment" joined>
672
+ * <ToggleIconButton value="left" icon={AlignLeftIcon} ariaLabel="Align left" />
673
+ * <ToggleIconButton value="center" icon={AlignCenterIcon} ariaLabel="Align center" />
674
+ * <ToggleIconButton value="right" icon={AlignRightIcon} ariaLabel="Align right" />
675
+ * </ToggleGroup>
676
+ */
677
+ declare const ToggleGroup: FC<ToggleGroupProps>;
678
+
679
+ /** Avatar size token controlling the avatar's width and height. */
680
+ type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
681
+ /** Avatar shape – circle (default) or rounded square. */
682
+ type AvatarShape = 'circle' | 'square';
683
+ /**
684
+ * Semantic color intent used for the fallback background
685
+ * (shown when no image is provided).
686
+ */
687
+ type AvatarColor = 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'orange' | 'pink' | 'violet';
688
+ /** Overlap density between avatars inside an AvatarGroup. */
689
+ type AvatarGroupOverlap = 'sm' | 'md' | 'lg';
690
+
691
+ type AvatarProps = {
692
+ /**
693
+ * URL of the image to display.
694
+ * Falls back to `initials` (or first letters of `name`) if the image fails to load.
695
+ */
696
+ src?: string;
697
+ /**
698
+ * Full name of the person/entity.
699
+ * Automatically extracts 1–2 initials when no `src` is provided.
700
+ * Also used as `aria-label` when no explicit `ariaLabel` is given.
701
+ */
702
+ name?: string;
703
+ /**
704
+ * Explicit initials to display when no image is available.
705
+ * Takes precedence over initials derived from `name`.
706
+ * Keep to 1–2 characters.
707
+ */
708
+ initials?: string;
709
+ /** Size token controlling width and height. @default 'md' */
710
+ size?: AvatarSize;
711
+ /** Shape of the avatar. @default 'circle' */
712
+ shape?: AvatarShape;
713
+ /**
714
+ * Background color token used for the fallback (initials/empty) state.
715
+ * @default 'primary'
716
+ */
717
+ color?: AvatarColor;
718
+ /**
719
+ * Makes the avatar interactive (adds `role="button"` and keyboard support).
720
+ * Called when the user clicks or presses Enter/Space.
721
+ */
722
+ onClick?: () => void;
723
+ /** Accessible label. Defaults to `name` when set, otherwise `'Avatar'`. */
724
+ ariaLabel?: string;
725
+ };
726
+
727
+ /**
728
+ * Displays a user's profile picture, falling back gracefully to initials
729
+ * and then to a blank coloured circle when no image is available.
730
+ *
731
+ * **Display priority:**
732
+ * 1. `src` image (hides on load error)
733
+ * 2. `initials` (explicit) or letters derived from `name`
734
+ * 3. Empty coloured circle
735
+ *
736
+ * **Accessibility:**
737
+ * - Static avatar → `role="img"` + `aria-label`
738
+ * - Interactive avatar (has `onClick`) → `role="button"` + keyboard support
739
+ *
740
+ * @example
741
+ * ```tsx
742
+ * // Image avatar:
743
+ * <Avatar src="/users/alice.jpg" name="Alice Dupont" size="md" />
744
+ *
745
+ * // Initials fallback:
746
+ * <Avatar name="Bob Martin" color="info" size="lg" />
747
+ *
748
+ * // Interactive:
749
+ * <Avatar src="/me.jpg" name="Me" onClick={() => openProfile()} ariaLabel="Open profile" />
750
+ * ```
751
+ */
752
+ declare const Avatar: FC<AvatarProps>;
753
+
754
+ type AvatarGroupProps = {
755
+ /** Avatar components to render inside the group. */
756
+ children: ReactNode;
757
+ /**
758
+ * Maximum number of avatars to display.
759
+ * When exceeded, a surplus counter (+N) avatar is shown at the end.
760
+ */
761
+ max?: number;
762
+ /**
763
+ * Size passed down to all Avatar children and to the surplus avatar.
764
+ * Individual Avatar size props are overridden by this value when set.
765
+ */
766
+ size?: AvatarSize;
767
+ /**
768
+ * Shape passed down to all Avatar children **and to the surplus avatar**.
769
+ * Ensures visual consistency — e.g. `shape="square"` makes the +N tile
770
+ * square as well.
771
+ * Individual Avatar shape props are overridden by this value when set.
772
+ */
773
+ shape?: AvatarShape;
774
+ /**
775
+ * Controls the horizontal overlap between adjacent avatars.
776
+ * - `sm` — tight (most overlap)
777
+ * - `md` — moderate overlap (default)
778
+ * - `lg` — loose (least overlap)
779
+ * @default 'md'
780
+ */
781
+ overlap?: AvatarGroupOverlap;
782
+ /**
783
+ * Background color of the surplus counter avatar (+N).
784
+ * @default 'default'
785
+ */
786
+ surplusColor?: AvatarColor;
787
+ /**
788
+ * Accessible label for the group (`aria-label` on `role="list"`).
789
+ *
790
+ * **Auto-computed when omitted** — built from the `name` props of child
791
+ * Avatars (e.g. *"Alice Dupont, Bob Martin et 3 autres"*).
792
+ * Pass an explicit value to override this behaviour.
793
+ */
794
+ ariaLabel?: string;
795
+ };
796
+
797
+ /**
798
+ * Renders a horizontally overlapping stack of `Avatar` components.
799
+ *
800
+ * When the number of children exceeds `max`, the remaining count is shown
801
+ * as a **surplus avatar** (`+N`) at the end of the row.
802
+ *
803
+ * **Accessibility:**
804
+ * - Root element uses `role="list"` so screen readers announce the item count.
805
+ * - Each slot uses `role="listitem"`.
806
+ * - The `aria-label` on the root is auto-built from children `name` props
807
+ * (e.g. *"Alice Dupont, Bob Martin et 3 autres"*) unless overridden.
808
+ *
809
+ * @example
810
+ * ```tsx
811
+ * <AvatarGroup max={4} size="md" overlap="md">
812
+ * <Avatar name="Alice Dupont" color="primary" />
813
+ * <Avatar name="Bob Martin" color="info" />
814
+ * <Avatar src="/carol.jpg" name="Carol" />
815
+ * <Avatar name="Dan Lee" color="success" />
816
+ * <Avatar name="Eve Chen" color="warning" />
817
+ * </AvatarGroup>
818
+ * // → shows 4 avatars + "+1"
819
+ * ```
820
+ */
821
+ declare const AvatarGroup: FC<AvatarGroupProps>;
822
+
398
823
  /** SVG icon component used by badge icon slots. */
399
824
  type BadgeIcon = ComponentType<SVGProps<SVGSVGElement>>;
400
825
  /** Visual style of the badge surface. */
@@ -521,6 +946,245 @@ interface InfoBubbleProps {
521
946
  */
522
947
  declare const InfoBubble: FC<InfoBubbleProps>;
523
948
 
949
+ /** Horizontal alignment of a cell's content. */
950
+ type TableAlign = 'left' | 'center' | 'right';
951
+ /** Strategy used to size the table columns. `'fixed'` honors `columns` widths strictly. */
952
+ type TableLayout = 'auto' | 'fixed';
953
+ /**
954
+ * Declarative column definition — the single source of truth for column widths.
955
+ *
956
+ * Widths are applied through a native `<colgroup>`, which (combined with
957
+ * `layout="fixed"`) is the simplest and most reliable way to control column
958
+ * sizing: declare it once at the root and every cell follows.
959
+ */
960
+ type TableColumn = {
961
+ /** Column width — any CSS width (e.g. `'40%'`, `120`, `'12rem'`, `'auto'`). */
962
+ width?: CSSProperties['width'];
963
+ /** Minimum width applied to the column. */
964
+ minWidth?: CSSProperties['minWidth'];
965
+ /** Maximum width applied to the column. */
966
+ maxWidth?: CSSProperties['maxWidth'];
967
+ /** Default horizontal alignment for the column's loading/empty cells. @default 'left' */
968
+ align?: TableAlign;
969
+ };
970
+
971
+ type TableProps = {
972
+ /**
973
+ * Compound children — typically a `Table.Head` and a `Table.Body`.
974
+ * Can be omitted when `loading` or `isEmpty` is `true` — the body placeholder
975
+ * is rendered by the context without requiring children.
976
+ */
977
+ children?: ReactNode;
978
+ /**
979
+ * Column definitions — the single source of truth for column widths.
980
+ * Rendered as a native `<colgroup>` and also used to size loading/empty rows.
981
+ * @example columns={[{ width: '40%' }, { width: 120 }, { width: 'auto' }]}
982
+ */
983
+ columns?: TableColumn[];
984
+ /** Column sizing strategy. `'fixed'` enforces `columns` widths strictly. @default 'fixed' */
985
+ layout?: TableLayout;
986
+ /** Alternate background color on even body rows. @default false */
987
+ striped?: boolean;
988
+ /** Highlight body rows on hover. @default false */
989
+ hoverable?: boolean;
990
+ /** Wrap the table in a bordered, rounded container. @default false */
991
+ bordered?: boolean;
992
+ /**
993
+ * Keep the header visible while the body scrolls vertically. @default false
994
+ * @remarks Requires `maxHeight` so the table's own container becomes the scroller.
995
+ */
996
+ stickyHeader?: boolean;
997
+ /**
998
+ * Constrain the table height and turn its container into the vertical scroller.
999
+ * Required for `stickyHeader` to take effect.
1000
+ */
1001
+ maxHeight?: CSSProperties['maxHeight'];
1002
+ /**
1003
+ * Render a skeleton placeholder body instead of the children.
1004
+ * Each skeleton cell fills the width of its column. @default false
1005
+ * @a11y Sets `aria-busy="true"` on the table while loading.
1006
+ */
1007
+ loading?: boolean;
1008
+ /** Number of skeleton rows rendered while `loading`. @default 3 */
1009
+ loadingRows?: number;
1010
+ /** Render the empty placeholder instead of the children (ignored while loading). @default false */
1011
+ isEmpty?: boolean;
1012
+ /** Content displayed when `isEmpty` is true. @default 'No data available' */
1013
+ emptyContent?: ReactNode;
1014
+ /**
1015
+ * Accessible name for the table.
1016
+ * @a11y Recommended — gives the table a name describing its content for assistive tech.
1017
+ */
1018
+ ariaLabel?: string;
1019
+ /** Id of an external element labelling the table. */
1020
+ ariaLabelledBy?: string;
1021
+ /** Optional id forwarded to the `<table>` element. */
1022
+ id?: string;
1023
+ };
1024
+
1025
+ type TableBodyProps = {
1026
+ /**
1027
+ * The data rows (`Table.Row`). Ignored while the parent `Table` is
1028
+ * `loading` (skeleton rows are shown) or `isEmpty` (placeholder is shown).
1029
+ */
1030
+ children?: ReactNode;
1031
+ };
1032
+
1033
+ type TableCellProps = TdHTMLAttributes<HTMLTableCellElement> & {
1034
+ ref?: Ref<HTMLTableCellElement>;
1035
+ /** Cell content. */
1036
+ children?: ReactNode;
1037
+ /** Horizontal alignment of the content. @default 'left' */
1038
+ align?: TableAlign;
1039
+ };
1040
+
1041
+ type TableFootProps = {
1042
+ /** One or more `Table.Row` rendered inside the `<tfoot>`. */
1043
+ children: ReactNode;
1044
+ };
1045
+
1046
+ type TableHeadProps = {
1047
+ /** One or more `Table.Row` containing `Table.HeaderCell`s. */
1048
+ children: ReactNode;
1049
+ };
1050
+
1051
+ type TableHeaderCellProps = ThHTMLAttributes<HTMLTableCellElement> & {
1052
+ ref?: Ref<HTMLTableCellElement>;
1053
+ /** Header content. */
1054
+ children?: ReactNode;
1055
+ /** Horizontal alignment of the content. @default 'left' */
1056
+ align?: TableAlign;
1057
+ /**
1058
+ * Scope of the header, mapped to the native `scope` attribute. @default 'col'
1059
+ * @a11y Required — associates the header with its column (`'col'`) or row (`'row'`).
1060
+ */
1061
+ scope?: 'col' | 'row' | 'colgroup' | 'rowgroup';
1062
+ /**
1063
+ * Current sort direction, mapped to `aria-sort`.
1064
+ * @a11y Recommended on sortable columns so assistive tech announces the order.
1065
+ */
1066
+ sortDirection?: AriaAttributes['aria-sort'];
1067
+ };
1068
+
1069
+ type TableRowProps = HTMLAttributes<HTMLTableRowElement> & {
1070
+ ref?: Ref<HTMLTableRowElement>;
1071
+ /** Cells of the row — `Table.HeaderCell` and/or `Table.Cell`. */
1072
+ children: ReactNode;
1073
+ /**
1074
+ * Marks the row as selected — sets `aria-selected="true"` and a highlighted background.
1075
+ * @a11y When rows are interactive, also provide keyboard handling and a focusable target.
1076
+ */
1077
+ selected?: boolean;
1078
+ };
1079
+
1080
+ /** Compound component type — `Table` plus its statically attached sub-components. */
1081
+ type TableComponent = FC<TableProps> & {
1082
+ Head: FC<TableHeadProps>;
1083
+ Body: FC<TableBodyProps>;
1084
+ Foot: FC<TableFootProps>;
1085
+ Row: FC<TableRowProps>;
1086
+ HeaderCell: FC<TableHeaderCellProps>;
1087
+ Cell: FC<TableCellProps>;
1088
+ };
1089
+ declare const Table: TableComponent;
1090
+
1091
+ type ErrorBoundaryFallbackRenderProps = {
1092
+ error: Error;
1093
+ reset: () => void;
1094
+ };
1095
+ type ErrorBoundaryProps = {
1096
+ /**
1097
+ * Custom fallback. Receives the caught error and a `reset()` callback that
1098
+ * clears the error state so the children can attempt to re-mount.
1099
+ * If omitted, `DefaultErrorFallback` is used.
1100
+ */
1101
+ fallback?: (props: ErrorBoundaryFallbackRenderProps) => ReactNode;
1102
+ /**
1103
+ * Side-effect hook for monitoring (Sentry, Datadog, custom logger…).
1104
+ * Pure UI consumers should not rely on this for state updates.
1105
+ */
1106
+ onError?: (error: Error, info: ErrorInfo) => void;
1107
+ children: ReactNode;
1108
+ };
1109
+ type ErrorBoundaryState = {
1110
+ error: Error | null;
1111
+ };
1112
+
1113
+ /**
1114
+ * Generic React error boundary.
1115
+ * Catches synchronous render-time errors thrown by descendant components
1116
+ * and renders a recoverable fallback UI instead of crashing the whole app.
1117
+ *
1118
+ * Note: error boundaries do NOT catch:
1119
+ * - errors in event handlers (use try/catch + setState),
1120
+ * - errors in async code (promises, setTimeout),
1121
+ * - errors during SSR,
1122
+ * - errors thrown in the boundary itself.
1123
+ *
1124
+ * For routing errors thrown by loaders/actions, use `RouteErrorBoundary`
1125
+ * (powered by `useRouteError`) directly on a `RouteObject.errorElement`.
1126
+ *
1127
+ * Class component is mandatory: hooks cannot replace `componentDidCatch`
1128
+ * / `getDerivedStateFromError` as of React 19.
1129
+ */
1130
+ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
1131
+ static displayName: string;
1132
+ state: ErrorBoundaryState;
1133
+ static getDerivedStateFromError: (error: Error) => ErrorBoundaryState;
1134
+ componentDidCatch(error: Error, info: ErrorInfo): void;
1135
+ private reset;
1136
+ render(): string | number | bigint | boolean | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
1137
+ }
1138
+
1139
+ type DefaultErrorFallbackProps = {
1140
+ /** Caught error passed by `ErrorBoundary`. */
1141
+ error: Error;
1142
+ /** Callback to clear the error state and re-mount children. */
1143
+ onRetry: () => void;
1144
+ /**
1145
+ * Heading displayed above the message.
1146
+ * @default 'Something went wrong'
1147
+ */
1148
+ title?: string;
1149
+ /**
1150
+ * Descriptive message shown below the title.
1151
+ * @default 'An unexpected error occurred. Please try again.'
1152
+ */
1153
+ message?: string;
1154
+ /**
1155
+ * Label of the retry button.
1156
+ * @default 'Try again'
1157
+ */
1158
+ retryLabel?: string;
1159
+ };
1160
+
1161
+ /**
1162
+ * Default fallback UI rendered by `ErrorBoundary` when no custom
1163
+ * `fallback` prop is provided.
1164
+ *
1165
+ * Displays a centred error message with a collapsible technical detail
1166
+ * section and a retry button that resets the boundary state.
1167
+ *
1168
+ * @example
1169
+ * ```tsx
1170
+ * // Used automatically by ErrorBoundary:
1171
+ * <ErrorBoundary>
1172
+ * <MyFeature />
1173
+ * </ErrorBoundary>
1174
+ *
1175
+ * // Or rendered directly with mocked data (e.g. in Storybook):
1176
+ * <DefaultErrorFallback
1177
+ * error={new Error('Network request failed')}
1178
+ * onRetry={() => refetch()}
1179
+ * title="Failed to load data"
1180
+ * />
1181
+ * ```
1182
+ */
1183
+ declare const DefaultErrorFallback: {
1184
+ ({ error, onRetry, title, message, retryLabel, }: DefaultErrorFallbackProps): react_jsx_runtime.JSX.Element;
1185
+ displayName: string;
1186
+ };
1187
+
524
1188
  type IconProps = HTMLAttributes<HTMLDivElement> & {
525
1189
  ref?: Ref<HTMLDivElement>;
526
1190
  /**
@@ -558,6 +1222,88 @@ type IconStyleParams = {
558
1222
  */
559
1223
  declare const Icon: FC<IconProps>;
560
1224
 
1225
+ type ImageProps = {
1226
+ /** URL source of the image */
1227
+ src: string;
1228
+ /**
1229
+ * Accessible alternative text.
1230
+ * - Provide a meaningful description for meaningful images.
1231
+ * - Pass an empty string `""` for purely decorative images.
1232
+ */
1233
+ alt: string;
1234
+ /** Width of the image — any valid CSS value (e.g. '200px', '50%', 200) */
1235
+ width?: CSSProperties['width'];
1236
+ /** Height of the image — any valid CSS value (e.g. '150px', 'auto', 150) */
1237
+ height?: CSSProperties['height'];
1238
+ /** Max-width constraint — useful for responsive layouts */
1239
+ maxWidth?: CSSProperties['maxWidth'];
1240
+ /** Max-height constraint */
1241
+ maxHeight?: CSSProperties['maxHeight'];
1242
+ /** CSS object-fit value controlling how the image fills its container */
1243
+ objectFit?: CSSProperties['objectFit'];
1244
+ /** Lazy-load the image to improve performance. Defaults to 'lazy' */
1245
+ loading?: 'lazy' | 'eager';
1246
+ /** Border radius using theme tokens */
1247
+ borderRadius?: keyof Theme['radius'];
1248
+ /** ID of element that describes this image */
1249
+ ariaDescribedBy?: string;
1250
+ };
1251
+
1252
+ /**
1253
+ * Renders a standard HTML image (`<img>`) with sizing, object-fit, border radius,
1254
+ * and accessibility support.
1255
+ *
1256
+ * **Features:**
1257
+ * - Free sizing via `width` / `height` (e.g. `'200px'`, `'50%'`, `200`)
1258
+ * - Responsive constraint via `maxWidth` / `maxHeight`
1259
+ * - `objectFit` to control how the image fills its container
1260
+ * - `borderRadius` using theme tokens (e.g. `'md'`, `'full'`)
1261
+ * - Native lazy-loading via `loading` prop (defaults to `'lazy'`)
1262
+ * - Accessibility: `alt` is required — pass `""` for decorative images
1263
+ *
1264
+ * @example
1265
+ * ```tsx
1266
+ * // Decorative image (empty alt):
1267
+ * <Image src="/bg.jpg" alt="" width="100%" height={200} objectFit="cover" />
1268
+ *
1269
+ * // Meaningful image:
1270
+ * <Image
1271
+ * src="/avatar.png"
1272
+ * alt="Profile picture of Jane Doe"
1273
+ * width={64}
1274
+ * height={64}
1275
+ * borderRadius="full"
1276
+ * objectFit="cover"
1277
+ * />
1278
+ * ```
1279
+ */
1280
+ declare const Image: FC<ImageProps>;
1281
+
1282
+ type LoaderScreenProps = {
1283
+ /**
1284
+ * Accessible label announced to screen readers while loading.
1285
+ * @default 'Loading…'
1286
+ */
1287
+ label?: string;
1288
+ };
1289
+
1290
+ /**
1291
+ * Full-screen loading placeholder shown while data is being fetched.
1292
+ *
1293
+ * Renders a centred spinner over a full-viewport surface.
1294
+ * The spinner rotation is suppressed when the user prefers reduced motion.
1295
+ *
1296
+ * @example
1297
+ * ```tsx
1298
+ * // Swap with real content once data is ready:
1299
+ * {isLoading ? <LoaderScreen /> : <AppContent />}
1300
+ *
1301
+ * // With a custom label for screen readers:
1302
+ * <LoaderScreen label="Loading your dashboard…" />
1303
+ * ```
1304
+ */
1305
+ declare const LoaderScreen: FC<LoaderScreenProps>;
1306
+
561
1307
  /** Shape variant of the Skeleton placeholder. */
562
1308
  type SkeletonVariant = 'text' | 'circular' | 'rectangular' | 'rounded';
563
1309
  /**
@@ -599,6 +1345,53 @@ type SkeletonProps = HTMLAttributes<HTMLSpanElement> & {
599
1345
  */
600
1346
  declare const Skeleton: FC<SkeletonProps>;
601
1347
 
1348
+ type SvgImageProps = {
1349
+ /** SVG image component to render (from ImagesRegistry) */
1350
+ image: ComponentType<SVGProps<SVGSVGElement>>;
1351
+ /** Width of the image — any valid CSS value (e.g. '200px', '50%', 200) */
1352
+ width?: CSSProperties['width'];
1353
+ /** Height of the image — any valid CSS value (e.g. '150px', 'auto', 150) */
1354
+ height?: CSSProperties['height'];
1355
+ /** Max width constraint — useful for responsive layouts */
1356
+ maxWidth?: CSSProperties['maxWidth'];
1357
+ /** Max height constraint */
1358
+ maxHeight?: CSSProperties['maxHeight'];
1359
+ /** Accessibility label for screen readers (marks the image as meaningful) */
1360
+ ariaLabel?: string;
1361
+ /** ID of element that labels this image */
1362
+ ariaLabelledBy?: string;
1363
+ /** ID of element that describes this image */
1364
+ ariaDescribedBy?: string;
1365
+ };
1366
+
1367
+ /**
1368
+ * Renders an SVG illustration with free-form sizing.
1369
+ *
1370
+ * Unlike `Icon` (constrained to theme font sizes), `SvgImage` accepts any
1371
+ * valid CSS value for `width` and `height`.
1372
+ *
1373
+ * **Features:**
1374
+ * - Free sizing via `width` / `height` (e.g. `'200px'`, `'50%'`, `200`)
1375
+ * - Responsive constraint via `maxWidth` / `maxHeight`
1376
+ * - Accessibility: `ariaLabel`, `ariaLabelledBy`, `ariaDescribedBy`
1377
+ * - No label → `aria-hidden` (decorative illustration)
1378
+ *
1379
+ * @example
1380
+ * ```tsx
1381
+ * // Decorative illustration (no accessible label needed):
1382
+ * <SvgImage image={ImagesRegistry.WelcomeIllustration} width={320} />
1383
+ *
1384
+ * // Meaningful illustration (must have a label):
1385
+ * <SvgImage
1386
+ * image={ImagesRegistry.EmptyStateIllustration}
1387
+ * width={'50%'}
1388
+ * maxWidth={400}
1389
+ * ariaLabel="No results found illustration"
1390
+ * />
1391
+ * ```
1392
+ */
1393
+ declare const SvgImage: FC<SvgImageProps>;
1394
+
602
1395
  type TextVariants = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'strong';
603
1396
  type TextVariantStyle = {
604
1397
  /** HTML tag to render. */
@@ -696,28 +1489,117 @@ type FormProps = {
696
1489
  /** Called when the form is submitted. Receives the native submit event. */
697
1490
  onSubmit: (event: FormEvent<HTMLFormElement>) => void;
698
1491
  /**
699
- * Accessible name for the form.
700
- * @a11y Recommended — names the form landmark; use `aria-labelledby` instead when a visible heading exists.
1492
+ * Accessible name for the form.
1493
+ * @a11y Recommended — names the form landmark; use `aria-labelledby` instead when a visible heading exists.
1494
+ */
1495
+ 'aria-label'?: string;
1496
+ /**
1497
+ * Id of an element that labels the form.
1498
+ * @a11y Recommended — references a visible heading to name the form landmark.
1499
+ */
1500
+ 'aria-labelledby'?: string;
1501
+ };
1502
+
1503
+ /**
1504
+ * Thin wrapper around `<form>`. Prevents the default browser submit and
1505
+ * delegates to the `onSubmit` callback.
1506
+ *
1507
+ * @example
1508
+ * <Form onSubmit={handleSubmit}>
1509
+ * <TextField label="Email" />
1510
+ * <Button type="submit">Send</Button>
1511
+ * </Form>
1512
+ */
1513
+ declare const Form: FC<FormProps>;
1514
+
1515
+ /** Size variant of the RadioButton. */
1516
+ type RadioButtonSize = 'sm' | 'md' | 'lg';
1517
+ /** Semantic status of the RadioButton, affecting border and helper text color. */
1518
+ type RadioButtonStatus = 'default' | 'error' | 'success' | 'warning';
1519
+
1520
+ type RadioButtonProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> & {
1521
+ ref?: Ref<HTMLInputElement>;
1522
+ /**
1523
+ * Visible label rendered next to the radio button.
1524
+ * @a11y Recommended — provides the radio button's accessible name (clickable to select it).
1525
+ */
1526
+ label?: ReactNode;
1527
+ /**
1528
+ * Helper text or validation message rendered below the radio button row.
1529
+ * @a11y Recommended — linked to the input via `aria-describedby`.
1530
+ */
1531
+ helperText?: string;
1532
+ /** Size variant controlling radio button size and text scale. @default 'md' */
1533
+ size?: RadioButtonSize;
1534
+ /**
1535
+ * Semantic status affecting border and helper text color. @default 'default'
1536
+ * @a11y Recommended — `status='error'` sets `aria-invalid` on the input.
1537
+ */
1538
+ status?: RadioButtonStatus;
1539
+ /** @deprecated Use `status='error'` instead. Kept for backward compatibility. */
1540
+ error?: boolean;
1541
+ };
1542
+
1543
+ declare const RadioButton: FC<RadioButtonProps>;
1544
+
1545
+ /** Orientation of the RadioGroup. */
1546
+ type RadioGroupOrientation = 'vertical' | 'horizontal';
1547
+
1548
+ type RadioGroupProps = {
1549
+ /** The radio options to render inside the group. Should be `RadioButton` components. */
1550
+ children: ReactNode;
1551
+ /**
1552
+ * The `name` attribute shared by all radio inputs in the group.
1553
+ * If omitted, a unique id is auto-generated.
1554
+ */
1555
+ name?: string;
1556
+ /** Controlled selected value. */
1557
+ value?: string;
1558
+ /** Default selected value for uncontrolled usage. */
1559
+ defaultValue?: string;
1560
+ /** Callback fired when the selected value changes. */
1561
+ onChange?: (value: string) => void;
1562
+ /**
1563
+ * Layout direction of the radio options.
1564
+ * @default 'vertical'
1565
+ */
1566
+ orientation?: RadioGroupOrientation;
1567
+ /** Disables all radio buttons in the group. */
1568
+ disabled?: boolean;
1569
+ /**
1570
+ * Legend text rendered as an accessible `<legend>` above the group.
1571
+ * @a11y Recommended — labels the entire radio group for screen readers.
1572
+ */
1573
+ legend?: ReactNode;
1574
+ /** Size applied to all radio buttons in the group unless individually overridden. @default 'md' */
1575
+ size?: RadioButtonSize;
1576
+ /**
1577
+ * Status applied to all radio buttons in the group unless individually overridden.
1578
+ * @default 'default'
701
1579
  */
702
- 'aria-label'?: string;
1580
+ status?: RadioButtonStatus;
703
1581
  /**
704
- * Id of an element that labels the form.
705
- * @a11y Recommendedreferences a visible heading to name the form landmark.
1582
+ * Marks the radio group as required.
1583
+ * @a11y Sets `aria-required` on the group element indicates that at least one option must be selected.
706
1584
  */
707
- 'aria-labelledby'?: string;
1585
+ required?: boolean;
1586
+ /** @deprecated Use `status='error'` instead. Kept for backward compatibility. */
1587
+ error?: boolean;
708
1588
  };
709
1589
 
710
1590
  /**
711
- * Thin wrapper around `<form>`. Prevents the default browser submit and
712
- * delegates to the `onSubmit` callback.
1591
+ * Accessible radio group wrapping multiple `RadioButton` components inside a `<fieldset>`.
1592
+ *
1593
+ * Supports controlled (`value` + `onChange`) and uncontrolled (`defaultValue`) modes.
1594
+ * Propagates `name`, `value`, `disabled`, `size`, and `status` to all child `RadioButton` elements via context.
713
1595
  *
714
1596
  * @example
715
- * <Form onSubmit={handleSubmit}>
716
- * <TextField label="Email" />
717
- * <Button type="submit">Send</Button>
718
- * </Form>
1597
+ * <RadioGroup legend="Preferred contact" defaultValue="email" onChange={setValue}>
1598
+ * <RadioButton value="email" label="Email" />
1599
+ * <RadioButton value="phone" label="Phone" />
1600
+ * </RadioGroup>
719
1601
  */
720
- declare const Form: FC<FormProps>;
1602
+ declare const RadioGroup: FC<RadioGroupProps>;
721
1603
 
722
1604
  type SwitchSize = 'sm' | 'md' | 'lg';
723
1605
  type SwitchColor = 'primary' | 'success' | 'error' | 'warning' | 'info' | 'neutral';
@@ -799,6 +1681,11 @@ type SelectOption = {
799
1681
  label: string;
800
1682
  /** Optional icon rendered before the label in the menu item. */
801
1683
  icon?: ComponentType<SVGProps<SVGSVGElement>>;
1684
+ /**
1685
+ * Color applied to the icon's stroke. Uses theme color tokens.
1686
+ * When omitted, the icon inherits the default item color behaviour (primaryMain when selected, textSecondary otherwise).
1687
+ */
1688
+ iconColor?: keyof Theme['colors'];
802
1689
  /** Whether the option cannot be selected. */
803
1690
  disabled?: boolean;
804
1691
  /**
@@ -882,6 +1769,81 @@ type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'
882
1769
 
883
1770
  declare const Checkbox: FC<CheckboxProps>;
884
1771
 
1772
+ /** Size variant of the DatePicker — aligned with the other form fields. */
1773
+ type DatePickerSize = TextFieldSize;
1774
+ /** Semantic status of the DatePicker — aligned with the other form fields. */
1775
+ type DatePickerStatus = TextFieldStatus;
1776
+ /** First day of the week shown in the calendar. `0` = Sunday … `6` = Saturday. */
1777
+ type WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6;
1778
+
1779
+ type DatePickerProps = {
1780
+ /** Ref forwarded to the underlying text input. */
1781
+ ref?: Ref<HTMLInputElement>;
1782
+ /** Selected date (controlled mode). Pass `null` for an empty value. */
1783
+ value?: Date | null;
1784
+ /** Initial date for uncontrolled mode. @default null */
1785
+ defaultValue?: Date | null;
1786
+ /** Called with the new `Date` (or `null` when cleared) whenever the selection changes. */
1787
+ onChange?: (date: Date | null) => void;
1788
+ /** Earliest selectable date (inclusive). Dates before it are disabled. */
1789
+ minDate?: Date;
1790
+ /** Latest selectable date (inclusive). Dates after it are disabled. */
1791
+ maxDate?: Date;
1792
+ /**
1793
+ * Label rendered above the field.
1794
+ * @a11y Recommended — provides the field's accessible name (linked via `htmlFor`/`id`).
1795
+ */
1796
+ label?: string;
1797
+ /**
1798
+ * Helper text or validation message rendered below the field.
1799
+ * @a11y Recommended — linked to the input via `aria-describedby` (and `aria-errormessage` when `status='error'`).
1800
+ */
1801
+ helperText?: string;
1802
+ /** Placeholder shown when no date is selected. Defaults to the display format in uppercase (e.g. `DD/MM/YYYY`). */
1803
+ placeholder?: string;
1804
+ /** Size variant. @default 'md' */
1805
+ size?: DatePickerSize;
1806
+ /**
1807
+ * Semantic status affecting border and helper text color. @default 'default'
1808
+ * @a11y Recommended — `status='error'` sets `aria-invalid` and links the error message.
1809
+ */
1810
+ status?: DatePickerStatus;
1811
+ /** Whether the field is disabled. */
1812
+ disabled?: boolean;
1813
+ /**
1814
+ * Whether the field is required.
1815
+ * @a11y Recommended — sets `aria-required` on the input and shows the visual asterisk on the label.
1816
+ */
1817
+ required?: boolean;
1818
+ /** Allow typing the date directly in the input. When `false` the input is read-only. @default true */
1819
+ editable?: boolean;
1820
+ /**
1821
+ * Token format used to display and parse the typed value. Supports `dd`, `MM`, `yyyy`.
1822
+ * When omitted, the format is derived from `locale` (field order and separators).
1823
+ */
1824
+ displayFormat?: string;
1825
+ /** BCP 47 locale used for month/weekday labels in the calendar. @default 'en-US' */
1826
+ locale?: string;
1827
+ /** First day of the week shown in the calendar. @default 1 (Monday) */
1828
+ weekStartsOn?: WeekStart;
1829
+ /** Fixed width for the field. Defaults to 100% of its container. */
1830
+ width?: string | number;
1831
+ /** HTML id for the input. */
1832
+ id?: string;
1833
+ };
1834
+
1835
+ /**
1836
+ * Accessible date field combining a text input trigger and a calendar popover.
1837
+ *
1838
+ * The input round-trips the value with `displayFormat` (typing is allowed unless
1839
+ * `editable={false}`), while the trailing icon button opens a focus-trapped
1840
+ * `role="dialog"` calendar following the WAI-ARIA date-grid pattern.
1841
+ *
1842
+ * @example <DatePicker label="Birth date" />
1843
+ * @example <DatePicker label="Start" minDate={new Date()} required helperText="Pick a future date." />
1844
+ */
1845
+ declare const DatePicker: FC<DatePickerProps>;
1846
+
885
1847
  type BoxProps = HTMLAttributes<HTMLDivElement> & BoxStyleProps & {
886
1848
  ref?: Ref<HTMLDivElement>;
887
1849
  };
@@ -953,6 +1915,54 @@ type BoxStyleProps = {
953
1915
  opacity?: CSSProperties['opacity'];
954
1916
  };
955
1917
 
1918
+ /**
1919
+ * Common props type for semantic HTML layout elements enriched with Box style props.
1920
+ *
1921
+ * Use this as the base type for semantic layout components (Article, Aside,
1922
+ * Footer, Header, Main, Nav, Section…) so they all expose the same token-aware
1923
+ * style props as `Box`.
1924
+ *
1925
+ * @template T - The underlying HTML element type (e.g. `HTMLElement`, `HTMLDivElement`).
1926
+ */
1927
+ type SemanticBoxProps<T extends HTMLElement = HTMLElement> = HTMLAttributes<T> & BoxStyleProps & {
1928
+ /** Ref forwarded to the underlying HTML element. */
1929
+ ref?: Ref<T>;
1930
+ };
1931
+
1932
+ /**
1933
+ * Props for the Article component.
1934
+ * Accepts all style tokens from Box, forwarded to a native `<article>` element.
1935
+ */
1936
+ type ArticleProps = SemanticBoxProps<HTMLElement>;
1937
+
1938
+ /**
1939
+ * Semantic `<article>` enriched with the same token-aware style props as `Box`.
1940
+ *
1941
+ * Use `Article` for self-contained content that could stand alone and be
1942
+ * re-distributed independently (blog posts, news articles, forum posts, cards).
1943
+ * Each `Article` should ideally have a heading.
1944
+ *
1945
+ * @example <Article padding="lg" borderRadius="md" backgroundColor="surfacePaper">…</Article>
1946
+ */
1947
+ declare const Article: FC<ArticleProps>;
1948
+
1949
+ /**
1950
+ * Props for the Aside component.
1951
+ * Accepts all style tokens from Box, forwarded to a native `<aside>` element.
1952
+ */
1953
+ type AsideProps = SemanticBoxProps<HTMLElement>;
1954
+
1955
+ /**
1956
+ * Semantic `<aside>` enriched with the same token-aware style props as `Box`.
1957
+ *
1958
+ * Use `Aside` for supplemental content that is tangentially related to the
1959
+ * surrounding content (sidebars, pull-quotes, ads, related links).
1960
+ * Screen-readers expose it as the `complementary` landmark.
1961
+ *
1962
+ * @example <Aside aria-label="Related articles" width="280px" padding="md">…</Aside>
1963
+ */
1964
+ declare const Aside: FC<AsideProps>;
1965
+
956
1966
  /**
957
1967
  * A plain `div` enriched with convenient, token-aware style props.
958
1968
  *
@@ -1005,6 +2015,23 @@ type CardComponent = FC<CardProps> & {
1005
2015
 
1006
2016
  declare const Card: CardComponent;
1007
2017
 
2018
+ /**
2019
+ * Props for the Footer component.
2020
+ * Accepts all style tokens from Box, forwarded to a native `<footer>` element.
2021
+ */
2022
+ type FooterProps = SemanticBoxProps<HTMLElement>;
2023
+
2024
+ /**
2025
+ * Semantic `<footer>` enriched with the same token-aware style props as `Box`.
2026
+ *
2027
+ * Use `Footer` for the closing content of a page or a section
2028
+ * (copyright, links, contact info). Screen-readers expose it as the
2029
+ * `contentinfo` landmark when it is a direct child of `<body>`.
2030
+ *
2031
+ * @example <Footer py="md" display="flex" justifyContent="space-between">…</Footer>
2032
+ */
2033
+ declare const Footer: FC<FooterProps>;
2034
+
1008
2035
  /**
1009
2036
  * Extra CSS Grid props not covered by BoxProps.
1010
2037
  * `columns` and `rows` are convenience shorthands:
@@ -1042,6 +2069,134 @@ type GridProps = Omit<BoxProps, 'display'> & GridStyleProps & {
1042
2069
  */
1043
2070
  declare const Grid: FC<GridProps>;
1044
2071
 
2072
+ /**
2073
+ * Props for the Header component.
2074
+ * Accepts all style tokens from Box, forwarded to a native `<header>` element.
2075
+ */
2076
+ type HeaderProps = SemanticBoxProps<HTMLElement>;
2077
+
2078
+ /**
2079
+ * Semantic `<header>` enriched with the same token-aware style props as `Box`.
2080
+ *
2081
+ * Use `Header` for the introductory content of a page or a section
2082
+ * (logo, site title, navigation). Screen-readers expose it as the
2083
+ * `banner` landmark when it is a direct child of `<body>`.
2084
+ *
2085
+ * @example <Header padding="md" display="flex" alignItems="center" gap="sm">…</Header>
2086
+ */
2087
+ declare const Header: FC<HeaderProps>;
2088
+
2089
+ /**
2090
+ * Props for the Main component.
2091
+ * Accepts all style tokens from Box, forwarded to a native `<main>` element.
2092
+ */
2093
+ type MainProps = SemanticBoxProps<HTMLElement>;
2094
+
2095
+ /**
2096
+ * Semantic `<main>` enriched with the same token-aware style props as `Box`.
2097
+ *
2098
+ * Use `Main` for the primary content of the page. There should be only **one**
2099
+ * `Main` per page. Screen-readers expose it as the `main` landmark, allowing
2100
+ * users to jump directly to the core content.
2101
+ *
2102
+ * @example <Main padding="xl" display="flex" flexDirection="column" gap="lg">…</Main>
2103
+ */
2104
+ declare const Main: FC<MainProps>;
2105
+
2106
+ /**
2107
+ * Props for the Nav component.
2108
+ * Accepts all style tokens from Box, forwarded to a native `<nav>` element.
2109
+ */
2110
+ type NavProps = SemanticBoxProps<HTMLElement>;
2111
+
2112
+ /**
2113
+ * Semantic `<nav>` enriched with the same token-aware style props as `Box`.
2114
+ *
2115
+ * Use `Nav` to wrap sets of navigation links. When multiple `Nav` elements
2116
+ * are present, give each a distinct `aria-label` so screen-reader users can
2117
+ * tell them apart (e.g. `aria-label="Main navigation"` vs `aria-label="Footer links"`).
2118
+ *
2119
+ * @example <Nav aria-label="Main navigation" display="flex" gap="sm">…</Nav>
2120
+ */
2121
+ declare const Nav: FC<NavProps>;
2122
+
2123
+ /**
2124
+ * Props for the Section component.
2125
+ * Accepts all style tokens from Box, forwarded to a native `<section>` element.
2126
+ */
2127
+ type SectionProps = SemanticBoxProps<HTMLElement>;
2128
+
2129
+ /**
2130
+ * Semantic `<section>` enriched with the same token-aware style props as `Box`.
2131
+ *
2132
+ * Use `Section` to group thematically related content — the browser outline
2133
+ * and screen-readers will announce it as a landmark region when it has an
2134
+ * accessible name (`aria-label` or `aria-labelledby`).
2135
+ *
2136
+ * @example <Section aria-label="Features" padding="lg" gap="md">…</Section>
2137
+ */
2138
+ declare const Section: FC<SectionProps>;
2139
+
2140
+ /** Orientation of the separator line. */
2141
+ type SeparatorOrientation = 'horizontal' | 'vertical';
2142
+ /** Visual thickness of the separator line in pixels. */
2143
+ type SeparatorThickness = '1' | '2' | '4';
2144
+
2145
+ type SeparatorProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
2146
+ ref?: Ref<HTMLElement>;
2147
+ /**
2148
+ * Orientation of the separator — determines layout direction. @default 'horizontal'
2149
+ * @a11y Sets `aria-orientation` accordingly on the rendered element.
2150
+ * For `'vertical'`, the parent must be a flex/grid container so `align-self: stretch` works.
2151
+ */
2152
+ orientation?: SeparatorOrientation;
2153
+ /**
2154
+ * Theme color token for the separator line. @default 'borderMain'
2155
+ */
2156
+ color?: keyof Theme['colors'];
2157
+ /**
2158
+ * Thickness of the separator line in pixels. @default '1'
2159
+ */
2160
+ thickness?: SeparatorThickness;
2161
+ /**
2162
+ * Spacing token applied as margin around the separator.
2163
+ * Horizontal: `margin-block`; Vertical: `margin-inline`.
2164
+ */
2165
+ spacing?: keyof Theme['spacing'];
2166
+ /**
2167
+ * Optional centered text label — only rendered on `orientation="horizontal"`.
2168
+ * When provided, the label is used as `aria-label` so screen readers announce
2169
+ * the section boundary with its name.
2170
+ */
2171
+ label?: string;
2172
+ /**
2173
+ * Mark the separator as decorative (visual only). Sets `aria-hidden="true"`. @default false
2174
+ * @a11y Use when the separator is purely cosmetic and does not convey structural meaning.
2175
+ */
2176
+ decorative?: boolean;
2177
+ };
2178
+ type SeparatorStyleParams = {
2179
+ orientation?: SeparatorOrientation;
2180
+ color?: keyof Theme['colors'];
2181
+ thickness?: SeparatorThickness;
2182
+ spacing?: keyof Theme['spacing'];
2183
+ hasLabel?: boolean;
2184
+ };
2185
+
2186
+ /**
2187
+ * A visual separator line (horizontal or vertical) with optional centered label.
2188
+ *
2189
+ * Uses `<hr>` for horizontal separators (implicit `role="separator"`) and a
2190
+ * `<div role="separator">` for vertical or labeled variants.
2191
+ *
2192
+ * @example <Separator />
2193
+ * @example <Separator orientation="vertical" />
2194
+ * @example <Separator label="Or" spacing="md" />
2195
+ * @example <Separator color="primaryMain" thickness="2" />
2196
+ * @example <Separator decorative />
2197
+ */
2198
+ declare const Separator: FC<SeparatorProps>;
2199
+
1045
2200
  /**
1046
2201
  * A flex `Box` for laying out children along a single axis.
1047
2202
  *
@@ -1291,6 +2446,83 @@ type DrawerContextValue = {
1291
2446
  };
1292
2447
  declare const useDrawerContext: () => DrawerContextValue;
1293
2448
 
2449
+ /** Size token controlling the dimensions and font scale of pagination items. */
2450
+ type PaginationSize = 'sm' | 'md' | 'lg';
2451
+ /** Visual shape of the pagination items. */
2452
+ type PaginationShape = 'rounded' | 'circular';
2453
+
2454
+ type PaginationProps = {
2455
+ /**
2456
+ * Currently active page (1-based). The component is controlled.
2457
+ * @a11y The matching page button exposes `aria-current="page"`.
2458
+ */
2459
+ currentPage: number;
2460
+ /** Total number of pages available. */
2461
+ totalPages: number;
2462
+ /** Called with the requested page when the user navigates. */
2463
+ onPageChange: (page: number) => void;
2464
+ /**
2465
+ * Number of pages displayed on each side of the current page.
2466
+ * @default 1
2467
+ */
2468
+ siblingCount?: number;
2469
+ /**
2470
+ * Number of pages always displayed at the very start and end.
2471
+ * @default 1
2472
+ */
2473
+ boundaryCount?: number;
2474
+ /** Size token controlling item dimensions and font scale. @default 'md' */
2475
+ size?: PaginationSize;
2476
+ /** Visual shape of the items. @default 'rounded' */
2477
+ shape?: PaginationShape;
2478
+ /** Render the previous / next arrow controls. @default true */
2479
+ showPrevNext?: boolean;
2480
+ /** Render the jump-to-first / jump-to-last controls. @default false */
2481
+ showFirstLast?: boolean;
2482
+ /** Disable the whole pagination. */
2483
+ disabled?: boolean;
2484
+ /**
2485
+ * Accessible label for the `<nav>` landmark.
2486
+ * @default 'Pagination'
2487
+ * @a11y Recommended — describe the navigation to assistive technologies.
2488
+ */
2489
+ ariaLabel?: string;
2490
+ /** Accessible label for the previous-page control. @default 'Go to previous page' */
2491
+ previousAriaLabel?: string;
2492
+ /** Accessible label for the next-page control. @default 'Go to next page' */
2493
+ nextAriaLabel?: string;
2494
+ /** Accessible label for the first-page control. @default 'Go to first page' */
2495
+ firstAriaLabel?: string;
2496
+ /** Accessible label for the last-page control. @default 'Go to last page' */
2497
+ lastAriaLabel?: string;
2498
+ /**
2499
+ * Builds the accessible label of a page button.
2500
+ * @default (page, selected) => selected ? `page ${page}` : `Go to page ${page}`
2501
+ */
2502
+ getPageAriaLabel?: (page: number, selected: boolean) => string;
2503
+ };
2504
+
2505
+ /**
2506
+ * Accessible, controlled pagination control.
2507
+ *
2508
+ * Renders a `<nav>` landmark wrapping a list of page buttons, with optional
2509
+ * previous/next and first/last controls. Collapses long ranges using ellipses
2510
+ * (configurable via `siblingCount` and `boundaryCount`). The active page exposes
2511
+ * `aria-current="page"`.
2512
+ *
2513
+ * ```tsx
2514
+ * const [page, setPage] = useState(1)
2515
+ *
2516
+ * <Pagination
2517
+ * currentPage={page}
2518
+ * totalPages={10}
2519
+ * onPageChange={setPage}
2520
+ * showFirstLast
2521
+ * />
2522
+ * ```
2523
+ */
2524
+ declare const Pagination: FC<PaginationProps>;
2525
+
1294
2526
  type TabsProps = {
1295
2527
  /** Children — typically a `Tabs.List` with `Tabs.Tab`s and one or more `Tabs.Panel`s. */
1296
2528
  children: ReactNode;
@@ -1347,6 +2579,48 @@ type TabsComponent = FC<TabsProps> & {
1347
2579
 
1348
2580
  declare const Tabs: TabsComponent;
1349
2581
 
2582
+ type AccordionProps = {
2583
+ /** Whether the accordion panel is expanded. Used for controlled mode. */
2584
+ open?: boolean;
2585
+ /** Initial open state in uncontrolled mode. @default false */
2586
+ defaultOpen?: boolean;
2587
+ /** Called when the open state changes. */
2588
+ onOpenChange?: (open: boolean) => void;
2589
+ /** `Accordion.Title` and `Accordion.Body` sub-components. */
2590
+ children: ReactNode;
2591
+ /**
2592
+ * Visual style variant. @default 'ghost'
2593
+ * - `ghost` — no border, minimal decoration.
2594
+ * - `outlined` — bordered card-like appearance.
2595
+ */
2596
+ variant?: 'outlined' | 'ghost';
2597
+ /** Whether the accordion is disabled. @default false */
2598
+ disabled?: boolean;
2599
+ };
2600
+
2601
+ type AccordionTitleProps = {
2602
+ /** Trigger label — accepts any ReactNode (string, Text, Stack with icon, etc.). */
2603
+ children: ReactNode;
2604
+ /**
2605
+ * Heading level wrapping the trigger button, as recommended by the WAI-ARIA Accordion pattern.
2606
+ * The heading allows screen-reader users to navigate accordion items via the heading outline.
2607
+ * Match the level to the surrounding document hierarchy. @default 3
2608
+ */
2609
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
2610
+ };
2611
+
2612
+ type AccordionBodyProps = {
2613
+ /** Content to reveal when the accordion is open. */
2614
+ children: ReactNode;
2615
+ };
2616
+
2617
+ type AccordionComponent = FC<AccordionProps> & {
2618
+ Title: FC<AccordionTitleProps>;
2619
+ Body: FC<AccordionBodyProps>;
2620
+ };
2621
+
2622
+ declare const Accordion: AccordionComponent;
2623
+
1350
2624
  type AlertProps = {
1351
2625
  /**
1352
2626
  * Visual style of the alert. @default 'default'
@@ -1463,10 +2737,36 @@ type DialogComponent = FC<DialogProps> & {
1463
2737
 
1464
2738
  declare const Dialog: DialogComponent;
1465
2739
 
2740
+ /** Where the menu opens relative to its anchor. */
2741
+ type MenuPlacement = 'bottom' | 'right';
2742
+ type UseMenuPositionOptions = {
2743
+ /** Anchor element the menu is positioned relative to. */
2744
+ anchorEl?: HTMLElement | null;
2745
+ /** Whether the menu is currently open. */
2746
+ open: boolean;
2747
+ /** Ref to the menu panel element — used to measure actual dimensions. */
2748
+ menuRef: RefObject<HTMLElement | null>;
2749
+ /** Minimum width override. Defaults to the anchor element's width. */
2750
+ minWidth?: number | string;
2751
+ /** Gap in px between anchor and menu. @default 4 */
2752
+ gap?: number;
2753
+ /**
2754
+ * Where the menu opens relative to the anchor.
2755
+ * - `'bottom'` — opens below the anchor (default dropdown).
2756
+ * - `'right'` — opens beside the anchor (submenu), flipping to the left when there is no room.
2757
+ * @default 'bottom'
2758
+ */
2759
+ placement?: MenuPlacement;
2760
+ };
2761
+ type UseMenuPositionResult = {
2762
+ /** Computed inline style to apply on the menu panel (top, left, minWidth). */
2763
+ style: CSSProperties;
2764
+ };
2765
+
1466
2766
  type MenuProps = {
1467
2767
  /** Whether the menu is visible. */
1468
2768
  open: boolean;
1469
- /** Called when the menu should close (click outside or Escape key). */
2769
+ /** Called when the menu should close (click outside, outside scroll or Escape key). */
1470
2770
  onClose: () => void;
1471
2771
  /** Reference element used to position the menu. */
1472
2772
  anchorEl?: HTMLElement | null;
@@ -1474,16 +2774,25 @@ type MenuProps = {
1474
2774
  minWidth?: number | string;
1475
2775
  /** Maximum height before scrolling. @default '20rem' */
1476
2776
  maxHeight?: string;
1477
- /** ARIA id for the listbox panel. */
2777
+ /** Where the menu opens relative to the anchor. @default 'bottom' */
2778
+ placement?: MenuPlacement;
2779
+ /** ARIA id for the menu panel. */
1478
2780
  id?: string;
1479
2781
  /**
1480
- * Accessible name for the listbox (use when there is no visible label).
1481
- * @a11y Recommendednames the listbox when no labelling element is referenced via `aria-labelledby`.
2782
+ * ARIA role of the panel surface.
2783
+ * - `'menu'` (default) action menu; children use `menuitem`.
2784
+ * - `'listbox'` — single/multi-select popup; children use `option`.
2785
+ * @default 'menu'
2786
+ */
2787
+ role?: 'menu' | 'listbox';
2788
+ /**
2789
+ * Accessible name for the menu (use when there is no visible label).
2790
+ * @a11y Recommended — names the menu when no labelling element is referenced via `aria-labelledby`.
1482
2791
  */
1483
2792
  'aria-label'?: string;
1484
2793
  /**
1485
- * Id of an element that labels the listbox (e.g. the trigger's label).
1486
- * @a11y Recommended — references the trigger's visible label to name the listbox.
2794
+ * Id of an element that labels the menu (e.g. the trigger's label).
2795
+ * @a11y Recommended — references the trigger's visible label to name the menu.
1487
2796
  */
1488
2797
  'aria-labelledby'?: string;
1489
2798
  /** Menu content — MenuGroup and/or MenuItem. */
@@ -1499,24 +2808,58 @@ type MenuGroupProps = {
1499
2808
  children: ReactNode;
1500
2809
  };
1501
2810
 
2811
+ /** ARIA role of a menu item. */
2812
+ type MenuItemRole = 'menuitem' | 'menuitemcheckbox' | 'menuitemradio' | 'option';
1502
2813
  type MenuItemProps = HTMLAttributes<HTMLLIElement> & {
1503
2814
  ref?: Ref<HTMLLIElement>;
1504
2815
  /**
1505
2816
  * Display text of the item.
1506
- * @a11y Recommended — provides the option's accessible name.
2817
+ * @a11y Recommended — provides the item's accessible name.
1507
2818
  */
1508
2819
  label: string;
1509
2820
  /** Optional SVG icon rendered before the label. */
1510
2821
  icon?: ComponentType<SVGProps<SVGSVGElement>>;
1511
2822
  /**
1512
- * Whether this item is currently selected.
1513
- * @a11y Recommended exposes the selected state via `aria-selected`.
2823
+ * Color applied to the icon's stroke. Uses theme color tokens.
2824
+ * When omitted, the icon inherits the default behaviour (primaryMain when selected, textSecondary otherwise).
2825
+ */
2826
+ iconColor?: keyof Theme['colors'];
2827
+ /**
2828
+ * ARIA role of the item.
2829
+ * - `'menuitem'` (default) — a regular action item.
2830
+ * - `'menuitemcheckbox'` — a toggleable item; pair with `checked`.
2831
+ * - `'menuitemradio'` — a single-choice item within a group; pair with `checked`.
2832
+ * @default 'menuitem'
2833
+ */
2834
+ role?: MenuItemRole;
2835
+ /**
2836
+ * Checked state for `menuitemcheckbox` / `menuitemradio` items.
2837
+ * @a11y Recommended — exposes the state via `aria-checked` and shows the indicator.
2838
+ */
2839
+ checked?: boolean;
2840
+ /**
2841
+ * Whether this item is visually highlighted as selected (e.g. the current value).
2842
+ * For checkbox/radio items prefer `checked`.
1514
2843
  */
1515
2844
  selected?: boolean;
1516
2845
  /** Whether this item has keyboard focus (highlighted via arrow navigation). */
1517
2846
  focused?: boolean;
1518
2847
  /** Whether the item is non-interactive. */
1519
2848
  disabled?: boolean;
2849
+ /**
2850
+ * Whether clicking the item closes the whole menu (in addition to running
2851
+ * `onClick`).
2852
+ * @default true for `menuitem`, false for `menuitemcheckbox` / `menuitemradio`
2853
+ */
2854
+ closeOnClick?: boolean;
2855
+ /**
2856
+ * Submenu content (MenuItem / MenuGroup). When provided, the item becomes a
2857
+ * submenu trigger that opens on hover, click, or ArrowRight.
2858
+ * @a11y Recommended — exposes `aria-haspopup="menu"` and `aria-expanded`.
2859
+ */
2860
+ submenu?: ReactNode;
2861
+ /** Where the submenu opens relative to the item. @default 'right' */
2862
+ submenuPlacement?: MenuPlacement;
1520
2863
  };
1521
2864
 
1522
2865
  type MenuComponent = FC<MenuProps> & {
@@ -1547,9 +2890,211 @@ declare const Menu: MenuComponent;
1547
2890
  */
1548
2891
  declare const Tooltip: FC<TooltipProps>;
1549
2892
 
2893
+ /**
2894
+ * Locks scrolling on `document.body` while `active` is true.
2895
+ *
2896
+ * Preserves the current scroll position and keeps the scrollbar gutter
2897
+ * (`overflow-y: scroll`) to avoid horizontal layout shift when the scrollbar
2898
+ * disappears. The original styles and scroll position are restored on cleanup.
2899
+ *
2900
+ * @example useBodyScrollLock(isDialogOpen)
2901
+ */
2902
+ declare const useBodyScrollLock: (active: boolean) => void;
2903
+
2904
+ type UseControllableStateOptions<T> = {
2905
+ /** Controlled value. When defined, the hook operates in controlled mode. */
2906
+ value?: T;
2907
+ /** Initial value used in uncontrolled mode. */
2908
+ defaultValue: T;
2909
+ /** Called with the next value whenever `setValue` runs. */
2910
+ onChange?: (value: T) => void;
2911
+ };
2912
+ type UseControllableStateResult<T> = [T, (next: T) => void];
2913
+
2914
+ /**
2915
+ * Unifies controlled and uncontrolled value handling.
2916
+ *
2917
+ * - When `value` is provided the hook is controlled: the returned value mirrors
2918
+ * it and internal state is never used to render.
2919
+ * - Otherwise it is uncontrolled: state starts at `defaultValue` and updates
2920
+ * internally.
2921
+ *
2922
+ * In both modes `setValue` calls `onChange` with the next value, so consumers
2923
+ * have a single code path regardless of mode.
2924
+ *
2925
+ * @example
2926
+ * const [value, setValue] = useControllableState({ value, defaultValue: '', onChange })
2927
+ */
2928
+ declare const useControllableState: <T>({ value, defaultValue, onChange, }: UseControllableStateOptions<T>) => UseControllableStateResult<T>;
2929
+
2930
+ /**
2931
+ * Traps Tab / Shift+Tab focus within the element referenced by `containerRef`
2932
+ * while `active` is true. Focusable elements are recomputed on each Tab press
2933
+ * so dynamic content is handled correctly. Required for accessible modals.
2934
+ *
2935
+ * @example useFocusTrap(panelRef, open)
2936
+ */
2937
+ declare const useFocusTrap: (containerRef: RefObject<HTMLElement | null>, active: boolean) => void;
2938
+
2939
+ type KeyPressHandler = (event: KeyboardEvent) => void;
2940
+ /** Map of key name → handler, for handling multiple keys in a single hook call. */
2941
+ type KeyPressMap = Partial<Record<KeyboardEvent['key'], KeyPressHandler>>;
2942
+ type UseKeyPressOptions = {
2943
+ /** Only trigger when this element is the target (defaults to the whole document) */
2944
+ target?: EventTarget | null;
2945
+ /** Whether the listener is active */
2946
+ enabled?: boolean;
2947
+ };
2948
+
2949
+ /**
2950
+ * Listens to keyboard events and dispatches to the matching handler in `keyMap`.
2951
+ * A single hook call can handle multiple keys.
2952
+ *
2953
+ * @example
2954
+ * ` s
2955
+ * useKeyPress(
2956
+ * { ArrowDown: onDown, ArrowUp: onUp, Enter: onEnter, Escape: onClose },
2957
+ * { enabled: isOpen }
2958
+ * )
2959
+ * `
2960
+ */
2961
+ declare const useKeyPress: (keyMap: KeyPressMap, { target, enabled }?: UseKeyPressOptions) => void;
2962
+
2963
+ /**
2964
+ * Merges several refs (callback or object) into a single stable callback ref.
2965
+ *
2966
+ * Useful when a component needs an internal ref while still forwarding the
2967
+ * consumer's `ref`. The returned callback keeps a stable identity across
2968
+ * renders to avoid detach/attach churn, always assigning to the latest refs.
2969
+ *
2970
+ * @example
2971
+ * const inputRef = useRef<HTMLInputElement | null>(null)
2972
+ * const mergedRef = useMergedRefs(ref, inputRef)
2973
+ */
2974
+ declare const useMergedRefs: <T>(...refs: Array<Ref<T> | undefined>) => RefCallback<T>;
2975
+
2976
+ type UseTransitionRenderReturnType = {
2977
+ /** Whether the element should be mounted in the DOM. */
2978
+ isVisible: boolean;
2979
+ /** Whether the fade-in CSS class should be applied. */
2980
+ isFadingIn: boolean;
2981
+ };
2982
+
2983
+ /**
2984
+ * Manages mount/unmount transitions with a two-phase approach (visible → fading-in).
2985
+ *
2986
+ * Opening sequence:
2987
+ * 1. `useLayoutEffect` sets `isVisible=true` synchronously before the browser paints
2988
+ * → element is in the DOM at its initial hidden state on the very first frame.
2989
+ * 2. Double `requestAnimationFrame` in `useEffect` waits for two rendered frames
2990
+ * before setting `isFadingIn=true`, guaranteeing the CSS transition always starts
2991
+ * from the painted hidden state (prevents flickering).
2992
+ *
2993
+ * Closing sequence:
2994
+ * `isFadingIn=false` → CSS transition plays → after `duration` ms → `isVisible=false`.
2995
+ *
2996
+ * @param isOpen - Whether the element should be shown.
2997
+ * @param duration - Transition duration in milliseconds (defaults to `DEFAULT_TRANSITION_DURATION_MS`).
2998
+ */
2999
+ declare const useTransitionRender: (isOpen: boolean, duration?: number) => UseTransitionRenderReturnType;
3000
+
3001
+ type UseListKeyNavOptions = {
3002
+ /** Total number of navigable items. */
3003
+ itemCount: number;
3004
+ /** Whether keyboard navigation is active (menu is open). */
3005
+ enabled: boolean;
3006
+ /** Called with the flat index of the item confirmed via Enter. */
3007
+ onSelect: (index: number) => void;
3008
+ /** Returns true if the item at a given index should be skipped during navigation. */
3009
+ isDisabled?: (index: number) => boolean;
3010
+ /** Whether navigation wraps around at boundaries. @default true */
3011
+ loop?: boolean;
3012
+ /** Index to focus when navigation becomes active. @default 0 */
3013
+ initialIndex?: number;
3014
+ };
3015
+ type UseListKeyNavResult = {
3016
+ /** Currently keyboard-focused item index, or -1 when navigation is inactive. */
3017
+ focusedIndex: number;
3018
+ /** Manually override the focused index. */
3019
+ setFocusedIndex: (index: number) => void;
3020
+ };
3021
+
3022
+ /**
3023
+ * Manages keyboard navigation for a listbox-style menu.
3024
+ *
3025
+ * Binds ArrowDown, ArrowUp, Home, End, and Enter using `useKeyPress`.
3026
+ * Automatically skips disabled items and optionally wraps around (loop).
3027
+ * Resets focus when `enabled` toggles.
3028
+ */
3029
+ declare const useListKeyNav: ({ itemCount, enabled, onSelect, isDisabled, loop, initialIndex, }: UseListKeyNavOptions) => UseListKeyNavResult;
3030
+
3031
+ /**
3032
+ * Computes and continuously updates the `position: fixed` style for a menu panel.
3033
+ *
3034
+ * Positioning strategy:
3035
+ * - `placement="bottom"` (default): the menu opens below the anchor. If it would
3036
+ * overflow the bottom of the viewport, `top` is shifted up so the menu bottom
3037
+ * lands at `viewportHeight - margin` (never going off the top of the screen).
3038
+ * - `placement="right"` (submenu): the menu opens to the right of the anchor and
3039
+ * flips to the left when there is no horizontal room. Its `top` aligns with the
3040
+ * anchor top and is clamped to the viewport.
3041
+ *
3042
+ * Scroll handling: the page scroll is locked while the menu is open (see
3043
+ * `MenuPanel`), so the anchor cannot move out from under the menu. As a safety
3044
+ * net for nested scroll containers, the menu re-positions on scroll/resize so it
3045
+ * always stays attached to its anchor.
3046
+ *
3047
+ * Uses a two-pass strategy: first render with `menuHeight = 0`, then a rAF
3048
+ * recompute with the actual rendered size to apply any overflow offset.
3049
+ */
3050
+ declare const useMenuPosition: ({ anchorEl, open, menuRef, minWidth, gap, placement, }: UseMenuPositionOptions) => UseMenuPositionResult;
3051
+
3052
+ type UseTooltipPositionOptions = {
3053
+ /** Preferred placement of the tooltip relative to its trigger. */
3054
+ placement: TooltipPlacement;
3055
+ };
3056
+ type TooltipPosition = {
3057
+ top: number;
3058
+ left: number;
3059
+ };
3060
+ type UseTooltipPositionResult = {
3061
+ /** Ref to attach to the wrapper element (trigger container). */
3062
+ wrapperRef: RefObject<HTMLDivElement | null>;
3063
+ /** Ref to attach to the tooltip bubble element. */
3064
+ bubbleRef: RefObject<HTMLDivElement | null>;
3065
+ /** Whether the tooltip bubble should be mounted in the DOM. */
3066
+ isVisible: boolean;
3067
+ /** Whether the tooltip has faded in (drives opacity/scale transition). */
3068
+ isFadingIn: boolean;
3069
+ /** Computed fixed position for the tooltip bubble. */
3070
+ position: TooltipPosition;
3071
+ handleMouseEnter: () => void;
3072
+ handleMouseLeave: () => void;
3073
+ handleFocus: () => void;
3074
+ handleBlur: () => void;
3075
+ /** Hides the tooltip immediately (used when hideOnClick=true). */
3076
+ handleClick: () => void;
3077
+ };
3078
+
3079
+ /**
3080
+ * Computes and continuously updates the `position: fixed` coordinates for a
3081
+ * tooltip bubble, clamping it to the viewport on all four sides.
3082
+ *
3083
+ * Positioning strategy (two-pass):
3084
+ * - First pass: mount the bubble at the preferred position.
3085
+ * - Second pass (rAF): read the actual rendered size and clamp all sides.
3086
+ *
3087
+ * Handles:
3088
+ * - All four placements: top, bottom, left, right.
3089
+ * - Screen-edge clamping so the tooltip never overflows any side.
3090
+ * - Fade-in animation (sets `isFadingIn` on next tick to trigger CSS transition).
3091
+ * - Mouse/focus event handlers for show/hide.
3092
+ */
3093
+ declare const useTooltipPosition: ({ placement, }: UseTooltipPositionOptions) => UseTooltipPositionResult;
3094
+
1550
3095
  declare const lightTheme: Theme;
1551
3096
 
1552
3097
  declare const darkTheme: Theme;
1553
3098
 
1554
- export { Alert, Backdrop, Badge, Box, Breadcrumb, Button, Card, Checkbox, Dialog, Drawer, Form, Grid, Icon, IconButton, InfoBubble, Link, Menu, Select, Skeleton, Stack, Switch, Tabs, Text, TextField, Tooltip, darkTheme, lightTheme, useDrawerContext };
1555
- export type { AlertBodyProps, AlertProps, AlertTitleProps, AlertVariant, BackdropProps, BadgeColor, BadgeIcon, BadgeProps, BadgeSize, BadgeVariant, BoxProps, BreadcrumbItemProps, BreadcrumbProps, BreadcrumbSeparator, ButtonColor, ButtonIcon, ButtonProps, ButtonSize, ButtonVariant, CardBodyProps, CardHeaderProps, CardProps, CardVariant, CheckboxProps, DialogBodyProps, DialogHeaderProps, DialogProps, DrawerBodyProps, DrawerFooterProps, DrawerHeaderProps, DrawerItemIcon, DrawerItemProps, DrawerProps, DrawerVariant, FormProps, GridProps, GridStyleProps, IconButtonProps, IconProps, IconStyleParams, InfoBubbleProps, LinkColor, LinkIcon, LinkProps, LinkUnderline, MenuGroupProps, MenuItemProps, MenuProps, Palette, SelectOption, SelectProps, SkeletonAnimation, SkeletonProps, SkeletonVariant, StackProps, SwitchColor, SwitchProps, SwitchSize, TabItemProps, TabsListProps, TabsPanelProps, TabsProps, TextFieldProps, TextFieldSize, TextFieldStatus, TextProps, TextStyleParams, TextVariantStyle, TextVariants, Theme, TooltipPlacement, TooltipProps };
3099
+ export { Accordion, Alert, Article, Aside, Avatar, AvatarGroup, Backdrop, Badge, Box, Breadcrumb, Button, Card, Checkbox, DatePicker, DefaultErrorFallback, Dialog, Drawer, ErrorBoundary, Fab, Footer, Form, Grid, Header, Icon, IconButton, Image, InfoBubble, Link, LoaderScreen, Main, Menu, Nav, Pagination, RadioButton, RadioGroup, Section, Select, Separator, Skeleton, Stack, SvgImage, Switch, Table, Tabs, Text, TextField, ToggleButton, ToggleGroup, ToggleIconButton, Tooltip, darkTheme, lightTheme, useBodyScrollLock, useControllableState, useDrawerContext, useFocusTrap, useKeyPress, useListKeyNav, useMenuPosition, useMergedRefs, useTooltipPosition, useTransitionRender };
3100
+ export type { AccordionBodyProps, AccordionProps, AccordionTitleProps, AlertBodyProps, AlertProps, AlertTitleProps, AlertVariant, ArticleProps, AsideProps, AvatarColor, AvatarGroupOverlap, AvatarGroupProps, AvatarProps, AvatarShape, AvatarSize, BackdropProps, BadgeColor, BadgeIcon, BadgeProps, BadgeSize, BadgeVariant, BoxProps, BreadcrumbItemProps, BreadcrumbProps, BreadcrumbSeparator, ButtonColor, ButtonIcon, ButtonProps, ButtonSize, ButtonVariant, CardBodyProps, CardHeaderProps, CardProps, CardVariant, CheckboxProps, DatePickerProps, DatePickerSize, DatePickerStatus, DefaultErrorFallbackProps, DialogBodyProps, DialogHeaderProps, DialogProps, DrawerBodyProps, DrawerFooterProps, DrawerHeaderProps, DrawerItemIcon, DrawerItemProps, DrawerProps, DrawerVariant, ErrorBoundaryFallbackRenderProps, ErrorBoundaryProps, FabColor, FabIcon, FabPlacement, FabProps, FabSize, FooterProps, FormProps, GridProps, GridStyleProps, HeaderProps, IconButtonProps, IconProps, IconStyleParams, ImageProps, InfoBubbleProps, KeyPressHandler, KeyPressMap, LinkColor, LinkIcon, LinkProps, LinkUnderline, LoaderScreenProps, MainProps, MenuGroupProps, MenuItemProps, MenuItemRole, MenuPlacement, MenuProps, NavProps, PaginationProps, PaginationShape, PaginationSize, Palette, RadioButtonProps, RadioGroupProps, SectionProps, SelectOption, SelectProps, SeparatorOrientation, SeparatorProps, SeparatorStyleParams, SeparatorThickness, SkeletonAnimation, SkeletonProps, SkeletonVariant, StackProps, SvgImageProps, SwitchColor, SwitchProps, SwitchSize, TabItemProps, TableAlign, TableBodyProps, TableCellProps, TableColumn, TableFootProps, TableHeadProps, TableHeaderCellProps, TableLayout, TableProps, TableRowProps, TabsListProps, TabsPanelProps, TabsProps, TextFieldProps, TextFieldSize, TextFieldStatus, TextProps, TextStyleParams, TextVariantStyle, TextVariants, Theme, ToggleButtonProps, ToggleButtonVariant, ToggleGroupProps, ToggleIconButtonProps, TooltipPlacement, TooltipPosition, TooltipProps, UseControllableStateOptions, UseControllableStateResult, UseKeyPressOptions, UseListKeyNavOptions, UseListKeyNavResult, UseMenuPositionOptions, UseMenuPositionResult, UseTooltipPositionOptions, UseTooltipPositionResult, UseTransitionRenderReturnType, WeekStart };