@tinybigui/react 0.1.1 → 0.2.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 +1548 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1561 -3
- package/dist/index.d.ts +1561 -3
- package/dist/index.js +1534 -20
- package/dist/index.js.map +1 -1
- package/dist/styles.css +5 -2
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -2,10 +2,11 @@ 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 } 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 } from 'react-aria';
|
|
9
|
+
import { Key } from 'react-stately';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Combines and merges Tailwind CSS classes efficiently.
|
|
@@ -438,6 +439,258 @@ declare function pxToRem(px: number | string): string;
|
|
|
438
439
|
*/
|
|
439
440
|
declare function truncateText(lines?: number): React.CSSProperties;
|
|
440
441
|
|
|
442
|
+
/**
|
|
443
|
+
* MD3 Top App Bar size variants
|
|
444
|
+
*
|
|
445
|
+
* Each variant differs in height, title alignment, and type scale.
|
|
446
|
+
* - `small`: 64dp height, title left-aligned, title-large type scale
|
|
447
|
+
* - `center-aligned`: 64dp height, title centered, title-large type scale
|
|
448
|
+
* - `medium`: 112dp height, title bottom-left, headline-small type scale
|
|
449
|
+
* - `large`: 152dp height, title bottom-left, display-small type scale
|
|
450
|
+
*
|
|
451
|
+
* @see https://m3.material.io/components/top-app-bar/specs
|
|
452
|
+
*/
|
|
453
|
+
type AppBarVariant = "small" | "center-aligned" | "medium" | "large";
|
|
454
|
+
/**
|
|
455
|
+
* Material Design 3 Top App Bar Component Props
|
|
456
|
+
*
|
|
457
|
+
* Provides a top app bar with navigation icon, title, and trailing action icon slots.
|
|
458
|
+
* Supports scroll-triggered elevation changes with both controlled and uncontrolled modes.
|
|
459
|
+
*
|
|
460
|
+
* **Usage:**
|
|
461
|
+
* - Pass existing `<IconButton>` components into `navigationIcon` and `actions` slots
|
|
462
|
+
* - No hardcoded slot components — fully composable API
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```tsx
|
|
466
|
+
* // Small variant with navigation icon and actions
|
|
467
|
+
* <AppBar
|
|
468
|
+
* title="Page Title"
|
|
469
|
+
* navigationIcon={
|
|
470
|
+
* <IconButton aria-label="Open navigation">
|
|
471
|
+
* <MenuIcon />
|
|
472
|
+
* </IconButton>
|
|
473
|
+
* }
|
|
474
|
+
* actions={
|
|
475
|
+
* <IconButton aria-label="Search">
|
|
476
|
+
* <SearchIcon />
|
|
477
|
+
* </IconButton>
|
|
478
|
+
* }
|
|
479
|
+
* />
|
|
480
|
+
*
|
|
481
|
+
* // Center-aligned with controlled scroll state
|
|
482
|
+
* <AppBar
|
|
483
|
+
* variant="center-aligned"
|
|
484
|
+
* title="My App"
|
|
485
|
+
* scrolled={isScrolled}
|
|
486
|
+
* onScrollStateChange={setIsScrolled}
|
|
487
|
+
* />
|
|
488
|
+
*
|
|
489
|
+
* // Large variant for hero/expanded layouts
|
|
490
|
+
* <AppBar
|
|
491
|
+
* variant="large"
|
|
492
|
+
* title="Article Title"
|
|
493
|
+
* />
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
interface AppBarProps {
|
|
497
|
+
/**
|
|
498
|
+
* Size variant of the Top App Bar
|
|
499
|
+
* Controls height, title position, and type scale
|
|
500
|
+
* @default 'small'
|
|
501
|
+
*/
|
|
502
|
+
variant?: AppBarVariant;
|
|
503
|
+
/**
|
|
504
|
+
* The title content. Accepts a string or any React node.
|
|
505
|
+
* Typography scale is automatically applied based on `variant`.
|
|
506
|
+
*/
|
|
507
|
+
title: React__default.ReactNode;
|
|
508
|
+
/**
|
|
509
|
+
* Navigation icon slot (leading position, optional).
|
|
510
|
+
* Expects a React node — typically an `<IconButton>` with `aria-label`.
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```tsx
|
|
514
|
+
* navigationIcon={
|
|
515
|
+
* <IconButton aria-label="Open navigation menu">
|
|
516
|
+
* <MenuIcon />
|
|
517
|
+
* </IconButton>
|
|
518
|
+
* }
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
navigationIcon?: React__default.ReactNode;
|
|
522
|
+
/**
|
|
523
|
+
* Trailing action icon slots (up to 3, optional).
|
|
524
|
+
* Expects one or more React nodes — typically `<IconButton>` components.
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* ```tsx
|
|
528
|
+
* actions={
|
|
529
|
+
* <>
|
|
530
|
+
* <IconButton aria-label="Search"><SearchIcon /></IconButton>
|
|
531
|
+
* <IconButton aria-label="More options"><MoreIcon /></IconButton>
|
|
532
|
+
* </>
|
|
533
|
+
* }
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
actions?: React__default.ReactNode;
|
|
537
|
+
/**
|
|
538
|
+
* Controlled scroll state.
|
|
539
|
+
* When provided, the component operates in controlled mode — the consumer
|
|
540
|
+
* is responsible for managing this value.
|
|
541
|
+
* When `undefined`, internal scroll detection is used (uncontrolled mode).
|
|
542
|
+
*
|
|
543
|
+
* - `false` (default): flat surface, `shadow-elevation-0`
|
|
544
|
+
* - `true`: elevated surface, `shadow-elevation-2`
|
|
545
|
+
*/
|
|
546
|
+
scrolled?: boolean;
|
|
547
|
+
/**
|
|
548
|
+
* Callback fired when the scroll elevation state changes.
|
|
549
|
+
* In uncontrolled mode, this fires when the user scrolls past the threshold.
|
|
550
|
+
* In controlled mode, this is an informational callback — the consumer
|
|
551
|
+
* decides whether to update `scrolled`.
|
|
552
|
+
*
|
|
553
|
+
* @param scrolled - The new scroll state
|
|
554
|
+
*/
|
|
555
|
+
onScrollStateChange?: (scrolled: boolean) => void;
|
|
556
|
+
/**
|
|
557
|
+
* Additional CSS classes to merge onto the root `<header>` element.
|
|
558
|
+
* Uses Tailwind CSS — conflicting classes are resolved by `cn()`.
|
|
559
|
+
*/
|
|
560
|
+
className?: string;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* AppBarHeadless Component Props
|
|
564
|
+
*
|
|
565
|
+
* Unstyled primitive for the Top App Bar.
|
|
566
|
+
* Renders a `<header role="banner">` and manages scroll elevation state.
|
|
567
|
+
* Use this for full visual control when the styled `AppBar` is not sufficient.
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```tsx
|
|
571
|
+
* <AppBarHeadless
|
|
572
|
+
* className="my-custom-appbar"
|
|
573
|
+
* scrolled={scrolled}
|
|
574
|
+
* onScrollStateChange={setScrolled}
|
|
575
|
+
* >
|
|
576
|
+
* <div>My custom layout</div>
|
|
577
|
+
* </AppBarHeadless>
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
interface AppBarHeadlessProps {
|
|
581
|
+
/**
|
|
582
|
+
* Additional CSS classes
|
|
583
|
+
*/
|
|
584
|
+
className?: string;
|
|
585
|
+
/**
|
|
586
|
+
* The content to render inside the header
|
|
587
|
+
*/
|
|
588
|
+
children: React__default.ReactNode;
|
|
589
|
+
/**
|
|
590
|
+
* Controlled scroll state.
|
|
591
|
+
* When `undefined`, the component uses internal scroll detection.
|
|
592
|
+
*/
|
|
593
|
+
scrolled?: boolean;
|
|
594
|
+
/**
|
|
595
|
+
* Callback fired when scroll state changes
|
|
596
|
+
*/
|
|
597
|
+
onScrollStateChange?: (scrolled: boolean) => void;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Material Design 3 Top App Bar Component
|
|
602
|
+
*
|
|
603
|
+
* Provides context and actions for the current screen. Supports four size variants,
|
|
604
|
+
* a navigation icon slot, title, and trailing action icon slots. Implements
|
|
605
|
+
* scroll-triggered elevation changes per MD3 specification.
|
|
606
|
+
*
|
|
607
|
+
* **Architecture:**
|
|
608
|
+
* - Layer 3 (this file): MD3 styled, CVA variants, layout composition
|
|
609
|
+
* - Layer 2: `AppBarHeadless` — `<header role="banner">`, scroll state
|
|
610
|
+
* - Layer 1: React Aria via `<IconButton>` in consumer slots
|
|
611
|
+
*
|
|
612
|
+
* **Key Features:**
|
|
613
|
+
* - 4 MD3 variants: small, center-aligned, medium, large
|
|
614
|
+
* - Composable API: pass `<IconButton>` nodes into navigation and action slots
|
|
615
|
+
* - Scroll elevation: flat at rest → elevated on scroll (MD3 motion tokens)
|
|
616
|
+
* - Controlled and uncontrolled scroll state
|
|
617
|
+
* - WCAG 2.1 AA: `role="banner"` landmark, keyboard accessible slots
|
|
618
|
+
* - Dark mode via existing token system
|
|
619
|
+
*
|
|
620
|
+
* @example
|
|
621
|
+
* ```tsx
|
|
622
|
+
* // Small variant (default)
|
|
623
|
+
* <AppBar
|
|
624
|
+
* title="Page Title"
|
|
625
|
+
* navigationIcon={
|
|
626
|
+
* <IconButton aria-label="Open navigation menu">
|
|
627
|
+
* <MenuIcon />
|
|
628
|
+
* </IconButton>
|
|
629
|
+
* }
|
|
630
|
+
* actions={
|
|
631
|
+
* <IconButton aria-label="Search">
|
|
632
|
+
* <SearchIcon />
|
|
633
|
+
* </IconButton>
|
|
634
|
+
* }
|
|
635
|
+
* />
|
|
636
|
+
*
|
|
637
|
+
* // Center-aligned with scroll elevation
|
|
638
|
+
* <AppBar
|
|
639
|
+
* variant="center-aligned"
|
|
640
|
+
* title="My App"
|
|
641
|
+
* scrolled={isScrolled}
|
|
642
|
+
* onScrollStateChange={setIsScrolled}
|
|
643
|
+
* />
|
|
644
|
+
*
|
|
645
|
+
* // Medium with expanded title area
|
|
646
|
+
* <AppBar
|
|
647
|
+
* variant="medium"
|
|
648
|
+
* title="Article Title"
|
|
649
|
+
* navigationIcon={
|
|
650
|
+
* <IconButton aria-label="Go back">
|
|
651
|
+
* <ArrowBackIcon />
|
|
652
|
+
* </IconButton>
|
|
653
|
+
* }
|
|
654
|
+
* />
|
|
655
|
+
* ```
|
|
656
|
+
*/
|
|
657
|
+
declare const AppBar: React$1.ForwardRefExoticComponent<AppBarProps & React$1.RefAttributes<HTMLElement>>;
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Headless AppBar Component (Layer 2)
|
|
661
|
+
*
|
|
662
|
+
* Unstyled Top App Bar primitive. Renders a `<header role="banner">` landmark
|
|
663
|
+
* and manages scroll elevation state via the `useScrollElevation` hook.
|
|
664
|
+
*
|
|
665
|
+
* Features:
|
|
666
|
+
* - Semantic `<header>` element with `role="banner"` ARIA landmark
|
|
667
|
+
* - Controlled scroll state via `scrolled` prop
|
|
668
|
+
* - Uncontrolled scroll state with internal `window` scroll detection
|
|
669
|
+
* - `onScrollStateChange` callback for both modes
|
|
670
|
+
* - Full ref forwarding to the header element
|
|
671
|
+
*
|
|
672
|
+
* Use this layer when you need full visual control beyond what the styled
|
|
673
|
+
* `AppBar` provides.
|
|
674
|
+
*
|
|
675
|
+
* @example
|
|
676
|
+
* ```tsx
|
|
677
|
+
* // Uncontrolled (auto scroll detection)
|
|
678
|
+
* <AppBarHeadless className="my-custom-appbar">
|
|
679
|
+
* <div>My custom layout</div>
|
|
680
|
+
* </AppBarHeadless>
|
|
681
|
+
*
|
|
682
|
+
* // Controlled scroll state
|
|
683
|
+
* <AppBarHeadless
|
|
684
|
+
* scrolled={isScrolled}
|
|
685
|
+
* onScrollStateChange={setIsScrolled}
|
|
686
|
+
* className="my-custom-appbar"
|
|
687
|
+
* >
|
|
688
|
+
* <div>My custom layout</div>
|
|
689
|
+
* </AppBarHeadless>
|
|
690
|
+
* ```
|
|
691
|
+
*/
|
|
692
|
+
declare const AppBarHeadless: React$1.ForwardRefExoticComponent<AppBarHeadlessProps & React$1.RefAttributes<HTMLElement>>;
|
|
693
|
+
|
|
441
694
|
/**
|
|
442
695
|
* Material Design 3 Button Variants (CVA)
|
|
443
696
|
*
|
|
@@ -1833,4 +2086,1309 @@ declare const RadioHeadless: React$1.ForwardRefExoticComponent<RadioHeadlessProp
|
|
|
1833
2086
|
*/
|
|
1834
2087
|
declare const RadioGroupHeadless: React$1.ForwardRefExoticComponent<RadioGroupHeadlessProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1835
2088
|
|
|
1836
|
-
|
|
2089
|
+
/**
|
|
2090
|
+
* Tab variant following MD3 spec
|
|
2091
|
+
* - primary: active indicator uses bg-primary; active text: text-primary
|
|
2092
|
+
* - secondary: active indicator uses bg-on-surface-variant; active text: text-on-surface
|
|
2093
|
+
*/
|
|
2094
|
+
type TabVariant = "primary" | "secondary";
|
|
2095
|
+
/**
|
|
2096
|
+
* Tab layout mode
|
|
2097
|
+
* - fixed: tabs fill available width equally
|
|
2098
|
+
* - scrollable: tabs overflow horizontally with no wrapping
|
|
2099
|
+
*/
|
|
2100
|
+
type TabLayout = "fixed" | "scrollable";
|
|
2101
|
+
/**
|
|
2102
|
+
* Badge value for a tab item
|
|
2103
|
+
* - number: displays count (999+ for values > 999, hidden for 0)
|
|
2104
|
+
* - true: displays a dot indicator
|
|
2105
|
+
* - false/undefined: no badge
|
|
2106
|
+
*/
|
|
2107
|
+
type TabBadgeValue = number | boolean;
|
|
2108
|
+
/**
|
|
2109
|
+
* Material Design 3 Tabs Wrapper Props
|
|
2110
|
+
*
|
|
2111
|
+
* The Tabs component manages shared state (selected key) and provides
|
|
2112
|
+
* context to TabList and TabPanel children.
|
|
2113
|
+
*
|
|
2114
|
+
* @example
|
|
2115
|
+
* ```tsx
|
|
2116
|
+
* // Uncontrolled
|
|
2117
|
+
* <Tabs defaultSelectedKey="tab1" aria-label="Settings tabs">
|
|
2118
|
+
* <TabList>
|
|
2119
|
+
* <Tab id="tab1" label="General" />
|
|
2120
|
+
* <Tab id="tab2" label="Privacy" />
|
|
2121
|
+
* </TabList>
|
|
2122
|
+
* <TabPanel id="tab1">General content</TabPanel>
|
|
2123
|
+
* <TabPanel id="tab2">Privacy content</TabPanel>
|
|
2124
|
+
* </Tabs>
|
|
2125
|
+
*
|
|
2126
|
+
* // Controlled
|
|
2127
|
+
* <Tabs selectedKey={selected} onSelectionChange={setSelected} aria-label="App tabs">
|
|
2128
|
+
* <TabList variant="secondary">
|
|
2129
|
+
* <Tab id="a" label="Overview" />
|
|
2130
|
+
* <Tab id="b" label="Details" />
|
|
2131
|
+
* </TabList>
|
|
2132
|
+
* <TabPanel id="a">Overview content</TabPanel>
|
|
2133
|
+
* <TabPanel id="b">Details content</TabPanel>
|
|
2134
|
+
* </Tabs>
|
|
2135
|
+
* ```
|
|
2136
|
+
*/
|
|
2137
|
+
interface TabsProps {
|
|
2138
|
+
/**
|
|
2139
|
+
* Controlled selected tab key
|
|
2140
|
+
*/
|
|
2141
|
+
selectedKey?: Key;
|
|
2142
|
+
/**
|
|
2143
|
+
* Default selected key for uncontrolled usage
|
|
2144
|
+
*/
|
|
2145
|
+
defaultSelectedKey?: Key;
|
|
2146
|
+
/**
|
|
2147
|
+
* Callback when selected tab changes
|
|
2148
|
+
*/
|
|
2149
|
+
onSelectionChange?: (key: Key) => void;
|
|
2150
|
+
/**
|
|
2151
|
+
* Tab variant — affects active indicator and label color
|
|
2152
|
+
* @default 'primary'
|
|
2153
|
+
*/
|
|
2154
|
+
variant?: TabVariant;
|
|
2155
|
+
/**
|
|
2156
|
+
* Layout mode
|
|
2157
|
+
* @default 'fixed'
|
|
2158
|
+
*/
|
|
2159
|
+
layout?: TabLayout;
|
|
2160
|
+
/**
|
|
2161
|
+
* TabList and TabPanel children
|
|
2162
|
+
*/
|
|
2163
|
+
children: React__default.ReactNode;
|
|
2164
|
+
/**
|
|
2165
|
+
* Additional CSS classes
|
|
2166
|
+
*/
|
|
2167
|
+
className?: string;
|
|
2168
|
+
/**
|
|
2169
|
+
* Accessible label for the tabs widget
|
|
2170
|
+
*/
|
|
2171
|
+
"aria-label"?: string;
|
|
2172
|
+
/**
|
|
2173
|
+
* Accessible labelledby reference
|
|
2174
|
+
*/
|
|
2175
|
+
"aria-labelledby"?: string;
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* Material Design 3 TabList Props
|
|
2179
|
+
*
|
|
2180
|
+
* Renders the tab row container with the active indicator.
|
|
2181
|
+
* Must be a child of Tabs.
|
|
2182
|
+
*
|
|
2183
|
+
* @example
|
|
2184
|
+
* ```tsx
|
|
2185
|
+
* <TabList>
|
|
2186
|
+
* <Tab id="overview" label="Overview" />
|
|
2187
|
+
* <Tab id="activity" label="Activity" icon={<ActivityIcon />} />
|
|
2188
|
+
* </TabList>
|
|
2189
|
+
* ```
|
|
2190
|
+
*/
|
|
2191
|
+
interface TabListProps {
|
|
2192
|
+
/**
|
|
2193
|
+
* Tab child elements
|
|
2194
|
+
*/
|
|
2195
|
+
children: React__default.ReactNode;
|
|
2196
|
+
/**
|
|
2197
|
+
* Additional CSS classes
|
|
2198
|
+
*/
|
|
2199
|
+
className?: string;
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* Material Design 3 Tab Props
|
|
2203
|
+
*
|
|
2204
|
+
* Represents a single tab item inside a TabList.
|
|
2205
|
+
* Supports icon-only, label-only, and icon+label content modes.
|
|
2206
|
+
*
|
|
2207
|
+
* @example
|
|
2208
|
+
* ```tsx
|
|
2209
|
+
* // Label only
|
|
2210
|
+
* <Tab id="overview" label="Overview" />
|
|
2211
|
+
*
|
|
2212
|
+
* // Icon + label
|
|
2213
|
+
* <Tab id="media" icon={<PhotoIcon />} label="Media" />
|
|
2214
|
+
*
|
|
2215
|
+
* // With badge
|
|
2216
|
+
* <Tab id="messages" label="Messages" badge={5} />
|
|
2217
|
+
*
|
|
2218
|
+
* // Dot badge
|
|
2219
|
+
* <Tab id="notifications" label="Notifications" badge={true} />
|
|
2220
|
+
*
|
|
2221
|
+
* // Disabled
|
|
2222
|
+
* <Tab id="archived" label="Archived" isDisabled />
|
|
2223
|
+
* ```
|
|
2224
|
+
*/
|
|
2225
|
+
interface TabProps {
|
|
2226
|
+
/**
|
|
2227
|
+
* Unique key identifying this tab (used to match with TabPanel)
|
|
2228
|
+
*/
|
|
2229
|
+
id: Key;
|
|
2230
|
+
/**
|
|
2231
|
+
* Icon element displayed above or instead of the label
|
|
2232
|
+
* Should be 24x24dp per MD3 Tabs spec
|
|
2233
|
+
*/
|
|
2234
|
+
icon?: React__default.ReactNode;
|
|
2235
|
+
/**
|
|
2236
|
+
* Text label for the tab
|
|
2237
|
+
*/
|
|
2238
|
+
label?: string;
|
|
2239
|
+
/**
|
|
2240
|
+
* Badge value
|
|
2241
|
+
* - number: shows count (999+ for values > 999, hidden for 0)
|
|
2242
|
+
* - true: shows dot indicator
|
|
2243
|
+
*/
|
|
2244
|
+
badge?: TabBadgeValue;
|
|
2245
|
+
/**
|
|
2246
|
+
* Disables the tab (not focusable, not selectable)
|
|
2247
|
+
* @default false
|
|
2248
|
+
*/
|
|
2249
|
+
isDisabled?: boolean;
|
|
2250
|
+
/**
|
|
2251
|
+
* Disables ripple effect
|
|
2252
|
+
* @default false
|
|
2253
|
+
*/
|
|
2254
|
+
disableRipple?: boolean;
|
|
2255
|
+
/**
|
|
2256
|
+
* Additional CSS classes
|
|
2257
|
+
*/
|
|
2258
|
+
className?: string;
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* Material Design 3 TabPanel Props
|
|
2262
|
+
*
|
|
2263
|
+
* Content area associated with a tab. Only the selected tab's panel is visible.
|
|
2264
|
+
* The `id` must match the corresponding Tab's `id`.
|
|
2265
|
+
*
|
|
2266
|
+
* @example
|
|
2267
|
+
* ```tsx
|
|
2268
|
+
* <TabPanel id="overview">
|
|
2269
|
+
* <p>Overview content here</p>
|
|
2270
|
+
* </TabPanel>
|
|
2271
|
+
* ```
|
|
2272
|
+
*/
|
|
2273
|
+
interface TabPanelProps {
|
|
2274
|
+
/**
|
|
2275
|
+
* Key matching the associated Tab's `id`
|
|
2276
|
+
*/
|
|
2277
|
+
id: Key;
|
|
2278
|
+
/**
|
|
2279
|
+
* Panel content
|
|
2280
|
+
*/
|
|
2281
|
+
children: React__default.ReactNode;
|
|
2282
|
+
/**
|
|
2283
|
+
* Additional CSS classes
|
|
2284
|
+
*/
|
|
2285
|
+
className?: string;
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* Internal tab item representation for React Aria collection
|
|
2289
|
+
*/
|
|
2290
|
+
interface TabItem {
|
|
2291
|
+
key: Key;
|
|
2292
|
+
id: Key;
|
|
2293
|
+
label?: string;
|
|
2294
|
+
icon?: React__default.ReactNode;
|
|
2295
|
+
badge?: TabBadgeValue;
|
|
2296
|
+
isDisabled?: boolean;
|
|
2297
|
+
textValue?: string;
|
|
2298
|
+
}
|
|
2299
|
+
/**
|
|
2300
|
+
* Props for HeadlessTab
|
|
2301
|
+
* Extends AriaTabProps for full React Aria accessibility support
|
|
2302
|
+
*/
|
|
2303
|
+
interface HeadlessTabProps extends AriaTabProps {
|
|
2304
|
+
/**
|
|
2305
|
+
* Tab item from the collection
|
|
2306
|
+
*/
|
|
2307
|
+
item: TabItem;
|
|
2308
|
+
/**
|
|
2309
|
+
* Additional CSS classes
|
|
2310
|
+
*/
|
|
2311
|
+
className?: string;
|
|
2312
|
+
/**
|
|
2313
|
+
* Mouse down handler (for ripple effect)
|
|
2314
|
+
*/
|
|
2315
|
+
onMouseDown?: (e: React__default.MouseEvent<HTMLButtonElement>) => void;
|
|
2316
|
+
/**
|
|
2317
|
+
* Render function receiving interaction states
|
|
2318
|
+
*/
|
|
2319
|
+
children?: (state: {
|
|
2320
|
+
isSelected: boolean;
|
|
2321
|
+
isDisabled: boolean;
|
|
2322
|
+
isFocusVisible: boolean;
|
|
2323
|
+
isPressed: boolean;
|
|
2324
|
+
}) => React__default.ReactNode;
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Props for HeadlessTabPanel
|
|
2328
|
+
* Extends AriaTabPanelProps for full React Aria accessibility support
|
|
2329
|
+
*/
|
|
2330
|
+
interface HeadlessTabPanelProps extends AriaTabPanelProps {
|
|
2331
|
+
/**
|
|
2332
|
+
* Panel content
|
|
2333
|
+
*/
|
|
2334
|
+
children: React__default.ReactNode;
|
|
2335
|
+
/**
|
|
2336
|
+
* Additional CSS classes
|
|
2337
|
+
*/
|
|
2338
|
+
className?: string;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
/**
|
|
2342
|
+
* Material Design 3 Tabs Component (Layer 3: Styled Wrapper)
|
|
2343
|
+
*
|
|
2344
|
+
* The Tabs component manages shared selected state via useTabListState (React Aria + Stately),
|
|
2345
|
+
* and provides this state to all child TabList, Tab, and TabPanel components via context.
|
|
2346
|
+
*
|
|
2347
|
+
* Architecture:
|
|
2348
|
+
* 1. Extracts Tab metadata from children to build the React Aria collection
|
|
2349
|
+
* 2. Creates tab list state with useTabListState
|
|
2350
|
+
* 3. Provides React Aria state via HeadlessTabsContext
|
|
2351
|
+
* 4. Provides MD3 styling context via TabsContext
|
|
2352
|
+
*
|
|
2353
|
+
* Features:
|
|
2354
|
+
* - ✅ Controlled and uncontrolled selection
|
|
2355
|
+
* - ✅ Primary and secondary variants
|
|
2356
|
+
* - ✅ Fixed and scrollable layouts
|
|
2357
|
+
* - ✅ Full keyboard navigation (via React Aria)
|
|
2358
|
+
* - ✅ WCAG 2.1 AA compliant
|
|
2359
|
+
*
|
|
2360
|
+
* @example
|
|
2361
|
+
* ```tsx
|
|
2362
|
+
* // Uncontrolled
|
|
2363
|
+
* <Tabs defaultSelectedKey="tab1" aria-label="Settings">
|
|
2364
|
+
* <TabList>
|
|
2365
|
+
* <Tab id="tab1" label="General" />
|
|
2366
|
+
* <Tab id="tab2" label="Privacy" />
|
|
2367
|
+
* </TabList>
|
|
2368
|
+
* <TabPanel id="tab1">General content</TabPanel>
|
|
2369
|
+
* <TabPanel id="tab2">Privacy content</TabPanel>
|
|
2370
|
+
* </Tabs>
|
|
2371
|
+
*
|
|
2372
|
+
* // Controlled
|
|
2373
|
+
* <Tabs selectedKey={tab} onSelectionChange={setTab} aria-label="App">
|
|
2374
|
+
* <TabList variant="secondary">
|
|
2375
|
+
* <Tab id="overview" label="Overview" />
|
|
2376
|
+
* <Tab id="details" label="Details" />
|
|
2377
|
+
* </TabList>
|
|
2378
|
+
* <TabPanel id="overview">Overview</TabPanel>
|
|
2379
|
+
* <TabPanel id="details">Details</TabPanel>
|
|
2380
|
+
* </Tabs>
|
|
2381
|
+
* ```
|
|
2382
|
+
*/
|
|
2383
|
+
declare const Tabs: React__default.ForwardRefExoticComponent<TabsProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
2384
|
+
|
|
2385
|
+
/**
|
|
2386
|
+
* Material Design 3 TabList Component (Layer 3: Styled)
|
|
2387
|
+
*
|
|
2388
|
+
* Renders the tab row container with an animated active indicator.
|
|
2389
|
+
* Uses React Aria's useTabList for role="tablist", keyboard navigation,
|
|
2390
|
+
* and accessibility attributes.
|
|
2391
|
+
*
|
|
2392
|
+
* The active indicator slides to the selected tab using CSS transitions
|
|
2393
|
+
* with MD3 motion tokens (medium2 duration, emphasized easing).
|
|
2394
|
+
*
|
|
2395
|
+
* MD3 Specifications:
|
|
2396
|
+
* - Container background: bg-surface
|
|
2397
|
+
* - Container height: 48dp
|
|
2398
|
+
* - Bottom border: 1dp, outline-variant color
|
|
2399
|
+
* - Fixed layout: tabs fill width equally
|
|
2400
|
+
* - Scrollable layout: overflow-x, no wrapping
|
|
2401
|
+
*
|
|
2402
|
+
* @example
|
|
2403
|
+
* ```tsx
|
|
2404
|
+
* <Tabs aria-label="Settings" defaultSelectedKey="general">
|
|
2405
|
+
* <TabList>
|
|
2406
|
+
* <Tab id="general" label="General" />
|
|
2407
|
+
* <Tab id="privacy" label="Privacy" />
|
|
2408
|
+
* </TabList>
|
|
2409
|
+
* ...
|
|
2410
|
+
* </Tabs>
|
|
2411
|
+
* ```
|
|
2412
|
+
*/
|
|
2413
|
+
declare const TabList: React__default.ForwardRefExoticComponent<TabListProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
2414
|
+
|
|
2415
|
+
/**
|
|
2416
|
+
* Material Design 3 Tab Component (Layer 3: Styled)
|
|
2417
|
+
*
|
|
2418
|
+
* Renders a single tab item inside a TabList.
|
|
2419
|
+
* Supports three content modes: icon-only, label-only, icon + label (stacked).
|
|
2420
|
+
*
|
|
2421
|
+
* Features:
|
|
2422
|
+
* - ✅ Icon-only, label-only, icon + label (stacked) content modes
|
|
2423
|
+
* - ✅ Ripple effect (Material Design)
|
|
2424
|
+
* - ✅ MD3 state layers (hover 8%, pressed 12%)
|
|
2425
|
+
* - ✅ Badge support (numeric, dot, 999+)
|
|
2426
|
+
* - ✅ Disabled state (opacity-38, not focusable)
|
|
2427
|
+
* - ✅ Full keyboard accessibility (via React Aria)
|
|
2428
|
+
* - ✅ Primary/secondary variant colors
|
|
2429
|
+
*
|
|
2430
|
+
* MD3 Specifications:
|
|
2431
|
+
* - Minimum height: 48dp
|
|
2432
|
+
* - Minimum width: 90dp
|
|
2433
|
+
* - Typography: Title Small (14px, weight 500, tracking 0.1px)
|
|
2434
|
+
* - Icon: 24x24dp
|
|
2435
|
+
* - Active indicator: 3dp primary / 2dp secondary
|
|
2436
|
+
* - State layers: 8% hover, 12% pressed/focus
|
|
2437
|
+
*
|
|
2438
|
+
* @example
|
|
2439
|
+
* ```tsx
|
|
2440
|
+
* // Label only
|
|
2441
|
+
* <Tab id="overview" label="Overview" />
|
|
2442
|
+
*
|
|
2443
|
+
* // Icon + label
|
|
2444
|
+
* <Tab id="media" icon={<PhotoIcon />} label="Media" />
|
|
2445
|
+
*
|
|
2446
|
+
* // With numeric badge
|
|
2447
|
+
* <Tab id="messages" label="Messages" badge={5} />
|
|
2448
|
+
*
|
|
2449
|
+
* // With dot badge
|
|
2450
|
+
* <Tab id="notifications" label="Notifications" badge={true} />
|
|
2451
|
+
*
|
|
2452
|
+
* // Disabled
|
|
2453
|
+
* <Tab id="archived" label="Archived" isDisabled />
|
|
2454
|
+
* ```
|
|
2455
|
+
*/
|
|
2456
|
+
declare const Tab: React__default.ForwardRefExoticComponent<TabProps & React__default.RefAttributes<HTMLButtonElement>>;
|
|
2457
|
+
|
|
2458
|
+
/**
|
|
2459
|
+
* Material Design 3 TabPanel Component (Layer 3: Styled)
|
|
2460
|
+
*
|
|
2461
|
+
* Renders the content area associated with a tab.
|
|
2462
|
+
* Only the selected tab's panel content is shown.
|
|
2463
|
+
*
|
|
2464
|
+
* Provides full accessibility:
|
|
2465
|
+
* - role="tabpanel"
|
|
2466
|
+
* - aria-labelledby (pointing to the associated tab)
|
|
2467
|
+
* - Focus management for panels without focusable children (tabIndex=-1)
|
|
2468
|
+
*
|
|
2469
|
+
* MD3 Specifications:
|
|
2470
|
+
* - No specific container styling mandated by MD3 for the panel itself
|
|
2471
|
+
* - The panel should be keyboard-reachable per WCAG requirements
|
|
2472
|
+
*
|
|
2473
|
+
* @example
|
|
2474
|
+
* ```tsx
|
|
2475
|
+
* <TabPanel id="overview">
|
|
2476
|
+
* <h2>Overview</h2>
|
|
2477
|
+
* <p>Content here...</p>
|
|
2478
|
+
* </TabPanel>
|
|
2479
|
+
* ```
|
|
2480
|
+
*/
|
|
2481
|
+
declare const TabPanel: React__default.ForwardRefExoticComponent<TabPanelProps & React__default.RefAttributes<HTMLDivElement>>;
|
|
2482
|
+
|
|
2483
|
+
/**
|
|
2484
|
+
* Props for the HeadlessTabList container.
|
|
2485
|
+
* State is injected from HeadlessTabsContext (created in Tabs wrapper).
|
|
2486
|
+
*/
|
|
2487
|
+
interface HeadlessTabListContainerProps {
|
|
2488
|
+
/** Children are Tab elements */
|
|
2489
|
+
children: React.ReactNode;
|
|
2490
|
+
/** Additional CSS classes */
|
|
2491
|
+
className?: string;
|
|
2492
|
+
}
|
|
2493
|
+
/**
|
|
2494
|
+
* Headless TabList Component (Layer 2)
|
|
2495
|
+
*
|
|
2496
|
+
* Unstyled tab list container. Applies useTabList to the container element
|
|
2497
|
+
* which wires up role="tablist", aria-label, and keyboard navigation.
|
|
2498
|
+
* State must be provided via HeadlessTabsContext (from the Tabs wrapper).
|
|
2499
|
+
*
|
|
2500
|
+
* @example
|
|
2501
|
+
* ```tsx
|
|
2502
|
+
* // Advanced usage via headless primitives
|
|
2503
|
+
* // State is provided by the Tabs wrapper above in the tree
|
|
2504
|
+
* <HeadlessTabList className="my-tablist">
|
|
2505
|
+
* {items.map(item => <HeadlessTab key={item.key} item={item} />)}
|
|
2506
|
+
* </HeadlessTabList>
|
|
2507
|
+
* ```
|
|
2508
|
+
*/
|
|
2509
|
+
declare const HeadlessTabList: React$1.ForwardRefExoticComponent<HeadlessTabListContainerProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2510
|
+
/**
|
|
2511
|
+
* Headless Tab Component (Layer 2)
|
|
2512
|
+
*
|
|
2513
|
+
* Unstyled individual tab item. Provides full React Aria accessibility:
|
|
2514
|
+
* - role="tab"
|
|
2515
|
+
* - aria-selected
|
|
2516
|
+
* - aria-controls (pointing to panel)
|
|
2517
|
+
* - roving tabIndex
|
|
2518
|
+
* - keyboard activation
|
|
2519
|
+
*
|
|
2520
|
+
* Must be used within HeadlessTabsContext.
|
|
2521
|
+
*
|
|
2522
|
+
* @example
|
|
2523
|
+
* ```tsx
|
|
2524
|
+
* <HeadlessTab item={item}>
|
|
2525
|
+
* {({ isSelected, isFocusVisible }) => (
|
|
2526
|
+
* <span className={isSelected ? 'font-bold' : ''}>
|
|
2527
|
+
* {item.label}
|
|
2528
|
+
* </span>
|
|
2529
|
+
* )}
|
|
2530
|
+
* </HeadlessTab>
|
|
2531
|
+
* ```
|
|
2532
|
+
*/
|
|
2533
|
+
declare const HeadlessTab: React$1.ForwardRefExoticComponent<HeadlessTabProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
2534
|
+
/**
|
|
2535
|
+
* Headless TabPanel Component (Layer 2)
|
|
2536
|
+
*
|
|
2537
|
+
* Unstyled tab panel. Provides:
|
|
2538
|
+
* - role="tabpanel"
|
|
2539
|
+
* - aria-labelledby (pointing to its tab)
|
|
2540
|
+
* - Focus management for panels without focusable children
|
|
2541
|
+
*
|
|
2542
|
+
* Must be used within HeadlessTabsContext.
|
|
2543
|
+
*
|
|
2544
|
+
* @example
|
|
2545
|
+
* ```tsx
|
|
2546
|
+
* <HeadlessTabPanel>
|
|
2547
|
+
* <p>Panel content here</p>
|
|
2548
|
+
* </HeadlessTabPanel>
|
|
2549
|
+
* ```
|
|
2550
|
+
*/
|
|
2551
|
+
declare const HeadlessTabPanel: React$1.ForwardRefExoticComponent<HeadlessTabPanelProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
2552
|
+
|
|
2553
|
+
/**
|
|
2554
|
+
* Badge value for a NavigationBarItem.
|
|
2555
|
+
*
|
|
2556
|
+
* - `true` — renders a dot indicator (no count)
|
|
2557
|
+
* - `number` — renders the count; 0 hides the badge; values > 999 display "999+"
|
|
2558
|
+
*/
|
|
2559
|
+
type NavigationBarBadge = number | true;
|
|
2560
|
+
/**
|
|
2561
|
+
* Configuration for a single NavigationBar destination item.
|
|
2562
|
+
*
|
|
2563
|
+
* @example
|
|
2564
|
+
* ```tsx
|
|
2565
|
+
* const item: NavigationBarItemConfig = {
|
|
2566
|
+
* key: 'home',
|
|
2567
|
+
* icon: <HomeIcon />,
|
|
2568
|
+
* label: 'Home',
|
|
2569
|
+
* badge: 3,
|
|
2570
|
+
* };
|
|
2571
|
+
* ```
|
|
2572
|
+
*/
|
|
2573
|
+
interface NavigationBarItemConfig {
|
|
2574
|
+
/**
|
|
2575
|
+
* Unique identifier for this destination (used as the selection key).
|
|
2576
|
+
*/
|
|
2577
|
+
key: string;
|
|
2578
|
+
/**
|
|
2579
|
+
* Icon element displayed at 24dp. Always visible regardless of `hideLabels`.
|
|
2580
|
+
*/
|
|
2581
|
+
icon: ReactNode;
|
|
2582
|
+
/**
|
|
2583
|
+
* Visible label beneath the icon.
|
|
2584
|
+
* Required unless `aria-label` is provided (icon-only mode with `hideLabels`).
|
|
2585
|
+
*/
|
|
2586
|
+
label?: string;
|
|
2587
|
+
/**
|
|
2588
|
+
* Badge displayed on the icon.
|
|
2589
|
+
* - `true` renders a dot indicator.
|
|
2590
|
+
* - `0` hides the badge.
|
|
2591
|
+
* - `1–999` renders the count.
|
|
2592
|
+
* - `> 999` renders "999+".
|
|
2593
|
+
*/
|
|
2594
|
+
badge?: NavigationBarBadge;
|
|
2595
|
+
/**
|
|
2596
|
+
* When `true`, the item cannot be focused or activated.
|
|
2597
|
+
* @default false
|
|
2598
|
+
*/
|
|
2599
|
+
isDisabled?: boolean;
|
|
2600
|
+
/**
|
|
2601
|
+
* Accessible name used when labels are hidden (`hideLabels` mode).
|
|
2602
|
+
* Required for icon-only items; enforced at runtime via dev warning.
|
|
2603
|
+
*/
|
|
2604
|
+
"aria-label"?: string;
|
|
2605
|
+
}
|
|
2606
|
+
/**
|
|
2607
|
+
* Material Design 3 Navigation Bar (Bottom Navigation) props.
|
|
2608
|
+
*
|
|
2609
|
+
* Accepts 3–5 destination items. Item count outside this range triggers a
|
|
2610
|
+
* dev-only `console.warn`.
|
|
2611
|
+
*
|
|
2612
|
+
* **Controlled usage:**
|
|
2613
|
+
* ```tsx
|
|
2614
|
+
* <NavigationBar
|
|
2615
|
+
* items={items}
|
|
2616
|
+
* activeKey={activeKey}
|
|
2617
|
+
* onActiveChange={setActiveKey}
|
|
2618
|
+
* aria-label="Main navigation"
|
|
2619
|
+
* />
|
|
2620
|
+
* ```
|
|
2621
|
+
*
|
|
2622
|
+
* **Uncontrolled usage:**
|
|
2623
|
+
* ```tsx
|
|
2624
|
+
* <NavigationBar
|
|
2625
|
+
* items={items}
|
|
2626
|
+
* defaultActiveKey="home"
|
|
2627
|
+
* aria-label="Main navigation"
|
|
2628
|
+
* />
|
|
2629
|
+
* ```
|
|
2630
|
+
*
|
|
2631
|
+
* @see https://m3.material.io/components/navigation-bar/overview
|
|
2632
|
+
*/
|
|
2633
|
+
interface NavigationBarProps {
|
|
2634
|
+
/**
|
|
2635
|
+
* Array of 3–5 destination items.
|
|
2636
|
+
* Item count outside the 3–5 range triggers a dev warning.
|
|
2637
|
+
*/
|
|
2638
|
+
items: NavigationBarItemConfig[];
|
|
2639
|
+
/**
|
|
2640
|
+
* Controlled active key. Pair with `onActiveChange`.
|
|
2641
|
+
* Use `null` to explicitly deselect all items.
|
|
2642
|
+
*/
|
|
2643
|
+
activeKey?: Key$1 | null;
|
|
2644
|
+
/**
|
|
2645
|
+
* Default active key for uncontrolled usage.
|
|
2646
|
+
*/
|
|
2647
|
+
defaultActiveKey?: Key$1;
|
|
2648
|
+
/**
|
|
2649
|
+
* Called when the active destination changes.
|
|
2650
|
+
*/
|
|
2651
|
+
onActiveChange?: (key: Key$1) => void;
|
|
2652
|
+
/**
|
|
2653
|
+
* When `true`, hides labels on all items (icon-only mode).
|
|
2654
|
+
* @default false
|
|
2655
|
+
*/
|
|
2656
|
+
hideLabels?: boolean;
|
|
2657
|
+
/**
|
|
2658
|
+
* Accessible label for the `<nav>` landmark element. Required.
|
|
2659
|
+
*
|
|
2660
|
+
* @example "Main navigation"
|
|
2661
|
+
*/
|
|
2662
|
+
"aria-label": string;
|
|
2663
|
+
/**
|
|
2664
|
+
* Disable ripple effect on all items.
|
|
2665
|
+
* @default false
|
|
2666
|
+
*/
|
|
2667
|
+
disableRipple?: boolean;
|
|
2668
|
+
/**
|
|
2669
|
+
* Additional CSS classes merged onto the `<nav>` element via `cn()`.
|
|
2670
|
+
*/
|
|
2671
|
+
className?: string;
|
|
2672
|
+
}
|
|
2673
|
+
/**
|
|
2674
|
+
* Standalone NavigationBarItem props.
|
|
2675
|
+
*
|
|
2676
|
+
* Used internally by `NavigationBar` and available for advanced consumers
|
|
2677
|
+
* composing with `HeadlessNavigationBar`.
|
|
2678
|
+
*
|
|
2679
|
+
* Extends `ButtonHTMLAttributes` (minus `disabled`) so that tab props from
|
|
2680
|
+
* `useTab` can be spread directly onto the rendered `<button>`.
|
|
2681
|
+
*/
|
|
2682
|
+
interface NavigationBarItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "disabled"> {
|
|
2683
|
+
/**
|
|
2684
|
+
* The unique key for this item (passed to the headless layer).
|
|
2685
|
+
*/
|
|
2686
|
+
itemKey: Key$1;
|
|
2687
|
+
/**
|
|
2688
|
+
* Icon element displayed at 24dp.
|
|
2689
|
+
*/
|
|
2690
|
+
icon: ReactNode;
|
|
2691
|
+
/**
|
|
2692
|
+
* Visible label beneath the icon.
|
|
2693
|
+
*/
|
|
2694
|
+
label?: string;
|
|
2695
|
+
/**
|
|
2696
|
+
* Badge value.
|
|
2697
|
+
*/
|
|
2698
|
+
badge?: NavigationBarBadge;
|
|
2699
|
+
/**
|
|
2700
|
+
* Whether this item is the currently selected destination.
|
|
2701
|
+
* @default false
|
|
2702
|
+
*/
|
|
2703
|
+
isActive?: boolean;
|
|
2704
|
+
/**
|
|
2705
|
+
* When `true`, hides the label for this item.
|
|
2706
|
+
* @default false
|
|
2707
|
+
*/
|
|
2708
|
+
hideLabels?: boolean;
|
|
2709
|
+
/**
|
|
2710
|
+
* Whether this item is disabled.
|
|
2711
|
+
* @default false
|
|
2712
|
+
*/
|
|
2713
|
+
isDisabled?: boolean;
|
|
2714
|
+
/**
|
|
2715
|
+
* Disable ripple effect on this item.
|
|
2716
|
+
* @default false
|
|
2717
|
+
*/
|
|
2718
|
+
disableRipple?: boolean;
|
|
2719
|
+
}
|
|
2720
|
+
/**
|
|
2721
|
+
* HeadlessNavigationBar props.
|
|
2722
|
+
*
|
|
2723
|
+
* Provides the accessibility foundation (`role="navigation"`, `role="tablist"`,
|
|
2724
|
+
* `useTabList`, `useTabListState`) without any visual styling.
|
|
2725
|
+
* Intended for advanced consumers who need full visual control.
|
|
2726
|
+
*
|
|
2727
|
+
* @example
|
|
2728
|
+
* ```tsx
|
|
2729
|
+
* <HeadlessNavigationBar
|
|
2730
|
+
* items={items}
|
|
2731
|
+
* defaultSelectedKey="home"
|
|
2732
|
+
* aria-label="Main navigation"
|
|
2733
|
+
* renderItem={(config) => (
|
|
2734
|
+
* <HeadlessNavigationBarItem key={config.key} itemKey={config.key}>
|
|
2735
|
+
* {config.icon}
|
|
2736
|
+
* <span>{config.label}</span>
|
|
2737
|
+
* </HeadlessNavigationBarItem>
|
|
2738
|
+
* )}
|
|
2739
|
+
* />
|
|
2740
|
+
* ```
|
|
2741
|
+
*/
|
|
2742
|
+
interface HeadlessNavigationBarProps {
|
|
2743
|
+
/**
|
|
2744
|
+
* Array of item configs used to build the React Aria collection.
|
|
2745
|
+
*/
|
|
2746
|
+
items: NavigationBarItemConfig[];
|
|
2747
|
+
/**
|
|
2748
|
+
* Controlled selected key. Pair with `onSelectionChange`.
|
|
2749
|
+
* Use `null` to explicitly deselect all items.
|
|
2750
|
+
*/
|
|
2751
|
+
selectedKey?: Key$1 | null;
|
|
2752
|
+
/**
|
|
2753
|
+
* Default selected key for uncontrolled usage.
|
|
2754
|
+
*/
|
|
2755
|
+
defaultSelectedKey?: Key$1;
|
|
2756
|
+
/**
|
|
2757
|
+
* Called when the selected key changes.
|
|
2758
|
+
*/
|
|
2759
|
+
onSelectionChange?: (key: Key$1) => void;
|
|
2760
|
+
/**
|
|
2761
|
+
* Accessible label for the `<nav>` landmark.
|
|
2762
|
+
*/
|
|
2763
|
+
"aria-label": string;
|
|
2764
|
+
/**
|
|
2765
|
+
* Additional CSS classes for the inner `<div role="tablist">`.
|
|
2766
|
+
*/
|
|
2767
|
+
className?: string;
|
|
2768
|
+
/**
|
|
2769
|
+
* Render function called for each item in the collection.
|
|
2770
|
+
* Receives the item config; use `HeadlessNavigationBarItem` inside.
|
|
2771
|
+
*/
|
|
2772
|
+
renderItem: (config: NavigationBarItemConfig) => ReactNode;
|
|
2773
|
+
}
|
|
2774
|
+
/**
|
|
2775
|
+
* Render props passed to `HeadlessNavigationBarItem`'s children when used as
|
|
2776
|
+
* a render function.
|
|
2777
|
+
*/
|
|
2778
|
+
interface NavigationBarItemRenderProps {
|
|
2779
|
+
/** Whether this item is the active destination. */
|
|
2780
|
+
isSelected: boolean;
|
|
2781
|
+
/** Whether the item has a visible keyboard focus ring. */
|
|
2782
|
+
isFocusVisible: boolean;
|
|
2783
|
+
}
|
|
2784
|
+
/**
|
|
2785
|
+
* HeadlessNavigationBarItem props.
|
|
2786
|
+
*
|
|
2787
|
+
* Renders a single tab-accessible button using `useTab` from React Aria.
|
|
2788
|
+
* Must be rendered inside `HeadlessNavigationBar` (reads state from context).
|
|
2789
|
+
*
|
|
2790
|
+
* Accepts children as ReactNode or as a render function receiving state props.
|
|
2791
|
+
*
|
|
2792
|
+
* @example
|
|
2793
|
+
* ```tsx
|
|
2794
|
+
* // Static children
|
|
2795
|
+
* <HeadlessNavigationBarItem itemKey="home">
|
|
2796
|
+
* Home
|
|
2797
|
+
* </HeadlessNavigationBarItem>
|
|
2798
|
+
*
|
|
2799
|
+
* // Render function (access to isSelected / isFocusVisible)
|
|
2800
|
+
* <HeadlessNavigationBarItem itemKey="home">
|
|
2801
|
+
* {({ isSelected }) => (
|
|
2802
|
+
* <span style={{ fontWeight: isSelected ? 'bold' : 'normal' }}>Home</span>
|
|
2803
|
+
* )}
|
|
2804
|
+
* </HeadlessNavigationBarItem>
|
|
2805
|
+
* ```
|
|
2806
|
+
*/
|
|
2807
|
+
interface HeadlessNavigationBarItemProps {
|
|
2808
|
+
/**
|
|
2809
|
+
* The key matching `NavigationBarItemConfig.key`. Used to look up the
|
|
2810
|
+
* item in the React Aria collection state.
|
|
2811
|
+
*/
|
|
2812
|
+
itemKey: Key$1;
|
|
2813
|
+
/**
|
|
2814
|
+
* Content to render inside the button — either a ReactNode or a render
|
|
2815
|
+
* function receiving `{ isSelected, isFocusVisible }`.
|
|
2816
|
+
*/
|
|
2817
|
+
children: ReactNode | ((renderProps: NavigationBarItemRenderProps) => ReactNode);
|
|
2818
|
+
/**
|
|
2819
|
+
* Additional CSS classes merged onto the `<button>` element.
|
|
2820
|
+
*/
|
|
2821
|
+
className?: string;
|
|
2822
|
+
/**
|
|
2823
|
+
* Accessible label for icon-only items (when no visible text label is present).
|
|
2824
|
+
* Applied as `aria-label` on the `<button>` element.
|
|
2825
|
+
*/
|
|
2826
|
+
"aria-label"?: string;
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
/**
|
|
2830
|
+
* Material Design 3 Navigation Bar (Bottom Navigation) — Layer 3.
|
|
2831
|
+
*
|
|
2832
|
+
* Renders a fixed bottom navigation bar with 3–5 destination items, each with
|
|
2833
|
+
* an icon, optional label, animated active indicator pill, and optional badge.
|
|
2834
|
+
*
|
|
2835
|
+
* **Architecture:**
|
|
2836
|
+
* - Layer 3 (this file): MD3 styled, CVA variants, `'use client'`
|
|
2837
|
+
* - Layer 2: `HeadlessNavigationBar` + `HeadlessNavigationBarItem` — React Aria
|
|
2838
|
+
* - Layer 1: `useTabList`, `useTab`, `useFocusRing` — accessibility foundation
|
|
2839
|
+
*
|
|
2840
|
+
* **Key Features:**
|
|
2841
|
+
* - 3–5 destination items (dev warning outside this range)
|
|
2842
|
+
* - Animated indicator pill per MD3 motion tokens (scale + opacity)
|
|
2843
|
+
* - Badge: dot, numeric count, "999+" truncation, hidden at 0
|
|
2844
|
+
* - `hideLabels` for icon-only mode
|
|
2845
|
+
* - Controlled (`activeKey` + `onActiveChange`) and uncontrolled (`defaultActiveKey`)
|
|
2846
|
+
* - Full keyboard navigation: Arrow Left/Right, Home, End, roving `tabIndex`
|
|
2847
|
+
* - WCAG 2.1 AA: `role="navigation"` + `aria-label`, `role="tablist"`,
|
|
2848
|
+
* `role="tab"` + `aria-selected`, visible focus ring
|
|
2849
|
+
*
|
|
2850
|
+
* **Future — Navigation Rail:**
|
|
2851
|
+
* At wider viewports, a NavigationBar may transition to a Navigation Rail.
|
|
2852
|
+
* This is a separate component tracked as a future Phase 5+ item.
|
|
2853
|
+
*
|
|
2854
|
+
* @example
|
|
2855
|
+
* ```tsx
|
|
2856
|
+
* // Uncontrolled
|
|
2857
|
+
* <NavigationBar
|
|
2858
|
+
* items={[
|
|
2859
|
+
* { key: 'home', icon: <HomeIcon />, label: 'Home' },
|
|
2860
|
+
* { key: 'search', icon: <SearchIcon />, label: 'Search', badge: 3 },
|
|
2861
|
+
* { key: 'profile', icon: <ProfileIcon />, label: 'Profile' },
|
|
2862
|
+
* ]}
|
|
2863
|
+
* defaultActiveKey="home"
|
|
2864
|
+
* aria-label="Main navigation"
|
|
2865
|
+
* />
|
|
2866
|
+
*
|
|
2867
|
+
* // Controlled
|
|
2868
|
+
* <NavigationBar
|
|
2869
|
+
* items={items}
|
|
2870
|
+
* activeKey={activeKey}
|
|
2871
|
+
* onActiveChange={setActiveKey}
|
|
2872
|
+
* aria-label="Main navigation"
|
|
2873
|
+
* />
|
|
2874
|
+
*
|
|
2875
|
+
* // Icon-only mode
|
|
2876
|
+
* <NavigationBar
|
|
2877
|
+
* items={iconOnlyItems}
|
|
2878
|
+
* defaultActiveKey="home"
|
|
2879
|
+
* aria-label="Main navigation"
|
|
2880
|
+
* hideLabels
|
|
2881
|
+
* />
|
|
2882
|
+
* ```
|
|
2883
|
+
*
|
|
2884
|
+
* @see https://m3.material.io/components/navigation-bar/overview
|
|
2885
|
+
* @see https://m3.material.io/components/navigation-bar/specs
|
|
2886
|
+
*/
|
|
2887
|
+
declare const NavigationBar: React$1.ForwardRefExoticComponent<NavigationBarProps & React$1.RefAttributes<HTMLElement>>;
|
|
2888
|
+
|
|
2889
|
+
/**
|
|
2890
|
+
* Material Design 3 Navigation Bar Item (Layer 3).
|
|
2891
|
+
*
|
|
2892
|
+
* Renders a single destination item within a `NavigationBar`. Handles:
|
|
2893
|
+
* - Active indicator pill (`rounded-full`, animated with MD3 motion tokens)
|
|
2894
|
+
* - Icon slot (24dp, always visible)
|
|
2895
|
+
* - Badge (dot, numeric count, 999+ truncation)
|
|
2896
|
+
* - Label (hidden in `hideLabels` mode)
|
|
2897
|
+
* - MD3 state layers (hover `opacity-8`, pressed `opacity-12`)
|
|
2898
|
+
* - Ripple effect via `useRipple`
|
|
2899
|
+
* - Focus ring via `data-focus-visible`
|
|
2900
|
+
*
|
|
2901
|
+
* Used internally by `NavigationBar`. Can also be composed with
|
|
2902
|
+
* `HeadlessNavigationBarItem` for advanced customization.
|
|
2903
|
+
*
|
|
2904
|
+
* **Future — Navigation Rail:**
|
|
2905
|
+
* At wider viewports, a NavigationBar may transition to a Navigation Rail.
|
|
2906
|
+
* This is a separate component tracked as a future Phase 5+ item.
|
|
2907
|
+
*
|
|
2908
|
+
* @example
|
|
2909
|
+
* ```tsx
|
|
2910
|
+
* // Used standalone (advanced consumer with HeadlessNavigationBar)
|
|
2911
|
+
* <NavigationBarItem
|
|
2912
|
+
* itemKey="home"
|
|
2913
|
+
* icon={<HomeIcon />}
|
|
2914
|
+
* label="Home"
|
|
2915
|
+
* isActive
|
|
2916
|
+
* />
|
|
2917
|
+
* ```
|
|
2918
|
+
*/
|
|
2919
|
+
declare const NavigationBarItem: React$1.ForwardRefExoticComponent<NavigationBarItemProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
2920
|
+
|
|
2921
|
+
/**
|
|
2922
|
+
* Headless Navigation Bar (Layer 2).
|
|
2923
|
+
*
|
|
2924
|
+
* Renders an accessible `<nav role="navigation">` landmark wrapping a
|
|
2925
|
+
* `<div role="tablist">`. Provides keyboard navigation (Arrow Left/Right,
|
|
2926
|
+
* Home, End) and full ARIA semantics via React Aria's `useTabList`.
|
|
2927
|
+
*
|
|
2928
|
+
* All item accessibility is handled by `HeadlessNavigationBarItem`.
|
|
2929
|
+
*
|
|
2930
|
+
* Use this component when you need complete visual control beyond what the
|
|
2931
|
+
* styled `NavigationBar` provides.
|
|
2932
|
+
*
|
|
2933
|
+
* @example
|
|
2934
|
+
* ```tsx
|
|
2935
|
+
* <HeadlessNavigationBar
|
|
2936
|
+
* items={items}
|
|
2937
|
+
* defaultSelectedKey="home"
|
|
2938
|
+
* aria-label="Main navigation"
|
|
2939
|
+
* renderItem={(config) => (
|
|
2940
|
+
* <HeadlessNavigationBarItem key={config.key} itemKey={config.key}>
|
|
2941
|
+
* {config.icon}
|
|
2942
|
+
* <span>{config.label}</span>
|
|
2943
|
+
* </HeadlessNavigationBarItem>
|
|
2944
|
+
* )}
|
|
2945
|
+
* />
|
|
2946
|
+
* ```
|
|
2947
|
+
*/
|
|
2948
|
+
declare const HeadlessNavigationBar: React$1.ForwardRefExoticComponent<HeadlessNavigationBarProps & React$1.RefAttributes<HTMLElement>>;
|
|
2949
|
+
/**
|
|
2950
|
+
* Headless Navigation Bar Item (Layer 2).
|
|
2951
|
+
*
|
|
2952
|
+
* Renders an accessible `<button role="tab">` using React Aria's `useTab`.
|
|
2953
|
+
* Provides `aria-selected`, `aria-disabled`, roving `tabIndex`, and
|
|
2954
|
+
* focus management via `useFocusRing`.
|
|
2955
|
+
*
|
|
2956
|
+
* Must be rendered inside `HeadlessNavigationBar`.
|
|
2957
|
+
*
|
|
2958
|
+
* @example
|
|
2959
|
+
* ```tsx
|
|
2960
|
+
* <HeadlessNavigationBarItem itemKey="home" className="my-item">
|
|
2961
|
+
* <HomeIcon aria-hidden />
|
|
2962
|
+
* <span>Home</span>
|
|
2963
|
+
* </HeadlessNavigationBarItem>
|
|
2964
|
+
* ```
|
|
2965
|
+
*/
|
|
2966
|
+
declare const HeadlessNavigationBarItem: React$1.ForwardRefExoticComponent<HeadlessNavigationBarItemProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
2967
|
+
|
|
2968
|
+
/**
|
|
2969
|
+
* Structural variant of the Navigation Drawer.
|
|
2970
|
+
*
|
|
2971
|
+
* - `standard` — inline `<nav>` landmark; no overlay or focus trap; supports
|
|
2972
|
+
* controlled `open` prop for collapsible layouts.
|
|
2973
|
+
* - `modal` — overlay dialog with scrim backdrop, slide-in animation,
|
|
2974
|
+
* focus trap, and `Escape` to close.
|
|
2975
|
+
*/
|
|
2976
|
+
type DrawerVariant = "standard" | "modal";
|
|
2977
|
+
/**
|
|
2978
|
+
* Material Design 3 Navigation Drawer props.
|
|
2979
|
+
*
|
|
2980
|
+
* Supports two structural variants — Standard (inline, permanently visible or
|
|
2981
|
+
* togglable) and Modal (overlay with scrim and focus trap).
|
|
2982
|
+
*
|
|
2983
|
+
* @example
|
|
2984
|
+
* ```tsx
|
|
2985
|
+
* // Standard variant
|
|
2986
|
+
* <Drawer variant="standard" open={open} onOpenChange={setOpen} aria-label="App navigation">
|
|
2987
|
+
* <DrawerItem label="Home" isActive />
|
|
2988
|
+
* <DrawerItem label="Settings" />
|
|
2989
|
+
* </Drawer>
|
|
2990
|
+
*
|
|
2991
|
+
* // Modal variant with trigger
|
|
2992
|
+
* <Drawer variant="modal" open={open} onOpenChange={setOpen} aria-label="App navigation">
|
|
2993
|
+
* <DrawerItem label="Home" isActive />
|
|
2994
|
+
* <DrawerSection header="Account">
|
|
2995
|
+
* <DrawerItem label="Profile" />
|
|
2996
|
+
* </DrawerSection>
|
|
2997
|
+
* </Drawer>
|
|
2998
|
+
* ```
|
|
2999
|
+
*/
|
|
3000
|
+
interface DrawerProps extends AriaDialogProps {
|
|
3001
|
+
/**
|
|
3002
|
+
* Structural variant — drives which React Aria hooks and DOM structure are used.
|
|
3003
|
+
* @default 'standard'
|
|
3004
|
+
*/
|
|
3005
|
+
variant?: DrawerVariant;
|
|
3006
|
+
/**
|
|
3007
|
+
* Controlled open state. Pair with `onOpenChange`.
|
|
3008
|
+
*/
|
|
3009
|
+
open?: boolean;
|
|
3010
|
+
/**
|
|
3011
|
+
* Default open state for uncontrolled usage.
|
|
3012
|
+
* @default false
|
|
3013
|
+
*/
|
|
3014
|
+
defaultOpen?: boolean;
|
|
3015
|
+
/**
|
|
3016
|
+
* Called when the open state changes (e.g. Escape key, scrim click).
|
|
3017
|
+
*/
|
|
3018
|
+
onOpenChange?: (open: boolean) => void;
|
|
3019
|
+
/**
|
|
3020
|
+
* Accessible label for the drawer landmark/dialog. Required.
|
|
3021
|
+
*
|
|
3022
|
+
* @example "App navigation"
|
|
3023
|
+
*/
|
|
3024
|
+
"aria-label": string;
|
|
3025
|
+
/**
|
|
3026
|
+
* Drawer content — typically `DrawerItem` and `DrawerSection` elements.
|
|
3027
|
+
*/
|
|
3028
|
+
children: ReactNode;
|
|
3029
|
+
/**
|
|
3030
|
+
* Additional CSS classes merged onto the drawer panel element.
|
|
3031
|
+
*/
|
|
3032
|
+
className?: string;
|
|
3033
|
+
/**
|
|
3034
|
+
* Disable ripple effect on all items within the drawer.
|
|
3035
|
+
* @default false
|
|
3036
|
+
*/
|
|
3037
|
+
disableRipple?: boolean;
|
|
3038
|
+
}
|
|
3039
|
+
/**
|
|
3040
|
+
* Material Design 3 Navigation Drawer Item props.
|
|
3041
|
+
*
|
|
3042
|
+
* Renders as `<a>` when `href` is provided (using `useLink`), or as `<button>`
|
|
3043
|
+
* when no `href` is provided (using `useButton`).
|
|
3044
|
+
*
|
|
3045
|
+
* @example
|
|
3046
|
+
* ```tsx
|
|
3047
|
+
* // Button-based item (no href)
|
|
3048
|
+
* <DrawerItem
|
|
3049
|
+
* icon={<HomeIcon />}
|
|
3050
|
+
* label="Home"
|
|
3051
|
+
* isActive
|
|
3052
|
+
* onPress={() => setPage('home')}
|
|
3053
|
+
* />
|
|
3054
|
+
*
|
|
3055
|
+
* // Link-based item (with href)
|
|
3056
|
+
* <DrawerItem href="/settings" icon={<SettingsIcon />} label="Settings" />
|
|
3057
|
+
*
|
|
3058
|
+
* // With badge
|
|
3059
|
+
* <DrawerItem label="Inbox" badge={<span>3</span>} />
|
|
3060
|
+
*
|
|
3061
|
+
* // Disabled
|
|
3062
|
+
* <DrawerItem label="Disabled" isDisabled />
|
|
3063
|
+
* ```
|
|
3064
|
+
*/
|
|
3065
|
+
interface DrawerItemProps extends AriaButtonProps, Pick<AriaLinkOptions, "href"> {
|
|
3066
|
+
/**
|
|
3067
|
+
* Optional URL — when provided, renders the item as `<a>` using `useLink`.
|
|
3068
|
+
* When absent, renders as `<button>` using `useButton`.
|
|
3069
|
+
*/
|
|
3070
|
+
href?: string;
|
|
3071
|
+
/**
|
|
3072
|
+
* Optional leading icon (24dp).
|
|
3073
|
+
*/
|
|
3074
|
+
icon?: ReactNode;
|
|
3075
|
+
/**
|
|
3076
|
+
* Visible label text. Required.
|
|
3077
|
+
*/
|
|
3078
|
+
label: string;
|
|
3079
|
+
/**
|
|
3080
|
+
* Optional trailing badge or secondary indicator element.
|
|
3081
|
+
*/
|
|
3082
|
+
badge?: ReactNode;
|
|
3083
|
+
/**
|
|
3084
|
+
* Optional secondary descriptive text rendered below the label.
|
|
3085
|
+
*/
|
|
3086
|
+
secondaryText?: string;
|
|
3087
|
+
/**
|
|
3088
|
+
* When `true`, marks this item as the active destination.
|
|
3089
|
+
* Applies `aria-current="page"`, active indicator background, and
|
|
3090
|
+
* `text-on-secondary-container`.
|
|
3091
|
+
* @default false
|
|
3092
|
+
*/
|
|
3093
|
+
isActive?: boolean;
|
|
3094
|
+
/**
|
|
3095
|
+
* Disable ripple effect on this specific item.
|
|
3096
|
+
* @default false
|
|
3097
|
+
*/
|
|
3098
|
+
disableRipple?: boolean;
|
|
3099
|
+
/**
|
|
3100
|
+
* Additional CSS classes merged via `cn()`.
|
|
3101
|
+
*/
|
|
3102
|
+
className?: string;
|
|
3103
|
+
}
|
|
3104
|
+
/**
|
|
3105
|
+
* Material Design 3 Navigation Drawer Section props.
|
|
3106
|
+
*
|
|
3107
|
+
* Groups related `DrawerItem` elements with an optional header label and
|
|
3108
|
+
* a preceding divider (except the first section).
|
|
3109
|
+
*
|
|
3110
|
+
* @example
|
|
3111
|
+
* ```tsx
|
|
3112
|
+
* <DrawerSection header="Account">
|
|
3113
|
+
* <DrawerItem label="Profile" />
|
|
3114
|
+
* <DrawerItem label="Logout" />
|
|
3115
|
+
* </DrawerSection>
|
|
3116
|
+
* ```
|
|
3117
|
+
*/
|
|
3118
|
+
interface DrawerSectionProps {
|
|
3119
|
+
/**
|
|
3120
|
+
* Optional section header label rendered in `text-title-small`.
|
|
3121
|
+
*/
|
|
3122
|
+
header?: string;
|
|
3123
|
+
/**
|
|
3124
|
+
* Section content — typically `DrawerItem` elements.
|
|
3125
|
+
*/
|
|
3126
|
+
children: ReactNode;
|
|
3127
|
+
/**
|
|
3128
|
+
* When `true`, renders a top divider line above the section.
|
|
3129
|
+
* @default false
|
|
3130
|
+
*/
|
|
3131
|
+
showDivider?: boolean;
|
|
3132
|
+
/**
|
|
3133
|
+
* Additional CSS classes merged via `cn()`.
|
|
3134
|
+
*/
|
|
3135
|
+
className?: string;
|
|
3136
|
+
}
|
|
3137
|
+
/**
|
|
3138
|
+
* Props for the headless Drawer primitive (Layer 2).
|
|
3139
|
+
* Provides behavior and ARIA semantics without visual styling.
|
|
3140
|
+
*/
|
|
3141
|
+
interface HeadlessDrawerProps {
|
|
3142
|
+
/**
|
|
3143
|
+
* Structural variant — drives which React Aria hooks are used.
|
|
3144
|
+
* @default 'standard'
|
|
3145
|
+
*/
|
|
3146
|
+
variant?: DrawerVariant;
|
|
3147
|
+
/**
|
|
3148
|
+
* Controlled open state.
|
|
3149
|
+
*/
|
|
3150
|
+
open?: boolean;
|
|
3151
|
+
/**
|
|
3152
|
+
* Default open state for uncontrolled usage.
|
|
3153
|
+
* @default false
|
|
3154
|
+
*/
|
|
3155
|
+
defaultOpen?: boolean;
|
|
3156
|
+
/**
|
|
3157
|
+
* Called when the open state changes.
|
|
3158
|
+
*/
|
|
3159
|
+
onOpenChange?: (open: boolean) => void;
|
|
3160
|
+
/**
|
|
3161
|
+
* Accessible label. Required.
|
|
3162
|
+
*/
|
|
3163
|
+
"aria-label": string;
|
|
3164
|
+
/**
|
|
3165
|
+
* Drawer content.
|
|
3166
|
+
*/
|
|
3167
|
+
children: ReactNode;
|
|
3168
|
+
/**
|
|
3169
|
+
* Additional CSS classes for the drawer panel element.
|
|
3170
|
+
*/
|
|
3171
|
+
className?: string;
|
|
3172
|
+
/**
|
|
3173
|
+
* Additional CSS classes for the scrim element (modal variant only).
|
|
3174
|
+
*/
|
|
3175
|
+
scrimClassName?: string;
|
|
3176
|
+
/**
|
|
3177
|
+
* Disable ripple on all items.
|
|
3178
|
+
* @default false
|
|
3179
|
+
*/
|
|
3180
|
+
disableRipple?: boolean;
|
|
3181
|
+
}
|
|
3182
|
+
/**
|
|
3183
|
+
* Props for the headless DrawerItem primitive (Layer 2).
|
|
3184
|
+
*/
|
|
3185
|
+
interface HeadlessDrawerItemProps extends AriaButtonProps, Pick<AriaLinkOptions, "href"> {
|
|
3186
|
+
/**
|
|
3187
|
+
* Optional URL — determines `<a>` vs `<button>` rendering.
|
|
3188
|
+
*/
|
|
3189
|
+
href?: string;
|
|
3190
|
+
/**
|
|
3191
|
+
* Whether this item is active (`aria-current="page"`).
|
|
3192
|
+
* @default false
|
|
3193
|
+
*/
|
|
3194
|
+
isActive?: boolean;
|
|
3195
|
+
/**
|
|
3196
|
+
* Item content.
|
|
3197
|
+
*/
|
|
3198
|
+
children: ReactNode;
|
|
3199
|
+
/**
|
|
3200
|
+
* Additional CSS classes.
|
|
3201
|
+
*/
|
|
3202
|
+
className?: string;
|
|
3203
|
+
/**
|
|
3204
|
+
* Mouse down handler (for ripple effect).
|
|
3205
|
+
*/
|
|
3206
|
+
onMouseDown?: (e: React.MouseEvent<HTMLElement>) => void;
|
|
3207
|
+
}
|
|
3208
|
+
/**
|
|
3209
|
+
* Context value shared between HeadlessDrawer and its children.
|
|
3210
|
+
* @internal
|
|
3211
|
+
*/
|
|
3212
|
+
interface DrawerContextValue {
|
|
3213
|
+
/** Whether the drawer is currently open. */
|
|
3214
|
+
isOpen: boolean;
|
|
3215
|
+
/** Callback to close the drawer. */
|
|
3216
|
+
close: () => void;
|
|
3217
|
+
/** Whether ripple is disabled for all items. */
|
|
3218
|
+
disableRipple: boolean;
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
/**
|
|
3222
|
+
* Material Design 3 Navigation Drawer (Layer 3: Styled).
|
|
3223
|
+
*
|
|
3224
|
+
* Supports two structural variants driven by the `variant` prop:
|
|
3225
|
+
*
|
|
3226
|
+
* - **`standard`** — Inline `<nav>` landmark. Permanently visible or
|
|
3227
|
+
* collapsible via controlled `open` prop. No overlay or focus trap.
|
|
3228
|
+
* Surface: `bg-surface-container-low`.
|
|
3229
|
+
*
|
|
3230
|
+
* - **`modal`** — Overlay dialog with scrim backdrop, slide-in animation,
|
|
3231
|
+
* focus trap, and `Escape` to close.
|
|
3232
|
+
* Surface: `bg-surface-container`, `shadow-elevation-1`.
|
|
3233
|
+
*
|
|
3234
|
+
* Both variants:
|
|
3235
|
+
* - `role="navigation"` on the outer wrapper
|
|
3236
|
+
* - `rounded-r-xl` (28px per MD3 shape extra-large on right side only)
|
|
3237
|
+
* - Slide-in animation: `translate-x` driven by MD3 motion tokens
|
|
3238
|
+
* - `w-drawer` (360dp per MD3 spec)
|
|
3239
|
+
*
|
|
3240
|
+
* Modal-only:
|
|
3241
|
+
* - `role="dialog"` + `aria-modal="true"` on the panel
|
|
3242
|
+
* - `FocusScope` containing focus + restoring on close
|
|
3243
|
+
* - `usePreventScroll` to lock body scroll
|
|
3244
|
+
* - Scrim: `bg-scrim opacity-32` — click closes drawer
|
|
3245
|
+
* - `Escape` key closes drawer
|
|
3246
|
+
*
|
|
3247
|
+
* @example
|
|
3248
|
+
* ```tsx
|
|
3249
|
+
* // Standard variant (collapsible sidebar)
|
|
3250
|
+
* <Drawer
|
|
3251
|
+
* variant="standard"
|
|
3252
|
+
* open={sidebarOpen}
|
|
3253
|
+
* onOpenChange={setSidebarOpen}
|
|
3254
|
+
* aria-label="App navigation"
|
|
3255
|
+
* >
|
|
3256
|
+
* <DrawerItem icon={<HomeIcon />} label="Home" isActive />
|
|
3257
|
+
* <DrawerSection header="Settings" showDivider>
|
|
3258
|
+
* <DrawerItem icon={<SettingsIcon />} label="Preferences" />
|
|
3259
|
+
* </DrawerSection>
|
|
3260
|
+
* </Drawer>
|
|
3261
|
+
*
|
|
3262
|
+
* // Modal variant (overlay)
|
|
3263
|
+
* <Drawer
|
|
3264
|
+
* variant="modal"
|
|
3265
|
+
* open={drawerOpen}
|
|
3266
|
+
* onOpenChange={setDrawerOpen}
|
|
3267
|
+
* aria-label="App navigation"
|
|
3268
|
+
* >
|
|
3269
|
+
* <DrawerItem label="Home" isActive />
|
|
3270
|
+
* <DrawerItem label="Inbox" badge={<span>5</span>} />
|
|
3271
|
+
* </Drawer>
|
|
3272
|
+
* ```
|
|
3273
|
+
*
|
|
3274
|
+
* @see https://m3.material.io/components/navigation-drawer/overview
|
|
3275
|
+
*/
|
|
3276
|
+
declare const Drawer: React$1.ForwardRefExoticComponent<DrawerProps & React$1.RefAttributes<HTMLElement>>;
|
|
3277
|
+
|
|
3278
|
+
/**
|
|
3279
|
+
* Material Design 3 Navigation Drawer Item (Layer 3: Styled).
|
|
3280
|
+
*
|
|
3281
|
+
* Renders a navigation destination row following MD3 Navigation Drawer specs.
|
|
3282
|
+
* Uses `HeadlessDrawerItem` for behavior and accessibility, CVA for variants.
|
|
3283
|
+
*
|
|
3284
|
+
* Renders as `<a>` when `href` is provided, `<button>` otherwise.
|
|
3285
|
+
*
|
|
3286
|
+
* Features:
|
|
3287
|
+
* - Active indicator: `bg-secondary-container` / `text-on-secondary-container`
|
|
3288
|
+
* - `aria-current="page"` on active item
|
|
3289
|
+
* - Ripple effect on interaction
|
|
3290
|
+
* - Hover/focus/pressed state layers (MD3 spec: 8% / 12%)
|
|
3291
|
+
* - Optional leading icon (24dp slot)
|
|
3292
|
+
* - Optional trailing badge or secondary text
|
|
3293
|
+
* - Disabled state: `opacity-38`, non-interactive
|
|
3294
|
+
*
|
|
3295
|
+
* @example
|
|
3296
|
+
* ```tsx
|
|
3297
|
+
* // Active item with icon
|
|
3298
|
+
* <DrawerItem icon={<HomeIcon />} label="Home" isActive onPress={() => navigate('/')} />
|
|
3299
|
+
*
|
|
3300
|
+
* // Link item
|
|
3301
|
+
* <DrawerItem href="/settings" icon={<SettingsIcon />} label="Settings" />
|
|
3302
|
+
*
|
|
3303
|
+
* // Item with badge
|
|
3304
|
+
* <DrawerItem label="Inbox" badge={<span>3</span>} />
|
|
3305
|
+
*
|
|
3306
|
+
* // Disabled
|
|
3307
|
+
* <DrawerItem label="Disabled Feature" isDisabled />
|
|
3308
|
+
* ```
|
|
3309
|
+
*
|
|
3310
|
+
* @see https://m3.material.io/components/navigation-drawer/specs
|
|
3311
|
+
*/
|
|
3312
|
+
declare const DrawerItem: React$1.ForwardRefExoticComponent<DrawerItemProps & React$1.RefAttributes<HTMLElement>>;
|
|
3313
|
+
|
|
3314
|
+
/**
|
|
3315
|
+
* Material Design 3 Navigation Drawer Section (Layer 3: Styled).
|
|
3316
|
+
*
|
|
3317
|
+
* Groups related `DrawerItem` elements with an optional header label and
|
|
3318
|
+
* a horizontal divider. Follows MD3 Navigation Drawer spec for section
|
|
3319
|
+
* grouping and typography.
|
|
3320
|
+
*
|
|
3321
|
+
* Features:
|
|
3322
|
+
* - Optional header label: `text-title-small text-on-surface-variant`
|
|
3323
|
+
* - Optional top divider: `border-outline-variant`
|
|
3324
|
+
* - Semantic `<hr role="separator">` for the divider
|
|
3325
|
+
*
|
|
3326
|
+
* @example
|
|
3327
|
+
* ```tsx
|
|
3328
|
+
* // Section with header and divider
|
|
3329
|
+
* <DrawerSection header="Account" showDivider>
|
|
3330
|
+
* <DrawerItem icon={<ProfileIcon />} label="Profile" />
|
|
3331
|
+
* <DrawerItem icon={<LogoutIcon />} label="Logout" />
|
|
3332
|
+
* </DrawerSection>
|
|
3333
|
+
*
|
|
3334
|
+
* // Section without header (just a visual group)
|
|
3335
|
+
* <DrawerSection showDivider>
|
|
3336
|
+
* <DrawerItem label="Help" />
|
|
3337
|
+
* </DrawerSection>
|
|
3338
|
+
* ```
|
|
3339
|
+
*
|
|
3340
|
+
* @see https://m3.material.io/components/navigation-drawer/specs
|
|
3341
|
+
*/
|
|
3342
|
+
declare const DrawerSection: React$1.ForwardRefExoticComponent<DrawerSectionProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
3343
|
+
|
|
3344
|
+
/**
|
|
3345
|
+
* Headless Navigation Drawer (Layer 2).
|
|
3346
|
+
*
|
|
3347
|
+
* Provides all behavior and ARIA semantics without any visual styling.
|
|
3348
|
+
* Renders two distinct DOM structures based on the `variant` prop:
|
|
3349
|
+
*
|
|
3350
|
+
* - **`standard`**: `<nav role="navigation">` — no overlay, no focus trap
|
|
3351
|
+
* - **`modal`**: `<nav role="navigation">` containing a `FocusScope`-wrapped
|
|
3352
|
+
* `<div role="dialog" aria-modal="true">` with scrim overlay
|
|
3353
|
+
*
|
|
3354
|
+
* React Aria hooks used:
|
|
3355
|
+
* - `useDialog` — `role="dialog"`, `aria-modal`, `aria-label` on modal panel
|
|
3356
|
+
* - `useOverlay` — dismiss on Escape key and outside click (modal)
|
|
3357
|
+
* - `usePreventScroll` — locks body scroll when modal is open
|
|
3358
|
+
* - `FocusScope` — focus trap + restoreFocus when modal closes
|
|
3359
|
+
* - `useOverlayTriggerState` — open/close state management
|
|
3360
|
+
*
|
|
3361
|
+
* @example
|
|
3362
|
+
* ```tsx
|
|
3363
|
+
* <HeadlessDrawer variant="modal" open aria-label="Navigation">
|
|
3364
|
+
* <HeadlessDrawerItem onPress={() => {}}>Home</HeadlessDrawerItem>
|
|
3365
|
+
* </HeadlessDrawer>
|
|
3366
|
+
* ```
|
|
3367
|
+
*/
|
|
3368
|
+
declare const HeadlessDrawer: React__default.ForwardRefExoticComponent<HeadlessDrawerProps & React__default.RefAttributes<HTMLElement>>;
|
|
3369
|
+
/**
|
|
3370
|
+
* Headless Navigation Drawer Item (Layer 2).
|
|
3371
|
+
*
|
|
3372
|
+
* Renders as:
|
|
3373
|
+
* - `<a>` using `useLink` when `href` is provided
|
|
3374
|
+
* - `<button>` using `useButton` when no `href`
|
|
3375
|
+
*
|
|
3376
|
+
* Applies `aria-current="page"` when `isActive` is true.
|
|
3377
|
+
* Uses `useFocusRing` for visible keyboard focus.
|
|
3378
|
+
*
|
|
3379
|
+
* @example
|
|
3380
|
+
* ```tsx
|
|
3381
|
+
* // Button-based item
|
|
3382
|
+
* <HeadlessDrawerItem onPress={() => navigate('home')} isActive>
|
|
3383
|
+
* Home
|
|
3384
|
+
* </HeadlessDrawerItem>
|
|
3385
|
+
*
|
|
3386
|
+
* // Link-based item
|
|
3387
|
+
* <HeadlessDrawerItem href="/settings">
|
|
3388
|
+
* Settings
|
|
3389
|
+
* </HeadlessDrawerItem>
|
|
3390
|
+
* ```
|
|
3391
|
+
*/
|
|
3392
|
+
declare const HeadlessDrawerItem: React__default.ForwardRefExoticComponent<HeadlessDrawerItemProps & React__default.RefAttributes<HTMLElement>>;
|
|
3393
|
+
|
|
3394
|
+
export { AppBar, AppBarHeadless, type AppBarHeadlessProps, type AppBarProps, type AppBarVariant, Button, type ButtonColor, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, 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, 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, NavigationBar, type NavigationBarBadge, NavigationBarItem, type NavigationBarItemConfig, type NavigationBarItemProps, type NavigationBarItemRenderProps, type NavigationBarProps, Radio, RadioGroup, RadioGroupHeadless, type RadioGroupHeadlessProps, type RadioGroupProps, RadioHeadless, type RadioHeadlessProps, type RadioProps, STATE_LAYER_OPACITY, 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, withOpacity };
|