@primitiv-ui/react 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/package.json +2 -1
- package/src/AccessibleIcon/AccessibleIcon.tsx +6 -2
- package/src/AccessibleIcon/__tests__/AccessibleIcon.test.tsx +1 -1
- package/src/AccessibleIcon/types.ts +4 -0
- package/src/Accordion/Accordion.tsx +34 -12
- package/src/Accordion/AccordionContext.ts +1 -1
- package/src/Accordion/__tests__/Accordion.reading-direction.test.tsx +1 -1
- package/src/Accordion/hooks/useAccordionItem.ts +1 -1
- package/src/Accordion/hooks/useAccordionRoot.ts +1 -1
- package/src/Accordion/hooks/useAccordionTrigger.ts +2 -2
- package/src/Accordion/index.ts +2 -1
- package/src/Accordion/types.ts +55 -13
- package/src/Alert/Alert.tsx +9 -2
- package/src/Alert/__tests__/Alert.test.tsx +1 -1
- package/src/Alert/types.ts +1 -0
- package/src/Avatar/Avatar.tsx +20 -7
- package/src/Avatar/AvatarContext.ts +12 -6
- package/src/Breadcrumb/Breadcrumb.tsx +32 -10
- package/src/Button/Button.tsx +5 -2
- package/src/Button/types.ts +4 -0
- package/src/Carousel/Carousel.tsx +30 -14
- package/src/Carousel/CarouselContext.ts +7 -3
- package/src/Carousel/__tests__/Carousel.asChild.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.auto-play.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.basic-rendering.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.controlled-state.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.error-handling.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.ids.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.imperative-api.test.tsx +2 -2
- package/src/Carousel/__tests__/Carousel.indicators.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.intersection-observer.test.tsx +2 -2
- package/src/Carousel/__tests__/Carousel.keyboard-navigation.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.play-pause.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.prev-next.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.reduced-motion.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.refresh-progress.test.tsx +2 -2
- package/src/Carousel/__tests__/Carousel.scroll-snap-change.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.scroll-sync.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.slides-per-move.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.slides-per-page.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.touch-interaction.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.transition-modes.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.translations.test.tsx +1 -1
- package/src/Carousel/__tests__/Carousel.uncontrolled-state.test.tsx +1 -1
- package/src/Carousel/types.ts +8 -0
- package/src/Checkbox/Checkbox.tsx +11 -6
- package/src/Checkbox/CheckboxContext.ts +1 -1
- package/src/Checkbox/hooks/useCheckboxRoot.ts +1 -1
- package/src/Checkbox/index.ts +1 -0
- package/src/Checkbox/types.ts +30 -3
- package/src/CheckboxCard/CheckboxCard.tsx +13 -11
- package/src/CheckboxCard/CheckboxCardContext.ts +19 -6
- package/src/CheckboxCard/hooks/useCheckboxCardRoot.ts +2 -2
- package/src/CheckboxCard/types.ts +21 -5
- package/src/Collapsible/Collapsible.tsx +37 -21
- package/src/Collapsible/CollapsibleContext.ts +1 -1
- package/src/Collapsible/hooks/useCollapsibleRoot.ts +1 -1
- package/src/Collapsible/hooks/useCollapsibleTrigger.ts +1 -1
- package/src/Collapsible/index.ts +1 -0
- package/src/Collapsible/types.ts +45 -12
- package/src/ContextMenu/ContextMenu.tsx +60 -34
- package/src/ContextMenu/ContextMenuContext.ts +2 -2
- package/src/ContextMenu/ContextMenuSubContext.ts +1 -1
- package/src/ContextMenu/__tests__/ContextMenu.reading-direction.test.tsx +1 -1
- package/src/ContextMenu/index.ts +2 -1
- package/src/ContextMenu/types.ts +160 -17
- package/src/DirectionProvider/DirectionProvider.tsx +7 -1
- package/src/DirectionProvider/__tests__/DirectionProvider.test.tsx +1 -1
- package/src/DirectionProvider/types.ts +1 -0
- package/src/Divider/Divider.tsx +4 -1
- package/src/Divider/__tests__/Divider.test.tsx +1 -1
- package/src/Divider/index.ts +2 -1
- package/src/Divider/types.ts +5 -0
- package/src/Dropdown/Dropdown.tsx +60 -34
- package/src/Dropdown/DropdownContext.ts +2 -2
- package/src/Dropdown/DropdownSubContext.ts +1 -1
- package/src/Dropdown/__tests__/Dropdown.reading-direction.test.tsx +1 -1
- package/src/Dropdown/hooks/useDropdownContent.ts +1 -1
- package/src/Dropdown/hooks/useDropdownItem.ts +1 -1
- package/src/Dropdown/hooks/useDropdownRoot.ts +2 -2
- package/src/Dropdown/hooks/useDropdownTrigger.ts +1 -1
- package/src/Dropdown/index.ts +2 -1
- package/src/Dropdown/types.ts +153 -25
- package/src/EmptyState/EmptyState.tsx +34 -20
- package/src/EmptyState/__tests__/EmptyState.Actions.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Description.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Media.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Root.test.tsx +1 -1
- package/src/EmptyState/__tests__/EmptyState.Title.test.tsx +1 -1
- package/src/EmptyState/types.ts +2 -1
- package/src/Field/Field.tsx +24 -10
- package/src/Field/FieldContext.ts +1 -1
- package/src/Field/types.ts +4 -0
- package/src/Fieldset/Fieldset.tsx +26 -10
- package/src/Fieldset/types.ts +2 -0
- package/src/Input/Input.tsx +6 -3
- package/src/Input/__tests__/Input.field-integration.test.tsx +1 -1
- package/src/Input/types.ts +4 -0
- package/src/InputGroup/InputGroup.tsx +15 -8
- package/src/InputGroup/types.ts +9 -0
- package/src/MillerColumns/MillerColumns.tsx +28 -8
- package/src/MillerColumns/MillerColumnsContext.ts +1 -1
- package/src/MillerColumns/hooks/useMillerColumnsItem.ts +2 -2
- package/src/MillerColumns/hooks/useMillerColumnsRoot.ts +0 -0
- package/src/MillerColumns/index.ts +1 -1
- package/src/MillerColumns/types.ts +67 -14
- package/src/MillerColumns/useMillerColumnsSelection.ts +1 -1
- package/src/Modal/Modal.tsx +25 -11
- package/src/Modal/ModalContext.ts +14 -7
- package/src/Modal/hooks/useModalRoot.ts +1 -1
- package/src/Modal/hooks/useModalTrigger.ts +2 -2
- package/src/Modal/types.ts +51 -2
- package/src/Portal/Portal.tsx +3 -1
- package/src/Portal/types.ts +4 -0
- package/src/Progress/Progress.tsx +12 -7
- package/src/Progress/ProgressContext.ts +18 -6
- package/src/RadioCard/RadioCard.tsx +17 -11
- package/src/RadioCard/RadioCardContext.ts +17 -5
- package/src/RadioCard/RadioCardItemContext.ts +18 -5
- package/src/RadioCard/__tests__/RadioCard.reading-direction.test.tsx +1 -1
- package/src/RadioCard/hooks/useRadioCardRoot.ts +1 -1
- package/src/RadioCard/types.ts +24 -3
- package/src/RadioGroup/RadioGroup.tsx +17 -11
- package/src/RadioGroup/RadioGroupContext.ts +1 -1
- package/src/RadioGroup/RadioGroupItemContext.ts +1 -1
- package/src/RadioGroup/__tests__/RadioGroup.reading-direction.test.tsx +1 -1
- package/src/RadioGroup/hooks/useRadioGroupRoot.ts +1 -1
- package/src/RadioGroup/index.ts +1 -0
- package/src/RadioGroup/types.ts +34 -3
- package/src/Select/Select.tsx +23 -8
- package/src/Select/__tests__/Select.field-integration.test.tsx +1 -1
- package/src/Select/index.ts +1 -1
- package/src/Select/types.ts +18 -3
- package/src/SkipNav/SkipNav.tsx +7 -2
- package/src/SkipNav/__tests__/SkipNav.ids.test.tsx +1 -1
- package/src/Slider/Slider.tsx +26 -11
- package/src/Slider/SliderContext.ts +13 -6
- package/src/Slider/__tests__/Slider.reading-direction.test.tsx +1 -1
- package/src/Slider/hooks/useSliderRoot.ts +1 -1
- package/src/Slider/types.ts +12 -3
- package/src/Status/Status.tsx +9 -2
- package/src/Status/__tests__/Status.test.tsx +1 -1
- package/src/Status/types.ts +4 -0
- package/src/Switch/Switch.tsx +16 -6
- package/src/Switch/SwitchContext.ts +13 -5
- package/src/Switch/hooks/useSwitchRoot.ts +1 -1
- package/src/Switch/types.ts +24 -3
- package/src/Table/Table.tsx +51 -25
- package/src/Table/__tests__/Table.Body.test.tsx +1 -1
- package/src/Table/__tests__/Table.Caption.test.tsx +1 -1
- package/src/Table/__tests__/Table.Cell.test.tsx +1 -1
- package/src/Table/__tests__/Table.Footer.test.tsx +1 -1
- package/src/Table/__tests__/Table.Head.test.tsx +1 -1
- package/src/Table/__tests__/Table.Header.test.tsx +1 -1
- package/src/Table/__tests__/Table.Root.test.tsx +1 -1
- package/src/Table/__tests__/Table.Row.test.tsx +1 -1
- package/src/Table/__tests__/Table.ScrollArea.test.tsx +1 -1
- package/src/Table/index.ts +2 -1
- package/src/Tabs/Tabs.tsx +30 -10
- package/src/Tabs/TabsContext.ts +15 -7
- package/src/Tabs/__tests__/Tabs.asChild.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.basic-rendering.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.change-event-callbacks.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.controlled-state.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.error-handling.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.imperative-api.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.keyboard-interaction.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.lazy-mount.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.mouse-interaction.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.reading-direction.test.tsx +1 -1
- package/src/Tabs/__tests__/Tabs.uncontrolled-state.test.tsx +1 -1
- package/src/Tabs/hooks/useTabsContent.ts +1 -1
- package/src/Tabs/hooks/useTabsRoot.ts +1 -1
- package/src/Tabs/hooks/useTabsTrigger.ts +1 -1
- package/src/Tabs/types.ts +35 -1
- package/src/Tabs/utils.ts +1 -1
- package/src/Textarea/Textarea.tsx +6 -3
- package/src/Textarea/__tests__/Textarea.field-integration.test.tsx +1 -1
- package/src/Textarea/types.ts +4 -0
- package/src/Toggle/Toggle.tsx +11 -4
- package/src/Toggle/types.ts +7 -3
- package/src/ToggleGroup/ToggleGroup.tsx +23 -13
- package/src/ToggleGroup/ToggleGroupContext.ts +1 -1
- package/src/ToggleGroup/__tests__/ToggleGroup.reading-direction.test.tsx +1 -1
- package/src/ToggleGroup/hooks/useToggleGroupRoot.ts +1 -1
- package/src/ToggleGroup/types.ts +45 -5
- package/src/Tooltip/Tooltip.tsx +46 -15
- package/src/Tooltip/TooltipContext.ts +1 -1
- package/src/Tooltip/hooks/useTooltipContent.ts +1 -1
- package/src/Tooltip/hooks/useTooltipRoot.ts +1 -1
- package/src/Tooltip/hooks/useTooltipTrigger.ts +1 -1
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/types.ts +50 -2
- package/src/Tree/Tree.tsx +58 -12
- package/src/Tree/TreeContext.ts +1 -1
- package/src/Tree/__tests__/Tree.selection-path.test.tsx +2 -2
- package/src/Tree/hooks/useTreeItemKeyboard.ts +1 -1
- package/src/Tree/hooks/useTreeRoot.ts +1 -1
- package/src/Tree/index.ts +1 -1
- package/src/Tree/types.ts +39 -7
- package/src/VisuallyHidden/VisuallyHidden.tsx +4 -2
- package/src/VisuallyHidden/__tests__/VisuallyHidden.test.tsx +1 -1
- package/src/VisuallyHidden/types.ts +4 -0
- package/src/index.ts +39 -38
- package/src/types.ts +1 -0
- package/src/utils/createStrictContext.ts +9 -5
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
|
|
3
|
+
import { Slot } from "../Slot/index.ts";
|
|
2
4
|
|
|
3
5
|
import {
|
|
4
6
|
BreadcrumbItemProps,
|
|
@@ -24,7 +26,10 @@ import {
|
|
|
24
26
|
* </Breadcrumb.Root>
|
|
25
27
|
* ```
|
|
26
28
|
*/
|
|
27
|
-
function BreadcrumbRoot({
|
|
29
|
+
export function BreadcrumbRoot({
|
|
30
|
+
children,
|
|
31
|
+
...rest
|
|
32
|
+
}: BreadcrumbRootProps): ReactElement {
|
|
28
33
|
return (
|
|
29
34
|
<nav aria-label="Breadcrumb" {...rest}>
|
|
30
35
|
{children}
|
|
@@ -32,6 +37,7 @@ function BreadcrumbRoot({ children, ...rest }: BreadcrumbRootProps) {
|
|
|
32
37
|
);
|
|
33
38
|
}
|
|
34
39
|
|
|
40
|
+
/** @internal */
|
|
35
41
|
BreadcrumbRoot.displayName = "BreadcrumbRoot";
|
|
36
42
|
|
|
37
43
|
/**
|
|
@@ -51,10 +57,14 @@ BreadcrumbRoot.displayName = "BreadcrumbRoot";
|
|
|
51
57
|
* </Breadcrumb.List>
|
|
52
58
|
* ```
|
|
53
59
|
*/
|
|
54
|
-
function BreadcrumbList({
|
|
60
|
+
export function BreadcrumbList({
|
|
61
|
+
children,
|
|
62
|
+
...rest
|
|
63
|
+
}: BreadcrumbListProps): ReactElement {
|
|
55
64
|
return <ol {...rest}>{children}</ol>;
|
|
56
65
|
}
|
|
57
66
|
|
|
67
|
+
/** @internal */
|
|
58
68
|
BreadcrumbList.displayName = "BreadcrumbList";
|
|
59
69
|
|
|
60
70
|
/**
|
|
@@ -70,10 +80,14 @@ BreadcrumbList.displayName = "BreadcrumbList";
|
|
|
70
80
|
* </Breadcrumb.Item>
|
|
71
81
|
* ```
|
|
72
82
|
*/
|
|
73
|
-
function BreadcrumbItem({
|
|
83
|
+
export function BreadcrumbItem({
|
|
84
|
+
children,
|
|
85
|
+
...rest
|
|
86
|
+
}: BreadcrumbItemProps): ReactElement {
|
|
74
87
|
return <li {...rest}>{children}</li>;
|
|
75
88
|
}
|
|
76
89
|
|
|
90
|
+
/** @internal */
|
|
77
91
|
BreadcrumbItem.displayName = "BreadcrumbItem";
|
|
78
92
|
|
|
79
93
|
/**
|
|
@@ -98,17 +112,18 @@ BreadcrumbItem.displayName = "BreadcrumbItem";
|
|
|
98
112
|
* </Breadcrumb.Link>
|
|
99
113
|
* ```
|
|
100
114
|
*/
|
|
101
|
-
function BreadcrumbLink({
|
|
115
|
+
export function BreadcrumbLink({
|
|
102
116
|
children,
|
|
103
117
|
asChild = false,
|
|
104
118
|
...rest
|
|
105
|
-
}: BreadcrumbLinkProps) {
|
|
119
|
+
}: BreadcrumbLinkProps): ReactElement {
|
|
106
120
|
if (asChild) {
|
|
107
121
|
return <Slot {...rest}>{children}</Slot>;
|
|
108
122
|
}
|
|
109
123
|
return <a {...rest}>{children}</a>;
|
|
110
124
|
}
|
|
111
125
|
|
|
126
|
+
/** @internal */
|
|
112
127
|
BreadcrumbLink.displayName = "BreadcrumbLink";
|
|
113
128
|
|
|
114
129
|
/**
|
|
@@ -125,7 +140,10 @@ BreadcrumbLink.displayName = "BreadcrumbLink";
|
|
|
125
140
|
* </Breadcrumb.Item>
|
|
126
141
|
* ```
|
|
127
142
|
*/
|
|
128
|
-
function BreadcrumbPage({
|
|
143
|
+
export function BreadcrumbPage({
|
|
144
|
+
children,
|
|
145
|
+
...rest
|
|
146
|
+
}: BreadcrumbPageProps): ReactElement {
|
|
129
147
|
return (
|
|
130
148
|
<span aria-current="page" {...rest}>
|
|
131
149
|
{children}
|
|
@@ -133,6 +151,7 @@ function BreadcrumbPage({ children, ...rest }: BreadcrumbPageProps) {
|
|
|
133
151
|
);
|
|
134
152
|
}
|
|
135
153
|
|
|
154
|
+
/** @internal */
|
|
136
155
|
BreadcrumbPage.displayName = "BreadcrumbPage";
|
|
137
156
|
|
|
138
157
|
/**
|
|
@@ -157,10 +176,10 @@ BreadcrumbPage.displayName = "BreadcrumbPage";
|
|
|
157
176
|
* <Breadcrumb.Separator><ChevronRight /></Breadcrumb.Separator>
|
|
158
177
|
* ```
|
|
159
178
|
*/
|
|
160
|
-
function BreadcrumbSeparator({
|
|
179
|
+
export function BreadcrumbSeparator({
|
|
161
180
|
children = "/",
|
|
162
181
|
...rest
|
|
163
|
-
}: BreadcrumbSeparatorProps) {
|
|
182
|
+
}: BreadcrumbSeparatorProps): ReactElement {
|
|
164
183
|
return (
|
|
165
184
|
<li role="presentation" aria-hidden="true" {...rest}>
|
|
166
185
|
{children}
|
|
@@ -168,9 +187,11 @@ function BreadcrumbSeparator({
|
|
|
168
187
|
);
|
|
169
188
|
}
|
|
170
189
|
|
|
190
|
+
/** @internal */
|
|
171
191
|
BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
|
|
172
192
|
|
|
173
|
-
|
|
193
|
+
/** Type of the {@link Breadcrumb} compound: the root callable plus its attached sub-components. */
|
|
194
|
+
export type TBreadcrumbCompound = typeof BreadcrumbRoot & {
|
|
174
195
|
Root: typeof BreadcrumbRoot;
|
|
175
196
|
List: typeof BreadcrumbList;
|
|
176
197
|
Item: typeof BreadcrumbItem;
|
|
@@ -229,6 +250,7 @@ const BreadcrumbCompound: TBreadcrumbCompound = Object.assign(BreadcrumbRoot, {
|
|
|
229
250
|
Separator: BreadcrumbSeparator,
|
|
230
251
|
});
|
|
231
252
|
|
|
253
|
+
/** @internal */
|
|
232
254
|
BreadcrumbCompound.displayName = "Breadcrumb";
|
|
233
255
|
|
|
234
256
|
export { BreadcrumbCompound as Breadcrumb };
|
package/src/Button/Button.tsx
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
|
|
3
|
+
import { Slot } from "../Slot/index.ts";
|
|
2
4
|
import { ButtonProps } from "./types";
|
|
3
5
|
|
|
4
6
|
/**
|
|
@@ -73,7 +75,7 @@ export function Button({
|
|
|
73
75
|
children,
|
|
74
76
|
ref,
|
|
75
77
|
...rest
|
|
76
|
-
}: ButtonProps) {
|
|
78
|
+
}: ButtonProps): ReactElement {
|
|
77
79
|
const rootProps = {
|
|
78
80
|
...rest,
|
|
79
81
|
ref,
|
|
@@ -92,4 +94,5 @@ export function Button({
|
|
|
92
94
|
);
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
/** @internal */
|
|
95
98
|
Button.displayName = "Button";
|
package/src/Button/types.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode, Ref } from "react";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Props for {@link Button} — all native `<button>` attributes (with `type`
|
|
5
|
+
* defaulting to `"button"`) plus the `asChild` escape hatch and a typed `ref`.
|
|
6
|
+
*/
|
|
3
7
|
export type ButtonProps = Omit<ComponentProps<"button">, "type"> & {
|
|
4
8
|
type?: "button" | "submit" | "reset";
|
|
5
9
|
asChild?: boolean;
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { forwardRef, MouseEvent, useCallback } from "react";
|
|
2
|
+
import type {
|
|
3
|
+
ForwardRefExoticComponent,
|
|
4
|
+
PropsWithoutRef,
|
|
5
|
+
ReactElement,
|
|
6
|
+
RefAttributes,
|
|
7
|
+
} from "react";
|
|
2
8
|
|
|
3
|
-
import { Slot } from "../Slot";
|
|
9
|
+
import { Slot } from "../Slot/index.ts";
|
|
4
10
|
import { CarouselProvider } from "./CarouselContext";
|
|
5
11
|
import {
|
|
6
12
|
useCarouselContext,
|
|
7
13
|
useCarouselRoot,
|
|
8
14
|
useCarouselSlide,
|
|
9
15
|
useCarouselViewport,
|
|
10
|
-
} from "./hooks";
|
|
16
|
+
} from "./hooks/index.ts";
|
|
11
17
|
import type {
|
|
12
18
|
CarouselImperativeApi,
|
|
13
19
|
CarouselRootProps,
|
|
@@ -69,10 +75,9 @@ import type {
|
|
|
69
75
|
* <Carousel.Root ariaLabelledBy="promos">…</Carousel.Root>
|
|
70
76
|
* ```
|
|
71
77
|
*/
|
|
72
|
-
export const CarouselRoot
|
|
73
|
-
CarouselImperativeApi
|
|
74
|
-
|
|
75
|
-
>(function CarouselRoot(
|
|
78
|
+
export const CarouselRoot: ForwardRefExoticComponent<
|
|
79
|
+
PropsWithoutRef<CarouselRootProps> & RefAttributes<CarouselImperativeApi>
|
|
80
|
+
> = forwardRef<CarouselImperativeApi, CarouselRootProps>(function CarouselRoot(
|
|
76
81
|
{
|
|
77
82
|
className = "",
|
|
78
83
|
ariaLabel,
|
|
@@ -185,7 +190,7 @@ export function CarouselViewport({
|
|
|
185
190
|
className = "",
|
|
186
191
|
children,
|
|
187
192
|
...rest
|
|
188
|
-
}: CarouselViewportProps) {
|
|
193
|
+
}: CarouselViewportProps): ReactElement {
|
|
189
194
|
const { isAutoRotating, ids } = useCarouselContext();
|
|
190
195
|
const { viewportRef, onKeyDown } = useCarouselViewport();
|
|
191
196
|
|
|
@@ -205,6 +210,7 @@ export function CarouselViewport({
|
|
|
205
210
|
);
|
|
206
211
|
}
|
|
207
212
|
|
|
213
|
+
/** @internal */
|
|
208
214
|
CarouselViewport.displayName = "CarouselViewport";
|
|
209
215
|
|
|
210
216
|
/**
|
|
@@ -254,7 +260,7 @@ export function CarouselSlide({
|
|
|
254
260
|
ariaLabel,
|
|
255
261
|
children,
|
|
256
262
|
...rest
|
|
257
|
-
}: CarouselSlideProps) {
|
|
263
|
+
}: CarouselSlideProps): ReactElement {
|
|
258
264
|
const { slideRef, index, total, state } = useCarouselSlide();
|
|
259
265
|
const { translations } = useCarouselContext();
|
|
260
266
|
const autoLabel =
|
|
@@ -281,6 +287,7 @@ export function CarouselSlide({
|
|
|
281
287
|
);
|
|
282
288
|
}
|
|
283
289
|
|
|
290
|
+
/** @internal */
|
|
284
291
|
CarouselSlide.displayName = "CarouselSlide";
|
|
285
292
|
|
|
286
293
|
/**
|
|
@@ -311,7 +318,7 @@ export function CarouselNextTrigger({
|
|
|
311
318
|
asChild = false,
|
|
312
319
|
children,
|
|
313
320
|
...rest
|
|
314
|
-
}: CarouselNextTriggerProps) {
|
|
321
|
+
}: CarouselNextTriggerProps): ReactElement {
|
|
315
322
|
const { next, canGoNext, ids } = useCarouselContext();
|
|
316
323
|
const isDisabled = disabled === true || !canGoNext;
|
|
317
324
|
|
|
@@ -348,6 +355,7 @@ export function CarouselNextTrigger({
|
|
|
348
355
|
);
|
|
349
356
|
}
|
|
350
357
|
|
|
358
|
+
/** @internal */
|
|
351
359
|
CarouselNextTrigger.displayName = "CarouselNextTrigger";
|
|
352
360
|
|
|
353
361
|
/**
|
|
@@ -377,7 +385,7 @@ export function CarouselPreviousTrigger({
|
|
|
377
385
|
asChild = false,
|
|
378
386
|
children,
|
|
379
387
|
...rest
|
|
380
|
-
}: CarouselPreviousTriggerProps) {
|
|
388
|
+
}: CarouselPreviousTriggerProps): ReactElement {
|
|
381
389
|
const { previous, canGoPrevious, ids } = useCarouselContext();
|
|
382
390
|
const isDisabled = disabled === true || !canGoPrevious;
|
|
383
391
|
|
|
@@ -410,6 +418,7 @@ export function CarouselPreviousTrigger({
|
|
|
410
418
|
);
|
|
411
419
|
}
|
|
412
420
|
|
|
421
|
+
/** @internal */
|
|
413
422
|
CarouselPreviousTrigger.displayName = "CarouselPreviousTrigger";
|
|
414
423
|
|
|
415
424
|
/**
|
|
@@ -445,7 +454,7 @@ export function CarouselIndicatorGroup({
|
|
|
445
454
|
ariaLabelledBy,
|
|
446
455
|
children,
|
|
447
456
|
...rest
|
|
448
|
-
}: CarouselIndicatorGroupProps) {
|
|
457
|
+
}: CarouselIndicatorGroupProps): ReactElement {
|
|
449
458
|
const { ids } = useCarouselContext();
|
|
450
459
|
|
|
451
460
|
return (
|
|
@@ -464,6 +473,7 @@ export function CarouselIndicatorGroup({
|
|
|
464
473
|
);
|
|
465
474
|
}
|
|
466
475
|
|
|
476
|
+
/** @internal */
|
|
467
477
|
CarouselIndicatorGroup.displayName = "CarouselIndicatorGroup";
|
|
468
478
|
|
|
469
479
|
/**
|
|
@@ -497,7 +507,7 @@ export function CarouselIndicator({
|
|
|
497
507
|
asChild = false,
|
|
498
508
|
children,
|
|
499
509
|
...rest
|
|
500
|
-
}: CarouselIndicatorProps) {
|
|
510
|
+
}: CarouselIndicatorProps): ReactElement {
|
|
501
511
|
const { goTo, currentPage, translations } = useCarouselContext();
|
|
502
512
|
const isActive = index === currentPage;
|
|
503
513
|
|
|
@@ -530,6 +540,7 @@ export function CarouselIndicator({
|
|
|
530
540
|
);
|
|
531
541
|
}
|
|
532
542
|
|
|
543
|
+
/** @internal */
|
|
533
544
|
CarouselIndicator.displayName = "CarouselIndicator";
|
|
534
545
|
|
|
535
546
|
/**
|
|
@@ -552,7 +563,9 @@ CarouselIndicator.displayName = "CarouselIndicator";
|
|
|
552
563
|
* <Carousel.Indicators label="Choose slide" />
|
|
553
564
|
* ```
|
|
554
565
|
*/
|
|
555
|
-
export function CarouselIndicators(
|
|
566
|
+
export function CarouselIndicators(
|
|
567
|
+
props: CarouselIndicatorsProps,
|
|
568
|
+
): ReactElement {
|
|
556
569
|
const { totalPages } = useCarouselContext();
|
|
557
570
|
|
|
558
571
|
return (
|
|
@@ -564,6 +577,7 @@ export function CarouselIndicators(props: CarouselIndicatorsProps) {
|
|
|
564
577
|
);
|
|
565
578
|
}
|
|
566
579
|
|
|
580
|
+
/** @internal */
|
|
567
581
|
CarouselIndicators.displayName = "CarouselIndicators";
|
|
568
582
|
|
|
569
583
|
/**
|
|
@@ -594,7 +608,7 @@ export function CarouselPlayPauseTrigger({
|
|
|
594
608
|
asChild = false,
|
|
595
609
|
children,
|
|
596
610
|
...rest
|
|
597
|
-
}: CarouselPlayPauseTriggerProps) {
|
|
611
|
+
}: CarouselPlayPauseTriggerProps): ReactElement {
|
|
598
612
|
const { playing, togglePlaying, translations, ids, autoplayEnabled } =
|
|
599
613
|
useCarouselContext();
|
|
600
614
|
|
|
@@ -637,8 +651,10 @@ export function CarouselPlayPauseTrigger({
|
|
|
637
651
|
);
|
|
638
652
|
}
|
|
639
653
|
|
|
654
|
+
/** @internal */
|
|
640
655
|
CarouselPlayPauseTrigger.displayName = "CarouselPlayPauseTrigger";
|
|
641
656
|
|
|
657
|
+
/** Static-property shape of the compound {@link Carousel} export: the callable {@link CarouselRoot} plus its namespaced sub-components. */
|
|
642
658
|
type CarouselCompound = typeof CarouselRoot & {
|
|
643
659
|
Root: typeof CarouselRoot;
|
|
644
660
|
Viewport: typeof CarouselViewport;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { createContext } from "react";
|
|
1
|
+
import { createContext, type Context, type Provider } from "react";
|
|
2
2
|
|
|
3
3
|
import type { CarouselContextValue } from "./types";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/** React context carrying the {@link CarouselContextValue} shared by the carousel's sub-components. */
|
|
6
|
+
export const CarouselContext: Context<CarouselContextValue | null> =
|
|
7
|
+
createContext<CarouselContextValue | null>(null);
|
|
6
8
|
|
|
7
9
|
CarouselContext.displayName = "CarouselContext";
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
/** Provider for {@link CarouselContext}; wraps the carousel subtree with its shared state. */
|
|
12
|
+
const CarouselProvider: Provider<CarouselContextValue | null> =
|
|
13
|
+
CarouselContext.Provider;
|
|
10
14
|
|
|
11
15
|
export { CarouselProvider };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
describe("Carousel.NextTrigger asChild", () => {
|
|
7
7
|
it("should render the supplied child element and route the click through to the page-advance handler", async () => {
|
|
@@ -2,7 +2,7 @@ import { useState } from "react";
|
|
|
2
2
|
import { render, screen } from "@testing-library/react";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
|
|
5
|
-
import { Carousel } from "
|
|
5
|
+
import { Carousel } from "../index.ts";
|
|
6
6
|
|
|
7
7
|
describe("Carousel controlled page state", () => {
|
|
8
8
|
it("should derive the active slide from the controlled page prop", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
|
|
3
|
-
import { Carousel } from "
|
|
3
|
+
import { Carousel } from "../index.ts";
|
|
4
4
|
|
|
5
5
|
describe("Carousel error handling", () => {
|
|
6
6
|
it("should throw when Carousel.PlayPauseTrigger is rendered without autoplay enabled on Carousel.Root", () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRef, useRef } from "react";
|
|
2
2
|
import { act, render, screen } from "@testing-library/react";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
5
|
-
import type { CarouselImperativeApi } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
|
+
import type { CarouselImperativeApi } from "../index.ts";
|
|
6
6
|
|
|
7
7
|
function ImperativeFixture({
|
|
8
8
|
apiRef,
|
|
@@ -2,7 +2,7 @@ import { useState } from "react";
|
|
|
2
2
|
import { render, screen } from "@testing-library/react";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
|
|
5
|
-
import { Carousel } from "
|
|
5
|
+
import { Carousel } from "../index.ts";
|
|
6
6
|
|
|
7
7
|
describe("Carousel.IndicatorGroup", () => {
|
|
8
8
|
it('should render with role="group"', () => {
|
|
@@ -2,8 +2,8 @@ import { RefObject, useRef } from "react";
|
|
|
2
2
|
import { act, render, screen } from "@testing-library/react";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
|
|
5
|
-
import { Carousel } from "
|
|
6
|
-
import type { CarouselImperativeApi } from "
|
|
5
|
+
import { Carousel } from "../index.ts";
|
|
6
|
+
import type { CarouselImperativeApi } from "../index.ts";
|
|
7
7
|
import { MockIntersectionObserver } from "../../test/intersectionObserverPolyfill";
|
|
8
8
|
|
|
9
9
|
describe("Carousel IntersectionObserver fallback + isInView", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
describe("Carousel keyboard navigation", () => {
|
|
7
7
|
it("should advance the active page when ArrowRight is pressed with the viewport focused", async () => {
|
|
@@ -2,7 +2,7 @@ import { useState } from "react";
|
|
|
2
2
|
import { render, screen } from "@testing-library/react";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
|
|
5
|
-
import { Carousel } from "
|
|
5
|
+
import { Carousel } from "../index.ts";
|
|
6
6
|
|
|
7
7
|
describe("Carousel.PlayPauseTrigger basic shape", () => {
|
|
8
8
|
it("should render the PlayPauseTrigger as <button type='button'>", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
function mockReducedMotion(matches: boolean) {
|
|
7
7
|
window.matchMedia = vi.fn().mockImplementation((query: string) => ({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRef } from "react";
|
|
2
2
|
import { act, render, screen } from "@testing-library/react";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
5
|
-
import type { CarouselImperativeApi } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
|
+
import type { CarouselImperativeApi } from "../index.ts";
|
|
6
6
|
|
|
7
7
|
function fixture(apiRef: React.Ref<CarouselImperativeApi>, slides = 3) {
|
|
8
8
|
return (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { act, render, screen } from "@testing-library/react";
|
|
2
2
|
|
|
3
|
-
import { Carousel } from "
|
|
3
|
+
import { Carousel } from "../index.ts";
|
|
4
4
|
|
|
5
5
|
function fireScrollSnapChange(viewport: HTMLElement, snapTarget: HTMLElement) {
|
|
6
6
|
const event = new Event("scrollsnapchange", { bubbles: false });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
describe("Carousel scroll sync (programmatic page change)", () => {
|
|
7
7
|
it("should call scrollIntoView on the first slide of the target page when the active page changes", async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
describe("Carousel numeric slidesPerMove", () => {
|
|
7
7
|
it("should render `floor((total - slidesPerPage) / slidesPerMove) + 1` indicators", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
describe("Carousel slidesPerPage", () => {
|
|
7
7
|
it("should mark every slide on the active page as active when slidesPerPage > 1", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
|
|
4
|
-
import { Carousel } from "
|
|
4
|
+
import { Carousel } from "../index.ts";
|
|
5
5
|
|
|
6
6
|
describe("Carousel uncontrolled page state", () => {
|
|
7
7
|
it("should mark the slide at index 0 as active by default when no defaultPage is provided", () => {
|
package/src/Carousel/types.ts
CHANGED
|
@@ -153,6 +153,7 @@ export type CarouselTranslations = {
|
|
|
153
153
|
stopSlideshow?: string;
|
|
154
154
|
};
|
|
155
155
|
|
|
156
|
+
/** Props for `Carousel.Root` — the labelled `<section>` wrapping the whole widget; combines label, page-state, and playing-state shapes with autoplay, transition, and layout options. */
|
|
156
157
|
export type CarouselRootProps = Omit<
|
|
157
158
|
ComponentProps<"section">,
|
|
158
159
|
"aria-label" | "aria-labelledby"
|
|
@@ -278,8 +279,10 @@ export type CarouselContextValue = {
|
|
|
278
279
|
isProgrammaticScrollRef: RefObject<boolean>;
|
|
279
280
|
};
|
|
280
281
|
|
|
282
|
+
/** Props for `Carousel.Viewport` — the scroll-snap slide container; accepts all native `<div>` props. */
|
|
281
283
|
export type CarouselViewportProps = ComponentProps<"div">;
|
|
282
284
|
|
|
285
|
+
/** Props for `Carousel.Slide` — an individual slide that self-registers with the Root; native `<div>` props plus an optional accessible-label override. */
|
|
283
286
|
export type CarouselSlideProps = Omit<ComponentProps<"div">, "aria-label"> & {
|
|
284
287
|
/** Override the auto-generated `"N of M"` `aria-label`. Use this when
|
|
285
288
|
* the slide has a more meaningful description than its position
|
|
@@ -288,6 +291,7 @@ export type CarouselSlideProps = Omit<ComponentProps<"div">, "aria-label"> & {
|
|
|
288
291
|
ariaLabel?: string;
|
|
289
292
|
};
|
|
290
293
|
|
|
294
|
+
/** Props for `Carousel.NextTrigger` — the button that advances one page; native `<button>` props plus `asChild`. */
|
|
291
295
|
export type CarouselNextTriggerProps = ComponentProps<"button"> & {
|
|
292
296
|
/** Render the child element instead of the default `<button>`. All
|
|
293
297
|
* trigger props (onClick, disabled, ids.nextTrigger, …) are merged
|
|
@@ -295,6 +299,7 @@ export type CarouselNextTriggerProps = ComponentProps<"button"> & {
|
|
|
295
299
|
asChild?: boolean;
|
|
296
300
|
};
|
|
297
301
|
|
|
302
|
+
/** Props for `Carousel.PreviousTrigger` — the button that retreats one page; native `<button>` props plus `asChild`. */
|
|
298
303
|
export type CarouselPreviousTriggerProps = ComponentProps<"button"> & {
|
|
299
304
|
/** See `CarouselNextTriggerProps.asChild`. */
|
|
300
305
|
asChild?: boolean;
|
|
@@ -315,6 +320,7 @@ export type CarouselIndicatorGroupProps = Omit<
|
|
|
315
320
|
| { label?: never; ariaLabelledBy: string }
|
|
316
321
|
);
|
|
317
322
|
|
|
323
|
+
/** Props for `Carousel.Indicator` — a button that jumps to its target page; native `<button>` props plus the target `index` and `asChild`. */
|
|
318
324
|
export type CarouselIndicatorProps = ComponentProps<"button"> & {
|
|
319
325
|
/** Zero-based page this indicator targets. Clicking jumps to it. */
|
|
320
326
|
index: number;
|
|
@@ -357,6 +363,7 @@ export type CarouselImperativeApi = {
|
|
|
357
363
|
isInView: (slideIndex: number) => boolean;
|
|
358
364
|
};
|
|
359
365
|
|
|
366
|
+
/** Live progress snapshot reported by the carousel: the active page, the total page count, and a normalised `value` in `[0, 1]`. */
|
|
360
367
|
export type CarouselProgress = {
|
|
361
368
|
page: number;
|
|
362
369
|
totalPages: number;
|
|
@@ -388,6 +395,7 @@ export type CarouselPlayPauseTriggerChildren =
|
|
|
388
395
|
| ReactNode
|
|
389
396
|
| ((state: { playing: boolean }) => ReactNode);
|
|
390
397
|
|
|
398
|
+
/** Props for `Carousel.PlayPauseTrigger` — toggles autoplay; native `<button>` props with a state-aware render-prop `children` and `asChild`. */
|
|
391
399
|
export type CarouselPlayPauseTriggerProps = Omit<
|
|
392
400
|
ComponentProps<"button">,
|
|
393
401
|
"children"
|