@tinybigui/react 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3210 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +53 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +3096 -11
- package/dist/index.d.ts +3096 -11
- package/dist/index.js +3170 -21
- package/dist/index.js.map +1 -1
- package/dist/styles.css +87 -2
- package/dist/styles.css.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -2,17 +2,20 @@ import { ClassValue } from 'clsx';
|
|
|
2
2
|
import { Theme } from '@material/material-color-utilities';
|
|
3
3
|
export { Theme, argbFromHex, hexFromArgb } from '@material/material-color-utilities';
|
|
4
4
|
import * as React$1 from 'react';
|
|
5
|
-
import React__default, { LabelHTMLAttributes, InputHTMLAttributes, HTMLAttributes, RefObject, ReactNode } from 'react';
|
|
5
|
+
import React__default, { LabelHTMLAttributes, InputHTMLAttributes, HTMLAttributes, RefObject, ReactNode, ButtonHTMLAttributes, Key as Key$2, JSX } from 'react';
|
|
6
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
8
|
-
import { AriaButtonProps, AriaTextFieldProps, AriaCheckboxProps, AriaSwitchProps, AriaRadioProps, AriaRadioGroupProps } from 'react-aria';
|
|
8
|
+
import { AriaButtonProps, AriaTextFieldProps, AriaCheckboxProps, AriaSwitchProps, AriaRadioProps, AriaRadioGroupProps, AriaTabProps, AriaTabPanelProps, Key as Key$1, AriaDialogProps, AriaLinkOptions, AriaProgressBarProps, AriaMenuTriggerProps, AriaMenuProps } from 'react-aria';
|
|
9
|
+
import { Key, SelectionMode } from 'react-stately';
|
|
10
|
+
import { MenuItemProps as MenuItemProps$1, SeparatorProps } from 'react-aria-components';
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Combines and merges Tailwind CSS classes efficiently.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* Uses `clsx` for conditional joining + extended `tailwind-merge` that is
|
|
16
|
+
* aware of MD3 typography scale utilities (`text-body-large`, etc.) so they
|
|
17
|
+
* are not incorrectly removed when merged alongside color utilities
|
|
18
|
+
* (`text-on-surface`, `text-primary`, etc.).
|
|
16
19
|
*
|
|
17
20
|
* @example
|
|
18
21
|
* ```tsx
|
|
@@ -20,10 +23,16 @@ import { AriaButtonProps, AriaTextFieldProps, AriaCheckboxProps, AriaSwitchProps
|
|
|
20
23
|
* // => 'px-2 py-1 bg-blue-500 text-white'
|
|
21
24
|
* ```
|
|
22
25
|
*
|
|
23
|
-
* @example Merging conflicting classes
|
|
26
|
+
* @example Merging conflicting classes (later wins)
|
|
24
27
|
* ```tsx
|
|
25
28
|
* cn('px-2', 'px-4')
|
|
26
|
-
* // => 'px-4'
|
|
29
|
+
* // => 'px-4'
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example MD3 typography + color (both kept — no false conflict)
|
|
33
|
+
* ```tsx
|
|
34
|
+
* cn('text-body-large', 'text-on-surface')
|
|
35
|
+
* // => 'text-body-large text-on-surface'
|
|
27
36
|
* ```
|
|
28
37
|
*/
|
|
29
38
|
declare function cn(...inputs: ClassValue[]): string;
|
|
@@ -438,6 +447,258 @@ declare function pxToRem(px: number | string): string;
|
|
|
438
447
|
*/
|
|
439
448
|
declare function truncateText(lines?: number): React.CSSProperties;
|
|
440
449
|
|
|
450
|
+
/**
|
|
451
|
+
* MD3 Top App Bar size variants
|
|
452
|
+
*
|
|
453
|
+
* Each variant differs in height, title alignment, and type scale.
|
|
454
|
+
* - `small`: 64dp height, title left-aligned, title-large type scale
|
|
455
|
+
* - `center-aligned`: 64dp height, title centered, title-large type scale
|
|
456
|
+
* - `medium`: 112dp height, title bottom-left, headline-small type scale
|
|
457
|
+
* - `large`: 152dp height, title bottom-left, display-small type scale
|
|
458
|
+
*
|
|
459
|
+
* @see https://m3.material.io/components/top-app-bar/specs
|
|
460
|
+
*/
|
|
461
|
+
type AppBarVariant = "small" | "center-aligned" | "medium" | "large";
|
|
462
|
+
/**
|
|
463
|
+
* Material Design 3 Top App Bar Component Props
|
|
464
|
+
*
|
|
465
|
+
* Provides a top app bar with navigation icon, title, and trailing action icon slots.
|
|
466
|
+
* Supports scroll-triggered elevation changes with both controlled and uncontrolled modes.
|
|
467
|
+
*
|
|
468
|
+
* **Usage:**
|
|
469
|
+
* - Pass existing `<IconButton>` components into `navigationIcon` and `actions` slots
|
|
470
|
+
* - No hardcoded slot components — fully composable API
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```tsx
|
|
474
|
+
* // Small variant with navigation icon and actions
|
|
475
|
+
* <AppBar
|
|
476
|
+
* title="Page Title"
|
|
477
|
+
* navigationIcon={
|
|
478
|
+
* <IconButton aria-label="Open navigation">
|
|
479
|
+
* <MenuIcon />
|
|
480
|
+
* </IconButton>
|
|
481
|
+
* }
|
|
482
|
+
* actions={
|
|
483
|
+
* <IconButton aria-label="Search">
|
|
484
|
+
* <SearchIcon />
|
|
485
|
+
* </IconButton>
|
|
486
|
+
* }
|
|
487
|
+
* />
|
|
488
|
+
*
|
|
489
|
+
* // Center-aligned with controlled scroll state
|
|
490
|
+
* <AppBar
|
|
491
|
+
* variant="center-aligned"
|
|
492
|
+
* title="My App"
|
|
493
|
+
* scrolled={isScrolled}
|
|
494
|
+
* onScrollStateChange={setIsScrolled}
|
|
495
|
+
* />
|
|
496
|
+
*
|
|
497
|
+
* // Large variant for hero/expanded layouts
|
|
498
|
+
* <AppBar
|
|
499
|
+
* variant="large"
|
|
500
|
+
* title="Article Title"
|
|
501
|
+
* />
|
|
502
|
+
* ```
|
|
503
|
+
*/
|
|
504
|
+
interface AppBarProps {
|
|
505
|
+
/**
|
|
506
|
+
* Size variant of the Top App Bar
|
|
507
|
+
* Controls height, title position, and type scale
|
|
508
|
+
* @default 'small'
|
|
509
|
+
*/
|
|
510
|
+
variant?: AppBarVariant;
|
|
511
|
+
/**
|
|
512
|
+
* The title content. Accepts a string or any React node.
|
|
513
|
+
* Typography scale is automatically applied based on `variant`.
|
|
514
|
+
*/
|
|
515
|
+
title: React__default.ReactNode;
|
|
516
|
+
/**
|
|
517
|
+
* Navigation icon slot (leading position, optional).
|
|
518
|
+
* Expects a React node — typically an `<IconButton>` with `aria-label`.
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```tsx
|
|
522
|
+
* navigationIcon={
|
|
523
|
+
* <IconButton aria-label="Open navigation menu">
|
|
524
|
+
* <MenuIcon />
|
|
525
|
+
* </IconButton>
|
|
526
|
+
* }
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
navigationIcon?: React__default.ReactNode;
|
|
530
|
+
/**
|
|
531
|
+
* Trailing action icon slots (up to 3, optional).
|
|
532
|
+
* Expects one or more React nodes — typically `<IconButton>` components.
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```tsx
|
|
536
|
+
* actions={
|
|
537
|
+
* <>
|
|
538
|
+
* <IconButton aria-label="Search"><SearchIcon /></IconButton>
|
|
539
|
+
* <IconButton aria-label="More options"><MoreIcon /></IconButton>
|
|
540
|
+
* </>
|
|
541
|
+
* }
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
actions?: React__default.ReactNode;
|
|
545
|
+
/**
|
|
546
|
+
* Controlled scroll state.
|
|
547
|
+
* When provided, the component operates in controlled mode — the consumer
|
|
548
|
+
* is responsible for managing this value.
|
|
549
|
+
* When `undefined`, internal scroll detection is used (uncontrolled mode).
|
|
550
|
+
*
|
|
551
|
+
* - `false` (default): flat surface, `shadow-elevation-0`
|
|
552
|
+
* - `true`: elevated surface, `shadow-elevation-2`
|
|
553
|
+
*/
|
|
554
|
+
scrolled?: boolean;
|
|
555
|
+
/**
|
|
556
|
+
* Callback fired when the scroll elevation state changes.
|
|
557
|
+
* In uncontrolled mode, this fires when the user scrolls past the threshold.
|
|
558
|
+
* In controlled mode, this is an informational callback — the consumer
|
|
559
|
+
* decides whether to update `scrolled`.
|
|
560
|
+
*
|
|
561
|
+
* @param scrolled - The new scroll state
|
|
562
|
+
*/
|
|
563
|
+
onScrollStateChange?: (scrolled: boolean) => void;
|
|
564
|
+
/**
|
|
565
|
+
* Additional CSS classes to merge onto the root `<header>` element.
|
|
566
|
+
* Uses Tailwind CSS — conflicting classes are resolved by `cn()`.
|
|
567
|
+
*/
|
|
568
|
+
className?: string;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* AppBarHeadless Component Props
|
|
572
|
+
*
|
|
573
|
+
* Unstyled primitive for the Top App Bar.
|
|
574
|
+
* Renders a `<header role="banner">` and manages scroll elevation state.
|
|
575
|
+
* Use this for full visual control when the styled `AppBar` is not sufficient.
|
|
576
|
+
*
|
|
577
|
+
* @example
|
|
578
|
+
* ```tsx
|
|
579
|
+
* <AppBarHeadless
|
|
580
|
+
* className="my-custom-appbar"
|
|
581
|
+
* scrolled={scrolled}
|
|
582
|
+
* onScrollStateChange={setScrolled}
|
|
583
|
+
* >
|
|
584
|
+
* <div>My custom layout</div>
|
|
585
|
+
* </AppBarHeadless>
|
|
586
|
+
* ```
|
|
587
|
+
*/
|
|
588
|
+
interface AppBarHeadlessProps {
|
|
589
|
+
/**
|
|
590
|
+
* Additional CSS classes
|
|
591
|
+
*/
|
|
592
|
+
className?: string;
|
|
593
|
+
/**
|
|
594
|
+
* The content to render inside the header
|
|
595
|
+
*/
|
|
596
|
+
children: React__default.ReactNode;
|
|
597
|
+
/**
|
|
598
|
+
* Controlled scroll state.
|
|
599
|
+
* When `undefined`, the component uses internal scroll detection.
|
|
600
|
+
*/
|
|
601
|
+
scrolled?: boolean;
|
|
602
|
+
/**
|
|
603
|
+
* Callback fired when scroll state changes
|
|
604
|
+
*/
|
|
605
|
+
onScrollStateChange?: (scrolled: boolean) => void;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Material Design 3 Top App Bar Component
|
|
610
|
+
*
|
|
611
|
+
* Provides context and actions for the current screen. Supports four size variants,
|
|
612
|
+
* a navigation icon slot, title, and trailing action icon slots. Implements
|
|
613
|
+
* scroll-triggered elevation changes per MD3 specification.
|
|
614
|
+
*
|
|
615
|
+
* **Architecture:**
|
|
616
|
+
* - Layer 3 (this file): MD3 styled, CVA variants, layout composition
|
|
617
|
+
* - Layer 2: `AppBarHeadless` — `<header role="banner">`, scroll state
|
|
618
|
+
* - Layer 1: React Aria via `<IconButton>` in consumer slots
|
|
619
|
+
*
|
|
620
|
+
* **Key Features:**
|
|
621
|
+
* - 4 MD3 variants: small, center-aligned, medium, large
|
|
622
|
+
* - Composable API: pass `<IconButton>` nodes into navigation and action slots
|
|
623
|
+
* - Scroll elevation: flat at rest → elevated on scroll (MD3 motion tokens)
|
|
624
|
+
* - Controlled and uncontrolled scroll state
|
|
625
|
+
* - WCAG 2.1 AA: `role="banner"` landmark, keyboard accessible slots
|
|
626
|
+
* - Dark mode via existing token system
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```tsx
|
|
630
|
+
* // Small variant (default)
|
|
631
|
+
* <AppBar
|
|
632
|
+
* title="Page Title"
|
|
633
|
+
* navigationIcon={
|
|
634
|
+
* <IconButton aria-label="Open navigation menu">
|
|
635
|
+
* <MenuIcon />
|
|
636
|
+
* </IconButton>
|
|
637
|
+
* }
|
|
638
|
+
* actions={
|
|
639
|
+
* <IconButton aria-label="Search">
|
|
640
|
+
* <SearchIcon />
|
|
641
|
+
* </IconButton>
|
|
642
|
+
* }
|
|
643
|
+
* />
|
|
644
|
+
*
|
|
645
|
+
* // Center-aligned with scroll elevation
|
|
646
|
+
* <AppBar
|
|
647
|
+
* variant="center-aligned"
|
|
648
|
+
* title="My App"
|
|
649
|
+
* scrolled={isScrolled}
|
|
650
|
+
* onScrollStateChange={setIsScrolled}
|
|
651
|
+
* />
|
|
652
|
+
*
|
|
653
|
+
* // Medium with expanded title area
|
|
654
|
+
* <AppBar
|
|
655
|
+
* variant="medium"
|
|
656
|
+
* title="Article Title"
|
|
657
|
+
* navigationIcon={
|
|
658
|
+
* <IconButton aria-label="Go back">
|
|
659
|
+
* <ArrowBackIcon />
|
|
660
|
+
* </IconButton>
|
|
661
|
+
* }
|
|
662
|
+
* />
|
|
663
|
+
* ```
|
|
664
|
+
*/
|
|
665
|
+
declare const AppBar: React$1.ForwardRefExoticComponent<AppBarProps & React$1.RefAttributes<HTMLElement>>;
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Headless AppBar Component (Layer 2)
|
|
669
|
+
*
|
|
670
|
+
* Unstyled Top App Bar primitive. Renders a `<header role="banner">` landmark
|
|
671
|
+
* and manages scroll elevation state via the `useScrollElevation` hook.
|
|
672
|
+
*
|
|
673
|
+
* Features:
|
|
674
|
+
* - Semantic `<header>` element with `role="banner"` ARIA landmark
|
|
675
|
+
* - Controlled scroll state via `scrolled` prop
|
|
676
|
+
* - Uncontrolled scroll state with internal `window` scroll detection
|
|
677
|
+
* - `onScrollStateChange` callback for both modes
|
|
678
|
+
* - Full ref forwarding to the header element
|
|
679
|
+
*
|
|
680
|
+
* Use this layer when you need full visual control beyond what the styled
|
|
681
|
+
* `AppBar` provides.
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* ```tsx
|
|
685
|
+
* // Uncontrolled (auto scroll detection)
|
|
686
|
+
* <AppBarHeadless className="my-custom-appbar">
|
|
687
|
+
* <div>My custom layout</div>
|
|
688
|
+
* </AppBarHeadless>
|
|
689
|
+
*
|
|
690
|
+
* // Controlled scroll state
|
|
691
|
+
* <AppBarHeadless
|
|
692
|
+
* scrolled={isScrolled}
|
|
693
|
+
* onScrollStateChange={setIsScrolled}
|
|
694
|
+
* className="my-custom-appbar"
|
|
695
|
+
* >
|
|
696
|
+
* <div>My custom layout</div>
|
|
697
|
+
* </AppBarHeadless>
|
|
698
|
+
* ```
|
|
699
|
+
*/
|
|
700
|
+
declare const AppBarHeadless: React$1.ForwardRefExoticComponent<AppBarHeadlessProps & React$1.RefAttributes<HTMLElement>>;
|
|
701
|
+
|
|
441
702
|
/**
|
|
442
703
|
* Material Design 3 Button Variants (CVA)
|
|
443
704
|
*
|
|
@@ -447,7 +708,7 @@ declare function truncateText(lines?: number): React.CSSProperties;
|
|
|
447
708
|
declare const buttonVariants: (props?: ({
|
|
448
709
|
variant?: "text" | "filled" | "outlined" | "tonal" | "elevated" | null | undefined;
|
|
449
710
|
color?: "primary" | "secondary" | "tertiary" | "error" | null | undefined;
|
|
450
|
-
size?: "
|
|
711
|
+
size?: "small" | "large" | "medium" | null | undefined;
|
|
451
712
|
fullWidth?: boolean | null | undefined;
|
|
452
713
|
disabled?: boolean | null | undefined;
|
|
453
714
|
loading?: boolean | null | undefined;
|
|
@@ -653,7 +914,7 @@ declare const Button: React__default.ForwardRefExoticComponent<ButtonProps & Omi
|
|
|
653
914
|
declare const iconButtonVariants: (props?: ({
|
|
654
915
|
variant?: "filled" | "outlined" | "tonal" | "standard" | null | undefined;
|
|
655
916
|
color?: "primary" | "secondary" | "tertiary" | "error" | null | undefined;
|
|
656
|
-
size?: "
|
|
917
|
+
size?: "small" | "large" | "medium" | null | undefined;
|
|
657
918
|
selected?: boolean | null | undefined;
|
|
658
919
|
isDisabled?: boolean | null | undefined;
|
|
659
920
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -885,7 +1146,7 @@ declare const IconButtonHeadless: React$1.ForwardRefExoticComponent<IconButtonHe
|
|
|
885
1146
|
* - Extended variant with variable width
|
|
886
1147
|
*/
|
|
887
1148
|
declare const fabVariants: (props?: ({
|
|
888
|
-
size?: "
|
|
1149
|
+
size?: "small" | "large" | "medium" | "extended" | null | undefined;
|
|
889
1150
|
color?: "primary" | "secondary" | "tertiary" | "surface" | null | undefined;
|
|
890
1151
|
isDisabled?: boolean | null | undefined;
|
|
891
1152
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -1833,4 +2094,2828 @@ declare const RadioHeadless: React$1.ForwardRefExoticComponent<RadioHeadlessProp
|
|
|
1833
2094
|
*/
|
|
1834
2095
|
declare const RadioGroupHeadless: React$1.ForwardRefExoticComponent<RadioGroupHeadlessProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1835
2096
|
|
|
1836
|
-
|
|
2097
|
+
/**
|
|
2098
|
+
* Tab variant following MD3 spec
|
|
2099
|
+
* - primary: active indicator uses bg-primary; active text: text-primary
|
|
2100
|
+
* - secondary: active indicator uses bg-on-surface-variant; active text: text-on-surface
|
|
2101
|
+
*/
|
|
2102
|
+
type TabVariant = "primary" | "secondary";
|
|
2103
|
+
/**
|
|
2104
|
+
* Tab layout mode
|
|
2105
|
+
* - fixed: tabs fill available width equally
|
|
2106
|
+
* - scrollable: tabs overflow horizontally with no wrapping
|
|
2107
|
+
*/
|
|
2108
|
+
type TabLayout = "fixed" | "scrollable";
|
|
2109
|
+
/**
|
|
2110
|
+
* Badge value for a tab item
|
|
2111
|
+
* - number: displays count (999+ for values > 999, hidden for 0)
|
|
2112
|
+
* - true: displays a dot indicator
|
|
2113
|
+
* - false/undefined: no badge
|
|
2114
|
+
*/
|
|
2115
|
+
type TabBadgeValue = number | boolean;
|
|
2116
|
+
/**
|
|
2117
|
+
* Material Design 3 Tabs Wrapper Props
|
|
2118
|
+
*
|
|
2119
|
+
* The Tabs component manages shared state (selected key) and provides
|
|
2120
|
+
* context to TabList and TabPanel children.
|
|
2121
|
+
*
|
|
2122
|
+
* @example
|
|
2123
|
+
* ```tsx
|
|
2124
|
+
* // Uncontrolled
|
|
2125
|
+
* <Tabs defaultSelectedKey="tab1" aria-label="Settings tabs">
|
|
2126
|
+
* <TabList>
|
|
2127
|
+
* <Tab id="tab1" label="General" />
|
|
2128
|
+
* <Tab id="tab2" label="Privacy" />
|
|
2129
|
+
* </TabList>
|
|
2130
|
+
* <TabPanel id="tab1">General content</TabPanel>
|
|
2131
|
+
* <TabPanel id="tab2">Privacy content</TabPanel>
|
|
2132
|
+
* </Tabs>
|
|
2133
|
+
*
|
|
2134
|
+
* // Controlled
|
|
2135
|
+
* <Tabs selectedKey={selected} onSelectionChange={setSelected} aria-label="App tabs">
|
|
2136
|
+
* <TabList variant="secondary">
|
|
2137
|
+
* <Tab id="a" label="Overview" />
|
|
2138
|
+
* <Tab id="b" label="Details" />
|
|
2139
|
+
* </TabList>
|
|
2140
|
+
* <TabPanel id="a">Overview content</TabPanel>
|
|
2141
|
+
* <TabPanel id="b">Details content</TabPanel>
|
|
2142
|
+
* </Tabs>
|
|
2143
|
+
* ```
|
|
2144
|
+
*/
|
|
2145
|
+
interface TabsProps {
|
|
2146
|
+
/**
|
|
2147
|
+
* Controlled selected tab key
|
|
2148
|
+
*/
|
|
2149
|
+
selectedKey?: Key;
|
|
2150
|
+
/**
|
|
2151
|
+
* Default selected key for uncontrolled usage
|
|
2152
|
+
*/
|
|
2153
|
+
defaultSelectedKey?: Key;
|
|
2154
|
+
/**
|
|
2155
|
+
* Callback when selected tab changes
|
|
2156
|
+
*/
|
|
2157
|
+
onSelectionChange?: (key: Key) => void;
|
|
2158
|
+
/**
|
|
2159
|
+
* Tab variant — affects active indicator and label color
|
|
2160
|
+
* @default 'primary'
|
|
2161
|
+
*/
|
|
2162
|
+
variant?: TabVariant;
|
|
2163
|
+
/**
|
|
2164
|
+
* Layout mode
|
|
2165
|
+
* @default 'fixed'
|
|
2166
|
+
*/
|
|
2167
|
+
layout?: TabLayout;
|
|
2168
|
+
/**
|
|
2169
|
+
* TabList and TabPanel children
|
|
2170
|
+
*/
|
|
2171
|
+
children: React__default.ReactNode;
|
|
2172
|
+
/**
|
|
2173
|
+
* Additional CSS classes
|
|
2174
|
+
*/
|
|
2175
|
+
className?: string;
|
|
2176
|
+
/**
|
|
2177
|
+
* Accessible label for the tabs widget
|
|
2178
|
+
*/
|
|
2179
|
+
"aria-label"?: string;
|
|
2180
|
+
/**
|
|
2181
|
+
* Accessible labelledby reference
|
|
2182
|
+
*/
|
|
2183
|
+
"aria-labelledby"?: string;
|
|
2184
|
+
}
|
|
2185
|
+
/**
|
|
2186
|
+
* Material Design 3 TabList Props
|
|
2187
|
+
*
|
|
2188
|
+
* Renders the tab row container with the active indicator.
|
|
2189
|
+
* Must be a child of Tabs.
|
|
2190
|
+
*
|
|
2191
|
+
* @example
|
|
2192
|
+
* ```tsx
|
|
2193
|
+
* <TabList>
|
|
2194
|
+
* <Tab id="overview" label="Overview" />
|
|
2195
|
+
* <Tab id="activity" label="Activity" icon={<ActivityIcon />} />
|
|
2196
|
+
* </TabList>
|
|
2197
|
+
* ```
|
|
2198
|
+
*/
|
|
2199
|
+
interface TabListProps {
|
|
2200
|
+
/**
|
|
2201
|
+
* Tab child elements
|
|
2202
|
+
*/
|
|
2203
|
+
children: React__default.ReactNode;
|
|
2204
|
+
/**
|
|
2205
|
+
* Additional CSS classes
|
|
2206
|
+
*/
|
|
2207
|
+
className?: string;
|
|
2208
|
+
}
|
|
2209
|
+
/**
|
|
2210
|
+
* Material Design 3 Tab Props
|
|
2211
|
+
*
|
|
2212
|
+
* Represents a single tab item inside a TabList.
|
|
2213
|
+
* Supports icon-only, label-only, and icon+label content modes.
|
|
2214
|
+
*
|
|
2215
|
+
* @example
|
|
2216
|
+
* ```tsx
|
|
2217
|
+
* // Label only
|
|
2218
|
+
* <Tab id="overview" label="Overview" />
|
|
2219
|
+
*
|
|
2220
|
+
* // Icon + label
|
|
2221
|
+
* <Tab id="media" icon={<PhotoIcon />} label="Media" />
|
|
2222
|
+
*
|
|
2223
|
+
* // With badge
|
|
2224
|
+
* <Tab id="messages" label="Messages" badge={5} />
|
|
2225
|
+
*
|
|
2226
|
+
* // Dot badge
|
|
2227
|
+
* <Tab id="notifications" label="Notifications" badge={true} />
|
|
2228
|
+
*
|
|
2229
|
+
* // Disabled
|
|
2230
|
+
* <Tab id="archived" label="Archived" isDisabled />
|
|
2231
|
+
* ```
|
|
2232
|
+
*/
|
|
2233
|
+
interface TabProps {
|
|
2234
|
+
/**
|
|
2235
|
+
* Unique key identifying this tab (used to match with TabPanel)
|
|
2236
|
+
*/
|
|
2237
|
+
id: Key;
|
|
2238
|
+
/**
|
|
2239
|
+
* Icon element displayed above or instead of the label
|
|
2240
|
+
* Should be 24x24dp per MD3 Tabs spec
|
|
2241
|
+
*/
|
|
2242
|
+
icon?: React__default.ReactNode;
|
|
2243
|
+
/**
|
|
2244
|
+
* Text label for the tab
|
|
2245
|
+
*/
|
|
2246
|
+
label?: string;
|
|
2247
|
+
/**
|
|
2248
|
+
* Badge value
|
|
2249
|
+
* - number: shows count (999+ for values > 999, hidden for 0)
|
|
2250
|
+
* - true: shows dot indicator
|
|
2251
|
+
*/
|
|
2252
|
+
badge?: TabBadgeValue;
|
|
2253
|
+
/**
|
|
2254
|
+
* Disables the tab (not focusable, not selectable)
|
|
2255
|
+
* @default false
|
|
2256
|
+
*/
|
|
2257
|
+
isDisabled?: boolean;
|
|
2258
|
+
/**
|
|
2259
|
+
* Disables ripple effect
|
|
2260
|
+
* @default false
|
|
2261
|
+
*/
|
|
2262
|
+
disableRipple?: boolean;
|
|
2263
|
+
/**
|
|
2264
|
+
* Additional CSS classes
|
|
2265
|
+
*/
|
|
2266
|
+
className?: string;
|
|
2267
|
+
}
|
|
2268
|
+
/**
|
|
2269
|
+
* Material Design 3 TabPanel Props
|
|
2270
|
+
*
|
|
2271
|
+
* Content area associated with a tab. Only the selected tab's panel is visible.
|
|
2272
|
+
* The `id` must match the corresponding Tab's `id`.
|
|
2273
|
+
*
|
|
2274
|
+
* @example
|
|
2275
|
+
* ```tsx
|
|
2276
|
+
* <TabPanel id="overview">
|
|
2277
|
+
* <p>Overview content here</p>
|
|
2278
|
+
* </TabPanel>
|
|
2279
|
+
* ```
|
|
2280
|
+
*/
|
|
2281
|
+
interface TabPanelProps {
|
|
2282
|
+
/**
|
|
2283
|
+
* Key matching the associated Tab's `id`
|
|
2284
|
+
*/
|
|
2285
|
+
id: Key;
|
|
2286
|
+
/**
|
|
2287
|
+
* Panel content
|
|
2288
|
+
*/
|
|
2289
|
+
children: React__default.ReactNode;
|
|
2290
|
+
/**
|
|
2291
|
+
* Additional CSS classes
|
|
2292
|
+
*/
|
|
2293
|
+
className?: string;
|
|
2294
|
+
}
|
|
2295
|
+
/**
|
|
2296
|
+
* Internal tab item representation for React Aria collection
|
|
2297
|
+
*/
|
|
2298
|
+
interface TabItem {
|
|
2299
|
+
key: Key;
|
|
2300
|
+
id: Key;
|
|
2301
|
+
label?: string;
|
|
2302
|
+
icon?: React__default.ReactNode;
|
|
2303
|
+
badge?: TabBadgeValue;
|
|
2304
|
+
isDisabled?: boolean;
|
|
2305
|
+
textValue?: string;
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Props for HeadlessTab
|
|
2309
|
+
* Extends AriaTabProps for full React Aria accessibility support
|
|
2310
|
+
*/
|
|
2311
|
+
interface HeadlessTabProps extends AriaTabProps {
|
|
2312
|
+
/**
|
|
2313
|
+
* Tab item from the collection
|
|
2314
|
+
*/
|
|
2315
|
+
item: TabItem;
|
|
2316
|
+
/**
|
|
2317
|
+
* Additional CSS classes
|
|
2318
|
+
*/
|
|
2319
|
+
className?: string;
|
|
2320
|
+
/**
|
|
2321
|
+
* Mouse down handler (for ripple effect)
|
|
2322
|
+
*/
|
|
2323
|
+
onMouseDown?: (e: React__default.MouseEvent<HTMLButtonElement>) => void;
|
|
2324
|
+
/**
|
|
2325
|
+
* Render function receiving interaction states
|
|
2326
|
+
*/
|
|
2327
|
+
children?: (state: {
|
|
2328
|
+
isSelected: boolean;
|
|
2329
|
+
isDisabled: boolean;
|
|
2330
|
+
isFocusVisible: boolean;
|
|
2331
|
+
isPressed: boolean;
|
|
2332
|
+
}) => React__default.ReactNode;
|
|
2333
|
+
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Props for HeadlessTabPanel
|
|
2336
|
+
* Extends AriaTabPanelProps for full React Aria accessibility support
|
|
2337
|
+
*/
|
|
2338
|
+
interface HeadlessTabPanelProps extends AriaTabPanelProps {
|
|
2339
|
+
/**
|
|
2340
|
+
* Panel content
|
|
2341
|
+
*/
|
|
2342
|
+
children: React__default.ReactNode;
|
|
2343
|
+
/**
|
|
2344
|
+
* Additional CSS classes
|
|
2345
|
+
*/
|
|
2346
|
+
className?: string;
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
/**
|
|
2350
|
+
* Material Design 3 Tabs Component (Layer 3: Styled Wrapper)
|
|
2351
|
+
*
|
|
2352
|
+
* The Tabs component manages shared selected state via useTabListState (React Aria + Stately),
|
|
2353
|
+
* and provides this state to all child TabList, Tab, and TabPanel components via context.
|
|
2354
|
+
*
|
|
2355
|
+
* Architecture:
|
|
2356
|
+
* 1. Extracts Tab metadata from children to build the React Aria collection
|
|
2357
|
+
* 2. Creates tab list state with useTabListState
|
|
2358
|
+
* 3. Provides React Aria state via HeadlessTabsContext
|
|
2359
|
+
* 4. Provides MD3 styling context via TabsContext
|
|
2360
|
+
*
|
|
2361
|
+
* Features:
|
|
2362
|
+
* - ✅ Controlled and uncontrolled selection
|
|
2363
|
+
* - ✅ Primary and secondary variants
|
|
2364
|
+
* - ✅ Fixed and scrollable layouts
|
|
2365
|
+
* - ✅ Full keyboard navigation (via React Aria)
|
|
2366
|
+
* - ✅ WCAG 2.1 AA compliant
|
|
2367
|
+
*
|
|
2368
|
+
* @example
|
|
2369
|
+
* ```tsx
|
|
2370
|
+
* // Uncontrolled
|
|
2371
|
+
* <Tabs defaultSelectedKey="tab1" aria-label="Settings">
|
|
2372
|
+
* <TabList>
|
|
2373
|
+
* <Tab id="tab1" label="General" />
|
|
2374
|
+
* <Tab id="tab2" label="Privacy" />
|
|
2375
|
+
* </TabList>
|
|
2376
|
+
* <TabPanel id="tab1">General content</TabPanel>
|
|
2377
|
+
* <TabPanel id="tab2">Privacy content</TabPanel>
|
|
2378
|
+
* </Tabs>
|
|
2379
|
+
*
|
|
2380
|
+
* // Controlled
|
|
2381
|
+
* <Tabs selectedKey={tab} onSelectionChange={setTab} aria-label="App">
|
|
2382
|
+
* <TabList variant="secondary">
|
|
2383
|
+
* <Tab id="overview" label="Overview" />
|
|
2384
|
+
* <Tab id="details" label="Details" />
|
|
2385
|
+
* </TabList>
|
|
2386
|
+
* <TabPanel id="overview">Overview</TabPanel>
|
|
2387
|
+
* <TabPanel id="details">Details</TabPanel>
|
|
2388
|
+
* </Tabs>
|
|
2389
|
+
* ```
|
|
2390
|
+
*/
|
|
2391
|
+
declare const Tabs: React__default.ForwardRefExoticComponent<TabsProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
2392
|
+
|
|
2393
|
+
/**
|
|
2394
|
+
* Material Design 3 TabList Component (Layer 3: Styled)
|
|
2395
|
+
*
|
|
2396
|
+
* Renders the tab row container with an animated active indicator.
|
|
2397
|
+
* Uses React Aria's useTabList for role="tablist", keyboard navigation,
|
|
2398
|
+
* and accessibility attributes.
|
|
2399
|
+
*
|
|
2400
|
+
* The active indicator slides to the selected tab using CSS transitions
|
|
2401
|
+
* with MD3 motion tokens (medium2 duration, emphasized easing).
|
|
2402
|
+
*
|
|
2403
|
+
* MD3 Specifications:
|
|
2404
|
+
* - Container background: bg-surface
|
|
2405
|
+
* - Container height: 48dp
|
|
2406
|
+
* - Bottom border: 1dp, outline-variant color
|
|
2407
|
+
* - Fixed layout: tabs fill width equally
|
|
2408
|
+
* - Scrollable layout: overflow-x, no wrapping
|
|
2409
|
+
*
|
|
2410
|
+
* @example
|
|
2411
|
+
* ```tsx
|
|
2412
|
+
* <Tabs aria-label="Settings" defaultSelectedKey="general">
|
|
2413
|
+
* <TabList>
|
|
2414
|
+
* <Tab id="general" label="General" />
|
|
2415
|
+
* <Tab id="privacy" label="Privacy" />
|
|
2416
|
+
* </TabList>
|
|
2417
|
+
* ...
|
|
2418
|
+
* </Tabs>
|
|
2419
|
+
* ```
|
|
2420
|
+
*/
|
|
2421
|
+
declare const TabList: React__default.ForwardRefExoticComponent<TabListProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
2422
|
+
|
|
2423
|
+
/**
|
|
2424
|
+
* Material Design 3 Tab Component (Layer 3: Styled)
|
|
2425
|
+
*
|
|
2426
|
+
* Renders a single tab item inside a TabList.
|
|
2427
|
+
* Supports three content modes: icon-only, label-only, icon + label (stacked).
|
|
2428
|
+
*
|
|
2429
|
+
* Features:
|
|
2430
|
+
* - ✅ Icon-only, label-only, icon + label (stacked) content modes
|
|
2431
|
+
* - ✅ Ripple effect (Material Design)
|
|
2432
|
+
* - ✅ MD3 state layers (hover 8%, pressed 12%)
|
|
2433
|
+
* - ✅ Badge support (numeric, dot, 999+)
|
|
2434
|
+
* - ✅ Disabled state (opacity-38, not focusable)
|
|
2435
|
+
* - ✅ Full keyboard accessibility (via React Aria)
|
|
2436
|
+
* - ✅ Primary/secondary variant colors
|
|
2437
|
+
*
|
|
2438
|
+
* MD3 Specifications:
|
|
2439
|
+
* - Minimum height: 48dp
|
|
2440
|
+
* - Minimum width: 90dp
|
|
2441
|
+
* - Typography: Title Small (14px, weight 500, tracking 0.1px)
|
|
2442
|
+
* - Icon: 24x24dp
|
|
2443
|
+
* - Active indicator: 3dp primary / 2dp secondary
|
|
2444
|
+
* - State layers: 8% hover, 12% pressed/focus
|
|
2445
|
+
*
|
|
2446
|
+
* @example
|
|
2447
|
+
* ```tsx
|
|
2448
|
+
* // Label only
|
|
2449
|
+
* <Tab id="overview" label="Overview" />
|
|
2450
|
+
*
|
|
2451
|
+
* // Icon + label
|
|
2452
|
+
* <Tab id="media" icon={<PhotoIcon />} label="Media" />
|
|
2453
|
+
*
|
|
2454
|
+
* // With numeric badge
|
|
2455
|
+
* <Tab id="messages" label="Messages" badge={5} />
|
|
2456
|
+
*
|
|
2457
|
+
* // With dot badge
|
|
2458
|
+
* <Tab id="notifications" label="Notifications" badge={true} />
|
|
2459
|
+
*
|
|
2460
|
+
* // Disabled
|
|
2461
|
+
* <Tab id="archived" label="Archived" isDisabled />
|
|
2462
|
+
* ```
|
|
2463
|
+
*/
|
|
2464
|
+
declare const Tab: React__default.ForwardRefExoticComponent<TabProps & React__default.RefAttributes<HTMLButtonElement>>;
|
|
2465
|
+
|
|
2466
|
+
/**
|
|
2467
|
+
* Material Design 3 TabPanel Component (Layer 3: Styled)
|
|
2468
|
+
*
|
|
2469
|
+
* Renders the content area associated with a tab.
|
|
2470
|
+
* Only the selected tab's panel content is shown.
|
|
2471
|
+
*
|
|
2472
|
+
* Provides full accessibility:
|
|
2473
|
+
* - role="tabpanel"
|
|
2474
|
+
* - aria-labelledby (pointing to the associated tab)
|
|
2475
|
+
* - Focus management for panels without focusable children (tabIndex=-1)
|
|
2476
|
+
*
|
|
2477
|
+
* MD3 Specifications:
|
|
2478
|
+
* - No specific container styling mandated by MD3 for the panel itself
|
|
2479
|
+
* - The panel should be keyboard-reachable per WCAG requirements
|
|
2480
|
+
*
|
|
2481
|
+
* @example
|
|
2482
|
+
* ```tsx
|
|
2483
|
+
* <TabPanel id="overview">
|
|
2484
|
+
* <h2>Overview</h2>
|
|
2485
|
+
* <p>Content here...</p>
|
|
2486
|
+
* </TabPanel>
|
|
2487
|
+
* ```
|
|
2488
|
+
*/
|
|
2489
|
+
declare const TabPanel: React__default.ForwardRefExoticComponent<TabPanelProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
2490
|
+
|
|
2491
|
+
/**
|
|
2492
|
+
* Props for the HeadlessTabList container.
|
|
2493
|
+
* State is injected from HeadlessTabsContext (created in Tabs wrapper).
|
|
2494
|
+
*/
|
|
2495
|
+
interface HeadlessTabListContainerProps {
|
|
2496
|
+
/** Children are Tab elements */
|
|
2497
|
+
children: React.ReactNode;
|
|
2498
|
+
/** Additional CSS classes */
|
|
2499
|
+
className?: string;
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* Headless TabList Component (Layer 2)
|
|
2503
|
+
*
|
|
2504
|
+
* Unstyled tab list container. Applies useTabList to the container element
|
|
2505
|
+
* which wires up role="tablist", aria-label, and keyboard navigation.
|
|
2506
|
+
* State must be provided via HeadlessTabsContext (from the Tabs wrapper).
|
|
2507
|
+
*
|
|
2508
|
+
* @example
|
|
2509
|
+
* ```tsx
|
|
2510
|
+
* // Advanced usage via headless primitives
|
|
2511
|
+
* // State is provided by the Tabs wrapper above in the tree
|
|
2512
|
+
* <HeadlessTabList className="my-tablist">
|
|
2513
|
+
* {items.map(item => <HeadlessTab key={item.key} item={item} />)}
|
|
2514
|
+
* </HeadlessTabList>
|
|
2515
|
+
* ```
|
|
2516
|
+
*/
|
|
2517
|
+
declare const HeadlessTabList: React$1.ForwardRefExoticComponent<HeadlessTabListContainerProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2518
|
+
/**
|
|
2519
|
+
* Headless Tab Component (Layer 2)
|
|
2520
|
+
*
|
|
2521
|
+
* Unstyled individual tab item. Provides full React Aria accessibility:
|
|
2522
|
+
* - role="tab"
|
|
2523
|
+
* - aria-selected
|
|
2524
|
+
* - aria-controls (pointing to panel)
|
|
2525
|
+
* - roving tabIndex
|
|
2526
|
+
* - keyboard activation
|
|
2527
|
+
*
|
|
2528
|
+
* Must be used within HeadlessTabsContext.
|
|
2529
|
+
*
|
|
2530
|
+
* @example
|
|
2531
|
+
* ```tsx
|
|
2532
|
+
* <HeadlessTab item={item}>
|
|
2533
|
+
* {({ isSelected, isFocusVisible }) => (
|
|
2534
|
+
* <span className={isSelected ? 'font-bold' : ''}>
|
|
2535
|
+
* {item.label}
|
|
2536
|
+
* </span>
|
|
2537
|
+
* )}
|
|
2538
|
+
* </HeadlessTab>
|
|
2539
|
+
* ```
|
|
2540
|
+
*/
|
|
2541
|
+
declare const HeadlessTab: React$1.ForwardRefExoticComponent<HeadlessTabProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
2542
|
+
/**
|
|
2543
|
+
* Headless TabPanel Component (Layer 2)
|
|
2544
|
+
*
|
|
2545
|
+
* Unstyled tab panel. Provides:
|
|
2546
|
+
* - role="tabpanel"
|
|
2547
|
+
* - aria-labelledby (pointing to its tab)
|
|
2548
|
+
* - Focus management for panels without focusable children
|
|
2549
|
+
*
|
|
2550
|
+
* Must be used within HeadlessTabsContext.
|
|
2551
|
+
*
|
|
2552
|
+
* @example
|
|
2553
|
+
* ```tsx
|
|
2554
|
+
* <HeadlessTabPanel>
|
|
2555
|
+
* <p>Panel content here</p>
|
|
2556
|
+
* </HeadlessTabPanel>
|
|
2557
|
+
* ```
|
|
2558
|
+
*/
|
|
2559
|
+
declare const HeadlessTabPanel: React$1.ForwardRefExoticComponent<HeadlessTabPanelProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2560
|
+
|
|
2561
|
+
/**
|
|
2562
|
+
* Badge value for a NavigationBarItem.
|
|
2563
|
+
*
|
|
2564
|
+
* - `true` — renders a dot indicator (no count)
|
|
2565
|
+
* - `number` — renders the count; 0 hides the badge; values > 999 display "999+"
|
|
2566
|
+
*/
|
|
2567
|
+
type NavigationBarBadge = number | true;
|
|
2568
|
+
/**
|
|
2569
|
+
* Configuration for a single NavigationBar destination item.
|
|
2570
|
+
*
|
|
2571
|
+
* @example
|
|
2572
|
+
* ```tsx
|
|
2573
|
+
* const item: NavigationBarItemConfig = {
|
|
2574
|
+
* key: 'home',
|
|
2575
|
+
* icon: <HomeIcon />,
|
|
2576
|
+
* label: 'Home',
|
|
2577
|
+
* badge: 3,
|
|
2578
|
+
* };
|
|
2579
|
+
* ```
|
|
2580
|
+
*/
|
|
2581
|
+
interface NavigationBarItemConfig {
|
|
2582
|
+
/**
|
|
2583
|
+
* Unique identifier for this destination (used as the selection key).
|
|
2584
|
+
*/
|
|
2585
|
+
key: string;
|
|
2586
|
+
/**
|
|
2587
|
+
* Icon element displayed at 24dp. Always visible regardless of `hideLabels`.
|
|
2588
|
+
*/
|
|
2589
|
+
icon: ReactNode;
|
|
2590
|
+
/**
|
|
2591
|
+
* Visible label beneath the icon.
|
|
2592
|
+
* Required unless `aria-label` is provided (icon-only mode with `hideLabels`).
|
|
2593
|
+
*/
|
|
2594
|
+
label?: string;
|
|
2595
|
+
/**
|
|
2596
|
+
* Badge displayed on the icon.
|
|
2597
|
+
* - `true` renders a dot indicator.
|
|
2598
|
+
* - `0` hides the badge.
|
|
2599
|
+
* - `1–999` renders the count.
|
|
2600
|
+
* - `> 999` renders "999+".
|
|
2601
|
+
*/
|
|
2602
|
+
badge?: NavigationBarBadge;
|
|
2603
|
+
/**
|
|
2604
|
+
* When `true`, the item cannot be focused or activated.
|
|
2605
|
+
* @default false
|
|
2606
|
+
*/
|
|
2607
|
+
isDisabled?: boolean;
|
|
2608
|
+
/**
|
|
2609
|
+
* Accessible name used when labels are hidden (`hideLabels` mode).
|
|
2610
|
+
* Required for icon-only items; enforced at runtime via dev warning.
|
|
2611
|
+
*/
|
|
2612
|
+
"aria-label"?: string;
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Material Design 3 Navigation Bar (Bottom Navigation) props.
|
|
2616
|
+
*
|
|
2617
|
+
* Accepts 3–5 destination items. Item count outside this range triggers a
|
|
2618
|
+
* dev-only `console.warn`.
|
|
2619
|
+
*
|
|
2620
|
+
* **Controlled usage:**
|
|
2621
|
+
* ```tsx
|
|
2622
|
+
* <NavigationBar
|
|
2623
|
+
* items={items}
|
|
2624
|
+
* activeKey={activeKey}
|
|
2625
|
+
* onActiveChange={setActiveKey}
|
|
2626
|
+
* aria-label="Main navigation"
|
|
2627
|
+
* />
|
|
2628
|
+
* ```
|
|
2629
|
+
*
|
|
2630
|
+
* **Uncontrolled usage:**
|
|
2631
|
+
* ```tsx
|
|
2632
|
+
* <NavigationBar
|
|
2633
|
+
* items={items}
|
|
2634
|
+
* defaultActiveKey="home"
|
|
2635
|
+
* aria-label="Main navigation"
|
|
2636
|
+
* />
|
|
2637
|
+
* ```
|
|
2638
|
+
*
|
|
2639
|
+
* @see https://m3.material.io/components/navigation-bar/overview
|
|
2640
|
+
*/
|
|
2641
|
+
interface NavigationBarProps {
|
|
2642
|
+
/**
|
|
2643
|
+
* Array of 3–5 destination items.
|
|
2644
|
+
* Item count outside the 3–5 range triggers a dev warning.
|
|
2645
|
+
*/
|
|
2646
|
+
items: NavigationBarItemConfig[];
|
|
2647
|
+
/**
|
|
2648
|
+
* Controlled active key. Pair with `onActiveChange`.
|
|
2649
|
+
* Use `null` to explicitly deselect all items.
|
|
2650
|
+
*/
|
|
2651
|
+
activeKey?: Key$1 | null;
|
|
2652
|
+
/**
|
|
2653
|
+
* Default active key for uncontrolled usage.
|
|
2654
|
+
*/
|
|
2655
|
+
defaultActiveKey?: Key$1;
|
|
2656
|
+
/**
|
|
2657
|
+
* Called when the active destination changes.
|
|
2658
|
+
*/
|
|
2659
|
+
onActiveChange?: (key: Key$1) => void;
|
|
2660
|
+
/**
|
|
2661
|
+
* When `true`, hides labels on all items (icon-only mode).
|
|
2662
|
+
* @default false
|
|
2663
|
+
*/
|
|
2664
|
+
hideLabels?: boolean;
|
|
2665
|
+
/**
|
|
2666
|
+
* Accessible label for the `<nav>` landmark element. Required.
|
|
2667
|
+
*
|
|
2668
|
+
* @example "Main navigation"
|
|
2669
|
+
*/
|
|
2670
|
+
"aria-label": string;
|
|
2671
|
+
/**
|
|
2672
|
+
* Disable ripple effect on all items.
|
|
2673
|
+
* @default false
|
|
2674
|
+
*/
|
|
2675
|
+
disableRipple?: boolean;
|
|
2676
|
+
/**
|
|
2677
|
+
* Additional CSS classes merged onto the `<nav>` element via `cn()`.
|
|
2678
|
+
*/
|
|
2679
|
+
className?: string;
|
|
2680
|
+
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Standalone NavigationBarItem props.
|
|
2683
|
+
*
|
|
2684
|
+
* Used internally by `NavigationBar` and available for advanced consumers
|
|
2685
|
+
* composing with `HeadlessNavigationBar`.
|
|
2686
|
+
*
|
|
2687
|
+
* Extends `ButtonHTMLAttributes` (minus `disabled`) so that tab props from
|
|
2688
|
+
* `useTab` can be spread directly onto the rendered `<button>`.
|
|
2689
|
+
*/
|
|
2690
|
+
interface NavigationBarItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "disabled"> {
|
|
2691
|
+
/**
|
|
2692
|
+
* The unique key for this item (passed to the headless layer).
|
|
2693
|
+
*/
|
|
2694
|
+
itemKey: Key$1;
|
|
2695
|
+
/**
|
|
2696
|
+
* Icon element displayed at 24dp.
|
|
2697
|
+
*/
|
|
2698
|
+
icon: ReactNode;
|
|
2699
|
+
/**
|
|
2700
|
+
* Visible label beneath the icon.
|
|
2701
|
+
*/
|
|
2702
|
+
label?: string;
|
|
2703
|
+
/**
|
|
2704
|
+
* Badge value.
|
|
2705
|
+
*/
|
|
2706
|
+
badge?: NavigationBarBadge;
|
|
2707
|
+
/**
|
|
2708
|
+
* Whether this item is the currently selected destination.
|
|
2709
|
+
* @default false
|
|
2710
|
+
*/
|
|
2711
|
+
isActive?: boolean;
|
|
2712
|
+
/**
|
|
2713
|
+
* When `true`, hides the label for this item.
|
|
2714
|
+
* @default false
|
|
2715
|
+
*/
|
|
2716
|
+
hideLabels?: boolean;
|
|
2717
|
+
/**
|
|
2718
|
+
* Whether this item is disabled.
|
|
2719
|
+
* @default false
|
|
2720
|
+
*/
|
|
2721
|
+
isDisabled?: boolean;
|
|
2722
|
+
/**
|
|
2723
|
+
* Disable ripple effect on this item.
|
|
2724
|
+
* @default false
|
|
2725
|
+
*/
|
|
2726
|
+
disableRipple?: boolean;
|
|
2727
|
+
}
|
|
2728
|
+
/**
|
|
2729
|
+
* HeadlessNavigationBar props.
|
|
2730
|
+
*
|
|
2731
|
+
* Provides the accessibility foundation (`role="navigation"`, `role="tablist"`,
|
|
2732
|
+
* `useTabList`, `useTabListState`) without any visual styling.
|
|
2733
|
+
* Intended for advanced consumers who need full visual control.
|
|
2734
|
+
*
|
|
2735
|
+
* @example
|
|
2736
|
+
* ```tsx
|
|
2737
|
+
* <HeadlessNavigationBar
|
|
2738
|
+
* items={items}
|
|
2739
|
+
* defaultSelectedKey="home"
|
|
2740
|
+
* aria-label="Main navigation"
|
|
2741
|
+
* renderItem={(config) => (
|
|
2742
|
+
* <HeadlessNavigationBarItem key={config.key} itemKey={config.key}>
|
|
2743
|
+
* {config.icon}
|
|
2744
|
+
* <span>{config.label}</span>
|
|
2745
|
+
* </HeadlessNavigationBarItem>
|
|
2746
|
+
* )}
|
|
2747
|
+
* />
|
|
2748
|
+
* ```
|
|
2749
|
+
*/
|
|
2750
|
+
interface HeadlessNavigationBarProps {
|
|
2751
|
+
/**
|
|
2752
|
+
* Array of item configs used to build the React Aria collection.
|
|
2753
|
+
*/
|
|
2754
|
+
items: NavigationBarItemConfig[];
|
|
2755
|
+
/**
|
|
2756
|
+
* Controlled selected key. Pair with `onSelectionChange`.
|
|
2757
|
+
* Use `null` to explicitly deselect all items.
|
|
2758
|
+
*/
|
|
2759
|
+
selectedKey?: Key$1 | null;
|
|
2760
|
+
/**
|
|
2761
|
+
* Default selected key for uncontrolled usage.
|
|
2762
|
+
*/
|
|
2763
|
+
defaultSelectedKey?: Key$1;
|
|
2764
|
+
/**
|
|
2765
|
+
* Called when the selected key changes.
|
|
2766
|
+
*/
|
|
2767
|
+
onSelectionChange?: (key: Key$1) => void;
|
|
2768
|
+
/**
|
|
2769
|
+
* Accessible label for the `<nav>` landmark.
|
|
2770
|
+
*/
|
|
2771
|
+
"aria-label": string;
|
|
2772
|
+
/**
|
|
2773
|
+
* Additional CSS classes for the inner `<div role="tablist">`.
|
|
2774
|
+
*/
|
|
2775
|
+
className?: string;
|
|
2776
|
+
/**
|
|
2777
|
+
* Render function called for each item in the collection.
|
|
2778
|
+
* Receives the item config; use `HeadlessNavigationBarItem` inside.
|
|
2779
|
+
*/
|
|
2780
|
+
renderItem: (config: NavigationBarItemConfig) => ReactNode;
|
|
2781
|
+
}
|
|
2782
|
+
/**
|
|
2783
|
+
* Render props passed to `HeadlessNavigationBarItem`'s children when used as
|
|
2784
|
+
* a render function.
|
|
2785
|
+
*/
|
|
2786
|
+
interface NavigationBarItemRenderProps {
|
|
2787
|
+
/** Whether this item is the active destination. */
|
|
2788
|
+
isSelected: boolean;
|
|
2789
|
+
/** Whether the item has a visible keyboard focus ring. */
|
|
2790
|
+
isFocusVisible: boolean;
|
|
2791
|
+
}
|
|
2792
|
+
/**
|
|
2793
|
+
* HeadlessNavigationBarItem props.
|
|
2794
|
+
*
|
|
2795
|
+
* Renders a single tab-accessible button using `useTab` from React Aria.
|
|
2796
|
+
* Must be rendered inside `HeadlessNavigationBar` (reads state from context).
|
|
2797
|
+
*
|
|
2798
|
+
* Accepts children as ReactNode or as a render function receiving state props.
|
|
2799
|
+
*
|
|
2800
|
+
* @example
|
|
2801
|
+
* ```tsx
|
|
2802
|
+
* // Static children
|
|
2803
|
+
* <HeadlessNavigationBarItem itemKey="home">
|
|
2804
|
+
* Home
|
|
2805
|
+
* </HeadlessNavigationBarItem>
|
|
2806
|
+
*
|
|
2807
|
+
* // Render function (access to isSelected / isFocusVisible)
|
|
2808
|
+
* <HeadlessNavigationBarItem itemKey="home">
|
|
2809
|
+
* {({ isSelected }) => (
|
|
2810
|
+
* <span style={{ fontWeight: isSelected ? 'bold' : 'normal' }}>Home</span>
|
|
2811
|
+
* )}
|
|
2812
|
+
* </HeadlessNavigationBarItem>
|
|
2813
|
+
* ```
|
|
2814
|
+
*/
|
|
2815
|
+
interface HeadlessNavigationBarItemProps {
|
|
2816
|
+
/**
|
|
2817
|
+
* The key matching `NavigationBarItemConfig.key`. Used to look up the
|
|
2818
|
+
* item in the React Aria collection state.
|
|
2819
|
+
*/
|
|
2820
|
+
itemKey: Key$1;
|
|
2821
|
+
/**
|
|
2822
|
+
* Content to render inside the button — either a ReactNode or a render
|
|
2823
|
+
* function receiving `{ isSelected, isFocusVisible }`.
|
|
2824
|
+
*/
|
|
2825
|
+
children: ReactNode | ((renderProps: NavigationBarItemRenderProps) => ReactNode);
|
|
2826
|
+
/**
|
|
2827
|
+
* Additional CSS classes merged onto the `<button>` element.
|
|
2828
|
+
*/
|
|
2829
|
+
className?: string;
|
|
2830
|
+
/**
|
|
2831
|
+
* Accessible label for icon-only items (when no visible text label is present).
|
|
2832
|
+
* Applied as `aria-label` on the `<button>` element.
|
|
2833
|
+
*/
|
|
2834
|
+
"aria-label"?: string;
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
/**
|
|
2838
|
+
* Material Design 3 Navigation Bar (Bottom Navigation) — Layer 3.
|
|
2839
|
+
*
|
|
2840
|
+
* Renders a fixed bottom navigation bar with 3–5 destination items, each with
|
|
2841
|
+
* an icon, optional label, animated active indicator pill, and optional badge.
|
|
2842
|
+
*
|
|
2843
|
+
* **Architecture:**
|
|
2844
|
+
* - Layer 3 (this file): MD3 styled, CVA variants, `'use client'`
|
|
2845
|
+
* - Layer 2: `HeadlessNavigationBar` + `HeadlessNavigationBarItem` — React Aria
|
|
2846
|
+
* - Layer 1: `useTabList`, `useTab`, `useFocusRing` — accessibility foundation
|
|
2847
|
+
*
|
|
2848
|
+
* **Key Features:**
|
|
2849
|
+
* - 3–5 destination items (dev warning outside this range)
|
|
2850
|
+
* - Animated indicator pill per MD3 motion tokens (scale + opacity)
|
|
2851
|
+
* - Badge: dot, numeric count, "999+" truncation, hidden at 0
|
|
2852
|
+
* - `hideLabels` for icon-only mode
|
|
2853
|
+
* - Controlled (`activeKey` + `onActiveChange`) and uncontrolled (`defaultActiveKey`)
|
|
2854
|
+
* - Full keyboard navigation: Arrow Left/Right, Home, End, roving `tabIndex`
|
|
2855
|
+
* - WCAG 2.1 AA: `role="navigation"` + `aria-label`, `role="tablist"`,
|
|
2856
|
+
* `role="tab"` + `aria-selected`, visible focus ring
|
|
2857
|
+
*
|
|
2858
|
+
* **Future — Navigation Rail:**
|
|
2859
|
+
* At wider viewports, a NavigationBar may transition to a Navigation Rail.
|
|
2860
|
+
* This is a separate component tracked as a future Phase 5+ item.
|
|
2861
|
+
*
|
|
2862
|
+
* @example
|
|
2863
|
+
* ```tsx
|
|
2864
|
+
* // Uncontrolled
|
|
2865
|
+
* <NavigationBar
|
|
2866
|
+
* items={[
|
|
2867
|
+
* { key: 'home', icon: <HomeIcon />, label: 'Home' },
|
|
2868
|
+
* { key: 'search', icon: <SearchIcon />, label: 'Search', badge: 3 },
|
|
2869
|
+
* { key: 'profile', icon: <ProfileIcon />, label: 'Profile' },
|
|
2870
|
+
* ]}
|
|
2871
|
+
* defaultActiveKey="home"
|
|
2872
|
+
* aria-label="Main navigation"
|
|
2873
|
+
* />
|
|
2874
|
+
*
|
|
2875
|
+
* // Controlled
|
|
2876
|
+
* <NavigationBar
|
|
2877
|
+
* items={items}
|
|
2878
|
+
* activeKey={activeKey}
|
|
2879
|
+
* onActiveChange={setActiveKey}
|
|
2880
|
+
* aria-label="Main navigation"
|
|
2881
|
+
* />
|
|
2882
|
+
*
|
|
2883
|
+
* // Icon-only mode
|
|
2884
|
+
* <NavigationBar
|
|
2885
|
+
* items={iconOnlyItems}
|
|
2886
|
+
* defaultActiveKey="home"
|
|
2887
|
+
* aria-label="Main navigation"
|
|
2888
|
+
* hideLabels
|
|
2889
|
+
* />
|
|
2890
|
+
* ```
|
|
2891
|
+
*
|
|
2892
|
+
* @see https://m3.material.io/components/navigation-bar/overview
|
|
2893
|
+
* @see https://m3.material.io/components/navigation-bar/specs
|
|
2894
|
+
*/
|
|
2895
|
+
declare const NavigationBar: React$1.ForwardRefExoticComponent<NavigationBarProps & React$1.RefAttributes<HTMLElement>>;
|
|
2896
|
+
|
|
2897
|
+
/**
|
|
2898
|
+
* Material Design 3 Navigation Bar Item (Layer 3).
|
|
2899
|
+
*
|
|
2900
|
+
* Renders a single destination item within a `NavigationBar`. Handles:
|
|
2901
|
+
* - Active indicator pill (`rounded-full`, animated with MD3 motion tokens)
|
|
2902
|
+
* - Icon slot (24dp, always visible)
|
|
2903
|
+
* - Badge (dot, numeric count, 999+ truncation)
|
|
2904
|
+
* - Label (hidden in `hideLabels` mode)
|
|
2905
|
+
* - MD3 state layers (hover `opacity-8`, pressed `opacity-12`)
|
|
2906
|
+
* - Ripple effect via `useRipple`
|
|
2907
|
+
* - Focus ring via `data-focus-visible`
|
|
2908
|
+
*
|
|
2909
|
+
* Used internally by `NavigationBar`. Can also be composed with
|
|
2910
|
+
* `HeadlessNavigationBarItem` for advanced customization.
|
|
2911
|
+
*
|
|
2912
|
+
* **Future — Navigation Rail:**
|
|
2913
|
+
* At wider viewports, a NavigationBar may transition to a Navigation Rail.
|
|
2914
|
+
* This is a separate component tracked as a future Phase 5+ item.
|
|
2915
|
+
*
|
|
2916
|
+
* @example
|
|
2917
|
+
* ```tsx
|
|
2918
|
+
* // Used standalone (advanced consumer with HeadlessNavigationBar)
|
|
2919
|
+
* <NavigationBarItem
|
|
2920
|
+
* itemKey="home"
|
|
2921
|
+
* icon={<HomeIcon />}
|
|
2922
|
+
* label="Home"
|
|
2923
|
+
* isActive
|
|
2924
|
+
* />
|
|
2925
|
+
* ```
|
|
2926
|
+
*/
|
|
2927
|
+
declare const NavigationBarItem: React$1.ForwardRefExoticComponent<NavigationBarItemProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
2928
|
+
|
|
2929
|
+
/**
|
|
2930
|
+
* Headless Navigation Bar (Layer 2).
|
|
2931
|
+
*
|
|
2932
|
+
* Renders an accessible `<nav role="navigation">` landmark wrapping a
|
|
2933
|
+
* `<div role="tablist">`. Provides keyboard navigation (Arrow Left/Right,
|
|
2934
|
+
* Home, End) and full ARIA semantics via React Aria's `useTabList`.
|
|
2935
|
+
*
|
|
2936
|
+
* All item accessibility is handled by `HeadlessNavigationBarItem`.
|
|
2937
|
+
*
|
|
2938
|
+
* Use this component when you need complete visual control beyond what the
|
|
2939
|
+
* styled `NavigationBar` provides.
|
|
2940
|
+
*
|
|
2941
|
+
* @example
|
|
2942
|
+
* ```tsx
|
|
2943
|
+
* <HeadlessNavigationBar
|
|
2944
|
+
* items={items}
|
|
2945
|
+
* defaultSelectedKey="home"
|
|
2946
|
+
* aria-label="Main navigation"
|
|
2947
|
+
* renderItem={(config) => (
|
|
2948
|
+
* <HeadlessNavigationBarItem key={config.key} itemKey={config.key}>
|
|
2949
|
+
* {config.icon}
|
|
2950
|
+
* <span>{config.label}</span>
|
|
2951
|
+
* </HeadlessNavigationBarItem>
|
|
2952
|
+
* )}
|
|
2953
|
+
* />
|
|
2954
|
+
* ```
|
|
2955
|
+
*/
|
|
2956
|
+
declare const HeadlessNavigationBar: React$1.ForwardRefExoticComponent<HeadlessNavigationBarProps & React$1.RefAttributes<HTMLElement>>;
|
|
2957
|
+
/**
|
|
2958
|
+
* Headless Navigation Bar Item (Layer 2).
|
|
2959
|
+
*
|
|
2960
|
+
* Renders an accessible `<button role="tab">` using React Aria's `useTab`.
|
|
2961
|
+
* Provides `aria-selected`, `aria-disabled`, roving `tabIndex`, and
|
|
2962
|
+
* focus management via `useFocusRing`.
|
|
2963
|
+
*
|
|
2964
|
+
* Must be rendered inside `HeadlessNavigationBar`.
|
|
2965
|
+
*
|
|
2966
|
+
* @example
|
|
2967
|
+
* ```tsx
|
|
2968
|
+
* <HeadlessNavigationBarItem itemKey="home" className="my-item">
|
|
2969
|
+
* <HomeIcon aria-hidden />
|
|
2970
|
+
* <span>Home</span>
|
|
2971
|
+
* </HeadlessNavigationBarItem>
|
|
2972
|
+
* ```
|
|
2973
|
+
*/
|
|
2974
|
+
declare const HeadlessNavigationBarItem: React$1.ForwardRefExoticComponent<HeadlessNavigationBarItemProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
2975
|
+
|
|
2976
|
+
/**
|
|
2977
|
+
* Structural variant of the Navigation Drawer.
|
|
2978
|
+
*
|
|
2979
|
+
* - `standard` — inline `<nav>` landmark; no overlay or focus trap; supports
|
|
2980
|
+
* controlled `open` prop for collapsible layouts.
|
|
2981
|
+
* - `modal` — overlay dialog with scrim backdrop, slide-in animation,
|
|
2982
|
+
* focus trap, and `Escape` to close.
|
|
2983
|
+
*/
|
|
2984
|
+
type DrawerVariant = "standard" | "modal";
|
|
2985
|
+
/**
|
|
2986
|
+
* Material Design 3 Navigation Drawer props.
|
|
2987
|
+
*
|
|
2988
|
+
* Supports two structural variants — Standard (inline, permanently visible or
|
|
2989
|
+
* togglable) and Modal (overlay with scrim and focus trap).
|
|
2990
|
+
*
|
|
2991
|
+
* @example
|
|
2992
|
+
* ```tsx
|
|
2993
|
+
* // Standard variant
|
|
2994
|
+
* <Drawer variant="standard" open={open} onOpenChange={setOpen} aria-label="App navigation">
|
|
2995
|
+
* <DrawerItem label="Home" isActive />
|
|
2996
|
+
* <DrawerItem label="Settings" />
|
|
2997
|
+
* </Drawer>
|
|
2998
|
+
*
|
|
2999
|
+
* // Modal variant with trigger
|
|
3000
|
+
* <Drawer variant="modal" open={open} onOpenChange={setOpen} aria-label="App navigation">
|
|
3001
|
+
* <DrawerItem label="Home" isActive />
|
|
3002
|
+
* <DrawerSection header="Account">
|
|
3003
|
+
* <DrawerItem label="Profile" />
|
|
3004
|
+
* </DrawerSection>
|
|
3005
|
+
* </Drawer>
|
|
3006
|
+
* ```
|
|
3007
|
+
*/
|
|
3008
|
+
interface DrawerProps extends AriaDialogProps {
|
|
3009
|
+
/**
|
|
3010
|
+
* Structural variant — drives which React Aria hooks and DOM structure are used.
|
|
3011
|
+
* @default 'standard'
|
|
3012
|
+
*/
|
|
3013
|
+
variant?: DrawerVariant;
|
|
3014
|
+
/**
|
|
3015
|
+
* Controlled open state. Pair with `onOpenChange`.
|
|
3016
|
+
*/
|
|
3017
|
+
open?: boolean;
|
|
3018
|
+
/**
|
|
3019
|
+
* Default open state for uncontrolled usage.
|
|
3020
|
+
* @default false
|
|
3021
|
+
*/
|
|
3022
|
+
defaultOpen?: boolean;
|
|
3023
|
+
/**
|
|
3024
|
+
* Called when the open state changes (e.g. Escape key, scrim click).
|
|
3025
|
+
*/
|
|
3026
|
+
onOpenChange?: (open: boolean) => void;
|
|
3027
|
+
/**
|
|
3028
|
+
* Accessible label for the drawer landmark/dialog. Required.
|
|
3029
|
+
*
|
|
3030
|
+
* @example "App navigation"
|
|
3031
|
+
*/
|
|
3032
|
+
"aria-label": string;
|
|
3033
|
+
/**
|
|
3034
|
+
* Drawer content — typically `DrawerItem` and `DrawerSection` elements.
|
|
3035
|
+
*/
|
|
3036
|
+
children: ReactNode;
|
|
3037
|
+
/**
|
|
3038
|
+
* Additional CSS classes merged onto the drawer panel element.
|
|
3039
|
+
*/
|
|
3040
|
+
className?: string;
|
|
3041
|
+
/**
|
|
3042
|
+
* Disable ripple effect on all items within the drawer.
|
|
3043
|
+
* @default false
|
|
3044
|
+
*/
|
|
3045
|
+
disableRipple?: boolean;
|
|
3046
|
+
}
|
|
3047
|
+
/**
|
|
3048
|
+
* Material Design 3 Navigation Drawer Item props.
|
|
3049
|
+
*
|
|
3050
|
+
* Renders as `<a>` when `href` is provided (using `useLink`), or as `<button>`
|
|
3051
|
+
* when no `href` is provided (using `useButton`).
|
|
3052
|
+
*
|
|
3053
|
+
* @example
|
|
3054
|
+
* ```tsx
|
|
3055
|
+
* // Button-based item (no href)
|
|
3056
|
+
* <DrawerItem
|
|
3057
|
+
* icon={<HomeIcon />}
|
|
3058
|
+
* label="Home"
|
|
3059
|
+
* isActive
|
|
3060
|
+
* onPress={() => setPage('home')}
|
|
3061
|
+
* />
|
|
3062
|
+
*
|
|
3063
|
+
* // Link-based item (with href)
|
|
3064
|
+
* <DrawerItem href="/settings" icon={<SettingsIcon />} label="Settings" />
|
|
3065
|
+
*
|
|
3066
|
+
* // With badge
|
|
3067
|
+
* <DrawerItem label="Inbox" badge={<span>3</span>} />
|
|
3068
|
+
*
|
|
3069
|
+
* // Disabled
|
|
3070
|
+
* <DrawerItem label="Disabled" isDisabled />
|
|
3071
|
+
* ```
|
|
3072
|
+
*/
|
|
3073
|
+
interface DrawerItemProps extends AriaButtonProps, Pick<AriaLinkOptions, "href"> {
|
|
3074
|
+
/**
|
|
3075
|
+
* Optional URL — when provided, renders the item as `<a>` using `useLink`.
|
|
3076
|
+
* When absent, renders as `<button>` using `useButton`.
|
|
3077
|
+
*/
|
|
3078
|
+
href?: string;
|
|
3079
|
+
/**
|
|
3080
|
+
* Optional leading icon (24dp).
|
|
3081
|
+
*/
|
|
3082
|
+
icon?: ReactNode;
|
|
3083
|
+
/**
|
|
3084
|
+
* Visible label text. Required.
|
|
3085
|
+
*/
|
|
3086
|
+
label: string;
|
|
3087
|
+
/**
|
|
3088
|
+
* Optional trailing badge or secondary indicator element.
|
|
3089
|
+
*/
|
|
3090
|
+
badge?: ReactNode;
|
|
3091
|
+
/**
|
|
3092
|
+
* Optional secondary descriptive text rendered below the label.
|
|
3093
|
+
*/
|
|
3094
|
+
secondaryText?: string;
|
|
3095
|
+
/**
|
|
3096
|
+
* When `true`, marks this item as the active destination.
|
|
3097
|
+
* Applies `aria-current="page"`, active indicator background, and
|
|
3098
|
+
* `text-on-secondary-container`.
|
|
3099
|
+
* @default false
|
|
3100
|
+
*/
|
|
3101
|
+
isActive?: boolean;
|
|
3102
|
+
/**
|
|
3103
|
+
* Disable ripple effect on this specific item.
|
|
3104
|
+
* @default false
|
|
3105
|
+
*/
|
|
3106
|
+
disableRipple?: boolean;
|
|
3107
|
+
/**
|
|
3108
|
+
* Additional CSS classes merged via `cn()`.
|
|
3109
|
+
*/
|
|
3110
|
+
className?: string;
|
|
3111
|
+
}
|
|
3112
|
+
/**
|
|
3113
|
+
* Material Design 3 Navigation Drawer Section props.
|
|
3114
|
+
*
|
|
3115
|
+
* Groups related `DrawerItem` elements with an optional header label and
|
|
3116
|
+
* a preceding divider (except the first section).
|
|
3117
|
+
*
|
|
3118
|
+
* @example
|
|
3119
|
+
* ```tsx
|
|
3120
|
+
* <DrawerSection header="Account">
|
|
3121
|
+
* <DrawerItem label="Profile" />
|
|
3122
|
+
* <DrawerItem label="Logout" />
|
|
3123
|
+
* </DrawerSection>
|
|
3124
|
+
* ```
|
|
3125
|
+
*/
|
|
3126
|
+
interface DrawerSectionProps {
|
|
3127
|
+
/**
|
|
3128
|
+
* Optional section header label rendered in `text-title-small`.
|
|
3129
|
+
*/
|
|
3130
|
+
header?: string;
|
|
3131
|
+
/**
|
|
3132
|
+
* Section content — typically `DrawerItem` elements.
|
|
3133
|
+
*/
|
|
3134
|
+
children: ReactNode;
|
|
3135
|
+
/**
|
|
3136
|
+
* When `true`, renders a top divider line above the section.
|
|
3137
|
+
* @default false
|
|
3138
|
+
*/
|
|
3139
|
+
showDivider?: boolean;
|
|
3140
|
+
/**
|
|
3141
|
+
* Additional CSS classes merged via `cn()`.
|
|
3142
|
+
*/
|
|
3143
|
+
className?: string;
|
|
3144
|
+
}
|
|
3145
|
+
/**
|
|
3146
|
+
* Props for the headless Drawer primitive (Layer 2).
|
|
3147
|
+
* Provides behavior and ARIA semantics without visual styling.
|
|
3148
|
+
*/
|
|
3149
|
+
interface HeadlessDrawerProps {
|
|
3150
|
+
/**
|
|
3151
|
+
* Structural variant — drives which React Aria hooks are used.
|
|
3152
|
+
* @default 'standard'
|
|
3153
|
+
*/
|
|
3154
|
+
variant?: DrawerVariant;
|
|
3155
|
+
/**
|
|
3156
|
+
* Controlled open state.
|
|
3157
|
+
*/
|
|
3158
|
+
open?: boolean;
|
|
3159
|
+
/**
|
|
3160
|
+
* Default open state for uncontrolled usage.
|
|
3161
|
+
* @default false
|
|
3162
|
+
*/
|
|
3163
|
+
defaultOpen?: boolean;
|
|
3164
|
+
/**
|
|
3165
|
+
* Called when the open state changes.
|
|
3166
|
+
*/
|
|
3167
|
+
onOpenChange?: (open: boolean) => void;
|
|
3168
|
+
/**
|
|
3169
|
+
* Accessible label. Required.
|
|
3170
|
+
*/
|
|
3171
|
+
"aria-label": string;
|
|
3172
|
+
/**
|
|
3173
|
+
* Drawer content.
|
|
3174
|
+
*/
|
|
3175
|
+
children: ReactNode;
|
|
3176
|
+
/**
|
|
3177
|
+
* Additional CSS classes for the drawer panel element.
|
|
3178
|
+
*/
|
|
3179
|
+
className?: string;
|
|
3180
|
+
/**
|
|
3181
|
+
* Additional CSS classes for the scrim element (modal variant only).
|
|
3182
|
+
*/
|
|
3183
|
+
scrimClassName?: string;
|
|
3184
|
+
/**
|
|
3185
|
+
* Disable ripple on all items.
|
|
3186
|
+
* @default false
|
|
3187
|
+
*/
|
|
3188
|
+
disableRipple?: boolean;
|
|
3189
|
+
}
|
|
3190
|
+
/**
|
|
3191
|
+
* Props for the headless DrawerItem primitive (Layer 2).
|
|
3192
|
+
*/
|
|
3193
|
+
interface HeadlessDrawerItemProps extends AriaButtonProps, Pick<AriaLinkOptions, "href"> {
|
|
3194
|
+
/**
|
|
3195
|
+
* Optional URL — determines `<a>` vs `<button>` rendering.
|
|
3196
|
+
*/
|
|
3197
|
+
href?: string;
|
|
3198
|
+
/**
|
|
3199
|
+
* Whether this item is active (`aria-current="page"`).
|
|
3200
|
+
* @default false
|
|
3201
|
+
*/
|
|
3202
|
+
isActive?: boolean;
|
|
3203
|
+
/**
|
|
3204
|
+
* Item content.
|
|
3205
|
+
*/
|
|
3206
|
+
children: ReactNode;
|
|
3207
|
+
/**
|
|
3208
|
+
* Additional CSS classes.
|
|
3209
|
+
*/
|
|
3210
|
+
className?: string;
|
|
3211
|
+
/**
|
|
3212
|
+
* Mouse down handler (for ripple effect).
|
|
3213
|
+
*/
|
|
3214
|
+
onMouseDown?: (e: React.MouseEvent<HTMLElement>) => void;
|
|
3215
|
+
}
|
|
3216
|
+
/**
|
|
3217
|
+
* Context value shared between HeadlessDrawer and its children.
|
|
3218
|
+
* @internal
|
|
3219
|
+
*/
|
|
3220
|
+
interface DrawerContextValue {
|
|
3221
|
+
/** Whether the drawer is currently open. */
|
|
3222
|
+
isOpen: boolean;
|
|
3223
|
+
/** Callback to close the drawer. */
|
|
3224
|
+
close: () => void;
|
|
3225
|
+
/** Whether ripple is disabled for all items. */
|
|
3226
|
+
disableRipple: boolean;
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
/**
|
|
3230
|
+
* Material Design 3 Navigation Drawer (Layer 3: Styled).
|
|
3231
|
+
*
|
|
3232
|
+
* Supports two structural variants driven by the `variant` prop:
|
|
3233
|
+
*
|
|
3234
|
+
* - **`standard`** — Inline `<nav>` landmark. Permanently visible or
|
|
3235
|
+
* collapsible via controlled `open` prop. No overlay or focus trap.
|
|
3236
|
+
* Surface: `bg-surface-container-low`.
|
|
3237
|
+
*
|
|
3238
|
+
* - **`modal`** — Overlay dialog with scrim backdrop, slide-in animation,
|
|
3239
|
+
* focus trap, and `Escape` to close.
|
|
3240
|
+
* Surface: `bg-surface-container`, `shadow-elevation-1`.
|
|
3241
|
+
*
|
|
3242
|
+
* Both variants:
|
|
3243
|
+
* - `role="navigation"` on the outer wrapper
|
|
3244
|
+
* - `rounded-r-xl` (28px per MD3 shape extra-large on right side only)
|
|
3245
|
+
* - Slide-in animation: `translate-x` driven by MD3 motion tokens
|
|
3246
|
+
* - `w-drawer` (360dp per MD3 spec)
|
|
3247
|
+
*
|
|
3248
|
+
* Modal-only:
|
|
3249
|
+
* - `role="dialog"` + `aria-modal="true"` on the panel
|
|
3250
|
+
* - `FocusScope` containing focus + restoring on close
|
|
3251
|
+
* - `usePreventScroll` to lock body scroll
|
|
3252
|
+
* - Scrim: `bg-scrim opacity-32` — click closes drawer
|
|
3253
|
+
* - `Escape` key closes drawer
|
|
3254
|
+
*
|
|
3255
|
+
* @example
|
|
3256
|
+
* ```tsx
|
|
3257
|
+
* // Standard variant (collapsible sidebar)
|
|
3258
|
+
* <Drawer
|
|
3259
|
+
* variant="standard"
|
|
3260
|
+
* open={sidebarOpen}
|
|
3261
|
+
* onOpenChange={setSidebarOpen}
|
|
3262
|
+
* aria-label="App navigation"
|
|
3263
|
+
* >
|
|
3264
|
+
* <DrawerItem icon={<HomeIcon />} label="Home" isActive />
|
|
3265
|
+
* <DrawerSection header="Settings" showDivider>
|
|
3266
|
+
* <DrawerItem icon={<SettingsIcon />} label="Preferences" />
|
|
3267
|
+
* </DrawerSection>
|
|
3268
|
+
* </Drawer>
|
|
3269
|
+
*
|
|
3270
|
+
* // Modal variant (overlay)
|
|
3271
|
+
* <Drawer
|
|
3272
|
+
* variant="modal"
|
|
3273
|
+
* open={drawerOpen}
|
|
3274
|
+
* onOpenChange={setDrawerOpen}
|
|
3275
|
+
* aria-label="App navigation"
|
|
3276
|
+
* >
|
|
3277
|
+
* <DrawerItem label="Home" isActive />
|
|
3278
|
+
* <DrawerItem label="Inbox" badge={<span>5</span>} />
|
|
3279
|
+
* </Drawer>
|
|
3280
|
+
* ```
|
|
3281
|
+
*
|
|
3282
|
+
* @see https://m3.material.io/components/navigation-drawer/overview
|
|
3283
|
+
*/
|
|
3284
|
+
declare const Drawer: React$1.ForwardRefExoticComponent<DrawerProps & React$1.RefAttributes<HTMLElement>>;
|
|
3285
|
+
|
|
3286
|
+
/**
|
|
3287
|
+
* Material Design 3 Navigation Drawer Item (Layer 3: Styled).
|
|
3288
|
+
*
|
|
3289
|
+
* Renders a navigation destination row following MD3 Navigation Drawer specs.
|
|
3290
|
+
* Uses `HeadlessDrawerItem` for behavior and accessibility, CVA for variants.
|
|
3291
|
+
*
|
|
3292
|
+
* Renders as `<a>` when `href` is provided, `<button>` otherwise.
|
|
3293
|
+
*
|
|
3294
|
+
* Features:
|
|
3295
|
+
* - Active indicator: `bg-secondary-container` / `text-on-secondary-container`
|
|
3296
|
+
* - `aria-current="page"` on active item
|
|
3297
|
+
* - Ripple effect on interaction
|
|
3298
|
+
* - Hover/focus/pressed state layers (MD3 spec: 8% / 12%)
|
|
3299
|
+
* - Optional leading icon (24dp slot)
|
|
3300
|
+
* - Optional trailing badge or secondary text
|
|
3301
|
+
* - Disabled state: `opacity-38`, non-interactive
|
|
3302
|
+
*
|
|
3303
|
+
* @example
|
|
3304
|
+
* ```tsx
|
|
3305
|
+
* // Active item with icon
|
|
3306
|
+
* <DrawerItem icon={<HomeIcon />} label="Home" isActive onPress={() => navigate('/')} />
|
|
3307
|
+
*
|
|
3308
|
+
* // Link item
|
|
3309
|
+
* <DrawerItem href="/settings" icon={<SettingsIcon />} label="Settings" />
|
|
3310
|
+
*
|
|
3311
|
+
* // Item with badge
|
|
3312
|
+
* <DrawerItem label="Inbox" badge={<span>3</span>} />
|
|
3313
|
+
*
|
|
3314
|
+
* // Disabled
|
|
3315
|
+
* <DrawerItem label="Disabled Feature" isDisabled />
|
|
3316
|
+
* ```
|
|
3317
|
+
*
|
|
3318
|
+
* @see https://m3.material.io/components/navigation-drawer/specs
|
|
3319
|
+
*/
|
|
3320
|
+
declare const DrawerItem: React$1.ForwardRefExoticComponent<DrawerItemProps & React$1.RefAttributes<HTMLElement>>;
|
|
3321
|
+
|
|
3322
|
+
/**
|
|
3323
|
+
* Material Design 3 Navigation Drawer Section (Layer 3: Styled).
|
|
3324
|
+
*
|
|
3325
|
+
* Groups related `DrawerItem` elements with an optional header label and
|
|
3326
|
+
* a horizontal divider. Follows MD3 Navigation Drawer spec for section
|
|
3327
|
+
* grouping and typography.
|
|
3328
|
+
*
|
|
3329
|
+
* Features:
|
|
3330
|
+
* - Optional header label: `text-title-small text-on-surface-variant`
|
|
3331
|
+
* - Optional top divider: `border-outline-variant`
|
|
3332
|
+
* - Semantic `<hr role="separator">` for the divider
|
|
3333
|
+
*
|
|
3334
|
+
* @example
|
|
3335
|
+
* ```tsx
|
|
3336
|
+
* // Section with header and divider
|
|
3337
|
+
* <DrawerSection header="Account" showDivider>
|
|
3338
|
+
* <DrawerItem icon={<ProfileIcon />} label="Profile" />
|
|
3339
|
+
* <DrawerItem icon={<LogoutIcon />} label="Logout" />
|
|
3340
|
+
* </DrawerSection>
|
|
3341
|
+
*
|
|
3342
|
+
* // Section without header (just a visual group)
|
|
3343
|
+
* <DrawerSection showDivider>
|
|
3344
|
+
* <DrawerItem label="Help" />
|
|
3345
|
+
* </DrawerSection>
|
|
3346
|
+
* ```
|
|
3347
|
+
*
|
|
3348
|
+
* @see https://m3.material.io/components/navigation-drawer/specs
|
|
3349
|
+
*/
|
|
3350
|
+
declare const DrawerSection: React$1.ForwardRefExoticComponent<DrawerSectionProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
3351
|
+
|
|
3352
|
+
/**
|
|
3353
|
+
* Headless Navigation Drawer (Layer 2).
|
|
3354
|
+
*
|
|
3355
|
+
* Provides all behavior and ARIA semantics without any visual styling.
|
|
3356
|
+
* Renders two distinct DOM structures based on the `variant` prop:
|
|
3357
|
+
*
|
|
3358
|
+
* - **`standard`**: `<nav role="navigation">` — no overlay, no focus trap
|
|
3359
|
+
* - **`modal`**: `<nav role="navigation">` containing a `FocusScope`-wrapped
|
|
3360
|
+
* `<div role="dialog" aria-modal="true">` with scrim overlay
|
|
3361
|
+
*
|
|
3362
|
+
* React Aria hooks used:
|
|
3363
|
+
* - `useDialog` — `role="dialog"`, `aria-modal`, `aria-label` on modal panel
|
|
3364
|
+
* - `useOverlay` — dismiss on Escape key and outside click (modal)
|
|
3365
|
+
* - `usePreventScroll` — locks body scroll when modal is open
|
|
3366
|
+
* - `FocusScope` — focus trap + restoreFocus when modal closes
|
|
3367
|
+
* - `useOverlayTriggerState` — open/close state management
|
|
3368
|
+
*
|
|
3369
|
+
* @example
|
|
3370
|
+
* ```tsx
|
|
3371
|
+
* <HeadlessDrawer variant="modal" open aria-label="Navigation">
|
|
3372
|
+
* <HeadlessDrawerItem onPress={() => {}}>Home</HeadlessDrawerItem>
|
|
3373
|
+
* </HeadlessDrawer>
|
|
3374
|
+
* ```
|
|
3375
|
+
*/
|
|
3376
|
+
declare const HeadlessDrawer: React__default.ForwardRefExoticComponent<HeadlessDrawerProps & React__default.RefAttributes<HTMLElement>>;
|
|
3377
|
+
/**
|
|
3378
|
+
* Headless Navigation Drawer Item (Layer 2).
|
|
3379
|
+
*
|
|
3380
|
+
* Renders as:
|
|
3381
|
+
* - `<a>` using `useLink` when `href` is provided
|
|
3382
|
+
* - `<button>` using `useButton` when no `href`
|
|
3383
|
+
*
|
|
3384
|
+
* Applies `aria-current="page"` when `isActive` is true.
|
|
3385
|
+
* Uses `useFocusRing` for visible keyboard focus.
|
|
3386
|
+
*
|
|
3387
|
+
* @example
|
|
3388
|
+
* ```tsx
|
|
3389
|
+
* // Button-based item
|
|
3390
|
+
* <HeadlessDrawerItem onPress={() => navigate('home')} isActive>
|
|
3391
|
+
* Home
|
|
3392
|
+
* </HeadlessDrawerItem>
|
|
3393
|
+
*
|
|
3394
|
+
* // Link-based item
|
|
3395
|
+
* <HeadlessDrawerItem href="/settings">
|
|
3396
|
+
* Settings
|
|
3397
|
+
* </HeadlessDrawerItem>
|
|
3398
|
+
* ```
|
|
3399
|
+
*/
|
|
3400
|
+
declare const HeadlessDrawerItem: React__default.ForwardRefExoticComponent<HeadlessDrawerItemProps & React__default.RefAttributes<HTMLElement>>;
|
|
3401
|
+
|
|
3402
|
+
/**
|
|
3403
|
+
* Material Design 3 Progress Indicator Component Props
|
|
3404
|
+
*
|
|
3405
|
+
* Built on React Aria for world-class accessibility.
|
|
3406
|
+
* Supports four variants: Linear Determinate, Linear Indeterminate,
|
|
3407
|
+
* Circular Determinate, and Circular Indeterminate.
|
|
3408
|
+
* Implementation uses CVA + Tailwind CSS classes mapped to MD3 tokens.
|
|
3409
|
+
*
|
|
3410
|
+
* @example
|
|
3411
|
+
* ```tsx
|
|
3412
|
+
* // Linear determinate
|
|
3413
|
+
* <Progress type="linear" value={60} label="Loading" />
|
|
3414
|
+
*
|
|
3415
|
+
* // Linear indeterminate
|
|
3416
|
+
* <Progress type="linear" indeterminate aria-label="Loading content" />
|
|
3417
|
+
*
|
|
3418
|
+
* // Circular determinate
|
|
3419
|
+
* <Progress type="circular" value={75} label="Uploading" />
|
|
3420
|
+
*
|
|
3421
|
+
* // Circular indeterminate (default spinner)
|
|
3422
|
+
* <Progress type="circular" indeterminate aria-label="Loading" />
|
|
3423
|
+
*
|
|
3424
|
+
* // Circular with size
|
|
3425
|
+
* <Progress type="circular" indeterminate size="small" aria-label="Loading" />
|
|
3426
|
+
*
|
|
3427
|
+
* // Custom range
|
|
3428
|
+
* <Progress type="linear" minValue={0} maxValue={200} value={150} label="Progress" />
|
|
3429
|
+
* ```
|
|
3430
|
+
*/
|
|
3431
|
+
interface ProgressProps extends AriaProgressBarProps {
|
|
3432
|
+
/**
|
|
3433
|
+
* The visual type of the progress indicator.
|
|
3434
|
+
* @default "linear"
|
|
3435
|
+
*/
|
|
3436
|
+
type?: "linear" | "circular";
|
|
3437
|
+
/**
|
|
3438
|
+
* When true, renders indeterminate (unknown progress) animation.
|
|
3439
|
+
* `value` is ignored when indeterminate is true.
|
|
3440
|
+
* @default false
|
|
3441
|
+
*/
|
|
3442
|
+
indeterminate?: boolean;
|
|
3443
|
+
/**
|
|
3444
|
+
* Size of the circular progress indicator (ignored for linear).
|
|
3445
|
+
* small=24dp, medium=48dp (default), large=64dp per MD3 spec.
|
|
3446
|
+
* @default "medium"
|
|
3447
|
+
*/
|
|
3448
|
+
size?: "small" | "medium" | "large";
|
|
3449
|
+
/**
|
|
3450
|
+
* Additional CSS classes (Tailwind).
|
|
3451
|
+
*/
|
|
3452
|
+
className?: string;
|
|
3453
|
+
}
|
|
3454
|
+
/**
|
|
3455
|
+
* Props for the headless Progress component.
|
|
3456
|
+
* Provides behavior and accessibility only — bring your own styles.
|
|
3457
|
+
*
|
|
3458
|
+
* @example
|
|
3459
|
+
* ```tsx
|
|
3460
|
+
* <ProgressHeadless
|
|
3461
|
+
* type="linear"
|
|
3462
|
+
* value={50}
|
|
3463
|
+
* label="Upload"
|
|
3464
|
+
* renderProgress={({ percentage }) => (
|
|
3465
|
+
* <div style={{ width: `${percentage}%` }} />
|
|
3466
|
+
* )}
|
|
3467
|
+
* />
|
|
3468
|
+
* ```
|
|
3469
|
+
*/
|
|
3470
|
+
interface ProgressHeadlessProps extends AriaProgressBarProps {
|
|
3471
|
+
/**
|
|
3472
|
+
* The visual type of the progress indicator.
|
|
3473
|
+
* @default "linear"
|
|
3474
|
+
*/
|
|
3475
|
+
type?: "linear" | "circular";
|
|
3476
|
+
/**
|
|
3477
|
+
* When true, renders indeterminate animation.
|
|
3478
|
+
* @default false
|
|
3479
|
+
*/
|
|
3480
|
+
indeterminate?: boolean;
|
|
3481
|
+
/**
|
|
3482
|
+
* Size for circular variant.
|
|
3483
|
+
* @default "medium"
|
|
3484
|
+
*/
|
|
3485
|
+
size?: "small" | "medium" | "large";
|
|
3486
|
+
/**
|
|
3487
|
+
* Additional CSS classes.
|
|
3488
|
+
*/
|
|
3489
|
+
className?: string;
|
|
3490
|
+
/**
|
|
3491
|
+
* Children rendered inside the container.
|
|
3492
|
+
*/
|
|
3493
|
+
children?: React__default.ReactNode;
|
|
3494
|
+
/**
|
|
3495
|
+
* Render prop for custom progress visual.
|
|
3496
|
+
* Receives computed state for building custom visuals.
|
|
3497
|
+
*/
|
|
3498
|
+
renderProgress?: (state: {
|
|
3499
|
+
percentage: number;
|
|
3500
|
+
isIndeterminate: boolean;
|
|
3501
|
+
type: "linear" | "circular";
|
|
3502
|
+
size: "small" | "medium" | "large";
|
|
3503
|
+
}) => React__default.ReactNode;
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3506
|
+
/**
|
|
3507
|
+
* Material Design 3 Progress Indicator (Layer 3: Styled)
|
|
3508
|
+
*
|
|
3509
|
+
* Built on React Aria for world-class accessibility.
|
|
3510
|
+
* Supports four variants driven by `type` + `indeterminate` props:
|
|
3511
|
+
* - Linear Determinate
|
|
3512
|
+
* - Linear Indeterminate
|
|
3513
|
+
* - Circular Determinate
|
|
3514
|
+
* - Circular Indeterminate
|
|
3515
|
+
*
|
|
3516
|
+
* MD3 Specifications:
|
|
3517
|
+
* - Linear track height: 4dp (h-1)
|
|
3518
|
+
* - Linear track shape: rounded-full
|
|
3519
|
+
* - Circular default size: 48dp (medium)
|
|
3520
|
+
* - Circular stroke width: 4dp (SVG attribute)
|
|
3521
|
+
* - Active track: primary
|
|
3522
|
+
* - Inactive track: surface-container-highest
|
|
3523
|
+
* - Determinate transitions: duration-medium4 + ease-standard
|
|
3524
|
+
* - Indeterminate linear cycle: duration-long2
|
|
3525
|
+
* - Indeterminate circular rotation: duration-long4
|
|
3526
|
+
*
|
|
3527
|
+
* @example
|
|
3528
|
+
* ```tsx
|
|
3529
|
+
* // Linear determinate
|
|
3530
|
+
* <Progress type="linear" value={60} label="Uploading" />
|
|
3531
|
+
*
|
|
3532
|
+
* // Linear indeterminate
|
|
3533
|
+
* <Progress type="linear" indeterminate aria-label="Loading" />
|
|
3534
|
+
*
|
|
3535
|
+
* // Circular determinate
|
|
3536
|
+
* <Progress type="circular" value={75} label="Processing" />
|
|
3537
|
+
*
|
|
3538
|
+
* // Circular indeterminate
|
|
3539
|
+
* <Progress type="circular" indeterminate aria-label="Loading" />
|
|
3540
|
+
*
|
|
3541
|
+
* // Circular small spinner
|
|
3542
|
+
* <Progress type="circular" indeterminate size="small" aria-label="Loading" />
|
|
3543
|
+
* ```
|
|
3544
|
+
*/
|
|
3545
|
+
declare const Progress: React__default.ForwardRefExoticComponent<ProgressProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
3546
|
+
|
|
3547
|
+
/**
|
|
3548
|
+
* Headless Progress Indicator Component (Layer 2)
|
|
3549
|
+
*
|
|
3550
|
+
* Unstyled progress bar primitive using React Aria for accessibility.
|
|
3551
|
+
* Provides behavior only — bring your own styles.
|
|
3552
|
+
*
|
|
3553
|
+
* Features:
|
|
3554
|
+
* - role="progressbar" with correct aria-value* attributes
|
|
3555
|
+
* - Determinate and indeterminate progress support
|
|
3556
|
+
* - Internationalized value label formatting via React Aria
|
|
3557
|
+
* - Label linkage via aria-labelledby / aria-label
|
|
3558
|
+
* - Render prop for custom visual rendering
|
|
3559
|
+
*
|
|
3560
|
+
* @example
|
|
3561
|
+
* ```tsx
|
|
3562
|
+
* // Custom visual via render prop
|
|
3563
|
+
* <ProgressHeadless
|
|
3564
|
+
* value={50}
|
|
3565
|
+
* label="Upload"
|
|
3566
|
+
* renderProgress={({ percentage }) => (
|
|
3567
|
+
* <div style={{ width: `${percentage}%` }} />
|
|
3568
|
+
* )}
|
|
3569
|
+
* />
|
|
3570
|
+
*
|
|
3571
|
+
* // Children-based rendering
|
|
3572
|
+
* <ProgressHeadless value={75} aria-label="Loading">
|
|
3573
|
+
* <MyCustomProgressVisual />
|
|
3574
|
+
* </ProgressHeadless>
|
|
3575
|
+
* ```
|
|
3576
|
+
*/
|
|
3577
|
+
declare const ProgressHeadless: React__default.ForwardRefExoticComponent<ProgressHeadlessProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
3578
|
+
|
|
3579
|
+
/**
|
|
3580
|
+
* Color scheme for the MD3 Menu container and items.
|
|
3581
|
+
*
|
|
3582
|
+
* - `standard` — surface-based colors; default for most use cases
|
|
3583
|
+
* - `vibrant` — tertiary-based colors; higher visual emphasis; use sparingly
|
|
3584
|
+
*
|
|
3585
|
+
* @see https://m3.material.io/components/menus/specs#color
|
|
3586
|
+
*/
|
|
3587
|
+
type MenuColorScheme = "standard" | "vibrant";
|
|
3588
|
+
/**
|
|
3589
|
+
* Visual style of the MD3 Menu.
|
|
3590
|
+
*
|
|
3591
|
+
* - `baseline` — original M3 design; 4dp corner radius; surface container background
|
|
3592
|
+
* - `vertical` — M3 Expressive style; 16dp corner radius; more expressive shapes and motion
|
|
3593
|
+
*
|
|
3594
|
+
* @see https://m3.material.io/components/menus/specs#variants
|
|
3595
|
+
*/
|
|
3596
|
+
type MenuStyle = "baseline" | "vertical";
|
|
3597
|
+
/**
|
|
3598
|
+
* Density level for the MD3 Menu (web only).
|
|
3599
|
+
*
|
|
3600
|
+
* Controls item height via top/bottom padding reduction:
|
|
3601
|
+
* - `0` → 48dp (default)
|
|
3602
|
+
* - `-1` → 44dp
|
|
3603
|
+
* - `-2` → 40dp
|
|
3604
|
+
* - `-3` → 36dp
|
|
3605
|
+
*
|
|
3606
|
+
* @see https://m3.material.io/m3/pages/understanding-layout/density
|
|
3607
|
+
*/
|
|
3608
|
+
type MenuDensity = 0 | -1 | -2 | -3;
|
|
3609
|
+
/**
|
|
3610
|
+
* Props for the `MenuTrigger` component (styled Layer 3).
|
|
3611
|
+
*
|
|
3612
|
+
* Wraps a trigger element and a `Menu`. The first child must be the trigger;
|
|
3613
|
+
* the second must be a `Menu` component.
|
|
3614
|
+
*
|
|
3615
|
+
* @example
|
|
3616
|
+
* ```tsx
|
|
3617
|
+
* <MenuTrigger>
|
|
3618
|
+
* <Button>Open</Button>
|
|
3619
|
+
* <Menu aria-label="Actions">
|
|
3620
|
+
* <MenuItem id="copy">Copy</MenuItem>
|
|
3621
|
+
* </Menu>
|
|
3622
|
+
* </MenuTrigger>
|
|
3623
|
+
* ```
|
|
3624
|
+
*/
|
|
3625
|
+
interface MenuTriggerProps extends AriaMenuTriggerProps {
|
|
3626
|
+
/** Trigger element + Menu children. */
|
|
3627
|
+
children: ReactNode;
|
|
3628
|
+
/**
|
|
3629
|
+
* Preferred placement of the menu relative to the trigger.
|
|
3630
|
+
* @default 'bottom start'
|
|
3631
|
+
*/
|
|
3632
|
+
placement?: "bottom" | "bottom start" | "bottom end" | "top" | "top start" | "top end";
|
|
3633
|
+
/**
|
|
3634
|
+
* Whether the menu should automatically flip to the opposite side when it
|
|
3635
|
+
* would be cut off by the viewport edge.
|
|
3636
|
+
* @default true
|
|
3637
|
+
*/
|
|
3638
|
+
shouldFlip?: boolean;
|
|
3639
|
+
}
|
|
3640
|
+
/**
|
|
3641
|
+
* Props for the `Menu` component (styled Layer 3).
|
|
3642
|
+
*
|
|
3643
|
+
* @example
|
|
3644
|
+
* ```tsx
|
|
3645
|
+
* <Menu aria-label="Edit">
|
|
3646
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3647
|
+
* <MenuItem id="copy">Copy</MenuItem>
|
|
3648
|
+
* <MenuItem id="paste">Paste</MenuItem>
|
|
3649
|
+
* </Menu>
|
|
3650
|
+
* ```
|
|
3651
|
+
*/
|
|
3652
|
+
interface MenuProps<T extends object = object> extends AriaMenuProps<T> {
|
|
3653
|
+
/**
|
|
3654
|
+
* Color scheme — standard (surface-based) or vibrant (tertiary-based).
|
|
3655
|
+
* Vibrant is more prominent and should be used sparingly.
|
|
3656
|
+
* @default 'standard'
|
|
3657
|
+
*/
|
|
3658
|
+
colorScheme?: MenuColorScheme;
|
|
3659
|
+
/**
|
|
3660
|
+
* Visual style — baseline (4dp corners) or vertical (16dp corners, expressive).
|
|
3661
|
+
* @default 'baseline'
|
|
3662
|
+
*/
|
|
3663
|
+
menuStyle?: MenuStyle;
|
|
3664
|
+
/**
|
|
3665
|
+
* Density level controlling item height (web only).
|
|
3666
|
+
* 0 = 48dp, -1 = 44dp, -2 = 40dp, -3 = 36dp.
|
|
3667
|
+
* @default 0
|
|
3668
|
+
*/
|
|
3669
|
+
density?: MenuDensity;
|
|
3670
|
+
/** Additional CSS classes merged onto the menu container element. */
|
|
3671
|
+
className?: string;
|
|
3672
|
+
/**
|
|
3673
|
+
* Disable ripple on all menu items.
|
|
3674
|
+
* @default false
|
|
3675
|
+
*/
|
|
3676
|
+
disableRipple?: boolean;
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3679
|
+
* Props for the `MenuItem` component (styled Layer 3).
|
|
3680
|
+
*
|
|
3681
|
+
* A single interactive item within a Menu. Supports leading/trailing icons,
|
|
3682
|
+
* keyboard shortcut labels, supporting text (description), and a badge slot.
|
|
3683
|
+
*
|
|
3684
|
+
* @example
|
|
3685
|
+
* ```tsx
|
|
3686
|
+
* // With leading icon and keyboard shortcut
|
|
3687
|
+
* <MenuItem id="copy" leadingIcon={<CopyIcon />} trailingText="⌘C">
|
|
3688
|
+
* Copy
|
|
3689
|
+
* </MenuItem>
|
|
3690
|
+
*
|
|
3691
|
+
* // With description
|
|
3692
|
+
* <MenuItem id="export" description="Export to various formats">
|
|
3693
|
+
* Export
|
|
3694
|
+
* </MenuItem>
|
|
3695
|
+
*
|
|
3696
|
+
* // Disabled
|
|
3697
|
+
* <MenuItem id="paste" isDisabled>Paste</MenuItem>
|
|
3698
|
+
* ```
|
|
3699
|
+
*/
|
|
3700
|
+
interface MenuItemProps extends MenuItemProps$1 {
|
|
3701
|
+
/** Item label content. */
|
|
3702
|
+
children?: ReactNode;
|
|
3703
|
+
/**
|
|
3704
|
+
* Optional leading icon element (24×24dp).
|
|
3705
|
+
* Rendered with `text-on-surface-variant`.
|
|
3706
|
+
*/
|
|
3707
|
+
leadingIcon?: ReactNode;
|
|
3708
|
+
/**
|
|
3709
|
+
* Optional trailing icon element (24×24dp).
|
|
3710
|
+
* Rendered with `text-on-surface-variant`.
|
|
3711
|
+
* Mutually exclusive with `trailingText`.
|
|
3712
|
+
*/
|
|
3713
|
+
trailingIcon?: ReactNode;
|
|
3714
|
+
/**
|
|
3715
|
+
* Optional keyboard-shortcut label at the trailing end (e.g. `"⌘C"`, `"Ctrl+V"`).
|
|
3716
|
+
* Screen readers announce this via `aria-keyshortcuts`.
|
|
3717
|
+
* Mutually exclusive with `trailingIcon`.
|
|
3718
|
+
*/
|
|
3719
|
+
trailingText?: string;
|
|
3720
|
+
/**
|
|
3721
|
+
* Optional supporting text (description) rendered below the label.
|
|
3722
|
+
* Uses `text-body-medium text-on-surface-variant`.
|
|
3723
|
+
* When present, item height becomes auto (multi-line).
|
|
3724
|
+
*
|
|
3725
|
+
* @see https://m3.material.io/components/menus/specs - Anatomy item 8
|
|
3726
|
+
*/
|
|
3727
|
+
description?: ReactNode;
|
|
3728
|
+
/**
|
|
3729
|
+
* Optional badge element rendered between the label and trailing content.
|
|
3730
|
+
*
|
|
3731
|
+
* @see https://m3.material.io/components/menus/specs - Anatomy item 5
|
|
3732
|
+
*/
|
|
3733
|
+
badge?: ReactNode;
|
|
3734
|
+
/** Additional CSS classes merged onto the item element. */
|
|
3735
|
+
className?: string;
|
|
3736
|
+
/**
|
|
3737
|
+
* Disable the ripple effect on this specific item.
|
|
3738
|
+
* @default false
|
|
3739
|
+
*/
|
|
3740
|
+
disableRipple?: boolean;
|
|
3741
|
+
}
|
|
3742
|
+
/**
|
|
3743
|
+
* Props for the `MenuSection` component (styled Layer 3).
|
|
3744
|
+
*
|
|
3745
|
+
* Groups related `MenuItem` elements with an optional section header and
|
|
3746
|
+
* an optional top divider.
|
|
3747
|
+
*
|
|
3748
|
+
* @example
|
|
3749
|
+
* ```tsx
|
|
3750
|
+
* <MenuSection header="Clipboard" showDivider>
|
|
3751
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3752
|
+
* <MenuItem id="copy">Copy</MenuItem>
|
|
3753
|
+
* </MenuSection>
|
|
3754
|
+
* ```
|
|
3755
|
+
*/
|
|
3756
|
+
/**
|
|
3757
|
+
* Base props shared by both `MenuSection` variants.
|
|
3758
|
+
*/
|
|
3759
|
+
interface MenuSectionBaseProps {
|
|
3760
|
+
/** Section content — typically `MenuItem` elements. */
|
|
3761
|
+
children: ReactNode;
|
|
3762
|
+
/**
|
|
3763
|
+
* When `true`, renders a horizontal divider above the section.
|
|
3764
|
+
* @default false
|
|
3765
|
+
*/
|
|
3766
|
+
showDivider?: boolean;
|
|
3767
|
+
/** Additional CSS classes. */
|
|
3768
|
+
className?: string;
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* Props for the `MenuSection` component (styled Layer 3).
|
|
3772
|
+
*
|
|
3773
|
+
* Either `header` or `aria-label` must be provided so the section has an
|
|
3774
|
+
* accessible name, as required by WCAG 2.1 (ARIA `group` role).
|
|
3775
|
+
*
|
|
3776
|
+
* @example
|
|
3777
|
+
* ```tsx
|
|
3778
|
+
* <MenuSection header="Clipboard" showDivider>
|
|
3779
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3780
|
+
* <MenuItem id="copy">Copy</MenuItem>
|
|
3781
|
+
* </MenuSection>
|
|
3782
|
+
* ```
|
|
3783
|
+
*/
|
|
3784
|
+
type MenuSectionProps = (MenuSectionBaseProps & {
|
|
3785
|
+
/**
|
|
3786
|
+
* Section header label (rendered visually and used as the accessible name).
|
|
3787
|
+
* Uses `text-title-small text-on-surface-variant`.
|
|
3788
|
+
*/
|
|
3789
|
+
header: string;
|
|
3790
|
+
"aria-label"?: string;
|
|
3791
|
+
}) | (MenuSectionBaseProps & {
|
|
3792
|
+
header?: string;
|
|
3793
|
+
/**
|
|
3794
|
+
* Accessible label for the section. Required when `header` is not provided.
|
|
3795
|
+
*/
|
|
3796
|
+
"aria-label": string;
|
|
3797
|
+
});
|
|
3798
|
+
/**
|
|
3799
|
+
* Props for the standalone `MenuDivider` component.
|
|
3800
|
+
*
|
|
3801
|
+
* Renders a semantic `role="separator"` with `border-outline-variant` styling.
|
|
3802
|
+
* 8dp top/bottom padding per MD3 spec.
|
|
3803
|
+
*
|
|
3804
|
+
* @example
|
|
3805
|
+
* ```tsx
|
|
3806
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3807
|
+
* <MenuDivider />
|
|
3808
|
+
* <MenuItem id="select-all">Select all</MenuItem>
|
|
3809
|
+
* ```
|
|
3810
|
+
*/
|
|
3811
|
+
interface MenuDividerProps {
|
|
3812
|
+
/** Additional CSS classes merged onto the separator element. */
|
|
3813
|
+
className?: string;
|
|
3814
|
+
}
|
|
3815
|
+
/**
|
|
3816
|
+
* Props for the headless `HeadlessMenuTrigger` primitive (Layer 2).
|
|
3817
|
+
*/
|
|
3818
|
+
interface HeadlessMenuTriggerProps extends AriaMenuTriggerProps {
|
|
3819
|
+
children: ReactNode;
|
|
3820
|
+
placement?: MenuTriggerProps["placement"];
|
|
3821
|
+
shouldFlip?: boolean;
|
|
3822
|
+
}
|
|
3823
|
+
/**
|
|
3824
|
+
* Props for the headless `HeadlessMenu` primitive (Layer 2).
|
|
3825
|
+
*/
|
|
3826
|
+
interface HeadlessMenuProps<T extends object = object> extends AriaMenuProps<T> {
|
|
3827
|
+
className?: string;
|
|
3828
|
+
}
|
|
3829
|
+
/**
|
|
3830
|
+
* Props for the headless `HeadlessMenuItem` primitive (Layer 2).
|
|
3831
|
+
*
|
|
3832
|
+
* `className` accepts either a static string or a render-prop function so
|
|
3833
|
+
* MD3 state-dependent styles (selection, disabled) can be applied directly
|
|
3834
|
+
* to the `<li role="menuitem">` element via RAC's render-prop mechanism.
|
|
3835
|
+
*/
|
|
3836
|
+
type HeadlessMenuItemProps = MenuItemProps$1;
|
|
3837
|
+
/**
|
|
3838
|
+
* Props for the headless `HeadlessMenuSection` primitive (Layer 2).
|
|
3839
|
+
*
|
|
3840
|
+
* The section header is handled at Layer 3 (`MenuSection`) using RAC's
|
|
3841
|
+
* `Header` component. At Layer 2, only `aria-label` is used for accessibility.
|
|
3842
|
+
*/
|
|
3843
|
+
interface HeadlessMenuSectionProps {
|
|
3844
|
+
children: ReactNode;
|
|
3845
|
+
className?: string;
|
|
3846
|
+
"aria-label"?: string;
|
|
3847
|
+
}
|
|
3848
|
+
/**
|
|
3849
|
+
* Context value shared between the Menu and its item descendants.
|
|
3850
|
+
* @internal
|
|
3851
|
+
*/
|
|
3852
|
+
interface MenuContextValue {
|
|
3853
|
+
/** Close the menu overlay. */
|
|
3854
|
+
close: () => void;
|
|
3855
|
+
/** Whether ripple is disabled for all items. */
|
|
3856
|
+
disableRipple: boolean;
|
|
3857
|
+
/** Color scheme — standard or vibrant. */
|
|
3858
|
+
colorScheme: MenuColorScheme;
|
|
3859
|
+
/** Visual style — baseline or vertical. */
|
|
3860
|
+
menuStyle: MenuStyle;
|
|
3861
|
+
/** Density level controlling item height. */
|
|
3862
|
+
density: MenuDensity;
|
|
3863
|
+
/** Currently selected keys (for selection menus). */
|
|
3864
|
+
selectedKeys?: Iterable<Key$2>;
|
|
3865
|
+
/** Current selection mode. */
|
|
3866
|
+
selectionMode?: SelectionMode;
|
|
3867
|
+
}
|
|
3868
|
+
|
|
3869
|
+
/**
|
|
3870
|
+
* MD3 styled Menu component (Layer 3).
|
|
3871
|
+
*
|
|
3872
|
+
* Renders a list of `MenuItem`, `MenuSection`, or `MenuDivider` children.
|
|
3873
|
+
* Intended to be used as `MenuTrigger.Menu` (nested inside a `MenuTrigger`).
|
|
3874
|
+
*
|
|
3875
|
+
* @example
|
|
3876
|
+
* ```tsx
|
|
3877
|
+
* <MenuTrigger>
|
|
3878
|
+
* <Button>Open</Button>
|
|
3879
|
+
* <Menu aria-label="Actions">
|
|
3880
|
+
* <MenuItem id="copy">Copy</MenuItem>
|
|
3881
|
+
* <MenuItem id="paste">Paste</MenuItem>
|
|
3882
|
+
* </Menu>
|
|
3883
|
+
* </MenuTrigger>
|
|
3884
|
+
* ```
|
|
3885
|
+
*/
|
|
3886
|
+
declare const Menu: React$1.ForwardRefExoticComponent<MenuProps<object> & React$1.RefAttributes<HTMLElement>>;
|
|
3887
|
+
/**
|
|
3888
|
+
* MD3 styled MenuTrigger component (Layer 3).
|
|
3889
|
+
*
|
|
3890
|
+
* Wraps a trigger element and a `Menu` to create a dropdown.
|
|
3891
|
+
* Attach `MenuTrigger.Menu` to specify the menu content, which gives IDE
|
|
3892
|
+
* autocompletion and makes the parent/child relationship explicit.
|
|
3893
|
+
*
|
|
3894
|
+
* @example
|
|
3895
|
+
* ```tsx
|
|
3896
|
+
* <MenuTrigger>
|
|
3897
|
+
* <button type="button">Open Menu</button>
|
|
3898
|
+
* <MenuTrigger.Menu aria-label="Actions">
|
|
3899
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3900
|
+
* </MenuTrigger.Menu>
|
|
3901
|
+
* </MenuTrigger>
|
|
3902
|
+
* ```
|
|
3903
|
+
*/
|
|
3904
|
+
declare function MenuTrigger({ children, placement, shouldFlip, ...rest }: MenuTriggerProps): JSX.Element;
|
|
3905
|
+
declare namespace MenuTrigger {
|
|
3906
|
+
var Menu: React$1.ForwardRefExoticComponent<MenuProps<object> & React$1.RefAttributes<HTMLElement>>;
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3909
|
+
/**
|
|
3910
|
+
* MD3 styled MenuItem component (Layer 3).
|
|
3911
|
+
*
|
|
3912
|
+
* All MD3 styles (selection colors, typography, density height) are applied
|
|
3913
|
+
* directly to the `<li role="menuitem">` element via RAC's render-prop className,
|
|
3914
|
+
* ensuring tests and assistive technologies see the correct classes on the
|
|
3915
|
+
* semantically meaningful element.
|
|
3916
|
+
*
|
|
3917
|
+
* @example
|
|
3918
|
+
* ```tsx
|
|
3919
|
+
* <MenuItem id="copy" leadingIcon={<CopyIcon />} trailingText="⌘C">
|
|
3920
|
+
* Copy
|
|
3921
|
+
* </MenuItem>
|
|
3922
|
+
* ```
|
|
3923
|
+
*/
|
|
3924
|
+
declare const MenuItem: React$1.ForwardRefExoticComponent<MenuItemProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
3925
|
+
|
|
3926
|
+
/**
|
|
3927
|
+
* MD3 styled MenuSection component (Layer 3).
|
|
3928
|
+
*
|
|
3929
|
+
* Groups related `MenuItem` elements with an optional section header and an
|
|
3930
|
+
* optional top divider.
|
|
3931
|
+
*
|
|
3932
|
+
* **Implementation note**: The divider is rendered as a SIBLING BEFORE the
|
|
3933
|
+
* `RACMenuSection`, NOT inside it. RAC's `Section`/`MenuSection` only accepts
|
|
3934
|
+
* `Header` and `MenuItem` children — placing a `Separator` inside the section
|
|
3935
|
+
* would create invalid HTML (`<li>` inside `<li role="group">`) and break RAC's
|
|
3936
|
+
* collection rendering.
|
|
3937
|
+
*
|
|
3938
|
+
* @example
|
|
3939
|
+
* ```tsx
|
|
3940
|
+
* <MenuSection header="Clipboard" showDivider aria-label="Clipboard">
|
|
3941
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3942
|
+
* <MenuItem id="copy">Copy</MenuItem>
|
|
3943
|
+
* </MenuSection>
|
|
3944
|
+
* ```
|
|
3945
|
+
*/
|
|
3946
|
+
declare function MenuSection({ children, header, showDivider, className, "aria-label": ariaLabel, }: MenuSectionProps): JSX.Element;
|
|
3947
|
+
|
|
3948
|
+
/**
|
|
3949
|
+
* MD3 styled MenuDivider component (Layer 3).
|
|
3950
|
+
*
|
|
3951
|
+
* Renders a horizontal `role="separator"` with `border-outline-variant` styling.
|
|
3952
|
+
* 8dp top/bottom padding (`my-2`) per MD3 spec.
|
|
3953
|
+
*
|
|
3954
|
+
* @example
|
|
3955
|
+
* ```tsx
|
|
3956
|
+
* <MenuItem id="cut">Cut</MenuItem>
|
|
3957
|
+
* <MenuDivider />
|
|
3958
|
+
* <MenuItem id="select-all">Select all</MenuItem>
|
|
3959
|
+
* ```
|
|
3960
|
+
*/
|
|
3961
|
+
declare function MenuDivider({ className }: MenuDividerProps): JSX.Element;
|
|
3962
|
+
|
|
3963
|
+
declare const MenuContext: React$1.Context<MenuContextValue | null>;
|
|
3964
|
+
declare function useMenuContext(): MenuContextValue | null;
|
|
3965
|
+
/**
|
|
3966
|
+
* Layer 2 headless primitive.
|
|
3967
|
+
*
|
|
3968
|
+
* Uses `RACMenuTrigger` (Layer 1) as the foundation. `RACMenuTrigger` manages:
|
|
3969
|
+
* - `aria-haspopup="menu"` and `aria-expanded` on the trigger (dynamic)
|
|
3970
|
+
* - Open/close state and keyboard opening (ArrowDown → focus first item)
|
|
3971
|
+
* - `OverlayTriggerStateContext` so the Popover can close on Escape / outside click
|
|
3972
|
+
* - `PopoverGroupContext` so the Popover's `ariaHideOutside` does NOT hide the
|
|
3973
|
+
* trigger button while the menu is open
|
|
3974
|
+
*
|
|
3975
|
+
* `TriggerBridge` adapts the context-injected button props to work with any
|
|
3976
|
+
* plain HTML element (native `<button>`, custom components, etc.).
|
|
3977
|
+
*/
|
|
3978
|
+
declare function HeadlessMenuTrigger({ children, placement, shouldFlip, ...rest }: HeadlessMenuTriggerProps): JSX.Element;
|
|
3979
|
+
declare namespace HeadlessMenuTrigger {
|
|
3980
|
+
var Menu: typeof HeadlessMenu;
|
|
3981
|
+
}
|
|
3982
|
+
/**
|
|
3983
|
+
* Layer 2 headless primitive wrapping RAC `Menu`.
|
|
3984
|
+
*
|
|
3985
|
+
* When nested inside `HeadlessMenuTrigger`, RAC automatically threads the
|
|
3986
|
+
* `MenuContext` (containing `autoFocus`, `onClose`, `aria-labelledby`, etc.)
|
|
3987
|
+
* from `RACMenuTrigger` through to `RACMenu`. No manual prop threading needed.
|
|
3988
|
+
*
|
|
3989
|
+
* **aria-label / aria-labelledby precedence fix**: `RACSubmenuTrigger` sets
|
|
3990
|
+
* `aria-labelledby` in `MenuContext` pointing to the trigger item. In ARIA
|
|
3991
|
+
* spec, `aria-labelledby` always overrides `aria-label`. So when the consumer
|
|
3992
|
+
* provides an explicit `aria-label`, we suppress the context's
|
|
3993
|
+
* `aria-labelledby` by passing `aria-labelledby={undefined}`, which takes
|
|
3994
|
+
* precedence over the `MenuContext` value in `useContextProps`'s `mergeProps`
|
|
3995
|
+
* call (last argument wins). This ensures `aria-label="My Submenu"` is
|
|
3996
|
+
* respected as the accessible name.
|
|
3997
|
+
*/
|
|
3998
|
+
declare function HeadlessMenu<T extends object = object>({ className, children, "aria-label": ariaLabel, ...props }: HeadlessMenuProps<T>): JSX.Element;
|
|
3999
|
+
/**
|
|
4000
|
+
* Layer 2 headless primitive wrapping RAC `MenuItem`.
|
|
4001
|
+
*
|
|
4002
|
+
* Accepts `className` as either a static string or a render-prop function
|
|
4003
|
+
* `(renderProps: MenuItemRenderProps) => string`, forwarding it directly to
|
|
4004
|
+
* `RACMenuItem` so MD3 selection-state styles are applied on the `<li>` element
|
|
4005
|
+
* (the element with `role="menuitem"`).
|
|
4006
|
+
*/
|
|
4007
|
+
declare const HeadlessMenuItem: React$1.ForwardRefExoticComponent<HeadlessMenuItemProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
4008
|
+
declare function HeadlessMenuSection({ children, "aria-label": ariaLabel, className, }: HeadlessMenuSectionProps): JSX.Element;
|
|
4009
|
+
declare function HeadlessMenuDivider({ className, ...props }: SeparatorProps & {
|
|
4010
|
+
className?: string;
|
|
4011
|
+
}): JSX.Element;
|
|
4012
|
+
|
|
4013
|
+
/**
|
|
4014
|
+
* Material Design 3 Menu container variants (CVA).
|
|
4015
|
+
*
|
|
4016
|
+
* Elevation: `shadow-elevation-2` (both styles)
|
|
4017
|
+
* Width: min 112dp / max 280dp per MD3 spec
|
|
4018
|
+
*
|
|
4019
|
+
* Shape per menuStyle:
|
|
4020
|
+
* - baseline: `rounded-xs` (4dp extra-small)
|
|
4021
|
+
* - vertical: `rounded-lg` (16dp large)
|
|
4022
|
+
*
|
|
4023
|
+
* Background per colorScheme + menuStyle:
|
|
4024
|
+
* - baseline + standard: `bg-surface-container`
|
|
4025
|
+
* - vertical + standard: `bg-surface-container-low`
|
|
4026
|
+
* - vertical + vibrant: `bg-tertiary-container`
|
|
4027
|
+
*
|
|
4028
|
+
* @see https://m3.material.io/components/menus/specs
|
|
4029
|
+
*/
|
|
4030
|
+
declare const menuContainerVariants: (props?: ({
|
|
4031
|
+
colorScheme?: "standard" | "vibrant" | null | undefined;
|
|
4032
|
+
menuStyle?: "vertical" | "baseline" | null | undefined;
|
|
4033
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
4034
|
+
type MenuContainerVariants = VariantProps<typeof menuContainerVariants>;
|
|
4035
|
+
|
|
4036
|
+
/**
|
|
4037
|
+
* Screen position of the Snackbar.
|
|
4038
|
+
*
|
|
4039
|
+
* MD3 default is `bottom-center`. All six positions are supported for
|
|
4040
|
+
* application-specific layout needs (e.g. presence of a FAB or navigation bar).
|
|
4041
|
+
*
|
|
4042
|
+
* @default 'bottom-center'
|
|
4043
|
+
*/
|
|
4044
|
+
type SnackbarPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
4045
|
+
/**
|
|
4046
|
+
* Severity level of the Snackbar message.
|
|
4047
|
+
*
|
|
4048
|
+
* Controls the ARIA live region role:
|
|
4049
|
+
* - `default` → `role="status" aria-live="polite"` (non-urgent information)
|
|
4050
|
+
* - `error` → `role="alert" aria-live="assertive"` (urgent error messages)
|
|
4051
|
+
*
|
|
4052
|
+
* @default 'default'
|
|
4053
|
+
*/
|
|
4054
|
+
type SnackbarSeverity = "default" | "error";
|
|
4055
|
+
/**
|
|
4056
|
+
* Internal animation state machine for the Snackbar.
|
|
4057
|
+
*
|
|
4058
|
+
* - `entering` → zoom-in start: scale-75 + opacity-0 (no duration, paints before transition)
|
|
4059
|
+
* - `visible` → scale-100 + opacity-100 (medium1 / standard-decelerate = 250ms)
|
|
4060
|
+
* - `exiting` → scale-75 + opacity-0 (short4 / standard-accelerate = 200ms)
|
|
4061
|
+
* - `exited` → removed from DOM / stack updated
|
|
4062
|
+
*/
|
|
4063
|
+
type SnackbarAnimationState = "entering" | "visible" | "exiting" | "exited";
|
|
4064
|
+
/**
|
|
4065
|
+
* Configuration for the single text action button on the Snackbar.
|
|
4066
|
+
*
|
|
4067
|
+
* @example
|
|
4068
|
+
* ```tsx
|
|
4069
|
+
* action={{ label: "Undo", onAction: () => handleUndo() }}
|
|
4070
|
+
* ```
|
|
4071
|
+
*/
|
|
4072
|
+
interface SnackbarAction {
|
|
4073
|
+
/** Visible label for the action button. Also used as the accessible name. */
|
|
4074
|
+
label: string;
|
|
4075
|
+
/** Callback fired when the action button is pressed. */
|
|
4076
|
+
onAction: () => void;
|
|
4077
|
+
}
|
|
4078
|
+
/**
|
|
4079
|
+
* Props for the MD3 Styled `Snackbar` component (Layer 3).
|
|
4080
|
+
*
|
|
4081
|
+
* Renders one of four MD3 content configurations:
|
|
4082
|
+
* 1. Single-line message only
|
|
4083
|
+
* 2. Two-line (message + supportingText)
|
|
4084
|
+
* 3. Single-line with action button
|
|
4085
|
+
* 4. Single-line with close icon
|
|
4086
|
+
*
|
|
4087
|
+
* @example
|
|
4088
|
+
* ```tsx
|
|
4089
|
+
* // Single-line
|
|
4090
|
+
* <Snackbar message="File deleted" />
|
|
4091
|
+
*
|
|
4092
|
+
* // With action
|
|
4093
|
+
* <Snackbar message="File deleted" action={{ label: "Undo", onAction: handleUndo }} />
|
|
4094
|
+
*
|
|
4095
|
+
* // With close icon
|
|
4096
|
+
* <Snackbar message="Connection lost" showClose onClose={() => {}} />
|
|
4097
|
+
*
|
|
4098
|
+
* // Error severity (assertive announcement)
|
|
4099
|
+
* <Snackbar message="Upload failed" severity="error" />
|
|
4100
|
+
* ```
|
|
4101
|
+
*/
|
|
4102
|
+
interface SnackbarProps {
|
|
4103
|
+
/**
|
|
4104
|
+
* Primary message text shown on the Snackbar.
|
|
4105
|
+
* Styled with `text-body-medium`.
|
|
4106
|
+
*/
|
|
4107
|
+
message: string;
|
|
4108
|
+
/**
|
|
4109
|
+
* Optional supporting text shown below the message (two-line configuration).
|
|
4110
|
+
* Styled with `text-body-medium`.
|
|
4111
|
+
*/
|
|
4112
|
+
supportingText?: string;
|
|
4113
|
+
/**
|
|
4114
|
+
* Optional text action button configuration.
|
|
4115
|
+
* Action button is styled as `Button variant="text"` with `inverse-primary` color.
|
|
4116
|
+
*/
|
|
4117
|
+
action?: SnackbarAction;
|
|
4118
|
+
/**
|
|
4119
|
+
* When `true`, renders a close icon button at the trailing end.
|
|
4120
|
+
* @default false
|
|
4121
|
+
*/
|
|
4122
|
+
showClose?: boolean;
|
|
4123
|
+
/**
|
|
4124
|
+
* Auto-dismiss duration in milliseconds. Set to `0` to disable auto-dismiss.
|
|
4125
|
+
* Timer pauses on pointer hover and keyboard focus.
|
|
4126
|
+
* @default 4000
|
|
4127
|
+
*/
|
|
4128
|
+
duration?: number;
|
|
4129
|
+
/**
|
|
4130
|
+
* Severity level — controls the ARIA live region role.
|
|
4131
|
+
* @default 'default'
|
|
4132
|
+
*/
|
|
4133
|
+
severity?: SnackbarSeverity;
|
|
4134
|
+
/**
|
|
4135
|
+
* Screen position of the Snackbar.
|
|
4136
|
+
* @default 'bottom-center'
|
|
4137
|
+
*/
|
|
4138
|
+
position?: SnackbarPosition;
|
|
4139
|
+
/**
|
|
4140
|
+
* Callback fired when the Snackbar finishes its exit animation and is removed.
|
|
4141
|
+
* Also fires when the close icon is pressed.
|
|
4142
|
+
*/
|
|
4143
|
+
onClose?: () => void;
|
|
4144
|
+
/**
|
|
4145
|
+
* Additional CSS classes merged onto the Snackbar container.
|
|
4146
|
+
*/
|
|
4147
|
+
className?: string;
|
|
4148
|
+
}
|
|
4149
|
+
/**
|
|
4150
|
+
* Props for the headless `SnackbarHeadless` primitive (Layer 2).
|
|
4151
|
+
*
|
|
4152
|
+
* Provides all Snackbar behavior (ARIA live region, auto-dismiss timer with
|
|
4153
|
+
* pause/resume, animation state machine) without any visual styling.
|
|
4154
|
+
*
|
|
4155
|
+
* @example
|
|
4156
|
+
* ```tsx
|
|
4157
|
+
* <SnackbarHeadless message="Hello" duration={3000} onClose={dismiss}>
|
|
4158
|
+
* {({ animationState }) => (
|
|
4159
|
+
* <div className={animationState === 'visible' ? 'opacity-100' : 'opacity-0'}>
|
|
4160
|
+
* Hello
|
|
4161
|
+
* </div>
|
|
4162
|
+
* )}
|
|
4163
|
+
* </SnackbarHeadless>
|
|
4164
|
+
* ```
|
|
4165
|
+
*/
|
|
4166
|
+
interface SnackbarHeadlessProps extends Omit<SnackbarProps, "className"> {
|
|
4167
|
+
/**
|
|
4168
|
+
* Children as a render function receiving the current animation state and
|
|
4169
|
+
* an imperative `onClose` callback to trigger the exit animation, or
|
|
4170
|
+
* static ReactNode content.
|
|
4171
|
+
*/
|
|
4172
|
+
children?: ReactNode | ((state: {
|
|
4173
|
+
animationState: SnackbarAnimationState;
|
|
4174
|
+
onClose: () => void;
|
|
4175
|
+
}) => ReactNode);
|
|
4176
|
+
/**
|
|
4177
|
+
* Additional CSS classes passed to the container element (base/structural classes).
|
|
4178
|
+
*/
|
|
4179
|
+
className?: string;
|
|
4180
|
+
/**
|
|
4181
|
+
* Optional callback that returns additional CSS classes based on the current
|
|
4182
|
+
* animation state and position. Used by the styled `Snackbar` layer to inject
|
|
4183
|
+
* CVA animation + position variant classes onto the headless container div.
|
|
4184
|
+
*
|
|
4185
|
+
* @example
|
|
4186
|
+
* ```tsx
|
|
4187
|
+
* getAnimationClassName={(state, pos) =>
|
|
4188
|
+
* snackbarAnimationVariants({ animationState: state, enterDirection: getEnterDirection(pos) })
|
|
4189
|
+
* }
|
|
4190
|
+
* ```
|
|
4191
|
+
*/
|
|
4192
|
+
getAnimationClassName?: (state: SnackbarAnimationState, position: SnackbarPosition) => string;
|
|
4193
|
+
}
|
|
4194
|
+
/**
|
|
4195
|
+
* Internal queue entry type used by `SnackbarProvider`.
|
|
4196
|
+
* Extends `SnackbarProps` with a unique `id` for queue management.
|
|
4197
|
+
*/
|
|
4198
|
+
interface SnackbarItem extends SnackbarProps {
|
|
4199
|
+
/** Unique identifier for this Snackbar instance. */
|
|
4200
|
+
id: string;
|
|
4201
|
+
}
|
|
4202
|
+
/**
|
|
4203
|
+
* Value exposed by `SnackbarContext` and consumed via `useSnackbar`.
|
|
4204
|
+
*
|
|
4205
|
+
* @example
|
|
4206
|
+
* ```tsx
|
|
4207
|
+
* const { showSnackbar } = useSnackbar();
|
|
4208
|
+
* showSnackbar({ message: "Saved successfully" });
|
|
4209
|
+
* ```
|
|
4210
|
+
*/
|
|
4211
|
+
interface SnackbarContextValue {
|
|
4212
|
+
/**
|
|
4213
|
+
* Show a new Snackbar. Returns the unique id assigned to this item.
|
|
4214
|
+
* Multiple snackbars are displayed simultaneously in a vertical stack,
|
|
4215
|
+
* grouped by their `position` prop. Once the stack reaches `maxVisible`,
|
|
4216
|
+
* additional items wait until existing ones are dismissed.
|
|
4217
|
+
*/
|
|
4218
|
+
showSnackbar: (options: SnackbarProps) => string;
|
|
4219
|
+
/**
|
|
4220
|
+
* Imperatively dismiss the oldest currently displayed Snackbar (triggers exit animation).
|
|
4221
|
+
*/
|
|
4222
|
+
closeSnackbar: () => void;
|
|
4223
|
+
}
|
|
4224
|
+
/**
|
|
4225
|
+
* Props for `SnackbarProvider`.
|
|
4226
|
+
*
|
|
4227
|
+
* Wrap your application (or Storybook decorator) with this provider to enable
|
|
4228
|
+
* the Snackbar stack and portal.
|
|
4229
|
+
*
|
|
4230
|
+
* @example
|
|
4231
|
+
* ```tsx
|
|
4232
|
+
* <SnackbarProvider>
|
|
4233
|
+
* <App />
|
|
4234
|
+
* </SnackbarProvider>
|
|
4235
|
+
*
|
|
4236
|
+
* // Limit visible snackbars per position group
|
|
4237
|
+
* <SnackbarProvider maxVisible={3}>
|
|
4238
|
+
* <App />
|
|
4239
|
+
* </SnackbarProvider>
|
|
4240
|
+
* ```
|
|
4241
|
+
*/
|
|
4242
|
+
interface SnackbarProviderProps {
|
|
4243
|
+
/** Application children. */
|
|
4244
|
+
children: ReactNode;
|
|
4245
|
+
/**
|
|
4246
|
+
* Maximum number of snackbars visible at once per position group.
|
|
4247
|
+
* Additional snackbars beyond this cap are queued and shown as existing
|
|
4248
|
+
* ones are dismissed.
|
|
4249
|
+
* @default 5
|
|
4250
|
+
*/
|
|
4251
|
+
maxVisible?: number;
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
/**
|
|
4255
|
+
* `Snackbar` — Layer 3 MD3 Styled Component.
|
|
4256
|
+
*
|
|
4257
|
+
* Renders one of four MD3 Snackbar content configurations:
|
|
4258
|
+
* 1. Single-line message only
|
|
4259
|
+
* 2. Two-line message + `supportingText`
|
|
4260
|
+
* 3. Single-line with text `action` button (styled `Button variant="text"` with
|
|
4261
|
+
* `inverse-primary` color per MD3 spec)
|
|
4262
|
+
* 4. Single-line with close icon (or combined with action)
|
|
4263
|
+
*
|
|
4264
|
+
* Uses `SnackbarHeadless` for all behavioral concerns (ARIA live region,
|
|
4265
|
+
* auto-dismiss timer with pause/resume, animation state machine) and CVA
|
|
4266
|
+
* variants for MD3-compliant visual styling.
|
|
4267
|
+
*
|
|
4268
|
+
* For typical app usage, render inside `SnackbarProvider` and trigger via
|
|
4269
|
+
* the `useSnackbar` hook. For declarative/test usage, it can be rendered
|
|
4270
|
+
* standalone.
|
|
4271
|
+
*
|
|
4272
|
+
* @example
|
|
4273
|
+
* ```tsx
|
|
4274
|
+
* // Imperative via hook (typical)
|
|
4275
|
+
* const { showSnackbar } = useSnackbar();
|
|
4276
|
+
* showSnackbar({ message: "File deleted", action: { label: "Undo", onAction: handleUndo } });
|
|
4277
|
+
*
|
|
4278
|
+
* // Declarative standalone
|
|
4279
|
+
* <SnackbarProvider>
|
|
4280
|
+
* <Snackbar message="Saved" severity="default" showClose onClose={() => {}} />
|
|
4281
|
+
* </SnackbarProvider>
|
|
4282
|
+
* ```
|
|
4283
|
+
*/
|
|
4284
|
+
declare const Snackbar: React$1.ForwardRefExoticComponent<SnackbarProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
4285
|
+
|
|
4286
|
+
/**
|
|
4287
|
+
* SnackbarHeadless — Layer 2 headless primitive.
|
|
4288
|
+
*
|
|
4289
|
+
* Handles all Snackbar behavior without opinionated visual styling:
|
|
4290
|
+
* - ARIA live region with correct `role`/`aria-live` pairing per severity
|
|
4291
|
+
* - Auto-dismiss timer with configurable `duration`
|
|
4292
|
+
* - Timer pause/resume on pointer hover (`mouseenter`/`mouseleave`) and
|
|
4293
|
+
* keyboard focus (`focusin`/`focusout`)
|
|
4294
|
+
* - Animation state machine: `entering → visible → exiting → exited`
|
|
4295
|
+
* - Exposes `onClose` imperative trigger via render-prop for close icon/action
|
|
4296
|
+
* - Merges base `className` with animation-state-dependent classes via
|
|
4297
|
+
* the optional `getAnimationClassName` prop
|
|
4298
|
+
*
|
|
4299
|
+
* No React Aria hook covers Snackbar; ARIA live region patterns follow the
|
|
4300
|
+
* ARIA authoring practices specification for status/alert regions.
|
|
4301
|
+
*
|
|
4302
|
+
* @example
|
|
4303
|
+
* ```tsx
|
|
4304
|
+
* // With render-prop children (typical usage from styled layer)
|
|
4305
|
+
* <SnackbarHeadless
|
|
4306
|
+
* message="Saved"
|
|
4307
|
+
* duration={3000}
|
|
4308
|
+
* onClose={dismiss}
|
|
4309
|
+
* className={baseClasses}
|
|
4310
|
+
* getAnimationClassName={(state) => snackbarAnimationVariants({ animationState: state })}
|
|
4311
|
+
* >
|
|
4312
|
+
* {({ onClose }) => (
|
|
4313
|
+
* <>
|
|
4314
|
+
* <span>Saved</span>
|
|
4315
|
+
* <button onClick={onClose}>Dismiss</button>
|
|
4316
|
+
* </>
|
|
4317
|
+
* )}
|
|
4318
|
+
* </SnackbarHeadless>
|
|
4319
|
+
* ```
|
|
4320
|
+
*/
|
|
4321
|
+
declare const SnackbarHeadless: React$1.ForwardRefExoticComponent<SnackbarHeadlessProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
4322
|
+
|
|
4323
|
+
/**
|
|
4324
|
+
* React context for the Snackbar queue.
|
|
4325
|
+
* Consumed via the `useSnackbar` hook.
|
|
4326
|
+
*/
|
|
4327
|
+
declare const SnackbarContext: React$1.Context<SnackbarContextValue | null>;
|
|
4328
|
+
/**
|
|
4329
|
+
* `useSnackbar` — imperative API for triggering Snackbars.
|
|
4330
|
+
*
|
|
4331
|
+
* Must be called inside a component that is a descendant of `SnackbarProvider`.
|
|
4332
|
+
* Throws a descriptive error in development if used outside the provider.
|
|
4333
|
+
*
|
|
4334
|
+
* @example
|
|
4335
|
+
* ```tsx
|
|
4336
|
+
* const { showSnackbar } = useSnackbar();
|
|
4337
|
+
*
|
|
4338
|
+
* // Single-line
|
|
4339
|
+
* showSnackbar({ message: "File deleted" });
|
|
4340
|
+
*
|
|
4341
|
+
* // With action
|
|
4342
|
+
* showSnackbar({
|
|
4343
|
+
* message: "File deleted",
|
|
4344
|
+
* action: { label: "Undo", onAction: () => handleUndo() },
|
|
4345
|
+
* });
|
|
4346
|
+
*
|
|
4347
|
+
* // Error severity (assertive announcement)
|
|
4348
|
+
* showSnackbar({ message: "Upload failed", severity: "error" });
|
|
4349
|
+
* ```
|
|
4350
|
+
*/
|
|
4351
|
+
declare function useSnackbar(): SnackbarContextValue;
|
|
4352
|
+
/**
|
|
4353
|
+
* `SnackbarProvider` — context provider, queue manager, and portal host.
|
|
4354
|
+
*
|
|
4355
|
+
* Wrap your application (or Storybook preview) with this component to enable
|
|
4356
|
+
* the Snackbar stack and portal rendering.
|
|
4357
|
+
*
|
|
4358
|
+
* - Multiple `showSnackbar` calls are displayed simultaneously in a vertical
|
|
4359
|
+
* stack, grouped by their `position` prop.
|
|
4360
|
+
* - Each position group is rendered in its own fixed container via `createPortal`
|
|
4361
|
+
* into `document.body`.
|
|
4362
|
+
* - Bottom positions stack upward (newest at bottom); top positions stack
|
|
4363
|
+
* downward (newest at top).
|
|
4364
|
+
* - The `maxVisible` prop caps how many snackbars can be visible at once per
|
|
4365
|
+
* position group. Snackbars beyond the cap are queued and shown as existing
|
|
4366
|
+
* ones are dismissed.
|
|
4367
|
+
*
|
|
4368
|
+
* @example
|
|
4369
|
+
* ```tsx
|
|
4370
|
+
* // Application root
|
|
4371
|
+
* <SnackbarProvider>
|
|
4372
|
+
* <App />
|
|
4373
|
+
* </SnackbarProvider>
|
|
4374
|
+
*
|
|
4375
|
+
* // With custom cap (default is 5)
|
|
4376
|
+
* <SnackbarProvider maxVisible={3}>
|
|
4377
|
+
* <App />
|
|
4378
|
+
* </SnackbarProvider>
|
|
4379
|
+
*
|
|
4380
|
+
* // Storybook preview.tsx decorator
|
|
4381
|
+
* export const decorators = [
|
|
4382
|
+
* (Story) => (
|
|
4383
|
+
* <SnackbarProvider>
|
|
4384
|
+
* <Story />
|
|
4385
|
+
* </SnackbarProvider>
|
|
4386
|
+
* ),
|
|
4387
|
+
* ];
|
|
4388
|
+
* ```
|
|
4389
|
+
*/
|
|
4390
|
+
declare function SnackbarProvider({ children, maxVisible }: SnackbarProviderProps): JSX.Element;
|
|
4391
|
+
|
|
4392
|
+
/**
|
|
4393
|
+
* Structural variant of the MD3 Dialog.
|
|
4394
|
+
*
|
|
4395
|
+
* - `basic` — Floating dialog with headline, body, and action buttons.
|
|
4396
|
+
* Supports scale + fade entry animation. Closes on scrim click or Escape.
|
|
4397
|
+
* Max width 560dp per MD3 spec.
|
|
4398
|
+
*
|
|
4399
|
+
* - `fullscreen` — Full viewport overlay suited for mobile and complex forms.
|
|
4400
|
+
* Replaces headline with a top app bar row (close icon + confirm action).
|
|
4401
|
+
* Slide-up entry animation. Does NOT close on scrim click per MD3 spec.
|
|
4402
|
+
*
|
|
4403
|
+
* @default 'basic'
|
|
4404
|
+
*/
|
|
4405
|
+
type DialogVariant = "basic" | "fullscreen";
|
|
4406
|
+
/**
|
|
4407
|
+
* Internal animation state machine for the Dialog.
|
|
4408
|
+
*
|
|
4409
|
+
* - `entering` — initial mount state before transition fires
|
|
4410
|
+
* - `visible` — fully shown, entry animation complete
|
|
4411
|
+
* - `exiting` — exit animation in progress
|
|
4412
|
+
* - `exited` — removed from DOM
|
|
4413
|
+
*/
|
|
4414
|
+
type DialogAnimationState = "entering" | "visible" | "exiting" | "exited";
|
|
4415
|
+
/**
|
|
4416
|
+
* Internal context shared between `DialogHeadless` and its slot sub-components
|
|
4417
|
+
* (`DialogHeadline`, `DialogContent`, `DialogActions`).
|
|
4418
|
+
*
|
|
4419
|
+
* Coordinates auto-generated `id` values for `aria-labelledby` and
|
|
4420
|
+
* `aria-describedby`, exposes the close callback, and propagates the variant.
|
|
4421
|
+
*
|
|
4422
|
+
* @internal
|
|
4423
|
+
*/
|
|
4424
|
+
interface DialogContextValue {
|
|
4425
|
+
/** Stable id for the headline element — used as `aria-labelledby` on the dialog panel. */
|
|
4426
|
+
headlineId: string;
|
|
4427
|
+
/** Stable id for the content element — used as `aria-describedby` on the dialog panel. */
|
|
4428
|
+
contentId: string;
|
|
4429
|
+
/** Callback to programmatically close the dialog (triggers exit animation). */
|
|
4430
|
+
close: () => void;
|
|
4431
|
+
/** Current structural variant, propagated to sub-components for variant-specific rendering. */
|
|
4432
|
+
variant: DialogVariant;
|
|
4433
|
+
}
|
|
4434
|
+
/**
|
|
4435
|
+
* Props for the headless `DialogHeadless` primitive (Layer 2).
|
|
4436
|
+
*
|
|
4437
|
+
* Provides all Dialog behavior (ARIA roles, focus trap, scroll lock,
|
|
4438
|
+
* portal rendering, animation state machine, open/close state) without
|
|
4439
|
+
* any visual styling.
|
|
4440
|
+
*
|
|
4441
|
+
* @example
|
|
4442
|
+
* ```tsx
|
|
4443
|
+
* <DialogHeadless
|
|
4444
|
+
* variant="basic"
|
|
4445
|
+
* open={open}
|
|
4446
|
+
* onOpenChange={setOpen}
|
|
4447
|
+
* aria-label="Confirm action"
|
|
4448
|
+
* className="bg-surface-container-high rounded-xl shadow-elevation-3"
|
|
4449
|
+
* scrimClassName="fixed inset-0 z-40 bg-scrim opacity-32"
|
|
4450
|
+
* >
|
|
4451
|
+
* <DialogHeadline>Confirm deletion?</DialogHeadline>
|
|
4452
|
+
* <DialogContent>This action cannot be undone.</DialogContent>
|
|
4453
|
+
* <DialogActions>
|
|
4454
|
+
* <Button variant="text" onPress={() => setOpen(false)}>Cancel</Button>
|
|
4455
|
+
* <Button variant="filled" onPress={handleDelete}>Delete</Button>
|
|
4456
|
+
* </DialogActions>
|
|
4457
|
+
* </DialogHeadless>
|
|
4458
|
+
* ```
|
|
4459
|
+
*/
|
|
4460
|
+
interface DialogHeadlessProps {
|
|
4461
|
+
/**
|
|
4462
|
+
* Structural variant — controls animation, scrim dismissal, and DOM structure.
|
|
4463
|
+
* @default 'basic'
|
|
4464
|
+
*/
|
|
4465
|
+
variant?: DialogVariant;
|
|
4466
|
+
/**
|
|
4467
|
+
* Controlled open state. Pair with `onOpenChange`.
|
|
4468
|
+
*/
|
|
4469
|
+
open?: boolean;
|
|
4470
|
+
/**
|
|
4471
|
+
* Default open state for uncontrolled usage.
|
|
4472
|
+
* @default false
|
|
4473
|
+
*/
|
|
4474
|
+
defaultOpen?: boolean;
|
|
4475
|
+
/**
|
|
4476
|
+
* Called when the open state changes (e.g. Escape key, scrim click, close button).
|
|
4477
|
+
*/
|
|
4478
|
+
onOpenChange?: (open: boolean) => void;
|
|
4479
|
+
/**
|
|
4480
|
+
* Accessible label for the dialog. Used when no `DialogHeadline` is provided.
|
|
4481
|
+
* When `DialogHeadline` is present, `aria-labelledby` is preferred automatically.
|
|
4482
|
+
*/
|
|
4483
|
+
"aria-label"?: string;
|
|
4484
|
+
/**
|
|
4485
|
+
* Dialog slot content — typically `DialogHeadline`, `DialogContent`, `DialogActions`.
|
|
4486
|
+
*/
|
|
4487
|
+
children: ReactNode;
|
|
4488
|
+
/**
|
|
4489
|
+
* Additional CSS classes applied to the dialog panel element.
|
|
4490
|
+
*/
|
|
4491
|
+
className?: string;
|
|
4492
|
+
/**
|
|
4493
|
+
* Additional CSS classes applied to the scrim overlay element.
|
|
4494
|
+
*/
|
|
4495
|
+
scrimClassName?: string;
|
|
4496
|
+
/**
|
|
4497
|
+
* Additional CSS classes injected based on the current animation state.
|
|
4498
|
+
* Called at render time to merge CVA animation classes onto the panel.
|
|
4499
|
+
*
|
|
4500
|
+
* @example
|
|
4501
|
+
* ```tsx
|
|
4502
|
+
* getAnimationClassName={(state) => dialogAnimationVariants({ animationState: state, variant })}
|
|
4503
|
+
* ```
|
|
4504
|
+
*/
|
|
4505
|
+
getAnimationClassName?: (state: DialogAnimationState) => string;
|
|
4506
|
+
}
|
|
4507
|
+
/**
|
|
4508
|
+
* Props for the MD3 Styled `Dialog` component (Layer 3).
|
|
4509
|
+
*
|
|
4510
|
+
* Supports two structural variants — Basic (floating dialog) and Full-screen
|
|
4511
|
+
* (full viewport overlay for mobile / complex forms) — with a composable
|
|
4512
|
+
* slot-based API via `DialogHeadline`, `DialogContent`, and `DialogActions`.
|
|
4513
|
+
*
|
|
4514
|
+
* Supports both controlled (`open` + `onOpenChange`) and uncontrolled
|
|
4515
|
+
* (`defaultOpen`) usage patterns.
|
|
4516
|
+
*
|
|
4517
|
+
* @example
|
|
4518
|
+
* ```tsx
|
|
4519
|
+
* // Basic dialog (controlled)
|
|
4520
|
+
* <Dialog open={open} onOpenChange={setOpen}>
|
|
4521
|
+
* <DialogHeadline>Delete file?</DialogHeadline>
|
|
4522
|
+
* <DialogContent>This action cannot be undone.</DialogContent>
|
|
4523
|
+
* <DialogActions>
|
|
4524
|
+
* <Button variant="text" onPress={() => setOpen(false)}>Cancel</Button>
|
|
4525
|
+
* <Button variant="filled" onPress={handleDelete}>Delete</Button>
|
|
4526
|
+
* </DialogActions>
|
|
4527
|
+
* </Dialog>
|
|
4528
|
+
*
|
|
4529
|
+
* // Full-screen dialog (controlled)
|
|
4530
|
+
* <Dialog variant="fullscreen" open={open} onOpenChange={setOpen}>
|
|
4531
|
+
* <DialogHeadline
|
|
4532
|
+
* closeButton={<IconButton aria-label="Close" onPress={() => setOpen(false)}><CloseIcon /></IconButton>}
|
|
4533
|
+
* confirmButton={<Button variant="text" onPress={handleSave}>Save</Button>}
|
|
4534
|
+
* >
|
|
4535
|
+
* New event
|
|
4536
|
+
* </DialogHeadline>
|
|
4537
|
+
* <DialogContent>
|
|
4538
|
+
* <TextField label="Event name" />
|
|
4539
|
+
* </DialogContent>
|
|
4540
|
+
* </Dialog>
|
|
4541
|
+
* ```
|
|
4542
|
+
*/
|
|
4543
|
+
interface DialogProps {
|
|
4544
|
+
/**
|
|
4545
|
+
* Structural variant — `basic` (default) or `fullscreen`.
|
|
4546
|
+
* @default 'basic'
|
|
4547
|
+
*/
|
|
4548
|
+
variant?: DialogVariant;
|
|
4549
|
+
/**
|
|
4550
|
+
* Controlled open state. Pair with `onOpenChange`.
|
|
4551
|
+
*/
|
|
4552
|
+
open?: boolean;
|
|
4553
|
+
/**
|
|
4554
|
+
* Default open state for uncontrolled usage.
|
|
4555
|
+
* @default false
|
|
4556
|
+
*/
|
|
4557
|
+
defaultOpen?: boolean;
|
|
4558
|
+
/**
|
|
4559
|
+
* Called when the open state changes.
|
|
4560
|
+
*/
|
|
4561
|
+
onOpenChange?: (open: boolean) => void;
|
|
4562
|
+
/**
|
|
4563
|
+
* Accessible label for the dialog when no `DialogHeadline` is present.
|
|
4564
|
+
*/
|
|
4565
|
+
"aria-label"?: string;
|
|
4566
|
+
/**
|
|
4567
|
+
* Dialog slot content — `DialogHeadline`, `DialogContent`, `DialogActions`.
|
|
4568
|
+
*/
|
|
4569
|
+
children: ReactNode;
|
|
4570
|
+
/**
|
|
4571
|
+
* Additional CSS classes merged onto the dialog panel element.
|
|
4572
|
+
*/
|
|
4573
|
+
className?: string;
|
|
4574
|
+
}
|
|
4575
|
+
/**
|
|
4576
|
+
* Props for the `DialogHeadline` slot sub-component.
|
|
4577
|
+
*
|
|
4578
|
+
* Renders as an `<h2>` element and provides its `id` to `DialogContext`
|
|
4579
|
+
* so the parent dialog panel can reference it via `aria-labelledby`.
|
|
4580
|
+
*
|
|
4581
|
+
* For the `fullscreen` variant, accepts optional `closeButton` and
|
|
4582
|
+
* `confirmButton` slots that are rendered in the top app bar row per MD3 spec.
|
|
4583
|
+
*
|
|
4584
|
+
* @example
|
|
4585
|
+
* ```tsx
|
|
4586
|
+
* // Basic variant
|
|
4587
|
+
* <DialogHeadline>Confirm deletion?</DialogHeadline>
|
|
4588
|
+
*
|
|
4589
|
+
* // Full-screen variant
|
|
4590
|
+
* <DialogHeadline
|
|
4591
|
+
* closeButton={<IconButton aria-label="Close" onPress={onClose}><CloseIcon /></IconButton>}
|
|
4592
|
+
* confirmButton={<Button variant="text" onPress={onSave}>Save</Button>}
|
|
4593
|
+
* >
|
|
4594
|
+
* New event
|
|
4595
|
+
* </DialogHeadline>
|
|
4596
|
+
* ```
|
|
4597
|
+
*/
|
|
4598
|
+
interface DialogHeadlineProps {
|
|
4599
|
+
/**
|
|
4600
|
+
* Headline text content.
|
|
4601
|
+
*/
|
|
4602
|
+
children: ReactNode;
|
|
4603
|
+
/**
|
|
4604
|
+
* Additional CSS classes merged onto the headline element.
|
|
4605
|
+
*/
|
|
4606
|
+
className?: string;
|
|
4607
|
+
/**
|
|
4608
|
+
* Close icon button slot — rendered leading in the top app bar row
|
|
4609
|
+
* for the `fullscreen` variant only.
|
|
4610
|
+
*/
|
|
4611
|
+
closeButton?: ReactNode;
|
|
4612
|
+
/**
|
|
4613
|
+
* Confirm action slot — rendered trailing in the top app bar row
|
|
4614
|
+
* for the `fullscreen` variant only.
|
|
4615
|
+
*/
|
|
4616
|
+
confirmButton?: ReactNode;
|
|
4617
|
+
}
|
|
4618
|
+
/**
|
|
4619
|
+
* Props for the `DialogContent` slot sub-component.
|
|
4620
|
+
*
|
|
4621
|
+
* Renders as a scrollable `<div>` and provides its `id` to `DialogContext`
|
|
4622
|
+
* so the parent dialog panel can reference it via `aria-describedby`.
|
|
4623
|
+
*
|
|
4624
|
+
* @example
|
|
4625
|
+
* ```tsx
|
|
4626
|
+
* <DialogContent>
|
|
4627
|
+
* <p>This action cannot be undone. All associated data will be permanently removed.</p>
|
|
4628
|
+
* </DialogContent>
|
|
4629
|
+
* ```
|
|
4630
|
+
*/
|
|
4631
|
+
interface DialogContentProps {
|
|
4632
|
+
/**
|
|
4633
|
+
* Body content — can be any React node.
|
|
4634
|
+
*/
|
|
4635
|
+
children: ReactNode;
|
|
4636
|
+
/**
|
|
4637
|
+
* Additional CSS classes merged onto the content element.
|
|
4638
|
+
*/
|
|
4639
|
+
className?: string;
|
|
4640
|
+
}
|
|
4641
|
+
/**
|
|
4642
|
+
* Props for the `DialogActions` slot sub-component.
|
|
4643
|
+
*
|
|
4644
|
+
* Renders a right-aligned flex row of action buttons per MD3 spec.
|
|
4645
|
+
* Typically contains `Button` components with `variant="text"` (secondary)
|
|
4646
|
+
* and `variant="filled"` (primary action).
|
|
4647
|
+
*
|
|
4648
|
+
* Not used in the `fullscreen` variant (confirm action is in the headline row).
|
|
4649
|
+
*
|
|
4650
|
+
* @example
|
|
4651
|
+
* ```tsx
|
|
4652
|
+
* <DialogActions>
|
|
4653
|
+
* <Button variant="text" onPress={onCancel}>Cancel</Button>
|
|
4654
|
+
* <Button variant="filled" onPress={onConfirm}>Confirm</Button>
|
|
4655
|
+
* </DialogActions>
|
|
4656
|
+
* ```
|
|
4657
|
+
*/
|
|
4658
|
+
interface DialogActionsProps {
|
|
4659
|
+
/**
|
|
4660
|
+
* Action button elements — typically `Button` components.
|
|
4661
|
+
*/
|
|
4662
|
+
children: ReactNode;
|
|
4663
|
+
/**
|
|
4664
|
+
* Additional CSS classes merged onto the actions container.
|
|
4665
|
+
*/
|
|
4666
|
+
className?: string;
|
|
4667
|
+
}
|
|
4668
|
+
|
|
4669
|
+
/**
|
|
4670
|
+
* `Dialog` — Layer 3 MD3 Styled Dialog Component.
|
|
4671
|
+
*
|
|
4672
|
+
* Supports two structural variants per MD3 spec, with a composable slot-based
|
|
4673
|
+
* API via `DialogHeadline`, `DialogContent`, and `DialogActions`:
|
|
4674
|
+
*
|
|
4675
|
+
* **Basic** (default):
|
|
4676
|
+
* - Floating card: `bg-surface-container-high`, `rounded-xl`, `shadow-elevation-3`
|
|
4677
|
+
* - Centered in viewport (min 280dp, max 560dp width)
|
|
4678
|
+
* - Scale + fade entry animation (`duration-medium4 / ease-emphasized-decelerate`)
|
|
4679
|
+
* - Fade exit animation (`duration-short2 / ease-emphasized-accelerate`)
|
|
4680
|
+
* - Closes on scrim click or Escape key
|
|
4681
|
+
*
|
|
4682
|
+
* **Full-screen**:
|
|
4683
|
+
* - Full viewport coverage — suited for mobile and complex forms
|
|
4684
|
+
* - No rounded corners, no elevation shadow
|
|
4685
|
+
* - Slide-up entry / slide-down exit animation
|
|
4686
|
+
* - Does NOT close on scrim click per MD3 spec (only via Escape or close button)
|
|
4687
|
+
* - Headline replaced by top app bar row (close icon + confirm action)
|
|
4688
|
+
*
|
|
4689
|
+
* Both variants:
|
|
4690
|
+
* - `role="dialog"` + `aria-modal="true"` (React Aria `useDialog`)
|
|
4691
|
+
* - `aria-labelledby` pointing to `DialogHeadline` id
|
|
4692
|
+
* - `aria-describedby` pointing to `DialogContent` id
|
|
4693
|
+
* - Focus trap active while open (`FocusScope`)
|
|
4694
|
+
* - Focus returns to trigger element on close (`FocusScope restoreFocus`)
|
|
4695
|
+
* - Body scroll locked while open (`usePreventScroll`)
|
|
4696
|
+
* - Escape key always closes the dialog
|
|
4697
|
+
* - Portal rendered to `document.body`
|
|
4698
|
+
*
|
|
4699
|
+
* @example
|
|
4700
|
+
* ```tsx
|
|
4701
|
+
* // Basic dialog — controlled
|
|
4702
|
+
* function DeleteDialog() {
|
|
4703
|
+
* const [open, setOpen] = useState(false);
|
|
4704
|
+
*
|
|
4705
|
+
* return (
|
|
4706
|
+
* <>
|
|
4707
|
+
* <Button onPress={() => setOpen(true)}>Delete file</Button>
|
|
4708
|
+
* <Dialog open={open} onOpenChange={setOpen}>
|
|
4709
|
+
* <DialogHeadline>Permanently delete?</DialogHeadline>
|
|
4710
|
+
* <DialogContent>
|
|
4711
|
+
* This action cannot be undone. The file and all associated data
|
|
4712
|
+
* will be permanently removed.
|
|
4713
|
+
* </DialogContent>
|
|
4714
|
+
* <DialogActions>
|
|
4715
|
+
* <Button variant="text" onPress={() => setOpen(false)}>Cancel</Button>
|
|
4716
|
+
* <Button variant="filled" onPress={handleDelete}>Delete</Button>
|
|
4717
|
+
* </DialogActions>
|
|
4718
|
+
* </Dialog>
|
|
4719
|
+
* </>
|
|
4720
|
+
* );
|
|
4721
|
+
* }
|
|
4722
|
+
*
|
|
4723
|
+
* // Full-screen dialog — mobile form flow
|
|
4724
|
+
* function NewEventDialog() {
|
|
4725
|
+
* const [open, setOpen] = useState(false);
|
|
4726
|
+
*
|
|
4727
|
+
* return (
|
|
4728
|
+
* <>
|
|
4729
|
+
* <Button onPress={() => setOpen(true)}>New event</Button>
|
|
4730
|
+
* <Dialog variant="fullscreen" open={open} onOpenChange={setOpen}>
|
|
4731
|
+
* <DialogHeadline
|
|
4732
|
+
* closeButton={
|
|
4733
|
+
* <IconButton aria-label="Close" onPress={() => setOpen(false)}>
|
|
4734
|
+
* <CloseIcon />
|
|
4735
|
+
* </IconButton>
|
|
4736
|
+
* }
|
|
4737
|
+
* confirmButton={
|
|
4738
|
+
* <Button variant="text" onPress={handleSave}>Save</Button>
|
|
4739
|
+
* }
|
|
4740
|
+
* >
|
|
4741
|
+
* New event
|
|
4742
|
+
* </DialogHeadline>
|
|
4743
|
+
* <DialogContent>
|
|
4744
|
+
* <TextField label="Event name" />
|
|
4745
|
+
* <TextField label="Date" type="date" />
|
|
4746
|
+
* </DialogContent>
|
|
4747
|
+
* </Dialog>
|
|
4748
|
+
* </>
|
|
4749
|
+
* );
|
|
4750
|
+
* }
|
|
4751
|
+
* ```
|
|
4752
|
+
*
|
|
4753
|
+
* @see https://m3.material.io/components/dialogs/overview
|
|
4754
|
+
* @see https://m3.material.io/components/dialogs/specs
|
|
4755
|
+
*/
|
|
4756
|
+
declare const Dialog: React$1.ForwardRefExoticComponent<DialogProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
4757
|
+
|
|
4758
|
+
/**
|
|
4759
|
+
* `DialogHeadline` — Headline slot sub-component (Layer 3).
|
|
4760
|
+
*
|
|
4761
|
+
* Renders as an `<h2>` element and registers its `id` with the parent
|
|
4762
|
+
* `DialogContext` so the dialog panel can wire `aria-labelledby` correctly.
|
|
4763
|
+
*
|
|
4764
|
+
* For the `fullscreen` variant, the headline renders as a top app bar row
|
|
4765
|
+
* containing optional `closeButton` (leading icon button) and `confirmButton`
|
|
4766
|
+
* (trailing text action) per MD3 Full-screen Dialog spec.
|
|
4767
|
+
*
|
|
4768
|
+
* Must be rendered inside a `<Dialog>` or `<DialogHeadless>` component.
|
|
4769
|
+
*
|
|
4770
|
+
* @example
|
|
4771
|
+
* ```tsx
|
|
4772
|
+
* // Basic variant
|
|
4773
|
+
* <Dialog open onOpenChange={setOpen}>
|
|
4774
|
+
* <DialogHeadline>Delete file?</DialogHeadline>
|
|
4775
|
+
* ...
|
|
4776
|
+
* </Dialog>
|
|
4777
|
+
*
|
|
4778
|
+
* // Full-screen variant with app bar controls
|
|
4779
|
+
* <Dialog variant="fullscreen" open onOpenChange={setOpen}>
|
|
4780
|
+
* <DialogHeadline
|
|
4781
|
+
* closeButton={
|
|
4782
|
+
* <IconButton aria-label="Close" onPress={() => setOpen(false)}>
|
|
4783
|
+
* <CloseIcon />
|
|
4784
|
+
* </IconButton>
|
|
4785
|
+
* }
|
|
4786
|
+
* confirmButton={
|
|
4787
|
+
* <Button variant="text" onPress={handleSave}>Save</Button>
|
|
4788
|
+
* }
|
|
4789
|
+
* >
|
|
4790
|
+
* New event
|
|
4791
|
+
* </DialogHeadline>
|
|
4792
|
+
* ...
|
|
4793
|
+
* </Dialog>
|
|
4794
|
+
* ```
|
|
4795
|
+
*/
|
|
4796
|
+
declare const DialogHeadline: React$1.ForwardRefExoticComponent<DialogHeadlineProps & React$1.RefAttributes<HTMLHeadingElement>>;
|
|
4797
|
+
|
|
4798
|
+
/**
|
|
4799
|
+
* `DialogContent` — Scrollable body slot sub-component (Layer 3).
|
|
4800
|
+
*
|
|
4801
|
+
* Renders as a scrollable `<div>` and registers its `id` with the parent
|
|
4802
|
+
* `DialogContext` so the dialog panel can wire `aria-describedby` correctly.
|
|
4803
|
+
*
|
|
4804
|
+
* Styled with `text-body-medium` and `text-on-surface-variant` per MD3 spec.
|
|
4805
|
+
* Overflows vertically when content exceeds the available height.
|
|
4806
|
+
*
|
|
4807
|
+
* Must be rendered inside a `<Dialog>` or `<DialogHeadless>` component.
|
|
4808
|
+
*
|
|
4809
|
+
* @example
|
|
4810
|
+
* ```tsx
|
|
4811
|
+
* <Dialog open onOpenChange={setOpen}>
|
|
4812
|
+
* <DialogHeadline>Confirm deletion?</DialogHeadline>
|
|
4813
|
+
* <DialogContent>
|
|
4814
|
+
* <p>
|
|
4815
|
+
* This will permanently delete the file and all associated data.
|
|
4816
|
+
* This action cannot be undone.
|
|
4817
|
+
* </p>
|
|
4818
|
+
* </DialogContent>
|
|
4819
|
+
* <DialogActions>
|
|
4820
|
+
* <Button variant="text" onPress={() => setOpen(false)}>Cancel</Button>
|
|
4821
|
+
* <Button variant="filled" onPress={handleDelete}>Delete</Button>
|
|
4822
|
+
* </DialogActions>
|
|
4823
|
+
* </Dialog>
|
|
4824
|
+
* ```
|
|
4825
|
+
*/
|
|
4826
|
+
declare const DialogContent: React$1.ForwardRefExoticComponent<DialogContentProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
4827
|
+
|
|
4828
|
+
/**
|
|
4829
|
+
* `DialogActions` — Action button row slot sub-component (Layer 3).
|
|
4830
|
+
*
|
|
4831
|
+
* Renders a right-aligned flex row of action buttons per MD3 spec.
|
|
4832
|
+
* Intended to contain `Button` components (typically `variant="text"` for
|
|
4833
|
+
* secondary actions and `variant="filled"` for the primary action).
|
|
4834
|
+
*
|
|
4835
|
+
* Not used in the `fullscreen` variant — the confirm action is placed in the
|
|
4836
|
+
* headline top app bar row via `DialogHeadline`'s `confirmButton` slot.
|
|
4837
|
+
*
|
|
4838
|
+
* Must be rendered inside a `<Dialog>` or `<DialogHeadless>` component.
|
|
4839
|
+
*
|
|
4840
|
+
* @example
|
|
4841
|
+
* ```tsx
|
|
4842
|
+
* <Dialog open onOpenChange={setOpen}>
|
|
4843
|
+
* <DialogHeadline>Discard changes?</DialogHeadline>
|
|
4844
|
+
* <DialogContent>Your unsaved changes will be lost.</DialogContent>
|
|
4845
|
+
* <DialogActions>
|
|
4846
|
+
* <Button variant="text" onPress={() => setOpen(false)}>Cancel</Button>
|
|
4847
|
+
* <Button variant="filled" onPress={handleDiscard}>Discard</Button>
|
|
4848
|
+
* </DialogActions>
|
|
4849
|
+
* </Dialog>
|
|
4850
|
+
* ```
|
|
4851
|
+
*/
|
|
4852
|
+
declare const DialogActions: React$1.ForwardRefExoticComponent<DialogActionsProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
4853
|
+
|
|
4854
|
+
/**
|
|
4855
|
+
* Context shared between `DialogHeadless` and slot sub-components
|
|
4856
|
+
* (`DialogHeadline`, `DialogContent`, `DialogActions`).
|
|
4857
|
+
*
|
|
4858
|
+
* Provides stable IDs for aria-labelledby / aria-describedby wiring,
|
|
4859
|
+
* the close callback, and the active variant.
|
|
4860
|
+
*
|
|
4861
|
+
* @internal
|
|
4862
|
+
*/
|
|
4863
|
+
declare const DialogContext: React__default.Context<DialogContextValue | null>;
|
|
4864
|
+
/**
|
|
4865
|
+
* Hook to consume `DialogContext` inside dialog slot sub-components.
|
|
4866
|
+
* Throws a descriptive error if used outside a `DialogHeadless` tree.
|
|
4867
|
+
*
|
|
4868
|
+
* @internal
|
|
4869
|
+
*/
|
|
4870
|
+
declare function useDialogContext(): DialogContextValue;
|
|
4871
|
+
/**
|
|
4872
|
+
* `DialogHeadless` — Layer 2 headless primitive.
|
|
4873
|
+
*
|
|
4874
|
+
* Provides all MD3 Dialog behavior and ARIA semantics without any visual styling:
|
|
4875
|
+
*
|
|
4876
|
+
* - **Portal rendering**: dialog and scrim render in `document.body` via
|
|
4877
|
+
* `createPortal` to avoid stacking context issues.
|
|
4878
|
+
* - **Open/close state**: via `useOverlayTriggerState` (supports controlled
|
|
4879
|
+
* `open` + `onOpenChange` and uncontrolled `defaultOpen`).
|
|
4880
|
+
* - **Scroll lock**: `usePreventScroll` locks body scroll while open.
|
|
4881
|
+
* - **Focus trap**: `FocusScope` with `contain`, `restoreFocus`, `autoFocus`.
|
|
4882
|
+
* - **Dismiss behavior**: `useOverlay` handles Escape key and outside click.
|
|
4883
|
+
* Basic variant is dismissable (Escape + outside click);
|
|
4884
|
+
* Full-screen variant is Escape-dismissable only (no scrim click) per MD3 spec.
|
|
4885
|
+
* - **Animation state machine**: `entering → visible → exiting → exited`
|
|
4886
|
+
* mirrors the Snackbar animation pattern.
|
|
4887
|
+
* - **ARIA wiring**: `DialogContext` provides stable IDs for `aria-labelledby`
|
|
4888
|
+
* and `aria-describedby`, consumed by slot sub-components.
|
|
4889
|
+
*
|
|
4890
|
+
* React Aria hooks used:
|
|
4891
|
+
* - `useDialog` — `role="dialog"`, `aria-modal`, `aria-labelledby`, `aria-describedby`
|
|
4892
|
+
* - `useOverlay` — Escape key + outside-click dismissal
|
|
4893
|
+
* - `usePreventScroll` — body scroll lock
|
|
4894
|
+
* - `FocusScope` — focus trap + restoreFocus on close
|
|
4895
|
+
* - `useOverlayTriggerState` — open/close state management
|
|
4896
|
+
*
|
|
4897
|
+
* @example
|
|
4898
|
+
* ```tsx
|
|
4899
|
+
* // Controlled basic dialog
|
|
4900
|
+
* <DialogHeadless
|
|
4901
|
+
* variant="basic"
|
|
4902
|
+
* open={open}
|
|
4903
|
+
* onOpenChange={setOpen}
|
|
4904
|
+
* className={cn(dialogWrapperVariants({ variant: 'basic' }), dialogPanelVariants({ variant: 'basic' }))}
|
|
4905
|
+
* scrimClassName={dialogScrimVariants()}
|
|
4906
|
+
* getAnimationClassName={(state) =>
|
|
4907
|
+
* dialogAnimationVariants({ animationState: state, variant: 'basic' })
|
|
4908
|
+
* }
|
|
4909
|
+
* >
|
|
4910
|
+
* <DialogHeadline>Confirm?</DialogHeadline>
|
|
4911
|
+
* <DialogContent>This action cannot be undone.</DialogContent>
|
|
4912
|
+
* <DialogActions>
|
|
4913
|
+
* <Button variant="text" onPress={() => setOpen(false)}>Cancel</Button>
|
|
4914
|
+
* <Button variant="filled" onPress={handleDelete}>Delete</Button>
|
|
4915
|
+
* </DialogActions>
|
|
4916
|
+
* </DialogHeadless>
|
|
4917
|
+
* ```
|
|
4918
|
+
*/
|
|
4919
|
+
declare const DialogHeadless: React__default.ForwardRefExoticComponent<DialogHeadlessProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
4920
|
+
|
|
4921
|
+
export { AppBar, AppBarHeadless, type AppBarHeadlessProps, type AppBarProps, type AppBarVariant, Button, type ButtonColor, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, Dialog, DialogActions, type DialogActionsProps, type DialogAnimationState, DialogContent, type DialogContentProps, DialogContext, type DialogContextValue, DialogHeadless, type DialogHeadlessProps, DialogHeadline, type DialogHeadlineProps, type DialogProps, type DialogVariant, Drawer, type DrawerContextValue, DrawerItem, type DrawerItemProps, type DrawerProps, DrawerSection, type DrawerSectionProps, type DrawerVariant, FAB, type FABColor, FABHeadless, type FABHeadlessProps, type FABProps, type FABSize, HeadlessDrawer, HeadlessDrawerItem, type HeadlessDrawerItemProps, type HeadlessDrawerProps, HeadlessMenu, HeadlessMenuDivider, HeadlessMenuItem, type HeadlessMenuItemProps, type HeadlessMenuProps, HeadlessMenuSection, type HeadlessMenuSectionProps, HeadlessMenuTrigger, type HeadlessMenuTriggerProps, HeadlessNavigationBar, HeadlessNavigationBarItem, type HeadlessNavigationBarItemProps, type HeadlessNavigationBarProps, HeadlessTab, HeadlessTabList, HeadlessTabPanel, type HeadlessTabPanelProps, type HeadlessTabProps, IconButton, type IconButtonColor, IconButtonHeadless, type IconButtonHeadlessProps, type IconButtonProps, type IconButtonSize, type IconButtonVariant, type MD3ColorRole, type MD3TypographyScale, type MD3TypographySize, type MD3TypographyStyle, Menu, type MenuContainerVariants, MenuContext, type MenuContextValue, MenuDivider, type MenuDividerProps, MenuItem, type MenuItemProps, type MenuProps, MenuSection, type MenuSectionProps, MenuTrigger, type MenuTriggerProps, NavigationBar, type NavigationBarBadge, NavigationBarItem, type NavigationBarItemConfig, type NavigationBarItemProps, type NavigationBarItemRenderProps, type NavigationBarProps, Progress, ProgressHeadless, type ProgressHeadlessProps, type ProgressProps, Radio, RadioGroup, RadioGroupHeadless, type RadioGroupHeadlessProps, type RadioGroupProps, RadioHeadless, type RadioHeadlessProps, type RadioProps, STATE_LAYER_OPACITY, Snackbar, type SnackbarAction, SnackbarContext, type SnackbarContextValue, SnackbarHeadless, type SnackbarHeadlessProps, type SnackbarItem, type SnackbarProps, SnackbarProvider, type SnackbarProviderProps, type SnackbarSeverity, Switch, type SwitchProps, TYPOGRAPHY_ELEMENT_MAP, TYPOGRAPHY_USAGE, Tab, type TabItem, type TabLayout, TabList, type TabListProps, TabPanel, type TabPanelProps, type TabProps, type TabVariant, Tabs, type TabsProps, TextField, type TextFieldProps, type TextFieldSize, type TextFieldVariant, type TypographyProperty, type TypographyStyleObject, applyStateLayer, cn, generateMD3Theme, getColorValue, getFontFamily, getMD3Color, getResponsiveTypography, getTypographyClassName, getTypographyForElement, getTypographyStyle, getTypographyToken, hexToRgb, pxToRem, remToPx, rgbToHex, truncateText, useDialogContext, useMenuContext, useSnackbar, withOpacity };
|