@cdx-ui/components 0.2.2 → 0.2.3
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/README.md +4 -2
- package/coverage.svg +1 -1
- package/lib/commonjs/components/Checkbox/index.js.map +1 -1
- package/lib/commonjs/components/Heading/index.js.map +1 -1
- package/lib/commonjs/components/Icon/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/index.js +170 -9
- package/lib/commonjs/components/ListItem/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/styles.js +36 -1
- package/lib/commonjs/components/ListItem/styles.js.map +1 -1
- package/lib/commonjs/components/Menu/index.js.map +1 -1
- package/lib/commonjs/components/RangeCalendar/index.js.map +1 -1
- package/lib/commonjs/components/ReorderableList/ReorderableListShared.js +91 -0
- package/lib/commonjs/components/ReorderableList/ReorderableListShared.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/index.js +135 -0
- package/lib/commonjs/components/ReorderableList/index.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/index.web.js +233 -0
- package/lib/commonjs/components/ReorderableList/index.web.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/labels.js +47 -0
- package/lib/commonjs/components/ReorderableList/labels.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/reorderItems.js +16 -0
- package/lib/commonjs/components/ReorderableList/reorderItems.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/rowContext.js +42 -0
- package/lib/commonjs/components/ReorderableList/rowContext.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/types.js +6 -0
- package/lib/commonjs/components/ReorderableList/types.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/useReorder.js +131 -0
- package/lib/commonjs/components/ReorderableList/useReorder.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/webDnd.js +64 -0
- package/lib/commonjs/components/ReorderableList/webDnd.js.map +1 -0
- package/lib/commonjs/components/ScopedTheme/index.js.map +1 -1
- package/lib/commonjs/components/Skeleton/index.js.map +1 -1
- package/lib/commonjs/components/TablePagination/index.js.map +1 -1
- package/lib/commonjs/components/Text/index.js.map +1 -1
- package/lib/commonjs/components/Tile/styles.js +1 -1
- package/lib/commonjs/components/Tile/styles.js.map +1 -1
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/reorderable-list.js +17 -0
- package/lib/commonjs/reorderable-list.js.map +1 -0
- package/lib/module/components/Checkbox/index.js.map +1 -1
- package/lib/module/components/Heading/index.js.map +1 -1
- package/lib/module/components/Icon/index.js.map +1 -1
- package/lib/module/components/ListItem/index.js +163 -14
- package/lib/module/components/ListItem/index.js.map +1 -1
- package/lib/module/components/ListItem/styles.js +35 -0
- package/lib/module/components/ListItem/styles.js.map +1 -1
- package/lib/module/components/Menu/index.js.map +1 -1
- package/lib/module/components/RangeCalendar/index.js.map +1 -1
- package/lib/module/components/ReorderableList/ReorderableListShared.js +86 -0
- package/lib/module/components/ReorderableList/ReorderableListShared.js.map +1 -0
- package/lib/module/components/ReorderableList/index.js +130 -0
- package/lib/module/components/ReorderableList/index.js.map +1 -0
- package/lib/module/components/ReorderableList/index.web.js +229 -0
- package/lib/module/components/ReorderableList/index.web.js.map +1 -0
- package/lib/module/components/ReorderableList/labels.js +41 -0
- package/lib/module/components/ReorderableList/labels.js.map +1 -0
- package/lib/module/components/ReorderableList/reorderItems.js +12 -0
- package/lib/module/components/ReorderableList/reorderItems.js.map +1 -0
- package/lib/module/components/ReorderableList/rowContext.js +38 -0
- package/lib/module/components/ReorderableList/rowContext.js.map +1 -0
- package/lib/module/components/ReorderableList/types.js +4 -0
- package/lib/module/components/ReorderableList/types.js.map +1 -0
- package/lib/module/components/ReorderableList/useReorder.js +123 -0
- package/lib/module/components/ReorderableList/useReorder.js.map +1 -0
- package/lib/module/components/ReorderableList/webDnd.js +59 -0
- package/lib/module/components/ReorderableList/webDnd.js.map +1 -0
- package/lib/module/components/ScopedTheme/index.js.map +1 -1
- package/lib/module/components/Skeleton/index.js.map +1 -1
- package/lib/module/components/TablePagination/index.js.map +1 -1
- package/lib/module/components/Text/index.js.map +1 -1
- package/lib/module/components/Tile/styles.js +1 -1
- package/lib/module/components/Tile/styles.js.map +1 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/reorderable-list.js +4 -0
- package/lib/module/reorderable-list.js.map +1 -0
- package/lib/typescript/components/Checkbox/index.d.ts +22 -0
- package/lib/typescript/components/Checkbox/index.d.ts.map +1 -1
- package/lib/typescript/components/Heading/index.d.ts +20 -2
- package/lib/typescript/components/Heading/index.d.ts.map +1 -1
- package/lib/typescript/components/Icon/index.d.ts +2 -0
- package/lib/typescript/components/Icon/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/index.d.ts +23 -1
- package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts +5 -0
- package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
- package/lib/typescript/components/Menu/index.d.ts +116 -4
- package/lib/typescript/components/Menu/index.d.ts.map +1 -1
- package/lib/typescript/components/RangeCalendar/index.d.ts +2 -0
- package/lib/typescript/components/RangeCalendar/index.d.ts.map +1 -1
- package/lib/typescript/components/ReorderableList/ReorderableListShared.d.ts +31 -0
- package/lib/typescript/components/ReorderableList/ReorderableListShared.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/index.d.ts +8 -0
- package/lib/typescript/components/ReorderableList/index.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/index.web.d.ts +8 -0
- package/lib/typescript/components/ReorderableList/index.web.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/labels.d.ts +16 -0
- package/lib/typescript/components/ReorderableList/labels.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/reorderItems.d.ts +3 -0
- package/lib/typescript/components/ReorderableList/reorderItems.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/rowContext.d.ts +57 -0
- package/lib/typescript/components/ReorderableList/rowContext.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/types.d.ts +75 -0
- package/lib/typescript/components/ReorderableList/types.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/useReorder.d.ts +31 -0
- package/lib/typescript/components/ReorderableList/useReorder.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/webDnd.d.ts +27 -0
- package/lib/typescript/components/ReorderableList/webDnd.d.ts.map +1 -0
- package/lib/typescript/components/ScopedTheme/index.d.ts +6 -1
- package/lib/typescript/components/ScopedTheme/index.d.ts.map +1 -1
- package/lib/typescript/components/Skeleton/index.d.ts +3 -0
- package/lib/typescript/components/Skeleton/index.d.ts.map +1 -1
- package/lib/typescript/components/TablePagination/index.d.ts +54 -0
- package/lib/typescript/components/TablePagination/index.d.ts.map +1 -1
- package/lib/typescript/components/Text/index.d.ts +12 -2
- package/lib/typescript/components/Text/index.d.ts.map +1 -1
- package/lib/typescript/components/Tile/styles.d.ts.map +1 -1
- package/lib/typescript/components/ToggleButton/styles.d.ts +1 -1
- package/lib/typescript/components/index.d.ts +1 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/reorderable-list.d.ts +2 -0
- package/lib/typescript/reorderable-list.d.ts.map +1 -0
- package/package.json +34 -7
- package/src/components/Checkbox/index.tsx +22 -0
- package/src/components/Heading/index.tsx +10 -1
- package/src/components/Icon/index.tsx +2 -0
- package/src/components/ListItem/index.tsx +227 -11
- package/src/components/ListItem/styles.ts +40 -0
- package/src/components/Menu/index.tsx +117 -4
- package/src/components/RangeCalendar/index.tsx +2 -0
- package/src/components/ReorderableList/ReorderableListShared.tsx +113 -0
- package/src/components/ReorderableList/index.tsx +162 -0
- package/src/components/ReorderableList/index.web.tsx +254 -0
- package/src/components/ReorderableList/labels.ts +52 -0
- package/src/components/ReorderableList/reorderItems.ts +16 -0
- package/src/components/ReorderableList/rowContext.tsx +72 -0
- package/src/components/ReorderableList/types.ts +80 -0
- package/src/components/ReorderableList/useReorder.ts +159 -0
- package/src/components/ReorderableList/webDnd.ts +60 -0
- package/src/components/ScopedTheme/index.tsx +6 -1
- package/src/components/Skeleton/index.tsx +3 -0
- package/src/components/TablePagination/index.tsx +54 -0
- package/src/components/Text/index.tsx +6 -1
- package/src/components/Tile/styles.ts +4 -1
- package/src/components/index.ts +5 -0
- package/src/reorderable-list.ts +1 -0
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
createContext,
|
|
4
|
+
forwardRef,
|
|
5
|
+
isValidElement,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useMemo,
|
|
9
|
+
type ReactElement,
|
|
10
|
+
type ReactNode,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import { Platform, Text, View, type TextProps, type ViewProps } from 'react-native';
|
|
13
|
+
import { DragIndicator } from '@cdx-ui/icons';
|
|
3
14
|
import {
|
|
4
15
|
ListItemRoot as ListItemRootPrimitive,
|
|
5
16
|
Slot,
|
|
@@ -8,12 +19,23 @@ import {
|
|
|
8
19
|
type IListItemProps,
|
|
9
20
|
type ListItemCrossAlign,
|
|
10
21
|
} from '@cdx-ui/primitives';
|
|
11
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
cn,
|
|
24
|
+
composeEventHandlers,
|
|
25
|
+
mergeRefs,
|
|
26
|
+
ParentContext,
|
|
27
|
+
useParentContext,
|
|
28
|
+
useStyleContext,
|
|
29
|
+
} from '@cdx-ui/utils';
|
|
30
|
+
import { Icon } from '../Icon';
|
|
31
|
+
import { useReorderableRow } from '../ReorderableList/rowContext';
|
|
12
32
|
import {
|
|
13
33
|
listItemContentVariants,
|
|
14
34
|
listItemDescriptionVariants,
|
|
35
|
+
listItemDragHandleVariants,
|
|
15
36
|
listItemLeadingSlotVariants,
|
|
16
37
|
listItemMetaVariants,
|
|
38
|
+
listItemPressableRegionVariants,
|
|
17
39
|
listItemRootVariants,
|
|
18
40
|
listItemSectionHeaderLabelVariants,
|
|
19
41
|
listItemSectionHeaderVariants,
|
|
@@ -34,6 +56,40 @@ const useListItemStyleContext = (): Pick<ListItemVariantProps, 'crossAlign'> =>
|
|
|
34
56
|
// ROOT
|
|
35
57
|
// =============================================================================
|
|
36
58
|
|
|
59
|
+
/**
|
|
60
|
+
* `true` inside a pressable row's interactive element. `ListItem.DragHandle` reads it to warn when it
|
|
61
|
+
* is nested there instead of being a direct child of the row.
|
|
62
|
+
*/
|
|
63
|
+
const ListItemPressableContext = createContext(false);
|
|
64
|
+
|
|
65
|
+
interface DragHandlePartition {
|
|
66
|
+
handle: ReactElement;
|
|
67
|
+
position: 'start' | 'end';
|
|
68
|
+
rest: ReactNode[];
|
|
69
|
+
misplaced: boolean;
|
|
70
|
+
extra: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Finds a direct-child `ListItem.DragHandle` (matched by identity) of a pressable row. */
|
|
74
|
+
function partitionDragHandle(children: ReactNode): DragHandlePartition | undefined {
|
|
75
|
+
const items = Children.toArray(children);
|
|
76
|
+
const handleIndexes: number[] = [];
|
|
77
|
+
items.forEach((child, index) => {
|
|
78
|
+
if (isValidElement(child) && child.type === ListItemDragHandle) handleIndexes.push(index);
|
|
79
|
+
});
|
|
80
|
+
if (handleIndexes.length === 0) return undefined;
|
|
81
|
+
const [first] = handleIndexes;
|
|
82
|
+
return {
|
|
83
|
+
handle: items[first] as ReactElement,
|
|
84
|
+
position: first === 0 ? 'start' : 'end',
|
|
85
|
+
rest: items.filter((_, index) => !handleIndexes.includes(index)),
|
|
86
|
+
misplaced: first !== 0 && first !== items.length - 1,
|
|
87
|
+
extra: handleIndexes.length > 1,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let hasWarnedDragHandlePlacement = false;
|
|
92
|
+
|
|
37
93
|
export interface ListItemProps extends Omit<IListItemProps, 'crossAlign'>, ListItemVariantProps {
|
|
38
94
|
/**
|
|
39
95
|
* Vertical density. `compact` reduces padding and min-height; typography stays the same.
|
|
@@ -60,6 +116,13 @@ export interface ListItemProps extends Omit<IListItemProps, 'crossAlign'>, ListI
|
|
|
60
116
|
className?: string;
|
|
61
117
|
}
|
|
62
118
|
|
|
119
|
+
/**
|
|
120
|
+
* A pressable row (`onPress`, or `asChild`) with a `ListItem.DragHandle` as its first or last
|
|
121
|
+
* direct child renders the handle beside the pressable element instead of inside it. The handle
|
|
122
|
+
* is matched by identity, so a `memo()` or wrapper component around it is not recognized. Under
|
|
123
|
+
* `asChild`, pass the handle and the single interactive element as siblings:
|
|
124
|
+
* `<ListItem asChild><ListItem.DragHandle /><Link>…</Link></ListItem>`.
|
|
125
|
+
*/
|
|
63
126
|
const ListItemRoot = forwardRef<View, ListItemProps>(
|
|
64
127
|
(
|
|
65
128
|
{
|
|
@@ -68,6 +131,7 @@ const ListItemRoot = forwardRef<View, ListItemProps>(
|
|
|
68
131
|
crossAlign: crossAlignProp = 'center',
|
|
69
132
|
className,
|
|
70
133
|
style,
|
|
134
|
+
children,
|
|
71
135
|
...props
|
|
72
136
|
},
|
|
73
137
|
ref,
|
|
@@ -75,22 +139,60 @@ const ListItemRoot = forwardRef<View, ListItemProps>(
|
|
|
75
139
|
const crossAlign: ListItemCrossAlign = crossAlignProp ?? 'center';
|
|
76
140
|
const parent = useParentContext();
|
|
77
141
|
const ctx = useMemo(() => ({ ...parent, [SCOPE]: { crossAlign } }), [parent, crossAlign]);
|
|
142
|
+
const isDragging = useReorderableRow()?.isDragging ?? false;
|
|
143
|
+
const isPressable = props.onPress != null || !!props.asChild;
|
|
144
|
+
const partition = isPressable ? partitionDragHandle(children) : undefined;
|
|
145
|
+
const misplacedHandle = !!partition && (partition.misplaced || partition.extra);
|
|
146
|
+
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (__DEV__ && misplacedHandle && !hasWarnedDragHandlePlacement) {
|
|
149
|
+
hasWarnedDragHandlePlacement = true;
|
|
150
|
+
console.warn(
|
|
151
|
+
'[ListItem] Place one ListItem.DragHandle as the first or last child of a pressable ListItem. A handle elsewhere is moved to the end, and extra handles are dropped.',
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}, [misplacedHandle]);
|
|
78
155
|
|
|
79
156
|
const computedClassName = cn(
|
|
80
157
|
listItemRootVariants({ size, showSeparator, crossAlign }),
|
|
81
158
|
className,
|
|
82
159
|
);
|
|
83
160
|
|
|
161
|
+
const splitProps = partition && {
|
|
162
|
+
accessory: (
|
|
163
|
+
<ListItemPressableContext.Provider value={false}>
|
|
164
|
+
{partition.handle}
|
|
165
|
+
</ListItemPressableContext.Provider>
|
|
166
|
+
),
|
|
167
|
+
accessoryPosition: partition.position,
|
|
168
|
+
pressableClassName: listItemPressableRegionVariants({
|
|
169
|
+
size: size ?? 'default',
|
|
170
|
+
handlePosition: partition.position,
|
|
171
|
+
}),
|
|
172
|
+
};
|
|
173
|
+
const regionChildren =
|
|
174
|
+
partition && props.asChild && partition.rest.length === 1
|
|
175
|
+
? partition.rest[0]
|
|
176
|
+
: partition?.rest;
|
|
177
|
+
|
|
84
178
|
return (
|
|
85
179
|
<ParentContext.Provider value={ctx}>
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
180
|
+
<ListItemPressableContext.Provider value={isPressable}>
|
|
181
|
+
<ListItemRootPrimitive
|
|
182
|
+
ref={ref}
|
|
183
|
+
className={computedClassName}
|
|
184
|
+
crossAlign={crossAlign}
|
|
185
|
+
style={style}
|
|
186
|
+
{...props}
|
|
187
|
+
{...splitProps}
|
|
188
|
+
{...mergeDataAttributes(
|
|
189
|
+
props,
|
|
190
|
+
dataAttributes({ slot: 'list-item', dragging: isDragging }),
|
|
191
|
+
)}
|
|
192
|
+
>
|
|
193
|
+
{partition ? regionChildren : children}
|
|
194
|
+
</ListItemRootPrimitive>
|
|
195
|
+
</ListItemPressableContext.Provider>
|
|
94
196
|
</ParentContext.Provider>
|
|
95
197
|
);
|
|
96
198
|
},
|
|
@@ -263,6 +365,116 @@ const ListItemTrailingSlot = forwardRef<View, ListItemTrailingSlotProps>(
|
|
|
263
365
|
|
|
264
366
|
ListItemTrailingSlot.displayName = 'ListItem.TrailingSlot';
|
|
265
367
|
|
|
368
|
+
function DefaultDragHandleGrip() {
|
|
369
|
+
return <Icon as={DragIndicator} className="size-5 text-content-secondary" />;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Screen reader hint for the default handle. Web omits it: react-native-web drops
|
|
374
|
+
* `accessibilityHint`, and dnd-kit describes the keyboard controls through `aria-describedby`.
|
|
375
|
+
*/
|
|
376
|
+
const DEFAULT_DRAG_HANDLE_HINT = Platform.select<string | undefined>({
|
|
377
|
+
ios: 'Drag to reorder, or swipe up or down to choose a move action.',
|
|
378
|
+
android: 'Drag to reorder, or open the actions menu to move this item.',
|
|
379
|
+
default: undefined,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
const dragHandleOuterStyle = { flexShrink: 0 as const };
|
|
383
|
+
|
|
384
|
+
let hasWarnedDragHandleOutsideList = false;
|
|
385
|
+
let hasWarnedNestedDragHandle = false;
|
|
386
|
+
|
|
387
|
+
export interface ListItemDragHandleProps extends ViewProps {
|
|
388
|
+
/**
|
|
389
|
+
* Merges the handle onto the consumer's single child (for example an `IconButton`) so that
|
|
390
|
+
* element is the one focusable handle.
|
|
391
|
+
*/
|
|
392
|
+
asChild?: boolean;
|
|
393
|
+
className?: string;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Drag activator for a row rendered by `ReorderableList`. Renders `null` outside a list. On a
|
|
398
|
+
* pressable `ListItem`, place it as the first or last direct child so it sits beside the row's
|
|
399
|
+
* pressable element rather than inside it.
|
|
400
|
+
*/
|
|
401
|
+
const ListItemDragHandle = forwardRef<View, ListItemDragHandleProps>(
|
|
402
|
+
(
|
|
403
|
+
{
|
|
404
|
+
asChild,
|
|
405
|
+
className,
|
|
406
|
+
style,
|
|
407
|
+
children,
|
|
408
|
+
accessibilityLabel = 'Reorder',
|
|
409
|
+
accessibilityHint,
|
|
410
|
+
accessibilityActions,
|
|
411
|
+
onAccessibilityAction,
|
|
412
|
+
...props
|
|
413
|
+
},
|
|
414
|
+
ref,
|
|
415
|
+
) => {
|
|
416
|
+
const row = useReorderableRow();
|
|
417
|
+
const insidePressable = useContext(ListItemPressableContext);
|
|
418
|
+
const isOutsideList = row === null;
|
|
419
|
+
|
|
420
|
+
useEffect(() => {
|
|
421
|
+
if (!__DEV__) return;
|
|
422
|
+
if (isOutsideList && !hasWarnedDragHandleOutsideList) {
|
|
423
|
+
hasWarnedDragHandleOutsideList = true;
|
|
424
|
+
console.warn(
|
|
425
|
+
'[ListItem.DragHandle] Rendered outside a ReorderableList row, so it renders nothing. Use it inside ReorderableList renderItem.',
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
if (insidePressable && !hasWarnedNestedDragHandle) {
|
|
429
|
+
hasWarnedNestedDragHandle = true;
|
|
430
|
+
console.warn(
|
|
431
|
+
"[ListItem.DragHandle] Nested inside a pressable ListItem, so it is part of the row's pressable element. Make it the first or last direct child of ListItem so it renders beside it.",
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
}, [isOutsideList, insidePressable]);
|
|
435
|
+
|
|
436
|
+
const handleRef = row?.handle.ref;
|
|
437
|
+
const hostRef = useMemo(() => mergeRefs(ref, handleRef), [ref, handleRef]);
|
|
438
|
+
|
|
439
|
+
if (!row) return null;
|
|
440
|
+
|
|
441
|
+
const { handle } = row;
|
|
442
|
+
const handleProps = {
|
|
443
|
+
...handle.props,
|
|
444
|
+
accessible: true,
|
|
445
|
+
accessibilityRole: 'button' as const,
|
|
446
|
+
accessibilityLabel,
|
|
447
|
+
accessibilityHint:
|
|
448
|
+
accessibilityHint ??
|
|
449
|
+
(row.accessibilityActions.length > 0 ? DEFAULT_DRAG_HANDLE_HINT : undefined),
|
|
450
|
+
accessibilityActions: [...row.accessibilityActions, ...(accessibilityActions ?? [])],
|
|
451
|
+
onAccessibilityAction: composeEventHandlers(onAccessibilityAction, row.onAccessibilityAction),
|
|
452
|
+
className: cn(listItemDragHandleVariants(), className),
|
|
453
|
+
...props,
|
|
454
|
+
...mergeDataAttributes(props, dataAttributes({ slot: 'list-item-drag-handle' })),
|
|
455
|
+
style: [handle.props.style, style],
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
if (asChild) {
|
|
459
|
+
return handle.wrap(
|
|
460
|
+
<Slot ref={hostRef} {...handleProps}>
|
|
461
|
+
{children}
|
|
462
|
+
</Slot>,
|
|
463
|
+
dragHandleOuterStyle,
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return handle.wrap(
|
|
468
|
+
<View ref={hostRef} {...handleProps}>
|
|
469
|
+
{children ?? <DefaultDragHandleGrip />}
|
|
470
|
+
</View>,
|
|
471
|
+
dragHandleOuterStyle,
|
|
472
|
+
);
|
|
473
|
+
},
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
ListItemDragHandle.displayName = 'ListItem.DragHandle';
|
|
477
|
+
|
|
266
478
|
const wrapSectionHeaderLabel = (children: ReactNode): ReactNode => {
|
|
267
479
|
if (typeof children === 'string' || typeof children === 'number') {
|
|
268
480
|
return <Text className={cn(listItemSectionHeaderLabelVariants())}>{children}</Text>;
|
|
@@ -367,6 +579,7 @@ ListItemSectionHeader.displayName = 'ListItem.SectionHeader';
|
|
|
367
579
|
|
|
368
580
|
type ListItemCompound = typeof ListItemRoot & {
|
|
369
581
|
LeadingSlot: typeof ListItemLeadingSlot;
|
|
582
|
+
DragHandle: typeof ListItemDragHandle;
|
|
370
583
|
Content: typeof ListItemContent;
|
|
371
584
|
Title: typeof ListItemTitle;
|
|
372
585
|
Description: typeof ListItemDescription;
|
|
@@ -377,6 +590,7 @@ type ListItemCompound = typeof ListItemRoot & {
|
|
|
377
590
|
|
|
378
591
|
export const ListItem = Object.assign(ListItemRoot, {
|
|
379
592
|
LeadingSlot: ListItemLeadingSlot,
|
|
593
|
+
DragHandle: ListItemDragHandle,
|
|
380
594
|
Content: ListItemContent,
|
|
381
595
|
Title: ListItemTitle,
|
|
382
596
|
Description: ListItemDescription,
|
|
@@ -389,8 +603,10 @@ export type { ListItemCrossAlign, ListItemSectionHeaderVariantProps, ListItemVar
|
|
|
389
603
|
export {
|
|
390
604
|
listItemContentVariants,
|
|
391
605
|
listItemDescriptionVariants,
|
|
606
|
+
listItemDragHandleVariants,
|
|
392
607
|
listItemLeadingSlotVariants,
|
|
393
608
|
listItemMetaVariants,
|
|
609
|
+
listItemPressableRegionVariants,
|
|
394
610
|
listItemRootVariants,
|
|
395
611
|
listItemSectionHeaderLabelVariants,
|
|
396
612
|
listItemSectionHeaderVariants,
|
|
@@ -31,6 +31,10 @@ export const listItemRootVariants = cva(
|
|
|
31
31
|
].join(' '),
|
|
32
32
|
default: 'data-[active=true]:bg-surface-primary-hover',
|
|
33
33
|
}),
|
|
34
|
+
'data-[dragging=true]:bg-surface-secondary',
|
|
35
|
+
// Native: changing the dragged row's zIndex mid-drag cancels the handle's pan on Fabric iOS;
|
|
36
|
+
// the drag engine stacks the active row itself.
|
|
37
|
+
Platform.select({ web: 'data-[dragging=true]:z-20', default: '' }),
|
|
34
38
|
],
|
|
35
39
|
{
|
|
36
40
|
variants: {
|
|
@@ -58,6 +62,37 @@ export const listItemRootVariants = cva(
|
|
|
58
62
|
},
|
|
59
63
|
);
|
|
60
64
|
|
|
65
|
+
// ── Pressable region (pressable row with a direct-child DragHandle) ─────────
|
|
66
|
+
//
|
|
67
|
+
// The root becomes a non-interactive container and keeps every visual above: the primitive
|
|
68
|
+
// mirrors the region's hover/active/focus state onto it, so the overlay, focus ring, and native
|
|
69
|
+
// tint still span the whole row. The region itself is transparent; negative margins extend it
|
|
70
|
+
// over the container's padding (and the gap beside the handle) so the hit area matches a row
|
|
71
|
+
// without a handle. A consumer `className` that changes the row's padding is not mirrored here.
|
|
72
|
+
|
|
73
|
+
export const listItemPressableRegionVariants = cva(
|
|
74
|
+
[
|
|
75
|
+
'relative flex-1 min-w-0 flex-row self-stretch gap-3 bg-transparent',
|
|
76
|
+
Platform.select({ web: 'outline-none', default: '' }),
|
|
77
|
+
],
|
|
78
|
+
{
|
|
79
|
+
variants: {
|
|
80
|
+
size: {
|
|
81
|
+
default: '-my-3 py-3',
|
|
82
|
+
compact: '-my-2 py-2',
|
|
83
|
+
},
|
|
84
|
+
handlePosition: {
|
|
85
|
+
start: '-ms-3 ps-3 -me-5 pe-5',
|
|
86
|
+
end: '-ms-5 ps-5 -me-3 pe-3',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
defaultVariants: {
|
|
90
|
+
size: 'default',
|
|
91
|
+
handlePosition: 'start',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
61
96
|
// ── Leading / trailing slots ─────────────────────────────────────────────────
|
|
62
97
|
|
|
63
98
|
export const listItemLeadingSlotVariants = cva([
|
|
@@ -79,6 +114,11 @@ export const listItemTrailingSlotVariants = cva(
|
|
|
79
114
|
},
|
|
80
115
|
);
|
|
81
116
|
|
|
117
|
+
export const listItemDragHandleVariants = cva([
|
|
118
|
+
'relative z-10 flex shrink-0 self-stretch items-center justify-center',
|
|
119
|
+
'web:cursor-grab web:active:cursor-grabbing',
|
|
120
|
+
]);
|
|
121
|
+
|
|
82
122
|
// ── Content stack (title / description / meta) ───────────────────────────────
|
|
83
123
|
|
|
84
124
|
export const listItemContentVariants = cva('relative z-10 flex min-w-0 flex-1 flex-col gap-1', {
|
|
@@ -98,7 +98,10 @@ const useMenuItemStyleValue = (
|
|
|
98
98
|
// =============================================================================
|
|
99
99
|
|
|
100
100
|
export interface MenuProps extends ViewProps, IMenuOverlayRootProps {
|
|
101
|
+
/** Additional Uniwind/Tailwind classes, merged after the root's own styles. */
|
|
101
102
|
className?: string;
|
|
103
|
+
/** The `Menu.Trigger` and `Menu.Popup`. */
|
|
104
|
+
children?: ReactNode;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
const MenuOverlayRoot = forwardRef<View, MenuProps>(
|
|
@@ -122,7 +125,9 @@ MenuOverlayRoot.displayName = 'Menu';
|
|
|
122
125
|
// =============================================================================
|
|
123
126
|
|
|
124
127
|
export interface MenuTriggerProps extends IMenuTriggerProps {
|
|
128
|
+
/** Additional Uniwind/Tailwind classes, merged after the trigger's own styles. */
|
|
125
129
|
className?: string;
|
|
130
|
+
/** Trigger content (or the element to render when `asChild` is set). */
|
|
126
131
|
children?: ReactNode;
|
|
127
132
|
}
|
|
128
133
|
|
|
@@ -147,7 +152,9 @@ MenuTrigger.displayName = 'Menu.Trigger';
|
|
|
147
152
|
// =============================================================================
|
|
148
153
|
|
|
149
154
|
export interface MenuPopupProps extends IMenuPopupProps {
|
|
155
|
+
/** Additional Uniwind/Tailwind classes, merged after the popup's own styles. */
|
|
150
156
|
className?: string;
|
|
157
|
+
/** Popup content, typically a `Menu.Content`. */
|
|
151
158
|
children?: ReactNode;
|
|
152
159
|
}
|
|
153
160
|
|
|
@@ -178,8 +185,16 @@ MenuPopup.displayName = 'Menu.Popup';
|
|
|
178
185
|
// =============================================================================
|
|
179
186
|
|
|
180
187
|
export interface MenuContentProps
|
|
181
|
-
extends ViewProps, Omit<IMenuProps, 'scrollable'>, MenuRootVariantProps {
|
|
188
|
+
extends ViewProps, Omit<IMenuProps, 'scrollable'>, Omit<MenuRootVariantProps, 'scrollable'> {
|
|
189
|
+
/** Additional Uniwind/Tailwind classes, merged after the menu surface's own styles. */
|
|
182
190
|
className?: string;
|
|
191
|
+
/**
|
|
192
|
+
* Caps the surface height and scrolls its items. Content inside a `Menu.Popup` always scrolls.
|
|
193
|
+
* @default false
|
|
194
|
+
*/
|
|
195
|
+
scrollable?: MenuRootVariantProps['scrollable'];
|
|
196
|
+
/** The menu's items, groups and separators. */
|
|
197
|
+
children?: ReactNode;
|
|
183
198
|
/** Visual-only surface without menu semantics (e.g. inside Select listbox). */
|
|
184
199
|
asSurface?: boolean;
|
|
185
200
|
}
|
|
@@ -241,14 +256,28 @@ MenuContent.displayName = 'Menu.Content';
|
|
|
241
256
|
// ITEM
|
|
242
257
|
// =============================================================================
|
|
243
258
|
|
|
244
|
-
export interface MenuItemProps
|
|
259
|
+
export interface MenuItemProps
|
|
260
|
+
extends Omit<MenuItemVariantProps, 'color' | 'inset' | 'layout'>, IMenuItemProps {
|
|
261
|
+
/** Render the consumer's child element in place of the default `Pressable` host. */
|
|
245
262
|
asChild?: boolean;
|
|
246
263
|
/**
|
|
247
264
|
* Color theme applied to the item content and interaction states.
|
|
248
265
|
* @default 'neutral'
|
|
249
266
|
*/
|
|
250
267
|
color?: 'neutral' | 'danger';
|
|
268
|
+
/**
|
|
269
|
+
* Indents the item content so its label lines up with items that have a leading icon.
|
|
270
|
+
* @default false
|
|
271
|
+
*/
|
|
272
|
+
inset?: MenuItemVariantProps['inset'];
|
|
273
|
+
/**
|
|
274
|
+
* Set automatically: `filter` when the item contains a `Menu.ItemControl` or `Menu.ItemAction`.
|
|
275
|
+
* @internal
|
|
276
|
+
*/
|
|
277
|
+
layout?: MenuItemVariantProps['layout'];
|
|
278
|
+
/** Additional Uniwind/Tailwind classes, merged after the item's own styles. */
|
|
251
279
|
className?: string;
|
|
280
|
+
/** Item content, typically a `Menu.ItemLabel` with optional icon, shortcut and indicator slots. */
|
|
252
281
|
children?: ReactNode;
|
|
253
282
|
}
|
|
254
283
|
|
|
@@ -279,10 +308,27 @@ const MenuItem = forwardRef<View, MenuItemProps>(
|
|
|
279
308
|
MenuItem.displayName = 'Menu.Item';
|
|
280
309
|
|
|
281
310
|
export interface MenuCheckboxItemProps
|
|
282
|
-
extends Omit<MenuItemVariantProps, 'color'>, IMenuCheckboxItemProps {
|
|
311
|
+
extends Omit<MenuItemVariantProps, 'color' | 'inset' | 'layout'>, IMenuCheckboxItemProps {
|
|
312
|
+
/** Render the consumer's child element in place of the default `Pressable` host. */
|
|
283
313
|
asChild?: boolean;
|
|
314
|
+
/**
|
|
315
|
+
* Color theme applied to the item content and interaction states.
|
|
316
|
+
* @default 'neutral'
|
|
317
|
+
*/
|
|
284
318
|
color?: 'neutral' | 'danger';
|
|
319
|
+
/**
|
|
320
|
+
* Indents the item content so its label lines up with items that have a leading icon.
|
|
321
|
+
* @default false
|
|
322
|
+
*/
|
|
323
|
+
inset?: MenuItemVariantProps['inset'];
|
|
324
|
+
/**
|
|
325
|
+
* Set automatically: `filter` when the item contains a `Menu.ItemControl` or `Menu.ItemAction`.
|
|
326
|
+
* @internal
|
|
327
|
+
*/
|
|
328
|
+
layout?: MenuItemVariantProps['layout'];
|
|
329
|
+
/** Additional Uniwind/Tailwind classes, merged after the item's own styles. */
|
|
285
330
|
className?: string;
|
|
331
|
+
/** Item content, typically a `Menu.ItemLabel` with optional icon, shortcut and indicator slots. */
|
|
286
332
|
children?: ReactNode;
|
|
287
333
|
}
|
|
288
334
|
|
|
@@ -311,8 +357,11 @@ const MenuCheckboxItem = forwardRef<View, MenuCheckboxItemProps>(
|
|
|
311
357
|
MenuCheckboxItem.displayName = 'Menu.CheckboxItem';
|
|
312
358
|
|
|
313
359
|
export interface MenuRadioGroupProps extends IMenuRadioGroupProps {
|
|
360
|
+
/** Render the consumer's child element in place of the default `View` host. */
|
|
314
361
|
asChild?: boolean;
|
|
362
|
+
/** Additional Uniwind/Tailwind classes, merged after the group's own styles. */
|
|
315
363
|
className?: string;
|
|
364
|
+
/** The `Menu.RadioItem` options in the group. */
|
|
316
365
|
children?: ReactNode;
|
|
317
366
|
}
|
|
318
367
|
|
|
@@ -334,10 +383,27 @@ const MenuRadioGroup = forwardRef<View, MenuRadioGroupProps>(
|
|
|
334
383
|
MenuRadioGroup.displayName = 'Menu.RadioGroup';
|
|
335
384
|
|
|
336
385
|
export interface MenuRadioItemProps
|
|
337
|
-
extends Omit<MenuItemVariantProps, 'color'>, IMenuRadioItemProps {
|
|
386
|
+
extends Omit<MenuItemVariantProps, 'color' | 'inset' | 'layout'>, IMenuRadioItemProps {
|
|
387
|
+
/** Render the consumer's child element in place of the default `Pressable` host. */
|
|
338
388
|
asChild?: boolean;
|
|
389
|
+
/**
|
|
390
|
+
* Color theme applied to the item content and interaction states.
|
|
391
|
+
* @default 'neutral'
|
|
392
|
+
*/
|
|
339
393
|
color?: 'neutral' | 'danger';
|
|
394
|
+
/**
|
|
395
|
+
* Indents the item content so its label lines up with items that have a leading icon.
|
|
396
|
+
* @default false
|
|
397
|
+
*/
|
|
398
|
+
inset?: MenuItemVariantProps['inset'];
|
|
399
|
+
/**
|
|
400
|
+
* Set automatically: `filter` when the item contains a `Menu.ItemControl` or `Menu.ItemAction`.
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
layout?: MenuItemVariantProps['layout'];
|
|
404
|
+
/** Additional Uniwind/Tailwind classes, merged after the item's own styles. */
|
|
340
405
|
className?: string;
|
|
406
|
+
/** Item content, typically a `Menu.ItemLabel` with optional icon, shortcut and indicator slots. */
|
|
341
407
|
children?: ReactNode;
|
|
342
408
|
}
|
|
343
409
|
|
|
@@ -383,8 +449,12 @@ MenuRadioItem.displayName = 'Menu.RadioItem';
|
|
|
383
449
|
// =============================================================================
|
|
384
450
|
|
|
385
451
|
export interface MenuItemLabelProps extends TextProps {
|
|
452
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
386
453
|
asChild?: boolean;
|
|
454
|
+
/** Additional Uniwind/Tailwind classes, merged after the label's own styles. */
|
|
387
455
|
className?: string;
|
|
456
|
+
/** Label text. */
|
|
457
|
+
children?: ReactNode;
|
|
388
458
|
/** Checked state when used outside a selectable Menu item (e.g. `Select.ItemLabel`). */
|
|
389
459
|
isChecked?: boolean;
|
|
390
460
|
}
|
|
@@ -423,10 +493,18 @@ const MenuItemLabel = forwardRef<Text, MenuItemLabelProps>(
|
|
|
423
493
|
MenuItemLabel.displayName = 'Menu.ItemLabel';
|
|
424
494
|
|
|
425
495
|
export interface MenuItemIconProps extends Omit<IconProps, 'as' | 'children' | 'color'> {
|
|
496
|
+
/** Render the consumer's child element in place of the icon. */
|
|
426
497
|
asChild?: boolean;
|
|
498
|
+
/** The `@cdx-ui/icons` component to render. */
|
|
427
499
|
as?: IconProps['as'];
|
|
500
|
+
/**
|
|
501
|
+
* Side of the label the icon sits on; sets the spacing between them.
|
|
502
|
+
* @default 'leading'
|
|
503
|
+
*/
|
|
428
504
|
position?: IconSlotPosition;
|
|
505
|
+
/** Additional Uniwind/Tailwind classes, merged after the icon's own styles. */
|
|
429
506
|
className?: string;
|
|
507
|
+
/** The element to render when `asChild` is set. */
|
|
430
508
|
children?: ReactNode;
|
|
431
509
|
}
|
|
432
510
|
|
|
@@ -482,8 +560,12 @@ const MenuItemIcon = ({
|
|
|
482
560
|
MenuItemIcon.displayName = 'Menu.ItemIcon';
|
|
483
561
|
|
|
484
562
|
export interface MenuItemShortcutProps extends TextProps {
|
|
563
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
485
564
|
asChild?: boolean;
|
|
565
|
+
/** Additional Uniwind/Tailwind classes, merged after the shortcut's own styles. */
|
|
486
566
|
className?: string;
|
|
567
|
+
/** Shortcut hint text, such as `⌘C`. */
|
|
568
|
+
children?: ReactNode;
|
|
487
569
|
}
|
|
488
570
|
|
|
489
571
|
const MenuItemShortcut = forwardRef<Text, MenuItemShortcutProps>(
|
|
@@ -509,11 +591,23 @@ const MenuItemShortcut = forwardRef<Text, MenuItemShortcutProps>(
|
|
|
509
591
|
MenuItemShortcut.displayName = 'Menu.ItemShortcut';
|
|
510
592
|
|
|
511
593
|
export interface MenuItemIndicatorProps extends Omit<IconProps, 'as' | 'children' | 'color'> {
|
|
594
|
+
/** Render the consumer's child element in place of the icon. */
|
|
512
595
|
asChild?: boolean;
|
|
596
|
+
/**
|
|
597
|
+
* The `@cdx-ui/icons` component to render.
|
|
598
|
+
* @default Check
|
|
599
|
+
*/
|
|
513
600
|
as?: IconProps['as'];
|
|
601
|
+
/** Shows the indicator. Defaults to the checked state of the enclosing item. */
|
|
514
602
|
isChecked?: boolean;
|
|
603
|
+
/**
|
|
604
|
+
* Side of the label the indicator sits on; sets the spacing between them.
|
|
605
|
+
* @default 'trailing'
|
|
606
|
+
*/
|
|
515
607
|
position?: IconSlotPosition;
|
|
608
|
+
/** Additional Uniwind/Tailwind classes, merged after the indicator's own styles. */
|
|
516
609
|
className?: string;
|
|
610
|
+
/** The element to render when `asChild` is set. */
|
|
517
611
|
children?: ReactNode;
|
|
518
612
|
}
|
|
519
613
|
|
|
@@ -575,8 +669,12 @@ MenuItemIndicator.displayName = 'Menu.ItemIndicator';
|
|
|
575
669
|
// =============================================================================
|
|
576
670
|
|
|
577
671
|
export interface MenuSectionLabelProps extends TextProps {
|
|
672
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
578
673
|
asChild?: boolean;
|
|
674
|
+
/** Additional Uniwind/Tailwind classes, merged after the section label's own styles. */
|
|
579
675
|
className?: string;
|
|
676
|
+
/** Section heading text. */
|
|
677
|
+
children?: ReactNode;
|
|
580
678
|
}
|
|
581
679
|
|
|
582
680
|
const MenuSectionLabel = forwardRef<Text, MenuSectionLabelProps>(
|
|
@@ -601,7 +699,10 @@ const MenuSectionLabel = forwardRef<Text, MenuSectionLabelProps>(
|
|
|
601
699
|
MenuSectionLabel.displayName = 'Menu.SectionLabel';
|
|
602
700
|
|
|
603
701
|
export interface MenuSeparatorProps extends ViewProps {
|
|
702
|
+
/** Additional Uniwind/Tailwind classes, merged after the separator's own styles. */
|
|
604
703
|
className?: string;
|
|
704
|
+
/** Not rendered; the separator draws its own line. */
|
|
705
|
+
children?: ReactNode;
|
|
605
706
|
}
|
|
606
707
|
|
|
607
708
|
const MenuSeparator = forwardRef<View, MenuSeparatorProps>(
|
|
@@ -630,8 +731,11 @@ MenuSeparator.displayName = 'Menu.Separator';
|
|
|
630
731
|
// =============================================================================
|
|
631
732
|
|
|
632
733
|
export interface MenuGroupHeaderProps extends ViewProps {
|
|
734
|
+
/** Render the consumer's child element in place of the default `View` host. */
|
|
633
735
|
asChild?: boolean;
|
|
736
|
+
/** Additional Uniwind/Tailwind classes, merged after the group header's own styles. */
|
|
634
737
|
className?: string;
|
|
738
|
+
/** Header content, typically a `Menu.ItemLabel` and an optional `Menu.ItemAction`. */
|
|
635
739
|
children?: ReactNode;
|
|
636
740
|
}
|
|
637
741
|
|
|
@@ -666,7 +770,9 @@ const MenuGroupHeader = forwardRef<View, MenuGroupHeaderProps>(
|
|
|
666
770
|
MenuGroupHeader.displayName = 'Menu.GroupHeader';
|
|
667
771
|
|
|
668
772
|
export interface MenuItemActionProps extends IMenuItemActionProps {
|
|
773
|
+
/** Additional Uniwind/Tailwind classes, merged after the action's own styles. */
|
|
669
774
|
className?: string;
|
|
775
|
+
/** The trailing interactive control, such as a `Button`. */
|
|
670
776
|
children?: ReactNode;
|
|
671
777
|
}
|
|
672
778
|
|
|
@@ -688,7 +794,10 @@ const MenuItemAction = forwardRef<View, MenuItemActionProps>(
|
|
|
688
794
|
MenuItemAction.displayName = 'Menu.ItemAction';
|
|
689
795
|
|
|
690
796
|
export interface MenuItemControlProps extends ViewProps {
|
|
797
|
+
/** Additional Uniwind/Tailwind classes, merged after the control's own styles. */
|
|
691
798
|
className?: string;
|
|
799
|
+
/** Not rendered; the control draws a checkbox or radio that mirrors the enclosing item. */
|
|
800
|
+
children?: ReactNode;
|
|
692
801
|
}
|
|
693
802
|
|
|
694
803
|
const MenuItemControl = ({ className, style, ...props }: MenuItemControlProps) => {
|
|
@@ -740,8 +849,12 @@ const MenuItemControl = ({ className, style, ...props }: MenuItemControlProps) =
|
|
|
740
849
|
MenuItemControl.displayName = 'Menu.ItemControl';
|
|
741
850
|
|
|
742
851
|
export interface MenuItemCountProps extends TextProps {
|
|
852
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
743
853
|
asChild?: boolean;
|
|
854
|
+
/** Additional Uniwind/Tailwind classes, merged after the count's own styles. */
|
|
744
855
|
className?: string;
|
|
856
|
+
/** The count to display. */
|
|
857
|
+
children?: ReactNode;
|
|
745
858
|
}
|
|
746
859
|
|
|
747
860
|
const MenuItemCount = forwardRef<Text, MenuItemCountProps>(
|
|
@@ -22,7 +22,9 @@ import { calendarRootVariants } from '../Calendar/styles';
|
|
|
22
22
|
|
|
23
23
|
export interface RangeCalendarProps
|
|
24
24
|
extends Omit<RangeCalendarRootProps, 'children'>, Omit<ViewProps, 'children'> {
|
|
25
|
+
/** Additional Uniwind/Tailwind classes, merged after the calendar's own styles. */
|
|
25
26
|
className?: string;
|
|
27
|
+
/** Custom calendar body. Omit to render the default header and month grid. */
|
|
26
28
|
children?: ReactNode;
|
|
27
29
|
}
|
|
28
30
|
|