panelui-web 0.10.0 → 0.11.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/components/alert/index.d.ts +15 -8
- package/dist/components/alert/index.js +65 -18
- package/dist/components/alert-dialog/index.d.ts +9 -3
- package/dist/components/alert-dialog/index.js +23 -7
- package/dist/components/avatar/index.d.ts +9 -3
- package/dist/components/avatar/index.js +34 -10
- package/dist/components/badge/index.d.ts +57 -0
- package/dist/components/badge/index.js +61 -0
- package/dist/components/bar-picker/index.d.ts +8 -1
- package/dist/components/bar-picker/index.js +35 -26
- package/dist/components/button/index.d.ts +68 -46
- package/dist/components/button/index.js +38 -2
- package/dist/components/button-group/index.d.ts +11 -5
- package/dist/components/button-group/index.js +31 -7
- package/dist/components/canvas/index.d.ts +9 -3
- package/dist/components/canvas/index.js +53 -25
- package/dist/components/card/index.d.ts +13 -7
- package/dist/components/card/index.js +45 -17
- package/dist/components/checkbox/index.d.ts +73 -0
- package/dist/components/checkbox/index.js +100 -0
- package/dist/components/chip/index.d.ts +79 -0
- package/dist/components/chip/index.js +112 -0
- package/dist/components/choice-cards/index.d.ts +11 -5
- package/dist/components/choice-cards/index.js +25 -6
- package/dist/components/command-dock/index.d.ts +16 -9
- package/dist/components/command-dock/index.js +76 -19
- package/dist/components/day-grid/index.d.ts +12 -6
- package/dist/components/day-grid/index.js +71 -27
- package/dist/components/dialog/index.d.ts +19 -12
- package/dist/components/dialog/index.js +84 -25
- package/dist/components/feedback/index.d.ts +20 -13
- package/dist/components/feedback/index.js +83 -27
- package/dist/components/field/index.d.ts +85 -0
- package/dist/components/field/index.js +90 -0
- package/dist/components/flow/index.d.ts +21 -14
- package/dist/components/flow/index.js +56 -20
- package/dist/components/frame/index.d.ts +17 -11
- package/dist/components/frame/index.js +73 -22
- package/dist/components/input/index.d.ts +9 -24
- package/dist/components/input/index.js +53 -6
- package/dist/components/inspector/index.d.ts +69 -63
- package/dist/components/inspector/index.js +31 -9
- package/dist/components/kpi/index.d.ts +20 -14
- package/dist/components/kpi/index.js +111 -36
- package/dist/components/label/index.d.ts +10 -4
- package/dist/components/label/index.js +39 -9
- package/dist/components/lane-board/index.d.ts +15 -9
- package/dist/components/lane-board/index.js +97 -57
- package/dist/components/menu/index.d.ts +10 -4
- package/dist/components/menu/index.js +28 -10
- package/dist/components/message/index.d.ts +15 -9
- package/dist/components/message/index.js +71 -19
- package/dist/components/not-found/index.d.ts +10 -4
- package/dist/components/not-found/index.js +48 -12
- package/dist/components/planet/index.d.ts +11 -5
- package/dist/components/planet/index.js +73 -20
- package/dist/components/prompt/index.d.ts +30 -23
- package/dist/components/prompt/index.js +148 -52
- package/dist/components/radio-group/index.d.ts +124 -0
- package/dist/components/radio-group/index.js +216 -0
- package/dist/components/range-meter/index.d.ts +9 -3
- package/dist/components/range-meter/index.js +61 -27
- package/dist/components/rolling-number/index.d.ts +8 -1
- package/dist/components/rolling-number/index.js +15 -6
- package/dist/components/select/index.d.ts +7 -1
- package/dist/components/select/index.js +13 -4
- package/dist/components/sheet/index.d.ts +8 -2
- package/dist/components/sheet/index.js +27 -15
- package/dist/components/slider/index.d.ts +11 -4
- package/dist/components/slider/index.js +30 -10
- package/dist/components/soundwave/index.d.ts +8 -2
- package/dist/components/soundwave/index.js +26 -6
- package/dist/components/stat/index.d.ts +13 -7
- package/dist/components/stat/index.js +45 -15
- package/dist/components/table/index.d.ts +128 -0
- package/dist/components/table/index.js +145 -0
- package/dist/components/tabs/index.d.ts +7 -1
- package/dist/components/tabs/index.js +8 -2
- package/dist/components/textarea/index.d.ts +0 -23
- package/dist/components/textarea/index.js +22 -5
- package/dist/components/tilt-card/index.d.ts +9 -3
- package/dist/components/tilt-card/index.js +28 -8
- package/dist/components/timeline/index.d.ts +20 -13
- package/dist/components/timeline/index.js +166 -59
- package/dist/components/toast/dither-text.d.ts +13 -0
- package/dist/components/toast/dither-text.js +143 -0
- package/dist/components/toast/dither.d.ts +29 -0
- package/dist/components/toast/dither.js +153 -0
- package/dist/components/toast/index.d.ts +108 -0
- package/dist/components/toast/index.js +225 -0
- package/dist/components/toolbar/index.d.ts +9 -3
- package/dist/components/toolbar/index.js +23 -6
- package/dist/components/workbench/index.d.ts +50 -43
- package/dist/components/workbench/index.js +77 -20
- package/dist/components/xy-pad/index.d.ts +9 -3
- package/dist/components/xy-pad/index.js +13 -2
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Field — a form control with its label, a line of help, and the reason it was refused.
|
|
4
|
+
*
|
|
5
|
+
* ```tsx
|
|
6
|
+
* <Field name="email">
|
|
7
|
+
* <Field.Label>Work email</Field.Label>
|
|
8
|
+
* <Input type="email" required placeholder="you@company.com" />
|
|
9
|
+
* <Field.Description>We send the receipt here.</Field.Description>
|
|
10
|
+
* <Field.Error match="valueMissing">Enter an email address.</Field.Error>
|
|
11
|
+
* </Field>
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* ## The ids are wired for you
|
|
15
|
+
*
|
|
16
|
+
* A label has to point at its control, and the control has to point at the
|
|
17
|
+
* help and the error, or a screen reader reads the field with no name and no
|
|
18
|
+
* reason. Field does that wiring: `Field.Label` is tied to the control inside
|
|
19
|
+
* the field, and the control is described by `Field.Description` and the
|
|
20
|
+
* error that is showing. Input, Textarea, Select, Checkbox, Radio Group and
|
|
21
|
+
* Switch all take part, with nothing passed.
|
|
22
|
+
*
|
|
23
|
+
* ## The label is a Label
|
|
24
|
+
*
|
|
25
|
+
* `Field.Label` is the Label component, so `required`, `optional`,
|
|
26
|
+
* `Label.Hint` and `Label.Action` work in it as they do anywhere else. It
|
|
27
|
+
* turns to the destructive colour and fades with the field, without
|
|
28
|
+
* `invalid` or `disabled` passed to it.
|
|
29
|
+
*
|
|
30
|
+
* ## Errors wait for the reader
|
|
31
|
+
*
|
|
32
|
+
* The browser's own checks — `required`, `type="email"`, `minLength` — run
|
|
33
|
+
* when the control is left, not on every key, so a field is not red while it
|
|
34
|
+
* is still being typed. `Field.Error` with `match` shows a message for one of
|
|
35
|
+
* those checks; with no `match`, it shows whenever the field is invalid,
|
|
36
|
+
* which is the one to use with `invalid` set from a server's answer. An
|
|
37
|
+
* error that appears slides in under the control, and the description it
|
|
38
|
+
* replaces steps aside.
|
|
39
|
+
*/
|
|
40
|
+
import { Field as BaseField } from '@base-ui/react/field';
|
|
41
|
+
import { tv } from 'tailwind-variants';
|
|
42
|
+
import { Label } from '../label/index.js';
|
|
43
|
+
const fieldVariants = tv({
|
|
44
|
+
slots: {
|
|
45
|
+
root: 'group/field flex w-full min-w-0 flex-col gap-2',
|
|
46
|
+
description: [
|
|
47
|
+
'text-xs leading-4 text-muted-foreground',
|
|
48
|
+
// An error showing says more than the help line, so the help steps aside.
|
|
49
|
+
'group-has-[[data-slot=field-error]]/field:hidden',
|
|
50
|
+
],
|
|
51
|
+
error: [
|
|
52
|
+
'text-xs leading-4 text-destructive',
|
|
53
|
+
'transition-[opacity,translate] duration-200 starting:-translate-y-1 starting:opacity-0 motion-reduce:transition-none',
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Groups a control with its label, help and error. Takes `name`, `invalid`
|
|
59
|
+
* (for an error from outside, such as a server), `disabled`, and `validate`
|
|
60
|
+
* for a check of your own.
|
|
61
|
+
*/
|
|
62
|
+
function FieldRoot({ className, ...props }) {
|
|
63
|
+
return _jsx(BaseField.Root, { "data-slot": "field", className: fieldVariants().root({ className }), ...props });
|
|
64
|
+
}
|
|
65
|
+
FieldRoot.displayName = 'Field';
|
|
66
|
+
/** The control's name, tied to it. Takes `required` and `optional` as Label does, and its parts. */
|
|
67
|
+
function FieldLabel({ required, optional, className, children, ...props }) {
|
|
68
|
+
return (_jsx(BaseField.Label, { "data-slot": "field-label", className: className, render: (labelProps) => _jsx(Label, { ...labelProps, required: required, optional: optional }), ...props, children: children }));
|
|
69
|
+
}
|
|
70
|
+
FieldLabel.displayName = 'Field.Label';
|
|
71
|
+
/** A line of help under the control. Hidden while an error is showing. */
|
|
72
|
+
function FieldDescription({ className, ...props }) {
|
|
73
|
+
return (_jsx(BaseField.Description, { "data-slot": "field-description", className: fieldVariants().description({ className }), ...props }));
|
|
74
|
+
}
|
|
75
|
+
FieldDescription.displayName = 'Field.Description';
|
|
76
|
+
/**
|
|
77
|
+
* Why the value was refused. `match` names the check it is for, such as
|
|
78
|
+
* `valueMissing` or `typeMismatch`; with none, it shows whenever the field is
|
|
79
|
+
* invalid. With no children it shows the browser's own message.
|
|
80
|
+
*/
|
|
81
|
+
function FieldError({ className, ...props }) {
|
|
82
|
+
return _jsx(BaseField.Error, { "data-slot": "field-error", className: fieldVariants().error({ className }), ...props });
|
|
83
|
+
}
|
|
84
|
+
FieldError.displayName = 'Field.Error';
|
|
85
|
+
export const Field = Object.assign(FieldRoot, {
|
|
86
|
+
Label: FieldLabel,
|
|
87
|
+
Description: FieldDescription,
|
|
88
|
+
Error: FieldError,
|
|
89
|
+
});
|
|
90
|
+
export { FieldLabel, FieldDescription, FieldError };
|
|
@@ -46,6 +46,13 @@
|
|
|
46
46
|
*/
|
|
47
47
|
import { type ComponentProps, type ReactNode } from 'react';
|
|
48
48
|
import { type FlowPoint, type FlowRect, type FlowSide } from './flow-paths.js';
|
|
49
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
50
|
+
import type * as ReactTypes from 'react';
|
|
51
|
+
import type { ElementType as RenderElementType } from 'react';
|
|
52
|
+
/** Draws a part as another element, or composes it with a component: `render={<a href="/" />}`. */
|
|
53
|
+
type RenderProp<Tag extends RenderElementType> = {
|
|
54
|
+
render?: useRender.ComponentProps<Tag>['render'];
|
|
55
|
+
};
|
|
49
56
|
export type FlowEdgeVariant = 'bezier' | 'smoothstep' | 'step' | 'straight';
|
|
50
57
|
/** Which of the theme's roles an edge is drawn in. */
|
|
51
58
|
export type FlowColor = 'primary' | 'info' | 'success' | 'warning' | 'destructive';
|
|
@@ -103,7 +110,7 @@ export interface FlowProps extends Omit<ComponentProps<'div'>, 'children'> {
|
|
|
103
110
|
label?: string;
|
|
104
111
|
children?: ReactNode;
|
|
105
112
|
}
|
|
106
|
-
declare function FlowRoot({ defaultViewport, minZoom, maxZoom, panOnDrag, zoomOnPinch, fitViewOnMount, fitViewPadding, onViewportChange, onNodeDragEnd, onConnect, isValidConnection, label, className, children, onKeyDown, ...props }: FlowProps):
|
|
113
|
+
declare function FlowRoot({ defaultViewport, minZoom, maxZoom, panOnDrag, zoomOnPinch, fitViewOnMount, fitViewPadding, onViewportChange, onNodeDragEnd, onConnect, isValidConnection, label, className, children, onKeyDown, ...props }: FlowProps): ReactTypes.JSX.Element;
|
|
107
114
|
declare namespace FlowRoot {
|
|
108
115
|
var displayName: string;
|
|
109
116
|
}
|
|
@@ -117,7 +124,7 @@ export interface FlowBackgroundProps {
|
|
|
117
124
|
className?: string;
|
|
118
125
|
}
|
|
119
126
|
/** The pattern behind the graph, which moves and scales with it. */
|
|
120
|
-
declare function FlowBackground({ variant, gap, size, className }: FlowBackgroundProps):
|
|
127
|
+
declare function FlowBackground({ variant, gap, size, className }: FlowBackgroundProps): ReactTypes.ReactPortal | null;
|
|
121
128
|
declare namespace FlowBackground {
|
|
122
129
|
var displayName: string;
|
|
123
130
|
}
|
|
@@ -148,7 +155,7 @@ export interface FlowNodeProps extends Omit<ComponentProps<'div'>, 'id'> {
|
|
|
148
155
|
moveStep?: number;
|
|
149
156
|
}
|
|
150
157
|
/** A box on the graph. Fill it with the node parts below, or with anything of your own. */
|
|
151
|
-
declare function FlowNode({ id, position, draggable, confine, pinned, selected, onPress, onDelete, moveStep, className, style, children, ...props }: FlowNodeProps):
|
|
158
|
+
declare function FlowNode({ id, position, draggable, confine, pinned, selected, onPress, onDelete, moveStep, className, style, children, ...props }: FlowNodeProps): ReactTypes.JSX.Element;
|
|
152
159
|
declare namespace FlowNode {
|
|
153
160
|
var displayName: string;
|
|
154
161
|
}
|
|
@@ -168,35 +175,35 @@ export interface FlowGroupProps extends Omit<FlowNodeProps, 'confine' | 'pinned'
|
|
|
168
175
|
* A dashed box round a few things that belong together. It is a node like any
|
|
169
176
|
* other: it is dragged as one, and an edge can be joined to it.
|
|
170
177
|
*/
|
|
171
|
-
declare function FlowGroup({ id, position, draggable, selected: _selected, onPress, onDelete, moveStep, label, size, className, style, children, ...props }: FlowGroupProps):
|
|
178
|
+
declare function FlowGroup({ id, position, draggable, selected: _selected, onPress, onDelete, moveStep, label, size, className, style, children, ...props }: FlowGroupProps): ReactTypes.JSX.Element;
|
|
172
179
|
declare namespace FlowGroup {
|
|
173
180
|
var displayName: string;
|
|
174
181
|
}
|
|
175
182
|
export interface FlowNodeHeaderProps extends ComponentProps<'div'> {
|
|
176
183
|
}
|
|
177
184
|
/** A strip across the top of a node, ruled off from the rest: a step number and a state. */
|
|
178
|
-
declare function FlowNodeHeader({ className, ...props }: FlowNodeHeaderProps):
|
|
185
|
+
declare function FlowNodeHeader({ className, render, ...props }: FlowNodeHeaderProps & RenderProp<'div'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
179
186
|
declare namespace FlowNodeHeader {
|
|
180
187
|
var displayName: string;
|
|
181
188
|
}
|
|
182
189
|
export interface FlowNodeContentProps extends ComponentProps<'div'> {
|
|
183
190
|
}
|
|
184
191
|
/** The body of a node, with the node's padding: a title over a description. */
|
|
185
|
-
declare function FlowNodeContent({ className, ...props }: FlowNodeContentProps):
|
|
192
|
+
declare function FlowNodeContent({ className, render, ...props }: FlowNodeContentProps & RenderProp<'div'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
186
193
|
declare namespace FlowNodeContent {
|
|
187
194
|
var displayName: string;
|
|
188
195
|
}
|
|
189
196
|
export interface FlowNodeTitleProps extends ComponentProps<'p'> {
|
|
190
197
|
}
|
|
191
198
|
/** What the node is. */
|
|
192
|
-
declare function FlowNodeTitle({ className, ...props }: FlowNodeTitleProps):
|
|
199
|
+
declare function FlowNodeTitle({ className, render, ...props }: FlowNodeTitleProps & RenderProp<'p'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
193
200
|
declare namespace FlowNodeTitle {
|
|
194
201
|
var displayName: string;
|
|
195
202
|
}
|
|
196
203
|
export interface FlowNodeDescriptionProps extends ComponentProps<'p'> {
|
|
197
204
|
}
|
|
198
205
|
/** A quieter line about the node. Smaller inside a `Flow.GroupItem`. */
|
|
199
|
-
declare function FlowNodeDescription({ className, ...props }: FlowNodeDescriptionProps):
|
|
206
|
+
declare function FlowNodeDescription({ className, render, ...props }: FlowNodeDescriptionProps & RenderProp<'p'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
200
207
|
declare namespace FlowNodeDescription {
|
|
201
208
|
var displayName: string;
|
|
202
209
|
}
|
|
@@ -205,7 +212,7 @@ export interface FlowNodeBadgeProps extends Omit<ComponentProps<'span'>, 'color'
|
|
|
205
212
|
color?: FlowColor | 'muted';
|
|
206
213
|
}
|
|
207
214
|
/** A word in a pill, for a node's state: done, now, waiting. */
|
|
208
|
-
declare function FlowNodeBadge({ color, className, ...props }: FlowNodeBadgeProps):
|
|
215
|
+
declare function FlowNodeBadge({ color, className, render, ...props }: FlowNodeBadgeProps & RenderProp<'span'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
209
216
|
declare namespace FlowNodeBadge {
|
|
210
217
|
var displayName: string;
|
|
211
218
|
}
|
|
@@ -215,7 +222,7 @@ export interface FlowGroupItemProps extends ComponentProps<'div'> {
|
|
|
215
222
|
* One thing inside a `Flow.Group` that is not a node of its own: an icon
|
|
216
223
|
* beside a `Flow.NodeContent`. It moves with the group and edges cannot join it.
|
|
217
224
|
*/
|
|
218
|
-
declare function FlowGroupItem({ className, ...props }: FlowGroupItemProps):
|
|
225
|
+
declare function FlowGroupItem({ className, render, ...props }: FlowGroupItemProps & RenderProp<'div'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
219
226
|
declare namespace FlowGroupItem {
|
|
220
227
|
var displayName: string;
|
|
221
228
|
}
|
|
@@ -228,7 +235,7 @@ export interface FlowHandleProps extends Omit<ComponentProps<'span'>, 'id'> {
|
|
|
228
235
|
offset?: number;
|
|
229
236
|
}
|
|
230
237
|
/** A point on a node's edge that a connection can be drawn from, or dropped on. */
|
|
231
|
-
declare function FlowHandle({ id, position, offset, className, style, ...props }: FlowHandleProps):
|
|
238
|
+
declare function FlowHandle({ id, position, offset, className, style, render, ...props }: FlowHandleProps & RenderProp<'span'>): ReactTypes.ReactElement<unknown, string | ReactTypes.JSXElementConstructor<any>>;
|
|
232
239
|
declare namespace FlowHandle {
|
|
233
240
|
var displayName: string;
|
|
234
241
|
}
|
|
@@ -261,7 +268,7 @@ export interface FlowEdgeProps {
|
|
|
261
268
|
curvature?: number;
|
|
262
269
|
}
|
|
263
270
|
/** A line from one node to another, which follows them as they move. */
|
|
264
|
-
declare function FlowEdge({ from, to, variant, animated, dashed, color, width, arrow, fromSide, toSide, radius, gap, curvature, }: FlowEdgeProps):
|
|
271
|
+
declare function FlowEdge({ from, to, variant, animated, dashed, color, width, arrow, fromSide, toSide, radius, gap, curvature, }: FlowEdgeProps): ReactTypes.JSX.Element | null;
|
|
265
272
|
declare namespace FlowEdge {
|
|
266
273
|
var displayName: string;
|
|
267
274
|
}
|
|
@@ -279,7 +286,7 @@ export interface FlowControlsProps extends Omit<ComponentProps<'div'>, 'children
|
|
|
279
286
|
position?: FlowCorner;
|
|
280
287
|
}
|
|
281
288
|
/** Buttons for what a pinch and a drag do, for anyone without either. */
|
|
282
|
-
declare function FlowControls({ zoom, fit, lock, step, position, className, ...props }: FlowControlsProps):
|
|
289
|
+
declare function FlowControls({ zoom, fit, lock, step, position, className, ...props }: FlowControlsProps): ReactTypes.ReactPortal | null;
|
|
283
290
|
declare namespace FlowControls {
|
|
284
291
|
var displayName: string;
|
|
285
292
|
}
|
|
@@ -292,7 +299,7 @@ export interface FlowMiniMapProps extends Omit<ComponentProps<'div'>, 'children'
|
|
|
292
299
|
position?: FlowCorner;
|
|
293
300
|
}
|
|
294
301
|
/** The whole graph, small, with the part in view marked on it. */
|
|
295
|
-
declare function FlowMiniMap({ width, height, position, className, style, ...props }: FlowMiniMapProps):
|
|
302
|
+
declare function FlowMiniMap({ width, height, position, className, style, ...props }: FlowMiniMapProps): ReactTypes.ReactPortal | null;
|
|
296
303
|
declare namespace FlowMiniMap {
|
|
297
304
|
var displayName: string;
|
|
298
305
|
}
|
|
@@ -50,6 +50,8 @@ import { createContext, useCallback, useContext, useEffect, useId, useLayoutEffe
|
|
|
50
50
|
import { createPortal } from 'react-dom';
|
|
51
51
|
import { tv } from 'tailwind-variants';
|
|
52
52
|
import { anchorOf, arrivalDirection, arrowHeadPath, autoSides, bezierPath, edgePath, } from './flow-paths.js';
|
|
53
|
+
import { mergeProps } from '@base-ui/react/merge-props';
|
|
54
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
53
55
|
const flowVariants = tv({
|
|
54
56
|
slots: {
|
|
55
57
|
root: 'relative h-96 w-full cursor-grab touch-none select-none overflow-hidden rounded-2xl border bg-background text-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring active:cursor-grabbing',
|
|
@@ -557,36 +559,60 @@ function FlowGroup({ id, position, draggable = true, selected: _selected, onPres
|
|
|
557
559
|
}
|
|
558
560
|
FlowGroup.displayName = 'Flow.Group';
|
|
559
561
|
/** A strip across the top of a node, ruled off from the rest: a step number and a state. */
|
|
560
|
-
function FlowNodeHeader({ className, ...props }) {
|
|
561
|
-
return
|
|
562
|
+
function FlowNodeHeader({ className, render, ...props }) {
|
|
563
|
+
return useRender({
|
|
564
|
+
defaultTagName: 'div',
|
|
565
|
+
render,
|
|
566
|
+
props: mergeProps({ 'data-slot': 'flow-node-header', className: flowVariants().nodeHeader({ className }) }, props),
|
|
567
|
+
});
|
|
562
568
|
}
|
|
563
569
|
FlowNodeHeader.displayName = 'Flow.NodeHeader';
|
|
564
570
|
/** The body of a node, with the node's padding: a title over a description. */
|
|
565
|
-
function FlowNodeContent({ className, ...props }) {
|
|
566
|
-
return
|
|
571
|
+
function FlowNodeContent({ className, render, ...props }) {
|
|
572
|
+
return useRender({
|
|
573
|
+
defaultTagName: 'div',
|
|
574
|
+
render,
|
|
575
|
+
props: mergeProps({ 'data-slot': 'flow-node-content', className: flowVariants().nodeContent({ className }) }, props),
|
|
576
|
+
});
|
|
567
577
|
}
|
|
568
578
|
FlowNodeContent.displayName = 'Flow.NodeContent';
|
|
569
579
|
/** What the node is. */
|
|
570
|
-
function FlowNodeTitle({ className, ...props }) {
|
|
571
|
-
return
|
|
580
|
+
function FlowNodeTitle({ className, render, ...props }) {
|
|
581
|
+
return useRender({
|
|
582
|
+
defaultTagName: 'p',
|
|
583
|
+
render,
|
|
584
|
+
props: mergeProps({ 'data-slot': 'flow-node-title', className: flowVariants().nodeTitle({ className }) }, props),
|
|
585
|
+
});
|
|
572
586
|
}
|
|
573
587
|
FlowNodeTitle.displayName = 'Flow.NodeTitle';
|
|
574
588
|
/** A quieter line about the node. Smaller inside a `Flow.GroupItem`. */
|
|
575
|
-
function FlowNodeDescription({ className, ...props }) {
|
|
576
|
-
return (
|
|
589
|
+
function FlowNodeDescription({ className, render, ...props }) {
|
|
590
|
+
return useRender({
|
|
591
|
+
defaultTagName: 'p',
|
|
592
|
+
render,
|
|
593
|
+
props: mergeProps({ 'data-slot': 'flow-node-description', className: flowVariants().nodeDescription({ className }) }, props),
|
|
594
|
+
});
|
|
577
595
|
}
|
|
578
596
|
FlowNodeDescription.displayName = 'Flow.NodeDescription';
|
|
579
597
|
/** A word in a pill, for a node's state: done, now, waiting. */
|
|
580
|
-
function FlowNodeBadge({ color = 'muted', className, ...props }) {
|
|
581
|
-
return (
|
|
598
|
+
function FlowNodeBadge({ color = 'muted', className, render, ...props }) {
|
|
599
|
+
return useRender({
|
|
600
|
+
defaultTagName: 'span',
|
|
601
|
+
render,
|
|
602
|
+
props: mergeProps({ 'data-slot': 'flow-node-badge', className: flowVariants({ color }).nodeBadge({ className }) }, props),
|
|
603
|
+
});
|
|
582
604
|
}
|
|
583
605
|
FlowNodeBadge.displayName = 'Flow.NodeBadge';
|
|
584
606
|
/**
|
|
585
607
|
* One thing inside a `Flow.Group` that is not a node of its own: an icon
|
|
586
608
|
* beside a `Flow.NodeContent`. It moves with the group and edges cannot join it.
|
|
587
609
|
*/
|
|
588
|
-
function FlowGroupItem({ className, ...props }) {
|
|
589
|
-
return
|
|
610
|
+
function FlowGroupItem({ className, render, ...props }) {
|
|
611
|
+
return useRender({
|
|
612
|
+
defaultTagName: 'div',
|
|
613
|
+
render,
|
|
614
|
+
props: mergeProps({ 'data-slot': 'flow-group-item', className: flowVariants().groupItem({ className }) }, props),
|
|
615
|
+
});
|
|
590
616
|
}
|
|
591
617
|
FlowGroupItem.displayName = 'Flow.GroupItem';
|
|
592
618
|
const SIDE_STYLE = {
|
|
@@ -596,7 +622,7 @@ const SIDE_STYLE = {
|
|
|
596
622
|
right: (offset) => ({ left: '100%', top: `${offset * 100}%` }),
|
|
597
623
|
};
|
|
598
624
|
/** A point on a node's edge that a connection can be drawn from, or dropped on. */
|
|
599
|
-
function FlowHandle({ id, position = 'right', offset = 0.5, className, style, ...props }) {
|
|
625
|
+
function FlowHandle({ id, position = 'right', offset = 0.5, className, style, render, ...props }) {
|
|
600
626
|
const flow = useFlow('Flow.Handle');
|
|
601
627
|
const node = useContext(NodeContext);
|
|
602
628
|
if (node === null)
|
|
@@ -607,13 +633,23 @@ function FlowHandle({ id, position = 'right', offset = 0.5, className, style, ..
|
|
|
607
633
|
setHandle(node, key, { id, side: position, offset });
|
|
608
634
|
return () => setHandle(node, key, null);
|
|
609
635
|
}, [node, id, position, offset, setHandle]);
|
|
610
|
-
return (
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
636
|
+
return useRender({
|
|
637
|
+
defaultTagName: 'span',
|
|
638
|
+
render,
|
|
639
|
+
props: mergeProps({
|
|
640
|
+
'data-flow-handle': id ?? '',
|
|
641
|
+
'aria-hidden': 'true',
|
|
642
|
+
className: flowVariants().handle({ className }),
|
|
643
|
+
style: { ...SIDE_STYLE[position](offset), ...style },
|
|
644
|
+
onPointerDown: (event) => {
|
|
645
|
+
if (event.button !== 0)
|
|
646
|
+
return;
|
|
647
|
+
event.stopPropagation();
|
|
648
|
+
event.preventDefault();
|
|
649
|
+
connectFrom(node, { id, side: position, offset }, event);
|
|
650
|
+
},
|
|
651
|
+
}, props),
|
|
652
|
+
});
|
|
617
653
|
}
|
|
618
654
|
FlowHandle.displayName = 'Flow.Handle';
|
|
619
655
|
/**
|
|
@@ -55,6 +55,12 @@
|
|
|
55
55
|
* through context, so a frame has no client JavaScript of its own.
|
|
56
56
|
*/
|
|
57
57
|
import type { ComponentProps, MouseEventHandler, ReactNode } from 'react';
|
|
58
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
59
|
+
import type { ElementType as RenderElementType } from 'react';
|
|
60
|
+
/** Draws a part as another element, or composes it with a component: `render={<a href="/" />}`. */
|
|
61
|
+
type RenderProp<Tag extends RenderElementType> = {
|
|
62
|
+
render?: useRender.ComponentProps<Tag>['render'];
|
|
63
|
+
};
|
|
58
64
|
export type FrameVariant = 'default' | 'band' | 'inset' | 'plain';
|
|
59
65
|
export interface FrameProps extends ComponentProps<'div'> {
|
|
60
66
|
/**
|
|
@@ -67,7 +73,7 @@ export interface FrameProps extends ComponentProps<'div'> {
|
|
|
67
73
|
*/
|
|
68
74
|
variant?: FrameVariant;
|
|
69
75
|
}
|
|
70
|
-
declare function FrameRoot({ variant, className, ...props }: FrameProps): import("react").
|
|
76
|
+
declare function FrameRoot({ variant, className, render, ...props }: FrameProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
71
77
|
declare namespace FrameRoot {
|
|
72
78
|
var displayName: string;
|
|
73
79
|
}
|
|
@@ -77,7 +83,7 @@ export interface FrameHeaderProps extends ComponentProps<'div'> {
|
|
|
77
83
|
* The strip of shell above the panel: a title, an optional description under
|
|
78
84
|
* it, and `Frame.Action` on the trailing side.
|
|
79
85
|
*/
|
|
80
|
-
declare function FrameHeader({ className, ...props }: FrameHeaderProps): import("react").
|
|
86
|
+
declare function FrameHeader({ className, render, ...props }: FrameHeaderProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
81
87
|
declare namespace FrameHeader {
|
|
82
88
|
var displayName: string;
|
|
83
89
|
}
|
|
@@ -93,21 +99,21 @@ declare namespace FrameTitle {
|
|
|
93
99
|
export interface FrameDescriptionProps extends ComponentProps<'p'> {
|
|
94
100
|
}
|
|
95
101
|
/** A line under a title, in the header or in a row. */
|
|
96
|
-
declare function FrameDescription({ className, ...props }: FrameDescriptionProps): import("react").
|
|
102
|
+
declare function FrameDescription({ className, render, ...props }: FrameDescriptionProps & RenderProp<'p'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
97
103
|
declare namespace FrameDescription {
|
|
98
104
|
var displayName: string;
|
|
99
105
|
}
|
|
100
106
|
export interface FrameActionProps extends ComponentProps<'div'> {
|
|
101
107
|
}
|
|
102
108
|
/** The header's trailing side: a short status, a link, a small button. */
|
|
103
|
-
declare function FrameAction({ className, ...props }: FrameActionProps): import("react").
|
|
109
|
+
declare function FrameAction({ className, render, ...props }: FrameActionProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
104
110
|
declare namespace FrameAction {
|
|
105
111
|
var displayName: string;
|
|
106
112
|
}
|
|
107
113
|
export interface FramePanelProps extends ComponentProps<'div'> {
|
|
108
114
|
}
|
|
109
115
|
/** The card the rows sit on. It draws the hairline between its children, except under `band`. */
|
|
110
|
-
declare function FramePanel({ className, ...props }: FramePanelProps): import("react").
|
|
116
|
+
declare function FramePanel({ className, render, ...props }: FramePanelProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
111
117
|
declare namespace FramePanel {
|
|
112
118
|
var displayName: string;
|
|
113
119
|
}
|
|
@@ -127,14 +133,14 @@ export interface FrameRowProps extends Omit<ComponentProps<'div'>, 'onClick'> {
|
|
|
127
133
|
* One line of the panel: `Frame.Media`, `Frame.Content` and `Frame.Actions`
|
|
128
134
|
* side by side. With `href` it is a link and with `onClick` a button.
|
|
129
135
|
*/
|
|
130
|
-
declare function FrameRow({ className, children, chevron, href, target, rel, ...props }: FrameRowProps): import("react").JSX.Element;
|
|
136
|
+
declare function FrameRow({ className, children, chevron, href, target, rel, render, ...props }: FrameRowProps & RenderProp<'div'>): import("react").JSX.Element;
|
|
131
137
|
declare namespace FrameRow {
|
|
132
138
|
var displayName: string;
|
|
133
139
|
}
|
|
134
140
|
export interface FrameMediaProps extends ComponentProps<'div'> {
|
|
135
141
|
}
|
|
136
142
|
/** A row's leading icon, avatar or picture. Holds its size. */
|
|
137
|
-
declare function FrameMedia({ className, ...props }: FrameMediaProps): import("react").
|
|
143
|
+
declare function FrameMedia({ className, render, ...props }: FrameMediaProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
138
144
|
declare namespace FrameMedia {
|
|
139
145
|
var displayName: string;
|
|
140
146
|
}
|
|
@@ -145,14 +151,14 @@ export interface FrameContentProps extends ComponentProps<'div'> {
|
|
|
145
151
|
* what the media and actions leave and may shrink past its content, which is
|
|
146
152
|
* what keeps a long line from pushing the rest of the row off the edge.
|
|
147
153
|
*/
|
|
148
|
-
declare function FrameContent({ className, ...props }: FrameContentProps): import("react").
|
|
154
|
+
declare function FrameContent({ className, render, ...props }: FrameContentProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
149
155
|
declare namespace FrameContent {
|
|
150
156
|
var displayName: string;
|
|
151
157
|
}
|
|
152
158
|
export interface FrameActionsProps extends ComponentProps<'div'> {
|
|
153
159
|
}
|
|
154
160
|
/** A row's trailing side: a badge, a value, a switch, a small button. Holds its size. */
|
|
155
|
-
declare function FrameActions({ className, ...props }: FrameActionsProps): import("react").
|
|
161
|
+
declare function FrameActions({ className, render, ...props }: FrameActionsProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
156
162
|
declare namespace FrameActions {
|
|
157
163
|
var displayName: string;
|
|
158
164
|
}
|
|
@@ -161,7 +167,7 @@ export interface FrameSectionProps extends Omit<ComponentProps<'section'>, 'titl
|
|
|
161
167
|
title?: ReactNode;
|
|
162
168
|
}
|
|
163
169
|
/** A labelled group of rows, for a panel holding more than one. */
|
|
164
|
-
declare function FrameSection({ title, className, children, ...props }: FrameSectionProps): import("react").
|
|
170
|
+
declare function FrameSection({ title, className, children, render, ...props }: FrameSectionProps & RenderProp<'section'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
165
171
|
declare namespace FrameSection {
|
|
166
172
|
var displayName: string;
|
|
167
173
|
}
|
|
@@ -171,7 +177,7 @@ export interface FrameFooterProps extends ComponentProps<'div'> {
|
|
|
171
177
|
* The strip below the panel. Under `inset` its children become equal pills in
|
|
172
178
|
* the recessed band, the shape a row of decisions takes.
|
|
173
179
|
*/
|
|
174
|
-
declare function FrameFooter({ className, ...props }: FrameFooterProps): import("react").
|
|
180
|
+
declare function FrameFooter({ className, render, ...props }: FrameFooterProps & RenderProp<'div'>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
175
181
|
declare namespace FrameFooter {
|
|
176
182
|
var displayName: string;
|
|
177
183
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { tv } from 'tailwind-variants';
|
|
4
|
+
import { mergeProps } from '@base-ui/react/merge-props';
|
|
5
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
3
6
|
/*
|
|
4
7
|
* `inset` geometry. The panel's radius is the shell's less the shell's padding,
|
|
5
8
|
* so the two curves are concentric — a panel radius that ignored the band
|
|
@@ -86,17 +89,25 @@ const frameVariants = tv({
|
|
|
86
89
|
},
|
|
87
90
|
defaultVariants: { variant: 'default' },
|
|
88
91
|
});
|
|
89
|
-
function FrameRoot({ variant = 'default', className, ...props }) {
|
|
92
|
+
function FrameRoot({ variant = 'default', className, render, ...props }) {
|
|
90
93
|
const slots = frameVariants({ variant });
|
|
91
|
-
return
|
|
94
|
+
return useRender({
|
|
95
|
+
defaultTagName: 'div',
|
|
96
|
+
render,
|
|
97
|
+
props: mergeProps({ 'data-slot': 'frame', 'data-variant': variant, className: slots.root({ className }) }, props),
|
|
98
|
+
});
|
|
92
99
|
}
|
|
93
100
|
FrameRoot.displayName = 'Frame';
|
|
94
101
|
/**
|
|
95
102
|
* The strip of shell above the panel: a title, an optional description under
|
|
96
103
|
* it, and `Frame.Action` on the trailing side.
|
|
97
104
|
*/
|
|
98
|
-
function FrameHeader({ className, ...props }) {
|
|
99
|
-
return
|
|
105
|
+
function FrameHeader({ className, render, ...props }) {
|
|
106
|
+
return useRender({
|
|
107
|
+
defaultTagName: 'div',
|
|
108
|
+
render,
|
|
109
|
+
props: mergeProps({ 'data-slot': 'frame-header', className: frameVariants().header({ className }) }, props),
|
|
110
|
+
});
|
|
100
111
|
}
|
|
101
112
|
FrameHeader.displayName = 'Frame.Header';
|
|
102
113
|
/** A caption in the header; the subject line inside `Frame.Content`. */
|
|
@@ -105,18 +116,30 @@ function FrameTitle({ as: Tag = 'h3', className, ...props }) {
|
|
|
105
116
|
}
|
|
106
117
|
FrameTitle.displayName = 'Frame.Title';
|
|
107
118
|
/** A line under a title, in the header or in a row. */
|
|
108
|
-
function FrameDescription({ className, ...props }) {
|
|
109
|
-
return (
|
|
119
|
+
function FrameDescription({ className, render, ...props }) {
|
|
120
|
+
return useRender({
|
|
121
|
+
defaultTagName: 'p',
|
|
122
|
+
render,
|
|
123
|
+
props: mergeProps({ 'data-slot': 'frame-description', className: frameVariants().description({ className }) }, props),
|
|
124
|
+
});
|
|
110
125
|
}
|
|
111
126
|
FrameDescription.displayName = 'Frame.Description';
|
|
112
127
|
/** The header's trailing side: a short status, a link, a small button. */
|
|
113
|
-
function FrameAction({ className, ...props }) {
|
|
114
|
-
return
|
|
128
|
+
function FrameAction({ className, render, ...props }) {
|
|
129
|
+
return useRender({
|
|
130
|
+
defaultTagName: 'div',
|
|
131
|
+
render,
|
|
132
|
+
props: mergeProps({ 'data-slot': 'frame-action', className: frameVariants().action({ className }) }, props),
|
|
133
|
+
});
|
|
115
134
|
}
|
|
116
135
|
FrameAction.displayName = 'Frame.Action';
|
|
117
136
|
/** The card the rows sit on. It draws the hairline between its children, except under `band`. */
|
|
118
|
-
function FramePanel({ className, ...props }) {
|
|
119
|
-
return
|
|
137
|
+
function FramePanel({ className, render, ...props }) {
|
|
138
|
+
return useRender({
|
|
139
|
+
defaultTagName: 'div',
|
|
140
|
+
render,
|
|
141
|
+
props: mergeProps({ 'data-slot': 'frame-panel', className: frameVariants().panel({ className }) }, props),
|
|
142
|
+
});
|
|
120
143
|
}
|
|
121
144
|
FramePanel.displayName = 'Frame.Panel';
|
|
122
145
|
const Chevron = ({ className }) => (_jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": true, className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "m9 6 6 6-6 6" }) }));
|
|
@@ -124,7 +147,7 @@ const Chevron = ({ className }) => (_jsx("svg", { viewBox: "0 0 24 24", "aria-hi
|
|
|
124
147
|
* One line of the panel: `Frame.Media`, `Frame.Content` and `Frame.Actions`
|
|
125
148
|
* side by side. With `href` it is a link and with `onClick` a button.
|
|
126
149
|
*/
|
|
127
|
-
function FrameRow({ className, children, chevron = false, href, target, rel, ...props }) {
|
|
150
|
+
function FrameRow({ className, children, chevron = false, href, target, rel, render, ...props }) {
|
|
128
151
|
const slots = frameVariants();
|
|
129
152
|
const inside = (_jsxs(_Fragment, { children: [children, chevron ? _jsx(Chevron, { className: slots.chevron() }) : null] }));
|
|
130
153
|
if (href !== undefined) {
|
|
@@ -134,12 +157,20 @@ function FrameRow({ className, children, chevron = false, href, target, rel, ...
|
|
|
134
157
|
if (props.onClick !== undefined) {
|
|
135
158
|
return (_jsx("button", { type: "button", "data-slot": "frame-row", className: slots.row({ className: [slots.rowPressable(), className] }), ...props, children: inside }));
|
|
136
159
|
}
|
|
137
|
-
return (
|
|
160
|
+
return useRender({
|
|
161
|
+
defaultTagName: 'div',
|
|
162
|
+
render,
|
|
163
|
+
props: mergeProps({ 'data-slot': 'frame-row', className: slots.row({ className }), children: _jsx(_Fragment, { children: inside }) }, props),
|
|
164
|
+
});
|
|
138
165
|
}
|
|
139
166
|
FrameRow.displayName = 'Frame.Row';
|
|
140
167
|
/** A row's leading icon, avatar or picture. Holds its size. */
|
|
141
|
-
function FrameMedia({ className, ...props }) {
|
|
142
|
-
return
|
|
168
|
+
function FrameMedia({ className, render, ...props }) {
|
|
169
|
+
return useRender({
|
|
170
|
+
defaultTagName: 'div',
|
|
171
|
+
render,
|
|
172
|
+
props: mergeProps({ 'data-slot': 'frame-media', className: frameVariants().media({ className }) }, props),
|
|
173
|
+
});
|
|
143
174
|
}
|
|
144
175
|
FrameMedia.displayName = 'Frame.Media';
|
|
145
176
|
/**
|
|
@@ -147,27 +178,47 @@ FrameMedia.displayName = 'Frame.Media';
|
|
|
147
178
|
* what the media and actions leave and may shrink past its content, which is
|
|
148
179
|
* what keeps a long line from pushing the rest of the row off the edge.
|
|
149
180
|
*/
|
|
150
|
-
function FrameContent({ className, ...props }) {
|
|
151
|
-
return
|
|
181
|
+
function FrameContent({ className, render, ...props }) {
|
|
182
|
+
return useRender({
|
|
183
|
+
defaultTagName: 'div',
|
|
184
|
+
render,
|
|
185
|
+
props: mergeProps({ 'data-slot': 'frame-content', className: frameVariants().content({ className }) }, props),
|
|
186
|
+
});
|
|
152
187
|
}
|
|
153
188
|
FrameContent.displayName = 'Frame.Content';
|
|
154
189
|
/** A row's trailing side: a badge, a value, a switch, a small button. Holds its size. */
|
|
155
|
-
function FrameActions({ className, ...props }) {
|
|
156
|
-
return
|
|
190
|
+
function FrameActions({ className, render, ...props }) {
|
|
191
|
+
return useRender({
|
|
192
|
+
defaultTagName: 'div',
|
|
193
|
+
render,
|
|
194
|
+
props: mergeProps({ 'data-slot': 'frame-actions', className: frameVariants().actions({ className }) }, props),
|
|
195
|
+
});
|
|
157
196
|
}
|
|
158
197
|
FrameActions.displayName = 'Frame.Actions';
|
|
159
198
|
/** A labelled group of rows, for a panel holding more than one. */
|
|
160
|
-
function FrameSection({ title, className, children, ...props }) {
|
|
199
|
+
function FrameSection({ title, className, children, render, ...props }) {
|
|
161
200
|
const slots = frameVariants();
|
|
162
|
-
return (
|
|
201
|
+
return useRender({
|
|
202
|
+
defaultTagName: 'section',
|
|
203
|
+
render,
|
|
204
|
+
props: mergeProps({
|
|
205
|
+
'data-slot': 'frame-section',
|
|
206
|
+
className: slots.section({ className }),
|
|
207
|
+
children: (_jsxs(_Fragment, { children: [title !== undefined ? _jsx("h4", { className: slots.sectionTitle(), children: title }) : null, children] })),
|
|
208
|
+
}, props),
|
|
209
|
+
});
|
|
163
210
|
}
|
|
164
211
|
FrameSection.displayName = 'Frame.Section';
|
|
165
212
|
/**
|
|
166
213
|
* The strip below the panel. Under `inset` its children become equal pills in
|
|
167
214
|
* the recessed band, the shape a row of decisions takes.
|
|
168
215
|
*/
|
|
169
|
-
function FrameFooter({ className, ...props }) {
|
|
170
|
-
return
|
|
216
|
+
function FrameFooter({ className, render, ...props }) {
|
|
217
|
+
return useRender({
|
|
218
|
+
defaultTagName: 'div',
|
|
219
|
+
render,
|
|
220
|
+
props: mergeProps({ 'data-slot': 'frame-footer', className: frameVariants().footer({ className }) }, props),
|
|
221
|
+
});
|
|
171
222
|
}
|
|
172
223
|
FrameFooter.displayName = 'Frame.Footer';
|
|
173
224
|
export const Frame = Object.assign(FrameRoot, {
|