@brycks/core-front 0.12.0 → 0.12.1
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/data.d.ts +387 -2
- package/dist/components/feedback.d.ts +317 -2
- package/dist/components/form.d.ts +889 -2
- package/dist/components/layout.d.ts +587 -2
- package/dist/components/media/Video/Video.cjs +1 -1
- package/dist/components/media/Video/Video.cjs.map +1 -1
- package/dist/components/media/Video/Video.js +54 -54
- package/dist/components/media/Video/Video.js.map +1 -1
- package/dist/components/navigation.d.ts +436 -2
- package/dist/components/utility.d.ts +278 -2
- package/dist/styles.css +1 -1
- package/package.json +22 -21
- package/dist/data.d.ts +0 -387
- package/dist/feedback.d.ts +0 -317
- package/dist/form.d.ts +0 -889
- package/dist/layout.d.ts +0 -587
- package/dist/navigation.d.ts +0 -436
- package/dist/utility.d.ts +0 -278
|
@@ -1,2 +1,587 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { ComponentPropsWithRef } from 'react';
|
|
3
|
+
import { CSSProperties } from 'react';
|
|
4
|
+
import { default as default_2 } from 'react';
|
|
5
|
+
import { ElementType } from 'react';
|
|
6
|
+
import { ForwardRefExoticComponent } from 'react';
|
|
7
|
+
import { HTMLAttributes } from 'react';
|
|
8
|
+
import { ReactNode } from 'react';
|
|
9
|
+
import { RefAttributes } from 'react';
|
|
10
|
+
|
|
11
|
+
export declare const Article: ForwardRefExoticComponent<SemanticProps & RefAttributes<HTMLElement>>;
|
|
12
|
+
|
|
13
|
+
export declare type ArticleProps = SemanticProps;
|
|
14
|
+
|
|
15
|
+
export declare const Aside: ForwardRefExoticComponent<AsideProps & RefAttributes<HTMLElement>>;
|
|
16
|
+
|
|
17
|
+
export declare interface AsideProps extends SemanticProps {
|
|
18
|
+
'aria-label'?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export declare const AspectRatio: ForwardRefExoticComponent<AspectRatioProps & RefAttributes<HTMLDivElement>>;
|
|
22
|
+
|
|
23
|
+
/** Common aspect ratio presets */
|
|
24
|
+
export declare type AspectRatioPreset = '1:1' | '4:3' | '3:2' | '16:9' | '21:9' | '2:3' | '3:4' | '9:16';
|
|
25
|
+
|
|
26
|
+
export declare interface AspectRatioProps extends HTMLAttributes<HTMLDivElement> {
|
|
27
|
+
/**
|
|
28
|
+
* Aspect ratio as a preset string or custom number.
|
|
29
|
+
* Number represents width/height (e.g., 16/9 = 1.777...)
|
|
30
|
+
* @default '16:9'
|
|
31
|
+
*/
|
|
32
|
+
ratio?: AspectRatioPreset | number;
|
|
33
|
+
/** Content to render inside the ratio container */
|
|
34
|
+
children?: ReactNode;
|
|
35
|
+
/** Custom class name */
|
|
36
|
+
className?: string;
|
|
37
|
+
/** Test ID */
|
|
38
|
+
testId?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export declare const Box: BoxComponent;
|
|
42
|
+
|
|
43
|
+
declare interface BoxComponent {
|
|
44
|
+
<E extends ElementType = 'div'>(props: BoxProps<E> & {
|
|
45
|
+
ref?: ComponentPropsWithRef<E>['ref'];
|
|
46
|
+
}): default_2.JSX.Element | null;
|
|
47
|
+
displayName?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export declare interface BoxOwnProps extends SpacingProps {
|
|
51
|
+
/** The element type to render */
|
|
52
|
+
as?: ElementType;
|
|
53
|
+
/** Custom class name */
|
|
54
|
+
className?: string;
|
|
55
|
+
/** Custom inline styles */
|
|
56
|
+
style?: CSSProperties;
|
|
57
|
+
/** Display property */
|
|
58
|
+
display?: CSSProperties['display'];
|
|
59
|
+
/** Position property */
|
|
60
|
+
position?: CSSProperties['position'];
|
|
61
|
+
/** Width */
|
|
62
|
+
width?: CSSProperties['width'];
|
|
63
|
+
/** Height */
|
|
64
|
+
height?: CSSProperties['height'];
|
|
65
|
+
/** Min width */
|
|
66
|
+
minWidth?: CSSProperties['minWidth'];
|
|
67
|
+
/** Max width */
|
|
68
|
+
maxWidth?: CSSProperties['maxWidth'];
|
|
69
|
+
/** Min height */
|
|
70
|
+
minHeight?: CSSProperties['minHeight'];
|
|
71
|
+
/** Max height */
|
|
72
|
+
maxHeight?: CSSProperties['maxHeight'];
|
|
73
|
+
/** Overflow */
|
|
74
|
+
overflow?: CSSProperties['overflow'];
|
|
75
|
+
/** Background color (CSS variable or direct value) */
|
|
76
|
+
bg?: string;
|
|
77
|
+
/** Border radius */
|
|
78
|
+
radius?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';
|
|
79
|
+
/** Box shadow */
|
|
80
|
+
shadow?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
81
|
+
/** Test ID */
|
|
82
|
+
testId?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export declare type BoxProps<E extends ElementType = 'div'> = BoxOwnProps & Omit<ComponentPropsWithoutRef<E>, keyof BoxOwnProps>;
|
|
86
|
+
|
|
87
|
+
export declare const Card: ForwardRefExoticComponent<CardProps & RefAttributes<HTMLDivElement>>;
|
|
88
|
+
|
|
89
|
+
export declare const CardBody: ForwardRefExoticComponent<CardBodyProps & RefAttributes<HTMLDivElement>>;
|
|
90
|
+
|
|
91
|
+
export declare interface CardBodyProps extends HTMLAttributes<HTMLDivElement> {
|
|
92
|
+
/** Custom class name */
|
|
93
|
+
className?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export declare const CardFooter: ForwardRefExoticComponent<CardFooterProps & RefAttributes<HTMLDivElement>>;
|
|
97
|
+
|
|
98
|
+
export declare interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
|
|
99
|
+
/** Whether to show a divider above the footer */
|
|
100
|
+
divider?: boolean;
|
|
101
|
+
/** Footer alignment */
|
|
102
|
+
align?: 'left' | 'center' | 'right' | 'between';
|
|
103
|
+
/** Custom class name */
|
|
104
|
+
className?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export declare const CardHeader: ForwardRefExoticComponent<CardHeaderProps & RefAttributes<HTMLDivElement>>;
|
|
108
|
+
|
|
109
|
+
export declare interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {
|
|
110
|
+
/** Whether to show a divider below the header */
|
|
111
|
+
divider?: boolean;
|
|
112
|
+
/** Custom class name */
|
|
113
|
+
className?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export declare type CardPadding = 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
117
|
+
|
|
118
|
+
export declare interface CardProps extends HTMLAttributes<HTMLDivElement> {
|
|
119
|
+
/** Card variant */
|
|
120
|
+
variant?: CardVariant;
|
|
121
|
+
/** Card padding */
|
|
122
|
+
padding?: CardPadding;
|
|
123
|
+
/** Whether the card is interactive (adds hover effect) */
|
|
124
|
+
interactive?: boolean;
|
|
125
|
+
/** Whether the card is selected */
|
|
126
|
+
selected?: boolean;
|
|
127
|
+
/** Custom class name */
|
|
128
|
+
className?: string;
|
|
129
|
+
/** Test ID */
|
|
130
|
+
testId?: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export declare type CardVariant = 'elevated' | 'outline' | 'filled' | 'ghost';
|
|
134
|
+
|
|
135
|
+
export declare const Collapse: ForwardRefExoticComponent<CollapseProps & RefAttributes<HTMLDivElement>>;
|
|
136
|
+
|
|
137
|
+
export declare interface CollapseProps {
|
|
138
|
+
/** Whether the content is expanded (controlled) */
|
|
139
|
+
isOpen?: boolean;
|
|
140
|
+
/** Default expanded state (uncontrolled) */
|
|
141
|
+
defaultIsOpen?: boolean;
|
|
142
|
+
/** Content to show when collapsed */
|
|
143
|
+
children: ReactNode;
|
|
144
|
+
/** Animation duration in milliseconds */
|
|
145
|
+
duration?: number;
|
|
146
|
+
/** Easing function */
|
|
147
|
+
easing?: string;
|
|
148
|
+
/** Whether to animate on initial render */
|
|
149
|
+
animateOnMount?: boolean;
|
|
150
|
+
/** Whether to unmount content when collapsed */
|
|
151
|
+
unmountOnCollapse?: boolean;
|
|
152
|
+
/** Custom class name */
|
|
153
|
+
className?: string;
|
|
154
|
+
/** Test ID */
|
|
155
|
+
testId?: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export declare const Collapsible: ForwardRefExoticComponent<CollapsibleProps & RefAttributes<HTMLDivElement>>;
|
|
159
|
+
|
|
160
|
+
export declare interface CollapsibleProps {
|
|
161
|
+
/** Header content (always visible) */
|
|
162
|
+
header: ReactNode;
|
|
163
|
+
/** Collapsible content */
|
|
164
|
+
children: ReactNode;
|
|
165
|
+
/** Whether expanded (controlled) */
|
|
166
|
+
isOpen?: boolean;
|
|
167
|
+
/** Default expanded state (uncontrolled) */
|
|
168
|
+
defaultIsOpen?: boolean;
|
|
169
|
+
/** Callback when expanded state changes */
|
|
170
|
+
onToggle?: (isOpen: boolean) => void;
|
|
171
|
+
/** Whether the collapsible is disabled */
|
|
172
|
+
disabled?: boolean;
|
|
173
|
+
/** Custom class name */
|
|
174
|
+
className?: string;
|
|
175
|
+
/** Test ID */
|
|
176
|
+
testId?: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export declare const Container: ContainerComponent;
|
|
180
|
+
|
|
181
|
+
declare interface ContainerComponent {
|
|
182
|
+
<E extends ElementType = 'div'>(props: ContainerProps<E> & {
|
|
183
|
+
ref?: ComponentPropsWithRef<E>['ref'];
|
|
184
|
+
}): default_2.JSX.Element | null;
|
|
185
|
+
displayName?: string;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export declare interface ContainerOwnProps extends SpacingProps {
|
|
189
|
+
/** The element type to render */
|
|
190
|
+
as?: ElementType;
|
|
191
|
+
/** Custom class name */
|
|
192
|
+
className?: string;
|
|
193
|
+
/** Custom inline styles */
|
|
194
|
+
style?: CSSProperties;
|
|
195
|
+
/** Container size / max-width */
|
|
196
|
+
size?: keyof typeof containers;
|
|
197
|
+
/** Whether to center the container */
|
|
198
|
+
centered?: boolean;
|
|
199
|
+
/** Whether to add default horizontal padding */
|
|
200
|
+
padded?: boolean;
|
|
201
|
+
/** Children */
|
|
202
|
+
children?: ReactNode;
|
|
203
|
+
/** Test ID */
|
|
204
|
+
testId?: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export declare type ContainerProps<E extends ElementType = 'div'> = ContainerOwnProps & Omit<ComponentPropsWithoutRef<E>, keyof ContainerOwnProps>;
|
|
208
|
+
|
|
209
|
+
/** Container max-widths aligned with breakpoints */
|
|
210
|
+
declare const containers: {
|
|
211
|
+
readonly xs: 320;
|
|
212
|
+
readonly sm: 480;
|
|
213
|
+
readonly md: 640;
|
|
214
|
+
readonly lg: 768;
|
|
215
|
+
readonly xl: 1024;
|
|
216
|
+
readonly '2xl': 1280;
|
|
217
|
+
readonly '3xl': 1440;
|
|
218
|
+
readonly full: "100%";
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export declare const Flex: ForwardRefExoticComponent<FlexProps & RefAttributes<HTMLDivElement>>;
|
|
222
|
+
|
|
223
|
+
declare type FlexAlign = 'start' | 'end' | 'center' | 'baseline' | 'stretch';
|
|
224
|
+
|
|
225
|
+
declare type FlexDirection = 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
226
|
+
|
|
227
|
+
export declare const FlexItem: ForwardRefExoticComponent<FlexItemProps & RefAttributes<HTMLDivElement>>;
|
|
228
|
+
|
|
229
|
+
export declare interface FlexItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
230
|
+
/** Flex grow */
|
|
231
|
+
grow?: number;
|
|
232
|
+
/** Flex shrink */
|
|
233
|
+
shrink?: number;
|
|
234
|
+
/** Flex basis */
|
|
235
|
+
basis?: string | number;
|
|
236
|
+
/** Align self */
|
|
237
|
+
alignSelf?: FlexAlign;
|
|
238
|
+
/** Order */
|
|
239
|
+
order?: number;
|
|
240
|
+
/** Children */
|
|
241
|
+
children?: ReactNode;
|
|
242
|
+
/** Custom class name */
|
|
243
|
+
className?: string;
|
|
244
|
+
/** Custom styles */
|
|
245
|
+
style?: CSSProperties;
|
|
246
|
+
/** Test ID */
|
|
247
|
+
testId?: string;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
declare type FlexJustify = 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly';
|
|
251
|
+
|
|
252
|
+
export declare interface FlexProps extends HTMLAttributes<HTMLDivElement> {
|
|
253
|
+
/** Flex direction */
|
|
254
|
+
direction?: FlexDirection;
|
|
255
|
+
/** Flex wrap */
|
|
256
|
+
wrap?: FlexWrap;
|
|
257
|
+
/** Justify content */
|
|
258
|
+
justify?: FlexJustify;
|
|
259
|
+
/** Align items */
|
|
260
|
+
align?: FlexAlign;
|
|
261
|
+
/** Gap between items */
|
|
262
|
+
gap?: SpacingKey_3;
|
|
263
|
+
/** Row gap */
|
|
264
|
+
rowGap?: SpacingKey_3;
|
|
265
|
+
/** Column gap */
|
|
266
|
+
columnGap?: SpacingKey_3;
|
|
267
|
+
/** Whether to display inline */
|
|
268
|
+
inline?: boolean;
|
|
269
|
+
/** Flex grow */
|
|
270
|
+
grow?: number;
|
|
271
|
+
/** Flex shrink */
|
|
272
|
+
shrink?: number;
|
|
273
|
+
/** Flex basis */
|
|
274
|
+
basis?: string | number;
|
|
275
|
+
/** Children */
|
|
276
|
+
children?: ReactNode;
|
|
277
|
+
/** Custom class name */
|
|
278
|
+
className?: string;
|
|
279
|
+
/** Custom styles */
|
|
280
|
+
style?: CSSProperties;
|
|
281
|
+
/** Test ID */
|
|
282
|
+
testId?: string;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
declare type FlexWrap = 'nowrap' | 'wrap' | 'wrap-reverse';
|
|
286
|
+
|
|
287
|
+
export declare const Footer: ForwardRefExoticComponent<FooterProps & RefAttributes<HTMLElement>>;
|
|
288
|
+
|
|
289
|
+
export declare interface FooterProps extends SemanticProps {
|
|
290
|
+
role?: 'contentinfo' | 'none';
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export declare const Grid: GridComponent;
|
|
294
|
+
|
|
295
|
+
declare interface GridComponent {
|
|
296
|
+
<E extends ElementType = 'div'>(props: GridProps<E> & {
|
|
297
|
+
ref?: ComponentPropsWithRef<E>['ref'];
|
|
298
|
+
}): default_2.JSX.Element | null;
|
|
299
|
+
displayName?: string;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export declare const GridItem: GridItemComponent;
|
|
303
|
+
|
|
304
|
+
declare interface GridItemComponent {
|
|
305
|
+
<E extends ElementType = 'div'>(props: GridItemProps<E> & {
|
|
306
|
+
ref?: ComponentPropsWithRef<E>['ref'];
|
|
307
|
+
}): default_2.JSX.Element | null;
|
|
308
|
+
displayName?: string;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** Grid Item Component */
|
|
312
|
+
export declare interface GridItemOwnProps {
|
|
313
|
+
/** Column span */
|
|
314
|
+
colSpan?: number | 'full';
|
|
315
|
+
/** Row span */
|
|
316
|
+
rowSpan?: number;
|
|
317
|
+
/** Column start */
|
|
318
|
+
colStart?: number;
|
|
319
|
+
/** Column end */
|
|
320
|
+
colEnd?: number;
|
|
321
|
+
/** Row start */
|
|
322
|
+
rowStart?: number;
|
|
323
|
+
/** Row end */
|
|
324
|
+
rowEnd?: number;
|
|
325
|
+
/** Custom class name */
|
|
326
|
+
className?: string;
|
|
327
|
+
/** Custom inline styles */
|
|
328
|
+
style?: CSSProperties;
|
|
329
|
+
/** Children */
|
|
330
|
+
children?: ReactNode;
|
|
331
|
+
/** Test ID */
|
|
332
|
+
testId?: string;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export declare type GridItemProps<E extends ElementType = 'div'> = GridItemOwnProps & Omit<ComponentPropsWithoutRef<E>, keyof GridItemOwnProps> & {
|
|
336
|
+
as?: E;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
export declare interface GridOwnProps extends SpacingProps {
|
|
340
|
+
/** The element type to render */
|
|
341
|
+
as?: ElementType;
|
|
342
|
+
/** Custom class name */
|
|
343
|
+
className?: string;
|
|
344
|
+
/** Custom inline styles */
|
|
345
|
+
style?: CSSProperties;
|
|
346
|
+
/** Number of columns */
|
|
347
|
+
columns?: number | string;
|
|
348
|
+
/** Number of rows */
|
|
349
|
+
rows?: number | string;
|
|
350
|
+
/** Gap between items */
|
|
351
|
+
gap?: SpacingKey;
|
|
352
|
+
/** Column gap */
|
|
353
|
+
gapX?: SpacingKey;
|
|
354
|
+
/** Row gap */
|
|
355
|
+
gapY?: SpacingKey;
|
|
356
|
+
/** Align items */
|
|
357
|
+
align?: CSSProperties['alignItems'];
|
|
358
|
+
/** Justify items */
|
|
359
|
+
justify?: CSSProperties['justifyItems'];
|
|
360
|
+
/** Template columns (CSS value) */
|
|
361
|
+
templateColumns?: string;
|
|
362
|
+
/** Template rows (CSS value) */
|
|
363
|
+
templateRows?: string;
|
|
364
|
+
/** Auto flow */
|
|
365
|
+
flow?: CSSProperties['gridAutoFlow'];
|
|
366
|
+
/** Whether to render as inline-grid */
|
|
367
|
+
inline?: boolean;
|
|
368
|
+
/** Children */
|
|
369
|
+
children?: ReactNode;
|
|
370
|
+
/** Test ID */
|
|
371
|
+
testId?: string;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export declare type GridProps<E extends ElementType = 'div'> = GridOwnProps & Omit<ComponentPropsWithoutRef<E>, keyof GridOwnProps>;
|
|
375
|
+
|
|
376
|
+
export declare const Header: ForwardRefExoticComponent<HeaderProps & RefAttributes<HTMLElement>>;
|
|
377
|
+
|
|
378
|
+
export declare interface HeaderProps extends SemanticProps {
|
|
379
|
+
role?: 'banner' | 'none';
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export declare const HStack: StackComponent;
|
|
383
|
+
|
|
384
|
+
export declare const Main: ForwardRefExoticComponent<MainProps & RefAttributes<HTMLElement>>;
|
|
385
|
+
|
|
386
|
+
export declare interface MainProps extends SemanticProps {
|
|
387
|
+
id?: string;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export declare const Nav: ForwardRefExoticComponent<NavProps & RefAttributes<HTMLElement>>;
|
|
391
|
+
|
|
392
|
+
export declare interface NavProps extends SemanticProps {
|
|
393
|
+
'aria-label'?: string;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export declare const Section: ForwardRefExoticComponent<SectionProps & RefAttributes<HTMLElement>>;
|
|
397
|
+
|
|
398
|
+
export declare interface SectionProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
399
|
+
/** Section title */
|
|
400
|
+
title?: ReactNode;
|
|
401
|
+
/** Section description */
|
|
402
|
+
description?: ReactNode;
|
|
403
|
+
/** Title level for accessibility */
|
|
404
|
+
titleLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
405
|
+
/** Spacing between sections */
|
|
406
|
+
spacing?: SectionSpacing;
|
|
407
|
+
/** Whether to show a divider above the section */
|
|
408
|
+
divider?: boolean;
|
|
409
|
+
/** Actions to display in the header (right side) */
|
|
410
|
+
actions?: ReactNode;
|
|
411
|
+
/** Custom class name */
|
|
412
|
+
className?: string;
|
|
413
|
+
/** Test ID */
|
|
414
|
+
testId?: string;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export declare type SectionSpacing = 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
418
|
+
|
|
419
|
+
declare interface SemanticProps extends HTMLAttributes<HTMLElement> {
|
|
420
|
+
children?: ReactNode;
|
|
421
|
+
className?: string;
|
|
422
|
+
style?: CSSProperties;
|
|
423
|
+
testId?: string;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
export declare const Spacer: ForwardRefExoticComponent<SpacerProps & RefAttributes<HTMLDivElement>>;
|
|
427
|
+
|
|
428
|
+
export declare interface SpacerProps extends HTMLAttributes<HTMLDivElement> {
|
|
429
|
+
/** Fixed size in spacing tokens */
|
|
430
|
+
size?: SpacingKey_2;
|
|
431
|
+
/** Custom size in pixels */
|
|
432
|
+
customSize?: number;
|
|
433
|
+
/** Whether to expand to fill available space (flex: 1) */
|
|
434
|
+
flex?: boolean;
|
|
435
|
+
/** Direction of the spacer */
|
|
436
|
+
direction?: 'horizontal' | 'vertical';
|
|
437
|
+
/** Custom class name */
|
|
438
|
+
className?: string;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
declare type Spacing = typeof spacing;
|
|
442
|
+
|
|
443
|
+
/** Spacing scale - values in pixels */
|
|
444
|
+
declare const spacing: {
|
|
445
|
+
/** 0px */
|
|
446
|
+
readonly 0: 0;
|
|
447
|
+
/** 1px - hairline */
|
|
448
|
+
readonly px: 1;
|
|
449
|
+
/** 2px - micro */
|
|
450
|
+
readonly 0.5: number;
|
|
451
|
+
/** 4px - tiny */
|
|
452
|
+
readonly 1: 4;
|
|
453
|
+
/** 6px */
|
|
454
|
+
readonly 1.5: number;
|
|
455
|
+
/** 8px - extra small */
|
|
456
|
+
readonly 2: number;
|
|
457
|
+
/** 10px */
|
|
458
|
+
readonly 2.5: number;
|
|
459
|
+
/** 12px - small */
|
|
460
|
+
readonly 3: number;
|
|
461
|
+
/** 14px */
|
|
462
|
+
readonly 3.5: number;
|
|
463
|
+
/** 16px - medium (base) */
|
|
464
|
+
readonly 4: number;
|
|
465
|
+
/** 20px */
|
|
466
|
+
readonly 5: number;
|
|
467
|
+
/** 24px - large */
|
|
468
|
+
readonly 6: number;
|
|
469
|
+
/** 28px */
|
|
470
|
+
readonly 7: number;
|
|
471
|
+
/** 32px - extra large */
|
|
472
|
+
readonly 8: number;
|
|
473
|
+
/** 36px */
|
|
474
|
+
readonly 9: number;
|
|
475
|
+
/** 40px */
|
|
476
|
+
readonly 10: number;
|
|
477
|
+
/** 44px */
|
|
478
|
+
readonly 11: number;
|
|
479
|
+
/** 48px - 2x large */
|
|
480
|
+
readonly 12: number;
|
|
481
|
+
/** 56px */
|
|
482
|
+
readonly 14: number;
|
|
483
|
+
/** 64px - 3x large */
|
|
484
|
+
readonly 16: number;
|
|
485
|
+
/** 80px */
|
|
486
|
+
readonly 20: number;
|
|
487
|
+
/** 96px - 4x large */
|
|
488
|
+
readonly 24: number;
|
|
489
|
+
/** 112px */
|
|
490
|
+
readonly 28: number;
|
|
491
|
+
/** 128px */
|
|
492
|
+
readonly 32: number;
|
|
493
|
+
/** 160px */
|
|
494
|
+
readonly 40: number;
|
|
495
|
+
/** 192px */
|
|
496
|
+
readonly 48: number;
|
|
497
|
+
/** 224px */
|
|
498
|
+
readonly 56: number;
|
|
499
|
+
/** 256px */
|
|
500
|
+
readonly 64: number;
|
|
501
|
+
/** 320px */
|
|
502
|
+
readonly 80: number;
|
|
503
|
+
/** 384px */
|
|
504
|
+
readonly 96: number;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
declare type SpacingKey = keyof Spacing;
|
|
508
|
+
|
|
509
|
+
declare type SpacingKey_2 = keyof typeof spacing;
|
|
510
|
+
|
|
511
|
+
declare type SpacingKey_3 = keyof typeof spacing;
|
|
512
|
+
|
|
513
|
+
/** Spacing props for components */
|
|
514
|
+
declare interface SpacingProps {
|
|
515
|
+
/** Margin all sides */
|
|
516
|
+
m?: SpacingKey;
|
|
517
|
+
/** Margin horizontal (left + right) */
|
|
518
|
+
mx?: SpacingKey;
|
|
519
|
+
/** Margin vertical (top + bottom) */
|
|
520
|
+
my?: SpacingKey;
|
|
521
|
+
/** Margin top */
|
|
522
|
+
mt?: SpacingKey;
|
|
523
|
+
/** Margin right */
|
|
524
|
+
mr?: SpacingKey;
|
|
525
|
+
/** Margin bottom */
|
|
526
|
+
mb?: SpacingKey;
|
|
527
|
+
/** Margin left */
|
|
528
|
+
ml?: SpacingKey;
|
|
529
|
+
/** Padding all sides */
|
|
530
|
+
p?: SpacingKey;
|
|
531
|
+
/** Padding horizontal (left + right) */
|
|
532
|
+
px?: SpacingKey;
|
|
533
|
+
/** Padding vertical (top + bottom) */
|
|
534
|
+
py?: SpacingKey;
|
|
535
|
+
/** Padding top */
|
|
536
|
+
pt?: SpacingKey;
|
|
537
|
+
/** Padding right */
|
|
538
|
+
pr?: SpacingKey;
|
|
539
|
+
/** Padding bottom */
|
|
540
|
+
pb?: SpacingKey;
|
|
541
|
+
/** Padding left */
|
|
542
|
+
pl?: SpacingKey;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export declare const Stack: StackComponent;
|
|
546
|
+
|
|
547
|
+
declare interface StackComponent {
|
|
548
|
+
<E extends ElementType = 'div'>(props: StackProps<E> & {
|
|
549
|
+
ref?: ComponentPropsWithRef<E>['ref'];
|
|
550
|
+
}): default_2.JSX.Element | null;
|
|
551
|
+
displayName?: string;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export declare interface StackOwnProps extends SpacingProps {
|
|
555
|
+
/** The element type to render */
|
|
556
|
+
as?: ElementType;
|
|
557
|
+
/** Custom class name */
|
|
558
|
+
className?: string;
|
|
559
|
+
/** Custom inline styles */
|
|
560
|
+
style?: CSSProperties;
|
|
561
|
+
/** Stack direction */
|
|
562
|
+
direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
563
|
+
/** Gap between items */
|
|
564
|
+
gap?: SpacingKey;
|
|
565
|
+
/** Horizontal gap (for row direction) */
|
|
566
|
+
gapX?: SpacingKey;
|
|
567
|
+
/** Vertical gap (for column direction) */
|
|
568
|
+
gapY?: SpacingKey;
|
|
569
|
+
/** Align items */
|
|
570
|
+
align?: CSSProperties['alignItems'];
|
|
571
|
+
/** Justify content */
|
|
572
|
+
justify?: CSSProperties['justifyContent'];
|
|
573
|
+
/** Flex wrap */
|
|
574
|
+
wrap?: CSSProperties['flexWrap'];
|
|
575
|
+
/** Whether to render as inline-flex */
|
|
576
|
+
inline?: boolean;
|
|
577
|
+
/** Children */
|
|
578
|
+
children?: ReactNode;
|
|
579
|
+
/** Test ID */
|
|
580
|
+
testId?: string;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
export declare type StackProps<E extends ElementType = 'div'> = StackOwnProps & Omit<ComponentPropsWithoutRef<E>, keyof StackOwnProps>;
|
|
584
|
+
|
|
585
|
+
export declare const VStack: StackComponent;
|
|
586
|
+
|
|
587
|
+
export { }
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),r=require("react"),x=require("../../../utils/styles.cjs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),r=require("react"),x=require("../../../utils/styles.cjs"),U=require("../../../hooks/useMediaQuery.cjs"),R={none:"0",sm:"var(--brycks-radius-sm)",md:"var(--brycks-radius-md)",lg:"var(--brycks-radius-lg)",xl:"var(--brycks-radius-xl)",full:"var(--brycks-radius-full)"};function G(s){if(s===void 0)return;if(typeof s=="number")return s;const n=s.split(/[:/]/);if(n.length===2){const l=parseFloat(n[0]),i=parseFloat(n[1]);if(!isNaN(l)&&!isNaN(i)&&i!==0)return l/i}const u=parseFloat(s);return isNaN(u)?void 0:u}const j=r.forwardRef(function({src:n,poster:u,aspectRatio:l,fit:i="cover",preload:w="metadata",autoPlay:y=!1,loop:C=!1,controls:N=!0,muted:S,playsInline:M=!0,radius:P="none",onPlay:p,onPause:b,onEnded:v,onCanPlay:E,onError:m,className:g,style:V,testId:h,...q},A){const e=r.useRef(null),[F,d]=r.useState(!1),[T,z]=r.useState(!1),f=!(U.usePrefersReducedMotion()||y===!1),B=S??(f||y==="muted");r.useImperativeHandle(A,()=>({play:async()=>{e.current&&await e.current.play()},pause:()=>{e.current?.pause()},toggle:()=>{e.current&&(e.current.paused?e.current.play():e.current.pause())},seek:t=>{e.current&&(e.current.currentTime=t)},getCurrentTime:()=>e.current?.currentTime??0,getDuration:()=>e.current?.duration??0,isPlaying:()=>!e.current?.paused,getElement:()=>e.current}),[]),r.useEffect(()=>{f&&e.current&&(async()=>{try{await e.current?.play()}catch{}})()},[f]);const H=r.useCallback(t=>{d(!0),p?.(t)},[p]),I=r.useCallback(t=>{d(!1),b?.(t)},[b]),O=r.useCallback(t=>{d(!1),v?.(t)},[v]),$=r.useCallback(t=>{z(!0),m?.(t)},[m]),a=G(l),c=R[P]??R.none,k={position:"relative",overflow:"hidden",borderRadius:c,backgroundColor:"var(--brycks-background-muted)",...a?{width:"100%",paddingBottom:`${1/a*100}%`}:{},...V},D={display:"block",objectFit:i,borderRadius:c,...a?{position:"absolute",top:0,left:0,width:"100%",height:"100%"}:{width:"100%",height:"auto"}},Q={position:"absolute",top:0,left:0,right:0,bottom:0,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"var(--brycks-background-muted)",color:"var(--brycks-foreground-muted)",fontSize:"var(--brycks-font-size-sm)",borderRadius:c};return T?o.jsxs("div",{className:x.cx("brycks-video","brycks-video--error",g),style:k,"data-testid":h,role:"img","aria-label":"Video failed to load",children:[a&&o.jsx("div",{style:{paddingBottom:`${1/a*100}%`}}),o.jsx("div",{style:Q,children:o.jsx("span",{children:"Unable to load video"})})]}):o.jsx("div",{className:x.cx("brycks-video",F&&"brycks-video--playing",g),style:a?k:{position:"relative",borderRadius:c},"data-testid":h,children:o.jsx("video",{ref:e,src:n,poster:u,preload:w,loop:C,controls:N,muted:B,playsInline:M,onPlay:H,onPause:I,onEnded:O,onCanPlay:E,onError:$,style:D,...q})})});j.displayName="Video";exports.Video=j;
|
|
2
2
|
//# sourceMappingURL=Video.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Video.cjs","sources":["../../../../src/components/media/Video/Video.tsx"],"sourcesContent":["/**\r\n * Video Component\r\n *\r\n * Accessible video player with customizable controls, poster support,\r\n * and respect for user motion preferences.\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n useRef,\r\n useState,\r\n useCallback,\r\n useEffect,\r\n useImperativeHandle,\r\n type CSSProperties,\r\n type VideoHTMLAttributes,\r\n type SyntheticEvent,\r\n} from 'react'\r\nimport { cx } from '../../../utils/styles'\r\nimport { usePrefersReducedMotion } from '../../../hooks/useMediaQuery'\r\n\r\nexport type VideoFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\r\nexport type VideoPreload = 'none' | 'metadata' | 'auto'\r\n\r\nexport interface VideoProps\r\n extends Omit<VideoHTMLAttributes<HTMLVideoElement>, 'autoPlay'> {\r\n /** Video source URL */\r\n src: string\r\n /** Poster image URL shown before playback */\r\n poster?: string\r\n /** Aspect ratio (width/height) */\r\n aspectRatio?: number | string\r\n /** How the video should fit within its container */\r\n fit?: VideoFit\r\n /** Preload behavior */\r\n preload?: VideoPreload\r\n /**\r\n * Autoplay behavior.\r\n * - true: Autoplay (muted, respects reduced motion)\r\n * - 'muted': Autoplay muted only\r\n * - false: No autoplay\r\n * @default false\r\n */\r\n autoPlay?: boolean | 'muted'\r\n /** Loop video playback */\r\n loop?: boolean\r\n /** Show native controls */\r\n controls?: boolean\r\n /** Start muted */\r\n muted?: boolean\r\n /** Play inline on mobile (vs fullscreen) */\r\n playsInline?: boolean\r\n /** Border radius using design tokens */\r\n radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'\r\n /** Callback when video starts playing */\r\n onPlay?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback when video pauses */\r\n onPause?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback when video ends */\r\n onEnded?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback when video can play */\r\n onCanPlay?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback on error */\r\n onError?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n}\r\n\r\nexport interface VideoRef {\r\n /** Play the video */\r\n play: () => Promise<void>\r\n /** Pause the video */\r\n pause: () => void\r\n /** Toggle play/pause */\r\n toggle: () => void\r\n /** Seek to time in seconds */\r\n seek: (time: number) => void\r\n /** Get current time in seconds */\r\n getCurrentTime: () => number\r\n /** Get duration in seconds */\r\n getDuration: () => number\r\n /** Check if video is playing */\r\n isPlaying: () => boolean\r\n /** Get the underlying video element */\r\n getElement: () => HTMLVideoElement | null\r\n}\r\n\r\nconst radiusMap: Record<string, string> = {\r\n none: '0',\r\n sm: 'var(--brycks-radius-sm)',\r\n md: 'var(--brycks-radius-md)',\r\n lg: 'var(--brycks-radius-lg)',\r\n xl: 'var(--brycks-radius-xl)',\r\n full: 'var(--brycks-radius-full)',\r\n}\r\n\r\nfunction parseAspectRatio(ratio: number | string | undefined): number | undefined {\r\n if (ratio === undefined) return undefined\r\n if (typeof ratio === 'number') return ratio\r\n\r\n const parts = ratio.split(/[:/]/)\r\n if (parts.length === 2) {\r\n const width = parseFloat(parts[0])\r\n const height = parseFloat(parts[1])\r\n if (!isNaN(width) && !isNaN(height) && height !== 0) {\r\n return width / height\r\n }\r\n }\r\n\r\n const parsed = parseFloat(ratio)\r\n return isNaN(parsed) ? undefined : parsed\r\n}\r\n\r\nexport const Video = forwardRef<VideoRef, VideoProps>(function Video(\r\n {\r\n src,\r\n poster,\r\n aspectRatio,\r\n fit = 'cover',\r\n preload = 'metadata',\r\n autoPlay = false,\r\n loop = false,\r\n controls = true,\r\n muted,\r\n playsInline = true,\r\n radius = 'none',\r\n onPlay,\r\n onPause,\r\n onEnded,\r\n onCanPlay,\r\n onError,\r\n className,\r\n style,\r\n testId,\r\n ...props\r\n },\r\n ref\r\n) {\r\n const videoRef = useRef<HTMLVideoElement>(null)\r\n const [isPlaying, setIsPlaying] = useState(false)\r\n const [hasError, setHasError] = useState(false)\r\n const prefersReducedMotion = usePrefersReducedMotion()\r\n\r\n // Determine if autoplay should be enabled\r\n const shouldAutoPlay = (() => {\r\n // Never autoplay if user prefers reduced motion\r\n if (prefersReducedMotion) return false\r\n if (autoPlay === false) return false\r\n return true\r\n })()\r\n\r\n // Autoplay must be muted to work in most browsers\r\n const shouldMute = muted ?? (shouldAutoPlay || autoPlay === 'muted')\r\n\r\n // Expose imperative handle\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n play: async () => {\r\n if (videoRef.current) {\r\n await videoRef.current.play()\r\n }\r\n },\r\n pause: () => {\r\n videoRef.current?.pause()\r\n },\r\n toggle: () => {\r\n if (videoRef.current) {\r\n if (videoRef.current.paused) {\r\n videoRef.current.play()\r\n } else {\r\n videoRef.current.pause()\r\n }\r\n }\r\n },\r\n seek: (time: number) => {\r\n if (videoRef.current) {\r\n videoRef.current.currentTime = time\r\n }\r\n },\r\n getCurrentTime: () => videoRef.current?.currentTime ?? 0,\r\n getDuration: () => videoRef.current?.duration ?? 0,\r\n isPlaying: () => !videoRef.current?.paused,\r\n getElement: () => videoRef.current,\r\n }),\r\n []\r\n )\r\n\r\n // Handle autoplay on mount\r\n useEffect(() => {\r\n if (shouldAutoPlay && videoRef.current) {\r\n // Use a small delay to ensure video is ready\r\n const attemptAutoplay = async () => {\r\n try {\r\n await videoRef.current?.play()\r\n } catch {\r\n // Autoplay was blocked - this is expected in many browsers\r\n // The video will remain paused with poster visible\r\n }\r\n }\r\n attemptAutoplay()\r\n }\r\n }, [shouldAutoPlay])\r\n\r\n const handlePlay = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setIsPlaying(true)\r\n onPlay?.(event)\r\n },\r\n [onPlay]\r\n )\r\n\r\n const handlePause = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setIsPlaying(false)\r\n onPause?.(event)\r\n },\r\n [onPause]\r\n )\r\n\r\n const handleEnded = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setIsPlaying(false)\r\n onEnded?.(event)\r\n },\r\n [onEnded]\r\n )\r\n\r\n const handleError = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setHasError(true)\r\n onError?.(event)\r\n },\r\n [onError]\r\n )\r\n\r\n const parsedRatio = parseAspectRatio(aspectRatio)\r\n const borderRadius = radiusMap[radius] ?? radiusMap.none\r\n\r\n const containerStyle: CSSProperties = {\r\n position: 'relative',\r\n overflow: 'hidden',\r\n borderRadius,\r\n backgroundColor: 'var(--brycks-background-muted)',\r\n ...(parsedRatio\r\n ? {\r\n width: '100%',\r\n paddingBottom: `${(1 / parsedRatio) * 100}%`,\r\n }\r\n : {}),\r\n ...style,\r\n }\r\n\r\n const videoStyle: CSSProperties = {\r\n display: 'block',\r\n objectFit: fit,\r\n borderRadius,\r\n ...(parsedRatio\r\n ? {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n }\r\n : {\r\n width: '100%',\r\n height: 'auto',\r\n }),\r\n }\r\n\r\n const errorOverlayStyle: CSSProperties = {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n backgroundColor: 'var(--brycks-background-muted)',\r\n color: 'var(--brycks-foreground-muted)',\r\n fontSize: 'var(--brycks-font-size-sm)',\r\n borderRadius,\r\n }\r\n\r\n if (hasError) {\r\n return (\r\n <div\r\n className={cx('brycks-video', 'brycks-video--error', className)}\r\n style={containerStyle}\r\n data-testid={testId}\r\n role=\"img\"\r\n aria-label=\"Video failed to load\"\r\n >\r\n {parsedRatio && <div style={{ paddingBottom: `${(1 / parsedRatio) * 100}%` }} />}\r\n <div style={errorOverlayStyle}>\r\n <span>Unable to load video</span>\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n 'brycks-video',\r\n isPlaying && 'brycks-video--playing',\r\n className\r\n )}\r\n style={parsedRatio ? containerStyle : { position: 'relative', borderRadius }}\r\n data-testid={testId}\r\n >\r\n <video\r\n ref={videoRef}\r\n src={src}\r\n poster={poster}\r\n preload={preload}\r\n loop={loop}\r\n controls={controls}\r\n muted={shouldMute}\r\n playsInline={playsInline}\r\n onPlay={handlePlay}\r\n onPause={handlePause}\r\n onEnded={handleEnded}\r\n onCanPlay={onCanPlay}\r\n onError={handleError}\r\n style={videoStyle}\r\n {...props}\r\n />\r\n </div>\r\n )\r\n})\r\n\r\nVideo.displayName = 'Video'\r\n"],"names":["radiusMap","parseAspectRatio","ratio","parts","width","height","parsed","Video","forwardRef","src","poster","aspectRatio","fit","preload","autoPlay","loop","controls","muted","playsInline","radius","onPlay","onPause","onEnded","onCanPlay","onError","className","style","testId","props","ref","videoRef","useRef","isPlaying","setIsPlaying","useState","hasError","setHasError","prefersReducedMotion","usePrefersReducedMotion","shouldAutoPlay","shouldMute","useImperativeHandle","time","useEffect","handlePlay","useCallback","event","handlePause","handleEnded","handleError","parsedRatio","borderRadius","containerStyle","videoStyle","errorOverlayStyle","jsxs","cx","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Video.cjs","sources":["../../../../src/components/media/Video/Video.tsx"],"sourcesContent":["/**\r\n * Video Component\r\n *\r\n * Accessible video player with customizable controls, poster support,\r\n * and respect for user motion preferences.\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n useRef,\r\n useState,\r\n useCallback,\r\n useEffect,\r\n useImperativeHandle,\r\n type CSSProperties,\r\n type VideoHTMLAttributes,\r\n type SyntheticEvent,\r\n} from 'react'\r\nimport { cx } from '../../../utils/styles'\r\nimport { usePrefersReducedMotion } from '../../../hooks/useMediaQuery'\r\n\r\nexport type VideoFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\r\nexport type VideoPreload = 'none' | 'metadata' | 'auto'\r\n\r\nexport interface VideoProps\r\n extends Omit<VideoHTMLAttributes<HTMLVideoElement>, 'autoPlay'> {\r\n /** Video source URL */\r\n src: string\r\n /** Poster image URL shown before playback */\r\n poster?: string\r\n /** Aspect ratio (width/height) */\r\n aspectRatio?: number | string\r\n /** How the video should fit within its container */\r\n fit?: VideoFit\r\n /** Preload behavior */\r\n preload?: VideoPreload\r\n /**\r\n * Autoplay behavior.\r\n * - true: Autoplay (muted, respects reduced motion)\r\n * - 'muted': Autoplay muted only\r\n * - false: No autoplay\r\n * @default false\r\n */\r\n autoPlay?: boolean | 'muted'\r\n /** Loop video playback */\r\n loop?: boolean\r\n /** Show native controls */\r\n controls?: boolean\r\n /** Start muted */\r\n muted?: boolean\r\n /** Play inline on mobile (vs fullscreen) */\r\n playsInline?: boolean\r\n /** Border radius using design tokens */\r\n radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'\r\n /** Callback when video starts playing */\r\n onPlay?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback when video pauses */\r\n onPause?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback when video ends */\r\n onEnded?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback when video can play */\r\n onCanPlay?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Callback on error */\r\n onError?: (event: SyntheticEvent<HTMLVideoElement>) => void\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n}\r\n\r\nexport interface VideoRef {\r\n /** Play the video */\r\n play: () => Promise<void>\r\n /** Pause the video */\r\n pause: () => void\r\n /** Toggle play/pause */\r\n toggle: () => void\r\n /** Seek to time in seconds */\r\n seek: (time: number) => void\r\n /** Get current time in seconds */\r\n getCurrentTime: () => number\r\n /** Get duration in seconds */\r\n getDuration: () => number\r\n /** Check if video is playing */\r\n isPlaying: () => boolean\r\n /** Get the underlying video element */\r\n getElement: () => HTMLVideoElement | null\r\n}\r\n\r\nconst radiusMap: Record<string, string> = {\r\n none: '0',\r\n sm: 'var(--brycks-radius-sm)',\r\n md: 'var(--brycks-radius-md)',\r\n lg: 'var(--brycks-radius-lg)',\r\n xl: 'var(--brycks-radius-xl)',\r\n full: 'var(--brycks-radius-full)',\r\n}\r\n\r\nfunction parseAspectRatio(ratio: number | string | undefined): number | undefined {\r\n if (ratio === undefined) return undefined\r\n if (typeof ratio === 'number') return ratio\r\n\r\n const parts = ratio.split(/[:/]/)\r\n if (parts.length === 2) {\r\n const width = parseFloat(parts[0])\r\n const height = parseFloat(parts[1])\r\n if (!isNaN(width) && !isNaN(height) && height !== 0) {\r\n return width / height\r\n }\r\n }\r\n\r\n const parsed = parseFloat(ratio)\r\n return isNaN(parsed) ? undefined : parsed\r\n}\r\n\r\nexport const Video = forwardRef<VideoRef, VideoProps>(function Video(\r\n {\r\n src,\r\n poster,\r\n aspectRatio,\r\n fit = 'cover',\r\n preload = 'metadata',\r\n autoPlay = false,\r\n loop = false,\r\n controls = true,\r\n muted,\r\n playsInline = true,\r\n radius = 'none',\r\n onPlay,\r\n onPause,\r\n onEnded,\r\n onCanPlay,\r\n onError,\r\n className,\r\n style,\r\n testId,\r\n ...props\r\n },\r\n ref\r\n) {\r\n const videoRef = useRef<HTMLVideoElement>(null)\r\n const [isPlaying, setIsPlaying] = useState(false)\r\n const [hasError, setHasError] = useState(false)\r\n const prefersReducedMotion = usePrefersReducedMotion()\r\n\r\n // Determine if autoplay should be enabled\r\n const shouldAutoPlay = (() => {\r\n // Never autoplay if user prefers reduced motion\r\n if (prefersReducedMotion) return false\r\n if (autoPlay === false) return false\r\n return true\r\n })()\r\n\r\n // Autoplay must be muted to work in most browsers\r\n const shouldMute = muted ?? (shouldAutoPlay || autoPlay === 'muted')\r\n\r\n // Expose imperative handle\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n play: async () => {\r\n if (videoRef.current) {\r\n await videoRef.current.play()\r\n }\r\n },\r\n pause: () => {\r\n videoRef.current?.pause()\r\n },\r\n toggle: () => {\r\n if (videoRef.current) {\r\n if (videoRef.current.paused) {\r\n videoRef.current.play()\r\n } else {\r\n videoRef.current.pause()\r\n }\r\n }\r\n },\r\n seek: (time: number) => {\r\n if (videoRef.current) {\r\n videoRef.current.currentTime = time\r\n }\r\n },\r\n getCurrentTime: () => videoRef.current?.currentTime ?? 0,\r\n getDuration: () => videoRef.current?.duration ?? 0,\r\n isPlaying: () => !videoRef.current?.paused,\r\n getElement: () => videoRef.current,\r\n }),\r\n []\r\n )\r\n\r\n // Handle autoplay on mount\r\n useEffect(() => {\r\n if (shouldAutoPlay && videoRef.current) {\r\n // Use a small delay to ensure video is ready\r\n const attemptAutoplay = async () => {\r\n try {\r\n await videoRef.current?.play()\r\n } catch {\r\n // Autoplay was blocked - this is expected in many browsers\r\n // The video will remain paused with poster visible\r\n }\r\n }\r\n attemptAutoplay()\r\n }\r\n }, [shouldAutoPlay])\r\n\r\n const handlePlay = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setIsPlaying(true)\r\n onPlay?.(event)\r\n },\r\n [onPlay]\r\n )\r\n\r\n const handlePause = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setIsPlaying(false)\r\n onPause?.(event)\r\n },\r\n [onPause]\r\n )\r\n\r\n const handleEnded = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setIsPlaying(false)\r\n onEnded?.(event)\r\n },\r\n [onEnded]\r\n )\r\n\r\n const handleError = useCallback(\r\n (event: SyntheticEvent<HTMLVideoElement>) => {\r\n setHasError(true)\r\n onError?.(event)\r\n },\r\n [onError]\r\n )\r\n\r\n const parsedRatio = parseAspectRatio(aspectRatio)\r\n const borderRadius = radiusMap[radius] ?? radiusMap.none\r\n\r\n const containerStyle: CSSProperties = {\r\n position: 'relative',\r\n overflow: 'hidden',\r\n borderRadius,\r\n backgroundColor: 'var(--brycks-background-muted)',\r\n ...(parsedRatio\r\n ? {\r\n width: '100%',\r\n paddingBottom: `${(1 / parsedRatio) * 100}%`,\r\n }\r\n : {}),\r\n ...style,\r\n }\r\n\r\n const videoStyle: CSSProperties = {\r\n display: 'block',\r\n objectFit: fit,\r\n borderRadius,\r\n ...(parsedRatio\r\n ? {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n }\r\n : {\r\n width: '100%',\r\n height: 'auto',\r\n }),\r\n }\r\n\r\n const errorOverlayStyle: CSSProperties = {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n backgroundColor: 'var(--brycks-background-muted)',\r\n color: 'var(--brycks-foreground-muted)',\r\n fontSize: 'var(--brycks-font-size-sm)',\r\n borderRadius,\r\n }\r\n\r\n if (hasError) {\r\n return (\r\n <div\r\n className={cx('brycks-video', 'brycks-video--error', className)}\r\n style={containerStyle}\r\n data-testid={testId}\r\n role=\"img\"\r\n aria-label=\"Video failed to load\"\r\n >\r\n {parsedRatio && <div style={{ paddingBottom: `${(1 / parsedRatio) * 100}%` }} />}\r\n <div style={errorOverlayStyle}>\r\n <span>Unable to load video</span>\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n 'brycks-video',\r\n isPlaying && 'brycks-video--playing',\r\n className\r\n )}\r\n style={parsedRatio ? containerStyle : { position: 'relative', borderRadius }}\r\n data-testid={testId}\r\n >\r\n <video\r\n ref={videoRef}\r\n src={src}\r\n poster={poster}\r\n preload={preload}\r\n loop={loop}\r\n controls={controls}\r\n muted={shouldMute}\r\n playsInline={playsInline}\r\n onPlay={handlePlay}\r\n onPause={handlePause}\r\n onEnded={handleEnded}\r\n onCanPlay={onCanPlay}\r\n onError={handleError}\r\n style={videoStyle}\r\n {...props}\r\n />\r\n </div>\r\n )\r\n})\r\n\r\nVideo.displayName = 'Video'\r\n"],"names":["radiusMap","parseAspectRatio","ratio","parts","width","height","parsed","Video","forwardRef","src","poster","aspectRatio","fit","preload","autoPlay","loop","controls","muted","playsInline","radius","onPlay","onPause","onEnded","onCanPlay","onError","className","style","testId","props","ref","videoRef","useRef","isPlaying","setIsPlaying","useState","hasError","setHasError","shouldAutoPlay","usePrefersReducedMotion","shouldMute","useImperativeHandle","time","useEffect","handlePlay","useCallback","event","handlePause","handleEnded","handleError","parsedRatio","borderRadius","containerStyle","videoStyle","errorOverlayStyle","jsxs","cx","jsx"],"mappings":"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"}
|