panelui-native 0.97.0 → 0.98.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.
@@ -0,0 +1,472 @@
1
+ /**
2
+ * StackCard — a pile of cards, taken one at a time by throwing the top one off.
3
+ *
4
+ * ```tsx
5
+ * <StackCard className="h-[460px]" onSwipe={(direction, index) => decide(people[index], direction)}>
6
+ * <StackCard.Stamp direction="right" color="success">Yes</StackCard.Stamp>
7
+ * <StackCard.Stamp direction="left" color="destructive">No</StackCard.Stamp>
8
+ * {people.map((person) => (
9
+ * <StackCard.Card key={person.id}>
10
+ * <Text>{person.name}</Text>
11
+ * </StackCard.Card>
12
+ * ))}
13
+ * <StackCard.Empty>
14
+ * <Text muted>Nobody left</Text>
15
+ * </StackCard.Empty>
16
+ * </StackCard>
17
+ * ```
18
+ *
19
+ * For a queue of things each answered with one decision and then gone: a
20
+ * review queue, a set of flashcards, an inbox of suggestions. The gesture is
21
+ * the answer, which is what makes it quicker than a list of rows with buttons
22
+ * on them — and what makes it wrong for anything the reader has to compare,
23
+ * skim or come back to. A deck shows one card and hides the rest.
24
+ *
25
+ * For a run of slides the reader browses rather than disposes of, use
26
+ * [Carousel](../carousel); for one row's actions in a list, [Swipe](../swipe).
27
+ *
28
+ * ## The pile is one drag, read by everything
29
+ *
30
+ * The top card's `x` and `y` are the only values a gesture writes, and every
31
+ * other moving part is derived from them: each stamp fades in on how far the
32
+ * drag has carried the card toward its own direction, and the cards behind
33
+ * climb toward the top position on the furthest of those.
34
+ *
35
+ * That derivation is also what makes a dismissal seamless. By the time the top
36
+ * card has been carried far enough to leave, the second card is already
37
+ * exactly where the top card sits — so when the deck advances there is nothing
38
+ * left for it to move, and no frame in which the pile re-arranges itself.
39
+ *
40
+ * ## The deck moves on the UI thread, and React catches up
41
+ *
42
+ * Which card is on top is held twice: as React state, for what is mounted and
43
+ * for the callbacks, and as a shared value, for what is drawn. A throw is
44
+ * handled entirely on the UI thread — the card leaves on the frame the finger
45
+ * lets go, and once it is off the screen the top card, the offset and the fade
46
+ * all move in one step — and only then is the new index requested from React.
47
+ *
48
+ * Nothing on the screen waits for a render, so a busy JavaScript thread cannot
49
+ * stall a throw or leave a frame where the two halves disagree. What React
50
+ * renders afterwards is kept from showing before the UI thread agrees with it:
51
+ * a stamp is only drawn on the card the UI thread has on top.
52
+ *
53
+ * A controlled deck is still the owner's to decide. An owner that declines the
54
+ * new index gets the card back, flown in from the way it went; one that
55
+ * accepts it sees nothing move at all, because it already has.
56
+ *
57
+ * One card behind the pile's stated depth stays mounted so it can fade in as
58
+ * it takes the last visible place, and one card ahead of the top stays mounted
59
+ * so `undo` has something to fly back in. The rest are unmounted, which is
60
+ * what makes a deck of five hundred cost what a deck of five costs.
61
+ *
62
+ * ## A deck is not reachable by a gesture alone
63
+ *
64
+ * A throw is not available to a screen reader, and neither is a card that can
65
+ * only be answered by throwing it. So the top card publishes an accessibility
66
+ * action for every direction the deck accepts, and `StackCard.Action` renders
67
+ * the same decisions as ordinary buttons — which sighted people reach for too,
68
+ * on the card they are not sure about.
69
+ */
70
+ import { type ReactNode } from 'react';
71
+ import { View, type ViewProps } from 'react-native';
72
+ import { type SharedValue } from 'react-native-reanimated';
73
+ import { type VariantProps } from 'tailwind-variants';
74
+ import { type StackCardDirection } from './stack-card-geometry.js';
75
+ export type { StackCardDirection } from './stack-card-geometry.js';
76
+ /**
77
+ * The deck's state, for a control that lives outside the pile — a counter, a
78
+ * progress bar, a button in a toolbar.
79
+ *
80
+ * `release` is a shared value running 0 to 1 as the top card is carried toward
81
+ * leaving, so something beside the deck can move with the drag rather than
82
+ * starting a second animation next to it.
83
+ */
84
+ export declare function useStackCard(): {
85
+ /** How many cards have been answered, which is also the top card's index. */
86
+ index: number;
87
+ /** How many cards the deck was given. */
88
+ count: number;
89
+ /** How many are left, the top one included. */
90
+ remaining: number;
91
+ /** Whether there is a card to bring back. */
92
+ canUndo: boolean;
93
+ release: SharedValue<number>;
94
+ send: (direction: StackCardDirection) => void;
95
+ undo: () => void;
96
+ reset: () => void;
97
+ };
98
+ /** How the cards behind the top one are arranged. */
99
+ export type StackCardLayout = 'stack' | 'fan' | 'flat';
100
+ export interface StackCardHandle {
101
+ /** Send the top card away as though it had been thrown that way. */
102
+ swipe: (direction: StackCardDirection) => void;
103
+ /** Bring the last card back, and with it the decision that removed it. */
104
+ undo: () => void;
105
+ /** Put every card back. */
106
+ reset: () => void;
107
+ }
108
+ export interface StackCardProps extends Omit<ViewProps, 'children'> {
109
+ /**
110
+ * A `StackCard.Card` for each card, plus any of `StackCard.Stamp`,
111
+ * `StackCard.Empty` and `StackCard.Actions`, in any order. Anything else is
112
+ * laid out under the pile.
113
+ */
114
+ children?: ReactNode;
115
+ /**
116
+ * Which card is on top, when the caller holds it. Leave unset to let the
117
+ * deck keep its own. A controlled deck that declines a request stays where
118
+ * it is and the thrown card comes back, so this is also how a decision is
119
+ * confirmed before it is taken.
120
+ */
121
+ index?: number;
122
+ /** Which card an uncontrolled deck starts on. */
123
+ defaultIndex?: number;
124
+ /** Fires whenever the deck asks to move, with the index it is asking for. */
125
+ onIndexChange?: (index: number) => void;
126
+ /**
127
+ * Fires when a card leaves, with the way it went and the index it was at.
128
+ * It fires before `onIndexChange` asks for the next index. Not called by
129
+ * `undo` — the index going back is what reports that.
130
+ */
131
+ onSwipe?: (direction: StackCardDirection, index: number) => void;
132
+ /** Fires once when the last card leaves. */
133
+ onEmpty?: () => void;
134
+ /**
135
+ * Which ways a card may be thrown. Left and right by default.
136
+ *
137
+ * A direction left out still follows the finger a little and then comes
138
+ * back, rather than refusing to move at all — a card that does not budge
139
+ * reads as a frozen screen.
140
+ */
141
+ directions?: readonly StackCardDirection[];
142
+ /**
143
+ * How the cards behind the top one are arranged. `stack` steps them down and
144
+ * back; `fan` turns them alternately, like a hand of cards; `flat` hides them
145
+ * entirely, for full-bleed cards where a peeking edge is only clutter.
146
+ */
147
+ layout?: StackCardLayout;
148
+ /** How many cards are drawn behind the top one. Two is a pile; five is a mess. */
149
+ depth?: number;
150
+ /**
151
+ * How far a card has to be taken for a release to send it away, as a
152
+ * fraction of the card. Momentum counts toward it, so a flick clears it
153
+ * without travelling.
154
+ */
155
+ threshold?: number;
156
+ /** Stop the deck taking a gesture, without changing how it looks. */
157
+ disabled?: boolean;
158
+ /** A tick when a drag first reaches the point of no return, and a knock as the card goes. */
159
+ haptics?: boolean;
160
+ /**
161
+ * What a screen reader is offered for each direction, in place of "Swipe
162
+ * left". Name the decision — `{ left: 'Skip', right: 'Save' }`.
163
+ */
164
+ directionLabels?: Partial<Record<StackCardDirection, string>>;
165
+ /** Classes for the whole control. Give it a height; the pile fills what is left. */
166
+ className?: string;
167
+ /** Classes for the box the cards are laid out in. */
168
+ pileClassName?: string;
169
+ }
170
+ export interface StackCardCardProps extends ViewProps {
171
+ className?: string;
172
+ children?: ReactNode;
173
+ }
174
+ /**
175
+ * A stamp is a filled block of colour with a word on it, turned a few degrees
176
+ * so it reads as pressed onto the card rather than laid out on it.
177
+ *
178
+ * The fill is the status colour at full strength rather than a tint of it: a
179
+ * stamp exists only for the moment it appears, and a six-per-cent wash of the
180
+ * card's own surface is a smudge rather than an answer. The word is carried in
181
+ * white, which is what the status colours are chosen to take — a status's
182
+ * `-foreground` token is its darker text form, meant for a neutral surface,
183
+ * and over the fill it is the same hue twice.
184
+ *
185
+ * It sits in the corner the card is being pulled away from, which is also the
186
+ * corner the thumb is not over.
187
+ */
188
+ declare const stampVariants: import("tailwind-variants").TVReturnType<{
189
+ color: {
190
+ default: {
191
+ pill: string;
192
+ label: string;
193
+ };
194
+ primary: {
195
+ pill: string;
196
+ label: string;
197
+ };
198
+ success: {
199
+ pill: string;
200
+ label: string;
201
+ };
202
+ warning: {
203
+ pill: string;
204
+ label: string;
205
+ };
206
+ info: {
207
+ pill: string;
208
+ label: string;
209
+ };
210
+ destructive: {
211
+ pill: string;
212
+ label: string;
213
+ };
214
+ };
215
+ direction: {
216
+ left: {
217
+ root: string;
218
+ pill: string;
219
+ };
220
+ right: {
221
+ root: string;
222
+ pill: string;
223
+ };
224
+ up: {
225
+ root: string;
226
+ };
227
+ down: {
228
+ root: string;
229
+ };
230
+ };
231
+ }, {
232
+ root: string;
233
+ pill: string;
234
+ label: string;
235
+ }, undefined, {
236
+ color: {
237
+ default: {
238
+ pill: string;
239
+ label: string;
240
+ };
241
+ primary: {
242
+ pill: string;
243
+ label: string;
244
+ };
245
+ success: {
246
+ pill: string;
247
+ label: string;
248
+ };
249
+ warning: {
250
+ pill: string;
251
+ label: string;
252
+ };
253
+ info: {
254
+ pill: string;
255
+ label: string;
256
+ };
257
+ destructive: {
258
+ pill: string;
259
+ label: string;
260
+ };
261
+ };
262
+ direction: {
263
+ left: {
264
+ root: string;
265
+ pill: string;
266
+ };
267
+ right: {
268
+ root: string;
269
+ pill: string;
270
+ };
271
+ up: {
272
+ root: string;
273
+ };
274
+ down: {
275
+ root: string;
276
+ };
277
+ };
278
+ }, {
279
+ root: string;
280
+ pill: string;
281
+ label: string;
282
+ }, import("tailwind-variants").TVReturnType<{
283
+ color: {
284
+ default: {
285
+ pill: string;
286
+ label: string;
287
+ };
288
+ primary: {
289
+ pill: string;
290
+ label: string;
291
+ };
292
+ success: {
293
+ pill: string;
294
+ label: string;
295
+ };
296
+ warning: {
297
+ pill: string;
298
+ label: string;
299
+ };
300
+ info: {
301
+ pill: string;
302
+ label: string;
303
+ };
304
+ destructive: {
305
+ pill: string;
306
+ label: string;
307
+ };
308
+ };
309
+ direction: {
310
+ left: {
311
+ root: string;
312
+ pill: string;
313
+ };
314
+ right: {
315
+ root: string;
316
+ pill: string;
317
+ };
318
+ up: {
319
+ root: string;
320
+ };
321
+ down: {
322
+ root: string;
323
+ };
324
+ };
325
+ }, {
326
+ root: string;
327
+ pill: string;
328
+ label: string;
329
+ }, undefined, unknown, unknown, undefined>>;
330
+ export type StackCardStampColor = 'default' | 'primary' | 'success' | 'warning' | 'info' | 'destructive';
331
+ export interface StackCardStampProps extends Omit<ViewProps, 'children'>, VariantProps<typeof stampVariants> {
332
+ className?: string;
333
+ /** The word, or anything else to draw on the stamp. */
334
+ children?: ReactNode;
335
+ /** Which direction the stamp answers for. Also where on the card it goes. */
336
+ direction?: StackCardDirection;
337
+ /** Extra classes for the label, when the stamp is given a string. */
338
+ labelClassName?: string;
339
+ }
340
+ export interface StackCardEmptyProps extends ViewProps {
341
+ className?: string;
342
+ children?: ReactNode;
343
+ }
344
+ export interface StackCardActionsProps extends ViewProps {
345
+ className?: string;
346
+ children?: ReactNode;
347
+ }
348
+ declare const actionVariants: import("tailwind-variants").TVReturnType<{
349
+ color: {
350
+ default: {
351
+ root: string;
352
+ };
353
+ primary: {
354
+ root: string;
355
+ };
356
+ success: {
357
+ root: string;
358
+ };
359
+ warning: {
360
+ root: string;
361
+ };
362
+ info: {
363
+ root: string;
364
+ };
365
+ destructive: {
366
+ root: string;
367
+ };
368
+ };
369
+ size: {
370
+ sm: {
371
+ root: string;
372
+ };
373
+ md: {
374
+ root: string;
375
+ };
376
+ lg: {
377
+ root: string;
378
+ };
379
+ };
380
+ }, {
381
+ root: string;
382
+ }, undefined, {
383
+ color: {
384
+ default: {
385
+ root: string;
386
+ };
387
+ primary: {
388
+ root: string;
389
+ };
390
+ success: {
391
+ root: string;
392
+ };
393
+ warning: {
394
+ root: string;
395
+ };
396
+ info: {
397
+ root: string;
398
+ };
399
+ destructive: {
400
+ root: string;
401
+ };
402
+ };
403
+ size: {
404
+ sm: {
405
+ root: string;
406
+ };
407
+ md: {
408
+ root: string;
409
+ };
410
+ lg: {
411
+ root: string;
412
+ };
413
+ };
414
+ }, {
415
+ root: string;
416
+ }, import("tailwind-variants").TVReturnType<{
417
+ color: {
418
+ default: {
419
+ root: string;
420
+ };
421
+ primary: {
422
+ root: string;
423
+ };
424
+ success: {
425
+ root: string;
426
+ };
427
+ warning: {
428
+ root: string;
429
+ };
430
+ info: {
431
+ root: string;
432
+ };
433
+ destructive: {
434
+ root: string;
435
+ };
436
+ };
437
+ size: {
438
+ sm: {
439
+ root: string;
440
+ };
441
+ md: {
442
+ root: string;
443
+ };
444
+ lg: {
445
+ root: string;
446
+ };
447
+ };
448
+ }, {
449
+ root: string;
450
+ }, undefined, unknown, unknown, undefined>>;
451
+ export interface StackCardActionProps extends Omit<ViewProps, 'children'>, VariantProps<typeof actionVariants> {
452
+ className?: string;
453
+ /** What pressing it does: send the top card that way, or bring the last one back. */
454
+ action: StackCardDirection | 'undo';
455
+ /** The glyph. Sized and tinted by the button — pass neither. */
456
+ icon?: ReactNode;
457
+ /**
458
+ * What a screen reader is offered. Falls back to "Undo", or to the plain
459
+ * name of the direction.
460
+ */
461
+ label?: string;
462
+ /** Run after the deck has been told, for a sound or a log. */
463
+ onPress?: () => void;
464
+ }
465
+ export declare const StackCard: import("react").ForwardRefExoticComponent<StackCardProps & import("react").RefAttributes<StackCardHandle>> & {
466
+ Card: import("react").ForwardRefExoticComponent<StackCardCardProps & import("react").RefAttributes<View>>;
467
+ Stamp: import("react").ForwardRefExoticComponent<StackCardStampProps & import("react").RefAttributes<View>>;
468
+ Empty: import("react").ForwardRefExoticComponent<StackCardEmptyProps & import("react").RefAttributes<View>>;
469
+ Actions: import("react").ForwardRefExoticComponent<StackCardActionsProps & import("react").RefAttributes<View>>;
470
+ Action: import("react").ForwardRefExoticComponent<StackCardActionProps & import("react").RefAttributes<View>>;
471
+ };
472
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/stack-card/index.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * The numbers a deck is made of, kept apart from the views that draw them so
3
+ * each rule can be checked on its own.
4
+ *
5
+ * Every function here is a worklet: they run inside the pan handler and the
6
+ * animated styles, on the UI thread, and none of them touches anything but
7
+ * its arguments.
8
+ */
9
+ /** Which way a card leaves the deck. */
10
+ export type StackCardDirection = 'left' | 'right' | 'up' | 'down';
11
+ /**
12
+ * iOS's scroll deceleration, and the constant behind `project`.
13
+ *
14
+ * Momentum is what lets a short fast flick count and a long slow drag not.
15
+ * Without it the only question a release can answer is how far the finger
16
+ * travelled, and a deck read that way feels heavy in the hand.
17
+ */
18
+ export declare const DECELERATION = 0.998;
19
+ /**
20
+ * Where a flick would come to rest if it kept decelerating, in points.
21
+ *
22
+ * The exponential-decay form the platform uses, not the `v² / 2a` from
23
+ * physics: the two disagree most at exactly the speeds a thumb produces.
24
+ */
25
+ export declare function project(velocity: number, deceleration?: number): number;
26
+ /**
27
+ * How far a finger gets on an axis the deck does not accept, given how far it
28
+ * pushed.
29
+ *
30
+ * Asymptotic rather than clamped. A card that stops dead at a limit reads as
31
+ * broken; one that keeps moving a little further for a lot more travel reads
32
+ * as held.
33
+ */
34
+ export declare function resist(travel: number, span: number, give: number): number;
35
+ /** How far a card has to be taken for a release to send it away, in points. */
36
+ export declare function commitReach(span: number, threshold: number): number;
37
+ /**
38
+ * How far a drag has carried a card toward leaving in one direction, 0 to 1.
39
+ *
40
+ * One number, and three things read it: the stamp for that direction fades in
41
+ * on it, the card behind climbs into place on it, and the haptic fires when it
42
+ * first reaches 1.
43
+ */
44
+ export declare function directionProgress(direction: StackCardDirection, x: number, y: number, width: number, height: number, threshold: number): number;
45
+ /** The furthest any accepted direction has been carried, 0 to 1. */
46
+ export declare function releaseProgress(allowed: readonly StackCardDirection[], x: number, y: number, width: number, height: number, threshold: number): number;
47
+ /**
48
+ * Which way a lifted finger sent the card, or `null` to put it back.
49
+ *
50
+ * Distance and momentum are added before the comparison rather than tested one
51
+ * after the other, so there is a single rule: a card leaves when the finger
52
+ * was going to take it past the reach, whether it got there or not.
53
+ *
54
+ * Where two directions both qualify — a diagonal fling in a deck that takes
55
+ * all four — the one carried furthest wins, so the card goes where it was
56
+ * actually thrown.
57
+ */
58
+ export declare function releasedDirection(allowed: readonly StackCardDirection[], x: number, y: number, velocityX: number, velocityY: number, width: number, height: number, threshold: number): StackCardDirection | null;
59
+ /**
60
+ * Where a card is animated to on its way off.
61
+ *
62
+ * The off-axis is carried rather than zeroed, so a card thrown up and to the
63
+ * right leaves up and to the right. Zeroing it straightens the throw out
64
+ * mid-flight, which is the one moment the animation is most obviously not the
65
+ * finger any more.
66
+ */
67
+ export declare function exitTarget(direction: StackCardDirection, width: number, height: number, x: number, y: number): {
68
+ x: number;
69
+ y: number;
70
+ };
71
+ /**
72
+ * How long a card takes to leave, in milliseconds.
73
+ *
74
+ * Long enough that the card starts out at the speed the finger let go of it.
75
+ * An ease-out starts `slope` times faster than its average, so covering
76
+ * `distance` from `speed` takes `slope × distance / speed`. Faster than that
77
+ * and the card leaps ahead of the finger; slower, and it drags as though it
78
+ * had caught on something.
79
+ *
80
+ * Clamped both ways. A hard flick would otherwise be gone in a frame or two,
81
+ * which reads as the card vanishing rather than being thrown; and a card
82
+ * released barely moving would drift off for a second. `speed` is only what
83
+ * was travelling toward the way out — none at all, for a card sent by a
84
+ * button, gives the longest.
85
+ */
86
+ export declare function exitDuration(distance: number, speed: number, slope: number, shortest: number, longest: number): number;
87
+ /**
88
+ * Which way the card pivots, from where it was taken hold of.
89
+ *
90
+ * A card pulled by its top corner turns one way and one pulled by its bottom
91
+ * corner turns the other, because that is what a piece of card on a table
92
+ * does. Read once when the finger lands and held for the whole gesture: a
93
+ * lever that changed sign mid-drag would flip the card over in the hand.
94
+ */
95
+ export declare function lever(grabY: number, height: number): number;
96
+ /**
97
+ * The card's tilt, in degrees.
98
+ *
99
+ * Measured against half the card rather than all of it: a card commits at
100
+ * roughly a third of its width, and scaled across the full width the tilt at
101
+ * the moment of release would be a couple of degrees — present in the numbers
102
+ * and invisible on the screen.
103
+ */
104
+ export declare function tiltAngle(x: number, width: number, maxTilt: number, pivot: number): number;
105
+ /**
106
+ * Where a card sits in the pile, counting the top one as 0, once the drag on
107
+ * the card in front of it is taken into account.
108
+ *
109
+ * This is what makes the pile continuous across a dismissal. By the time the
110
+ * top card has been carried far enough to leave, the one behind it has already
111
+ * arrived at the top position — so when it becomes the top card there is
112
+ * nothing left to move.
113
+ */
114
+ export declare function effectiveDepth(depth: number, release: number): number;
115
+ /**
116
+ * How opaque a card at a given depth is drawn, where `visible` is how many the
117
+ * pile shows behind its top card.
118
+ *
119
+ * One more card is kept than the pile shows, and this is what fades it in: one
120
+ * place further back than the pile goes it is invisible, and it reaches full
121
+ * strength exactly as it takes the last visible place. Without it a card
122
+ * appears out of nothing at the bottom of the pile every time one leaves the
123
+ * top.
124
+ */
125
+ export declare function depthOpacity(depth: number, visible: number): number;
126
+ //# sourceMappingURL=stack-card-geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-card-geometry.d.ts","sourceRoot":"","sources":["../../../../../src/components/stack-card/stack-card-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wCAAwC;AACxC,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,QAAQ,CAAC;AAElC;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAcvE;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,kBAAkB,EAC7B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAOR;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAUR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,kBAAkB,GAAG,IAAI,CAgC3B;AAQD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,kBAAkB,EAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAY1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,CAKR;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnE"}
@@ -126,6 +126,7 @@ export { Sortable, reorderItems, useSortableItem, type SortableProps, type Sorta
126
126
  export { Spinner, type SpinnerProps } from './components/spinner/index.js';
127
127
  export { Splitter, type SplitterProps, type SplitterPanelProps, type SplitterHandleProps, type SplitterOrientation, type SplitterConstraint, } from './components/splitter/index.js';
128
128
  export { SplitView, useSplitView, type SplitViewProps, type SplitViewPaneProps, type SplitViewDragAreaProps, type SplitViewHandleProps, type SplitViewVariant, } from './components/split-view/index.js';
129
+ export { StackCard, useStackCard, type StackCardProps, type StackCardHandle, type StackCardCardProps, type StackCardStampProps, type StackCardEmptyProps, type StackCardActionsProps, type StackCardActionProps, type StackCardDirection, type StackCardLayout, type StackCardStampColor, } from './components/stack-card/index.js';
129
130
  export { Steps, type StepsProps, type StepsItemProps, type StepsTriggerProps, type StepsIndicatorProps, type StepsSeparatorProps, type StepState, type StepsOrientation, } from './components/steps/index.js';
130
131
  export { Surface, type SurfaceProps } from './components/surface/index.js';
131
132
  export { Swipe, useSwipeGroup, type SwipeProps, type SwipeGroupProps, type SwipePanelProps, type SwipeActionProps, type SwipeActionColor, type SwipeOpenSide, type SwipeHandle, } from './components/swipe/index.js';