nuvox 0.1.4 → 0.1.6

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,1092 @@
1
+ interface ColorScale {
2
+ 50: string;
3
+ 100: string;
4
+ 200: string;
5
+ 300: string;
6
+ 400: string;
7
+ 500: string;
8
+ 600: string;
9
+ 700: string;
10
+ 800: string;
11
+ 900: string;
12
+ }
13
+ interface SemanticColor {
14
+ light: string;
15
+ subtle: string;
16
+ base: string;
17
+ dark: string;
18
+ deeper: string;
19
+ }
20
+ interface ThemeTokens {
21
+ meta: {
22
+ name: string;
23
+ label: string;
24
+ /** Short description of the visual identity — kept out of CSS, used in docs/registry UI. */
25
+ description: string;
26
+ };
27
+ color: {
28
+ neutral: ColorScale & {
29
+ 0: string;
30
+ 950: string;
31
+ };
32
+ success: SemanticColor;
33
+ danger: SemanticColor;
34
+ warning: SemanticColor;
35
+ info: SemanticColor;
36
+ /** Page/app background, not component surface. */
37
+ background: string;
38
+ /** Default component surface (card, input, modal body). */
39
+ surface: string;
40
+ /** Elevated surface (popover, dropdown, tooltip). */
41
+ surfaceRaised: string;
42
+ border: string;
43
+ borderFocus: string;
44
+ text: string;
45
+ textMuted: string;
46
+ textInverse: string;
47
+ };
48
+ radius: {
49
+ sm: string;
50
+ md: string;
51
+ lg: string;
52
+ xl: string;
53
+ "2xl": string;
54
+ full: string;
55
+ };
56
+ spacing: {
57
+ xs: string;
58
+ sm: string;
59
+ md: string;
60
+ lg: string;
61
+ xl: string;
62
+ "2xl": string;
63
+ };
64
+ typography: {
65
+ fontSans: string;
66
+ fontMono: string;
67
+ sizeXs: string;
68
+ sizeSm: string;
69
+ sizeMd: string;
70
+ sizeLg: string;
71
+ sizeXl: string;
72
+ weightNormal: string;
73
+ weightMedium: string;
74
+ weightBold: string;
75
+ lineHeightTight: string;
76
+ lineHeightNormal: string;
77
+ };
78
+ shadow: {
79
+ xs: string;
80
+ sm: string;
81
+ md: string;
82
+ lg: string;
83
+ xl: string;
84
+ "2xl": string;
85
+ inner: string;
86
+ };
87
+ elevation: {
88
+ /**
89
+ * z-index steps — must be consistent across every portal-based
90
+ * component. Deliberately NOT alphabetical-by-concept order:
91
+ * `modal` is the LOWEST tier, not the highest. Every portal
92
+ * target shares one stacking context (usually the end of
93
+ * `<body>`), so a Select/Combobox/DropdownMenu/Popover opened
94
+ * from *inside* an open Modal must out-rank the Modal itself
95
+ * to render above its backdrop instead of being swallowed
96
+ * behind it. Real order, low to high:
97
+ * modal < dropdown < popover < tooltip < toast.
98
+ */
99
+ dropdown: number;
100
+ popover: number;
101
+ modal: number;
102
+ toast: number;
103
+ tooltip: number;
104
+ };
105
+ motion: {
106
+ durationFast: string;
107
+ durationNormal: string;
108
+ durationSlow: string;
109
+ easeStandard: string;
110
+ easeEmphasized: string;
111
+ /** Set to '0.01ms' by a reduced-motion-aware theme variant if needed. */
112
+ durationInstant: string;
113
+ };
114
+ border: {
115
+ widthThin: string;
116
+ widthMedium: string;
117
+ widthThick: string;
118
+ style: string;
119
+ };
120
+ effects: {
121
+ /**
122
+ * CSS `backdrop-filter: blur()` amount, e.g. "16px" or "0px".
123
+ * Every non-glass theme sets this to "0px" — an explicit zero,
124
+ * not an absent field, so `defineTheme`'s completeness check
125
+ * still catches an accidentally-forgotten theme. Translucent
126
+ * `color.surface`/`color.border` values (glass, dark-glass) are
127
+ * only actually visible as "glass" when something behind them
128
+ * is blurred; without this, a translucent white surface over a
129
+ * plain page background is indistinguishable from opaque white.
130
+ */
131
+ backdropBlur: string;
132
+ };
133
+ }
134
+ /**
135
+ * Identity function with a strict parameter type.
136
+ * Its only job is to make an incomplete theme a compile error
137
+ * at the call site, with TypeScript naming the exact missing key.
138
+ */
139
+ declare function defineTheme(tokens: ThemeTokens): ThemeTokens;
140
+ /** Every top-level and nested key path, used by the completeness test. */
141
+ declare const TOKEN_CATEGORIES: readonly ["meta", "color", "radius", "spacing", "typography", "shadow", "elevation", "motion", "border", "effects"];
142
+ /**
143
+ * Every required leaf path, hardcoded independently of any
144
+ * theme instance. This is deliberately NOT derived from
145
+ * whichever theme happens to register first — that would make
146
+ * the very first theme registered the unverified "trust me"
147
+ * reference. Every path listed here corresponds 1:1 to a field
148
+ * in ThemeTokens; if you add a field to the contract, add its
149
+ * path here too (a mismatch here is caught by
150
+ * registry.test.ts's cross-check against `light`).
151
+ */
152
+ declare const REQUIRED_TOKEN_PATHS: readonly ["meta.name", "meta.label", "meta.description", ...string[], "color.background", "color.surface", "color.surfaceRaised", "color.border", "color.borderFocus", "color.text", "color.textMuted", "color.textInverse", "radius.sm", "radius.md", "radius.lg", "radius.xl", "radius.2xl", "radius.full", "spacing.xs", "spacing.sm", "spacing.md", "spacing.lg", "spacing.xl", "spacing.2xl", "typography.fontSans", "typography.fontMono", "typography.sizeXs", "typography.sizeSm", "typography.sizeMd", "typography.sizeLg", "typography.sizeXl", "typography.weightNormal", "typography.weightMedium", "typography.weightBold", "typography.lineHeightTight", "typography.lineHeightNormal", "shadow.xs", "shadow.sm", "shadow.md", "shadow.lg", "shadow.xl", "shadow.2xl", "shadow.inner", "elevation.dropdown", "elevation.popover", "elevation.modal", "elevation.toast", "elevation.tooltip", "motion.durationFast", "motion.durationNormal", "motion.durationSlow", "motion.easeStandard", "motion.easeEmphasized", "motion.durationInstant", "border.widthThin", "border.widthMedium", "border.widthThick", "border.style", "effects.backdropBlur"];
153
+ /** Returns every required path that is missing or empty on the given theme-like object. */
154
+ declare function findMissingTokenPaths(theme: unknown): string[];
155
+
156
+ interface AccentDefinition {
157
+ name: string;
158
+ label: string;
159
+ scale: ColorScale;
160
+ }
161
+ declare function registerAccent(def: AccentDefinition): void;
162
+ declare function getAccent(name: string): AccentDefinition | undefined;
163
+ declare function listAccents(): AccentDefinition[];
164
+ declare const DEFAULT_ACCENT = "indigo";
165
+
166
+ type Size = "xs" | "sm" | "md" | "lg" | "xl";
167
+ /**
168
+ * Every component accepts these. `theme` and `color` are two
169
+ * independent axes: `theme` overrides shape (radius, shadow,
170
+ * motion, glass/gradient/glow — see NuvoxProvider/withThemeOverride),
171
+ * `color` overrides brand accent only (see accents.ts/withAccentOverride)
172
+ * and touches nothing structural. A component can use either, both,
173
+ * or neither without the other being implied.
174
+ */
175
+ interface BaseComponentProps {
176
+ className?: string;
177
+ style?: React.CSSProperties;
178
+ /** Component-level theme (shape) override. */
179
+ theme?: string;
180
+ /** Component-level accent (brand color) override. */
181
+ color?: string;
182
+ }
183
+ type Variant = "solid" | "outline" | "ghost" | "soft";
184
+
185
+ interface FieldProps {
186
+ disabled?: boolean;
187
+ required?: boolean;
188
+ /** Whether the field is in an invalid/error state. */
189
+ error?: boolean;
190
+ size?: Size;
191
+ }
192
+ interface FieldState {
193
+ isDisabled: boolean;
194
+ isRequired: boolean;
195
+ isInvalid: boolean;
196
+ size: Size;
197
+ }
198
+
199
+ interface RatingCoreProps {
200
+ /** Number of stars. Default 5. */
201
+ max?: number;
202
+ /** Allow half-star increments (0.5 steps) instead of whole stars only. Default false. */
203
+ allowHalf?: boolean;
204
+ disabled?: boolean;
205
+ /** Displays the current value but blocks changing it — distinct from `disabled` (still focusable/announced, just not editable). Default false. */
206
+ readOnly?: boolean;
207
+ size?: Size;
208
+ }
209
+ type StarFill = "empty" | "half" | "full";
210
+
211
+ type OTPInputType = "numeric" | "alphanumeric";
212
+ interface OTPInputCoreProps extends FieldProps {
213
+ /** Number of boxes. Default 6. */
214
+ length?: number;
215
+ /** Which characters are accepted. Default "numeric". */
216
+ type?: OTPInputType;
217
+ /** Renders each filled box as a dot instead of the character — the "Pin Input" variant of this same component. Default false. */
218
+ mask?: boolean;
219
+ }
220
+
221
+ type Placement = "top" | "bottom" | "left" | "right";
222
+ type Alignment = "start" | "center" | "end";
223
+
224
+ interface SelectOptionItem {
225
+ value: string;
226
+ label: string;
227
+ /**
228
+ * Optional shorter label for the closed trigger only. Falls back
229
+ * to `label` when omitted. Exists for cases like PhoneInput's
230
+ * country select, where the listbox row needs more context
231
+ * ("🇺🇸 US +1") than the narrow, fixed-width trigger has room for
232
+ * — rather than forcing one string to serve both and either
233
+ * cramping the trigger or truncating it.
234
+ */
235
+ triggerLabel?: string;
236
+ disabled?: boolean;
237
+ }
238
+ interface SelectCoreProps extends FieldProps {
239
+ placement?: Placement;
240
+ align?: Alignment;
241
+ }
242
+
243
+ interface PhoneCountry {
244
+ iso2: string;
245
+ name: string;
246
+ /** Digits only, no "+". */
247
+ dialCode: string;
248
+ /** Emoji flag — zero-dependency, no icon/image asset needed. */
249
+ flag: string;
250
+ }
251
+ interface PhoneInputCoreProps extends FieldProps {
252
+ /** Overrides DEFAULT_COUNTRIES with a consumer-supplied list. */
253
+ countries?: PhoneCountry[];
254
+ /** ISO 3166-1 alpha-2 code to preselect when the value has no recognizable dial code yet. Default "US". */
255
+ defaultCountry?: string;
256
+ }
257
+
258
+ type BadgeVariant = "solid" | "outline" | "soft";
259
+ interface BadgeCoreProps {
260
+ variant?: BadgeVariant;
261
+ size?: Size;
262
+ /** Renders a small status dot instead of any label/count content. */
263
+ dot?: boolean;
264
+ /** Numeric count — 999+ caps display, same convention as the old codebase. */
265
+ count?: number;
266
+ /** Derived by the React layer from whether onDismiss was passed, not set directly. */
267
+ dismissible?: boolean;
268
+ hasIconLeft?: boolean;
269
+ hasIconRight?: boolean;
270
+ }
271
+
272
+ type AvatarSize = Size | "2xl";
273
+ type AvatarShape = "circle" | "square";
274
+ type AvatarStatus = "online" | "offline" | "away" | "busy";
275
+ interface AvatarCoreProps {
276
+ size?: AvatarSize;
277
+ shape?: AvatarShape;
278
+ status?: AvatarStatus;
279
+ /** Derived by the React layer (image present and not errored), not set directly. */
280
+ hasImage?: boolean;
281
+ /** Derived by the React layer from whether an onClick was passed. */
282
+ isClickable?: boolean;
283
+ }
284
+
285
+ type SpinnerVariant = "ring" | "dots" | "bars" | "pulse" | "dual-ring" | "ripple" | "orbit" | "bounce" | "conic" | "buffer" | "linear" | "heartbeat" | "infinity" | "hourglass" | "pinwheel" | "radar" | "wave" | "helix" | "atom" | "comet" | "gauge" | "stack" | "spiral" | "burst" | "eclipse" | "petal" | "sine" | "gear" | "pendulum" | "dancer";
286
+ interface SpinnerCoreProps {
287
+ size?: Size;
288
+ variant?: SpinnerVariant;
289
+ /** Accessible label — defaults to "Loading" if not given. */
290
+ label?: string;
291
+ }
292
+
293
+ type DividerOrientation = "horizontal" | "vertical";
294
+ interface DividerCoreProps {
295
+ orientation?: DividerOrientation;
296
+ /** Derived by the React layer from whether label content was passed. */
297
+ hasLabel?: boolean;
298
+ }
299
+
300
+ type CardVariant = "elevated" | "outlined" | "flat" | "filled";
301
+ type CardPadding = "none" | "sm" | "md" | "lg";
302
+ /** vertical: media stacked above/below content (default). horizontal: media beside content, fixed-width. */
303
+ type CardLayout = "vertical" | "horizontal";
304
+ interface CardCoreProps {
305
+ variant?: CardVariant;
306
+ padding?: CardPadding;
307
+ layout?: CardLayout;
308
+ /** Renders header/footer/badge/children on top of media with a gradient scrim, instead of stacked below it. */
309
+ overlay?: boolean;
310
+ disabled?: boolean;
311
+ /** Derived by the React layer from whether onClick was passed. */
312
+ isClickable?: boolean;
313
+ }
314
+
315
+ type ScrollAreaOrientation = "vertical" | "horizontal" | "both";
316
+ /**
317
+ * - "always": the scrollbar is permanently visible.
318
+ * - "hover": fades in while the pointer is over the scroll area (or a
319
+ * thumb is being dragged), fades out otherwise — the common desktop
320
+ * app convention.
321
+ * - "auto": fades in only while actively scrolling (wheel, touch, or
322
+ * thumb drag) and fades out shortly after activity stops — the
323
+ * common OS convention (e.g. macOS "Show scroll bars: When
324
+ * scrolling").
325
+ * - "never": no custom scrollbar is rendered at all. This is the
326
+ * "hide the scrollbar entirely" option — content still scrolls by
327
+ * every other means, it's just never indicated visually.
328
+ */
329
+ type ScrollbarVisibility = "always" | "hover" | "auto" | "never";
330
+ /**
331
+ * The thumb's color is a separate choice from the ambient theme/accent
332
+ * split every other component follows, because a scrollbar is UI
333
+ * chrome, not a branded surface — so it defaults to a neutral,
334
+ * theme-adaptive gray rather than always taking the accent color the
335
+ * way e.g. Slider's thumb does.
336
+ * - "neutral" (default): theme-adaptive gray (`--color-textMuted`).
337
+ * - "accent": the active accent's brand color (`--color-brand-500`,
338
+ * same variable Slider's thumb uses), for when a scroll area should
339
+ * read as more prominent/branded.
340
+ * - any other string: used as a literal CSS color value directly —
341
+ * an escape hatch for a one-off color that isn't a theme token.
342
+ */
343
+ type ScrollAreaThumbColor = "neutral" | "accent" | string;
344
+ interface ScrollAreaCoreProps {
345
+ orientation?: ScrollAreaOrientation;
346
+ scrollbarVisibility?: ScrollbarVisibility;
347
+ thumbColor?: ScrollAreaThumbColor;
348
+ }
349
+
350
+ type AlertVariant = "info" | "success" | "warning" | "danger";
351
+ interface AlertCoreProps {
352
+ variant?: AlertVariant;
353
+ /** Derived by the React layer from whether onDismiss was passed. */
354
+ dismissible?: boolean;
355
+ /** Derived by the React layer from whether an icon slot was explicitly hidden. */
356
+ hasIcon?: boolean;
357
+ }
358
+
359
+ type ModalSize = Size | "full";
360
+ interface ModalCoreProps {
361
+ size?: ModalSize;
362
+ /** Clicking the backdrop closes the modal. Default true. */
363
+ closeOnBackdropClick?: boolean;
364
+ /** Escape closes the modal. Default true. */
365
+ closeOnEscape?: boolean;
366
+ hasTitle?: boolean;
367
+ }
368
+
369
+ type ToastVariant = "info" | "success" | "warning" | "danger";
370
+ type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
371
+
372
+ /**
373
+ * A tone, not a shape. Progress deliberately does NOT reuse the
374
+ * shared `Variant` union ("solid" | "outline" | "ghost" | "soft") —
375
+ * that describes fill treatment for interactive controls and means
376
+ * nothing for a meter. What varies here is semantic color, so this
377
+ * is its own small union, and (per CONTRACT.md Rule 5b) `success`/
378
+ * `warning`/`danger` are the theme-defined SEMANTIC colors, kept
379
+ * separate from the brand accent. `brand` is the default and is the
380
+ * one tone that tracks the accent.
381
+ */
382
+ type ProgressVariant = "brand" | "success" | "warning" | "danger";
383
+ interface ProgressCoreProps {
384
+ /** 0..max. Ignored (and the bar animates) when `indeterminate`. */
385
+ value?: number;
386
+ /** Upper bound. Default 100. */
387
+ max?: number;
388
+ /** Unknown-duration state: an animated bar, no numeric value. */
389
+ indeterminate?: boolean;
390
+ size?: Size;
391
+ variant?: ProgressVariant;
392
+ /** Render the numeric percent next to the track. Default false. */
393
+ showValue?: boolean;
394
+ }
395
+
396
+ /**
397
+ * Horizontal is the default (a row of tabs above their panels).
398
+ * Vertical changes two things at once, which is why it's a single
399
+ * flag and not two: the visual layout AND — per WAI-ARIA — which
400
+ * arrow keys move between tabs (Up/Down instead of Left/Right).
401
+ */
402
+ type TabsOrientation = "horizontal" | "vertical";
403
+ /**
404
+ * "automatic" (the WAI-ARIA default) selects a tab the moment it's
405
+ * focused via the arrow keys — good for cheap panels. "manual"
406
+ * moves focus without selecting, requiring Enter/Space to commit —
407
+ * the right choice when showing a panel is expensive (a network
408
+ * fetch, a heavy chart) and you don't want every arrow press to
409
+ * trigger it.
410
+ */
411
+ type TabsActivationMode = "automatic" | "manual";
412
+ /** Visual treatment of the tab row. Shape only — never encodes color meaning. */
413
+ type TabsVariant = "line" | "soft" | "solid";
414
+ interface TabsCoreProps {
415
+ orientation?: TabsOrientation;
416
+ activationMode?: TabsActivationMode;
417
+ variant?: TabsVariant;
418
+ size?: Size;
419
+ }
420
+
421
+ type StepWizardOrientation = "horizontal" | "vertical";
422
+ /** Visual treatment of the step indicator. Shape only — never encodes color meaning (Rule 5b). */
423
+ type StepWizardVariant = "numbered" | "dots" | "progress";
424
+ type StepStatus = "complete" | "current" | "upcoming" | "disabled";
425
+ /**
426
+ * The minimal shape the core logic needs per step. The React layer's
427
+ * public `<StepWizardStep>` accepts a `label`/description as JSX
428
+ * children, which have no meaning here — this module only ever sees
429
+ * the fields that affect navigation and status math.
430
+ */
431
+ interface StepWizardStepDef {
432
+ id: string;
433
+ disabled?: boolean;
434
+ /**
435
+ * Explicit completion override. Left unset (the common case), a
436
+ * step's completeness is derived purely from its position relative
437
+ * to the active step (everything before it is done). Set this when
438
+ * that default is wrong for your flow — e.g. an optional step the
439
+ * user skipped shouldn't read as "complete" just because the wizard
440
+ * has moved past it.
441
+ */
442
+ completed?: boolean;
443
+ }
444
+ interface StepWizardCoreProps {
445
+ orientation?: StepWizardOrientation;
446
+ variant?: StepWizardVariant;
447
+ size?: Size;
448
+ /**
449
+ * When true (default), a step can only be reached by completing the
450
+ * ones before it: going backward is always allowed, but going
451
+ * forward is limited to the very next step, unless a later step was
452
+ * explicitly marked `completed`. Set false for a free-navigation
453
+ * wizard (e.g. an already-submitted form the user can revisit and
454
+ * edit any section of).
455
+ */
456
+ linear?: boolean;
457
+ }
458
+
459
+ /**
460
+ * "single" allows one open section at a time (optionally
461
+ * `collapsible`, so the open one can be closed to leave all shut).
462
+ * "multiple" lets any number be open at once. The two modes carry
463
+ * different value shapes (a string vs. a string[]), which is why
464
+ * the React props are a discriminated union on this field.
465
+ */
466
+ type AccordionType = "single" | "multiple";
467
+ interface AccordionCoreProps {
468
+ size?: Size;
469
+ }
470
+
471
+ /**
472
+ * A menu opens below its trigger, left-aligned, by default — the
473
+ * conventional action-menu placement (unlike Tooltip, which centers
474
+ * above). Both are passthroughs to core/floating.ts so a consumer
475
+ * can flip a menu that would collide with the viewport edge; the
476
+ * positioner also flips automatically when it doesn't fit.
477
+ */
478
+ interface DropdownCoreProps {
479
+ size?: Size;
480
+ placement?: Placement;
481
+ align?: Alignment;
482
+ }
483
+ /**
484
+ * Menu items have two visual variants: the default, and a
485
+ * destructive one ("danger") for actions like Delete. "danger" is a
486
+ * SEMANTIC color drawn from the separate success/warning/danger
487
+ * registry (CONTRACT.md Rule 5b) — it is not the theme accent, and
488
+ * it stays red across every accent so a destructive action never
489
+ * blends into a brand-colored menu.
490
+ */
491
+ type DropdownItemVariant = "default" | "danger";
492
+
493
+ type SliderValue = number | readonly [number, number];
494
+ interface SliderCoreProps {
495
+ min?: number;
496
+ max?: number;
497
+ step?: number;
498
+ disabled?: boolean;
499
+ size?: Size;
500
+ }
501
+
502
+ interface ComboboxOption {
503
+ value: string;
504
+ label: string;
505
+ disabled?: boolean;
506
+ }
507
+ interface ComboboxCoreProps extends FieldProps {
508
+ placement?: Placement;
509
+ align?: Alignment;
510
+ /**
511
+ * When the typed query matches no option and the field loses
512
+ * focus or Enter is pressed, this controls what happens to it:
513
+ * `false` (default) reverts the input back to the last committed
514
+ * value's label (or clears it if nothing was ever selected) — the
515
+ * same "you must pick a real option" behavior Select enforces.
516
+ * `true` commits the typed text itself as the value, letting
517
+ * Combobox double as a free-text field with suggestions rather
518
+ * than a strict picker.
519
+ */
520
+ allowCustomValue?: boolean;
521
+ }
522
+
523
+ interface SearchSuggestion {
524
+ id: string;
525
+ label: string;
526
+ disabled?: boolean;
527
+ }
528
+ interface SearchBarCoreProps extends FieldProps {
529
+ placement?: Placement;
530
+ align?: Alignment;
531
+ }
532
+
533
+ type WeekStart = 0 | 1;
534
+ interface CalendarDay {
535
+ date: Date;
536
+ /** False for the leading/trailing days from adjacent months that fill out the grid. */
537
+ isCurrentMonth: boolean;
538
+ isToday: boolean;
539
+ }
540
+
541
+ interface DatePickerCoreProps extends FieldProps {
542
+ min?: Date;
543
+ max?: Date;
544
+ /** An extra predicate for one-off disabled dates (holidays, already-booked days) beyond the min/max range. */
545
+ isDateDisabled?: (date: Date) => boolean;
546
+ weekStartsOn?: 0 | 1;
547
+ locale?: string;
548
+ }
549
+
550
+ /** A time of day, no date attached. `hours` is 0-23 (24-hour, locale-independent internally); `minutes` is 0-59. */
551
+ interface TimeValue {
552
+ hours: number;
553
+ minutes: number;
554
+ }
555
+ interface TimePickerCoreProps extends FieldProps {
556
+ min?: TimeValue;
557
+ max?: TimeValue;
558
+ /** 12-hour (AM/PM) vs 24-hour display and parsing. Default true. */
559
+ use12Hour?: boolean;
560
+ /** An extra predicate for one-off disabled slots (e.g. already-booked times) beyond min/max. */
561
+ isTimeDisabled?: (time: TimeValue) => boolean;
562
+ locale?: string;
563
+ }
564
+ type TimePanelMode = "dial" | "digital";
565
+
566
+ type ColorPickerVariant = "both" | "presets" | "custom";
567
+ interface ColorPickerCoreProps extends FieldProps {
568
+ /** Preset swatches offered in the popover, as hex strings. Defaults to DEFAULT_PRESETS. */
569
+ presets?: string[];
570
+ /**
571
+ * Which part(s) of the popover to show. `"both"` (default) is the
572
+ * preset grid plus the custom saturation/hue panel underneath it.
573
+ * `"presets"` shows only the grid — a fixed palette with no
574
+ * arbitrary-color escape hatch. `"custom"` shows only the
575
+ * saturation/hue panel — no preset shortcuts at all.
576
+ */
577
+ variant?: ColorPickerVariant;
578
+ }
579
+ declare const DEFAULT_PRESETS: string[];
580
+
581
+ type CarouselOrientation = "horizontal" | "vertical";
582
+ interface CarouselCoreProps {
583
+ /** Wrap past the last slide back to the first (and vice versa). Default false. */
584
+ loop?: boolean;
585
+ orientation?: CarouselOrientation;
586
+ /** Auto-advance on a timer. Default false. */
587
+ autoPlay?: boolean;
588
+ /** Milliseconds between auto-advances. Default 5000. */
589
+ autoPlayInterval?: number;
590
+ /** Pause the autoplay timer while the pointer is over the carousel. Default true. */
591
+ pauseOnHover?: boolean;
592
+ }
593
+
594
+ type TimelineOrientation = "vertical" | "horizontal";
595
+ /** Vertical only — which side of the line each item's content sits on. "alternate" ignores this per-item and flips by list position (even/odd), in CSS. Ignored for horizontal orientation. */
596
+ type TimelineAlign = "start" | "end" | "alternate";
597
+ type TimelineStatus = "default" | "success" | "warning" | "danger" | "info";
598
+ interface TimelineCoreProps {
599
+ orientation?: TimelineOrientation;
600
+ align?: TimelineAlign;
601
+ }
602
+ interface TimelineItemCoreProps {
603
+ status?: TimelineStatus;
604
+ }
605
+
606
+ type ChatBubbleAlign = "start" | "end";
607
+ type ChatBubbleStatus = "sent" | "delivered" | "read";
608
+ interface ChatBubbleCoreProps {
609
+ align?: ChatBubbleAlign;
610
+ variant?: Variant;
611
+ /** Shows a small pointer on the bubble, on the side that points toward the avatar. Default false — a plain rounded bubble with no pointer is this component's own default look; pass true for the classic speech-bubble tail. */
612
+ hasTail?: boolean;
613
+ hasAvatar?: boolean;
614
+ hasName?: boolean;
615
+ hasTimestamp?: boolean;
616
+ status?: ChatBubbleStatus;
617
+ }
618
+ interface ChatBubbleReaction {
619
+ emoji: string;
620
+ count: number;
621
+ /** Whether the current viewer is included in this reaction's count — toggles its active styling. */
622
+ reactedByMe?: boolean;
623
+ }
624
+
625
+ type PanelGroupDirection = "horizontal" | "vertical";
626
+ interface PanelConstraints {
627
+ /** Percent (0-100) of the group's main axis. */
628
+ minSize: number;
629
+ /** Percent (0-100) of the group's main axis. */
630
+ maxSize: number;
631
+ /** Initial percent, if specified. Panels without one split the remainder evenly. */
632
+ defaultSize?: number;
633
+ }
634
+
635
+ interface SidebarCoreProps {
636
+ size?: Size;
637
+ }
638
+
639
+ interface SpeedDialCoreProps {
640
+ size?: Size;
641
+ /** Which side the actions expand toward from the trigger. Default "top" — the common bottom-corner-FAB convention. */
642
+ placement?: Placement;
643
+ align?: Alignment;
644
+ }
645
+
646
+ interface CommandItem {
647
+ id: string;
648
+ label: string;
649
+ description?: string;
650
+ /** A short label for the keyboard shortcut, shown but not wired up — the consumer's own global key listener is what actually triggers `onSelect`, this is display only (e.g. "⌘K"). */
651
+ shortcut?: string;
652
+ disabled?: boolean;
653
+ group?: string;
654
+ /** Extra terms that count toward a match without being shown (e.g. "settings" also matching an item labeled "Preferences"). */
655
+ keywords?: string[];
656
+ }
657
+ interface CommandGroup {
658
+ /** `undefined` for items with no `group` set — still a real group (rendered without a header), not dropped. */
659
+ group: string | undefined;
660
+ items: CommandItem[];
661
+ }
662
+
663
+ interface PopoverCoreProps {
664
+ placement?: Placement;
665
+ align?: Alignment;
666
+ /**
667
+ * Whether the popover behaves like a modal dialog — traps focus
668
+ * inside (Tab cycles rather than leaving), sets aria-modal, and
669
+ * is the right choice when the content is itself a small form the
670
+ * user must finish or dismiss. Default false: a non-modal popup
671
+ * that still receives real focus and closes on Escape or an
672
+ * outside click, but doesn't trap Tab — the right default for
673
+ * lighter content like a menu-adjacent info panel. This is
674
+ * exactly the axis DatePicker's calendar panel needs to be false
675
+ * on: focus must be able to move between the Input and the grid
676
+ * without Tab getting trapped inside just the calendar.
677
+ */
678
+ modal?: boolean;
679
+ }
680
+
681
+ type SkeletonVariant = "text" | "circular" | "rectangular";
682
+ type SkeletonAnimation = "pulse" | "wave" | "shine" | "glow" | "none";
683
+ interface SkeletonCoreProps {
684
+ variant?: SkeletonVariant;
685
+ animation?: SkeletonAnimation;
686
+ /**
687
+ * Category-A-specific radius override (BUILDING-COMPONENTS.md's
688
+ * Category A note: "radius as an extra override prop... display
689
+ * primitives are the case where overriding a single shape
690
+ * property without a full theme override makes sense"). Only
691
+ * meaningful for "rectangular" — "circular" always renders fully
692
+ * round and "text" uses a small fixed radius regardless, the same
693
+ * way Card's radius prop only affects Card's own corners.
694
+ */
695
+ radius?: string;
696
+ }
697
+
698
+ type PaginationItem = number | "ellipsis";
699
+ interface PaginationCoreProps {
700
+ totalPages: number;
701
+ /** How many page numbers show on each side of the current page. Default 1. */
702
+ siblingCount?: number;
703
+ /** How many page numbers are always pinned at the start and end. Default 1. */
704
+ boundaryCount?: number;
705
+ size?: Size;
706
+ disabled?: boolean;
707
+ /** Renders "first page" / "last page" jump buttons. Default false. */
708
+ showFirstLast?: boolean;
709
+ /** Renders previous/next buttons. Default true. */
710
+ showPrevNext?: boolean;
711
+ }
712
+
713
+ interface BreadcrumbCoreProps {
714
+ size?: Size;
715
+ }
716
+ type BreadcrumbSlot = number | "ellipsis";
717
+
718
+ interface FileUploadCoreProps extends FieldProps {
719
+ /** Same syntax as the native <input accept>: comma-separated extensions (".png"), MIME types ("image/png"), or MIME wildcards ("image/*"). Undefined accepts anything. */
720
+ accept?: string;
721
+ multiple?: boolean;
722
+ /** Files larger than this are rejected. Undefined means no limit. */
723
+ maxSizeBytes?: number;
724
+ }
725
+ type FileVerdict = "ok" | "type" | "size";
726
+
727
+ interface TableCoreProps {
728
+ size?: Size;
729
+ /** Alternating row background. Default false. */
730
+ striped?: boolean;
731
+ /** Borders around every cell, not just horizontal row rules. Default false. */
732
+ bordered?: boolean;
733
+ /** Keeps the header visible while the body scrolls — only has something to stick within if an ancestor bounds the table's height (e.g. a wrapping div with max-height). Default false. */
734
+ stickyHeader?: boolean;
735
+ }
736
+ type SortDirection = "asc" | "desc" | null;
737
+ /** The conventional 3-state cycle a sortable header click steps through: unsorted → asc → desc → unsorted. */
738
+ declare function getNextSortDirection(current: SortDirection): SortDirection;
739
+ type SelectAllState = "none" | "some" | "all";
740
+ /** The tri-state a "select all" header checkbox should show, computed from how many of the total rows are currently selected. */
741
+ declare function getSelectAllState(totalCount: number, selectedCount: number): SelectAllState;
742
+
743
+ /** Movement (in px) a pointer-down must travel before it commits to a drag — below this, it's treated as a click/tap instead, so interactive content inside a card's children still works. */
744
+ declare const DRAG_START_THRESHOLD_PX = 4;
745
+ interface KanbanCoreProps {
746
+ /** Tighter column padding/gaps and smaller card chrome. Default false. */
747
+ compact?: boolean;
748
+ }
749
+ interface KanbanColumnValue {
750
+ id: string;
751
+ cardIds: string[];
752
+ }
753
+ interface KanbanBoardValue {
754
+ columns: KanbanColumnValue[];
755
+ }
756
+ interface KanbanCardLocation {
757
+ columnId: string;
758
+ index: number;
759
+ }
760
+ /** Where a card currently sits, or null if it isn't in any column's cardIds — either it hasn't been added to the board value yet, or it was just removed. */
761
+ declare function findCardLocation(value: KanbanBoardValue, cardId: string): KanbanCardLocation | null;
762
+ /**
763
+ * Pure, immutable removal of a card from wherever it currently sits.
764
+ * A no-op if the card isn't found. There's no delete UI in KanbanCard
765
+ * itself — a delete affordance is card CONTENT, same as everything
766
+ * else `renderCard` returns — this is just the board-state half: call
767
+ * it, then `onChange` the result the same way a move does.
768
+ */
769
+ declare function removeCard(value: KanbanBoardValue, cardId: string): KanbanBoardValue;
770
+ interface MoveCardTarget {
771
+ cardId: string;
772
+ toColumnId: string;
773
+ /** Insertion index within the destination column's list, AFTER the card has been removed from wherever it was. Clamped to [0, length]. */
774
+ toIndex: number;
775
+ }
776
+ /**
777
+ * Pure, immutable move: removes `cardId` from wherever it currently
778
+ * sits (same column or a different one — both are just "wherever it
779
+ * sits" to this function) and inserts it at `toIndex` in
780
+ * `toColumnId`. A no-op — returns `value` unchanged — if the card or
781
+ * the destination column can't be found, so a caller doesn't need to
782
+ * guard every call site itself.
783
+ */
784
+ declare function moveCard(value: KanbanBoardValue, target: MoveCardTarget): KanbanBoardValue;
785
+ /** The column immediately before (`-1`) or after (`1`) `columnId`, or null at either end. */
786
+ declare function getAdjacentColumnId(value: KanbanBoardValue, columnId: string, direction: 1 | -1): string | null;
787
+ type KeyboardMoveDirection = "up" | "down" | "prev" | "next";
788
+ /**
789
+ * Given a picked-up card and a keyboard direction, returns the move
790
+ * it should perform — or null if that direction is a no-op from here
791
+ * (already first/last in the column, or no adjacent column that way).
792
+ * `up`/`down` reorder within the current column; `prev`/`next` move
793
+ * to the adjacent column, keeping the same relative position (clamped
794
+ * to that column's length) rather than always landing at the top or
795
+ * bottom.
796
+ */
797
+ declare function getKeyboardMoveTarget(value: KanbanBoardValue, cardId: string, direction: KeyboardMoveDirection): MoveCardTarget | null;
798
+ interface RectLike {
799
+ top: number;
800
+ bottom: number;
801
+ left: number;
802
+ right: number;
803
+ }
804
+ /**
805
+ * Given the pointer's Y position and the rects of the cards currently
806
+ * rendered in a column (top-to-bottom render order, with the card
807
+ * being dragged already excluded by the caller), returns the index a
808
+ * dropped card would land at: before the first card whose vertical
809
+ * midpoint the pointer is above, or at the end if the pointer is
810
+ * below all of them.
811
+ */
812
+ declare function computeDropIndex(pointerY: number, cardRects: RectLike[]): number;
813
+ /** Which column (by id) the pointer is currently over, given each column body's rect — or null if it's outside all of them. */
814
+ declare function computeDropColumn(pointerX: number, pointerY: number, columns: Array<RectLike & {
815
+ id: string;
816
+ }>): string | null;
817
+ interface MoveColumnTarget {
818
+ columnId: string;
819
+ toIndex: number;
820
+ }
821
+ /** Pure, immutable reorder of the columns array itself. A no-op if columnId isn't found. `toIndex` is clamped to [0, columns.length - 1]. */
822
+ declare function moveColumn(value: KanbanBoardValue, target: MoveColumnTarget): KanbanBoardValue;
823
+ /** Pure, immutable removal of a column (and every card in it). A no-op if columnId isn't found. */
824
+ declare function removeColumn(value: KanbanBoardValue, columnId: string): KanbanBoardValue;
825
+ type ColumnKeyboardMoveDirection = "prev" | "next";
826
+ /** Given a picked-up column and a keyboard direction, the move it should perform — or null at either end of the row. */
827
+ declare function getColumnKeyboardMoveTarget(value: KanbanBoardValue, columnId: string, direction: ColumnKeyboardMoveDirection): MoveColumnTarget | null;
828
+ /**
829
+ * The horizontal counterpart of computeDropIndex: given the pointer's
830
+ * X position and the rects of the columns currently in the row (left-
831
+ * to-right render order, with the column being dragged already
832
+ * excluded by the caller), returns the index it would land at.
833
+ */
834
+ declare function computeColumnDropIndex(pointerX: number, columnRects: RectLike[]): number;
835
+
836
+ type DrawerSide = "left" | "right" | "top" | "bottom";
837
+ type DrawerSize = Size | "full";
838
+ interface DrawerCoreProps {
839
+ /** Which edge the panel slides in from. Default "right". */
840
+ side?: DrawerSide;
841
+ /**
842
+ * For a left/right drawer this is the panel's width; for a
843
+ * top/bottom drawer it's the panel's height — "size" always means
844
+ * "how far the panel extends from its edge," regardless of side.
845
+ */
846
+ size?: DrawerSize;
847
+ closeOnBackdropClick?: boolean;
848
+ closeOnEscape?: boolean;
849
+ hasTitle?: boolean;
850
+ }
851
+
852
+ interface ContextMenuCoreProps {
853
+ size?: Size;
854
+ }
855
+ /** A right-click position, in viewport coordinates. */
856
+ interface MenuPoint {
857
+ x: number;
858
+ y: number;
859
+ }
860
+
861
+ interface CodeToken {
862
+ type: string;
863
+ content: string;
864
+ }
865
+ type CodeLine = CodeToken[];
866
+ /**
867
+ * The shape any tokenizer must satisfy to plug into CodeBlock via its
868
+ * `highlighter` prop — including `nuvoxHighlight` itself. A consumer
869
+ * wiring in Shiki/Prism just needs to adapt that engine's output to
870
+ * this shape once.
871
+ */
872
+ type HighlightEngine = (code: string, language: string) => CodeLine[];
873
+ /** Human-readable labels for CodeBlock's default header — overridable via the `filename` prop. */
874
+ declare const LANGUAGE_LABELS: Record<string, string>;
875
+ /**
876
+ * The built-in, zero-dependency highlighter. Unknown languages (and
877
+ * any grammar that somehow throws on malformed/adversarial input)
878
+ * degrade to a single unhighlighted "plain" token per line rather
879
+ * than surfacing an error — see this module's header for why that's
880
+ * the deliberate scope boundary here rather than expanding grammar
881
+ * coverage indefinitely.
882
+ */
883
+ declare const nuvoxHighlight: HighlightEngine;
884
+
885
+ interface CodeBlockCoreProps {
886
+ /** The source code to display. */
887
+ code: string;
888
+ /** Language name or common alias (e.g. "js", "ts", "sh"). Defaults to "plaintext" (no highlighting). */
889
+ language?: string;
890
+ /** Escape hatch — see module comment. Same signature as `nuvoxHighlight`. */
891
+ highlighter?: HighlightEngine;
892
+ withLineNumbers?: boolean;
893
+ /** 1-indexed line numbers to visually highlight. */
894
+ highlightLines?: number[];
895
+ /** Wrap long lines instead of horizontal scroll. */
896
+ wrap?: boolean;
897
+ size?: Size;
898
+ }
899
+
900
+ type RichTextMark = "bold" | "italic" | "underline" | "strike" | "code";
901
+ type RichTextBlock = "paragraph" | "h1" | "h2" | "h3" | "blockquote" | "bulletList" | "orderedList";
902
+ type RichTextCommand = RichTextMark | RichTextBlock | "link" | "unlink" | "textColor" | "clearTextColor" | "highlight" | "clearHighlight";
903
+ /**
904
+ * The interface a rendering engine must satisfy to plug into
905
+ * `<RichTextEditor engine={...}>` in place of the built-in
906
+ * contentEditable engine — the escape hatch described in the
907
+ * project's design discussion. A consumer needing full-schema
908
+ * editing can hand-write a thin adapter over Tiptap/ProseMirror
909
+ * satisfying this shape; Nuvox itself never imports either.
910
+ */
911
+ interface EditorEngine {
912
+ getHTML(): string;
913
+ setHTML(html: string): void;
914
+ exec(command: RichTextCommand, value?: string): void;
915
+ isActive(command: RichTextCommand): boolean;
916
+ canUndo(): boolean;
917
+ canRedo(): boolean;
918
+ undo(): void;
919
+ redo(): void;
920
+ }
921
+ /**
922
+ * The single dispatch point the React layer's `exec()` calls into.
923
+ * Mutates the DOM under `root` directly and leaves selection in a
924
+ * sensible place; does NOT itself read the result back out (the
925
+ * caller reads `root.innerHTML` afterward) or manage history (the
926
+ * caller decides when a checkpoint is worth recording).
927
+ */
928
+ declare function execRichTextCommand(root: HTMLElement, command: RichTextCommand, value?: string): void;
929
+ /**
930
+ * Walks the current selection's ancestor chain (bounded by `root`)
931
+ * and returns every command that's currently active — what the
932
+ * toolbar buttons should render as "pressed". Returns an empty set
933
+ * outside a browser (SSR) rather than throwing.
934
+ */
935
+ declare function getActiveCommands(root: HTMLElement): Set<RichTextCommand>;
936
+ /**
937
+ * Strips any tag/attribute not on the allow-list. Uses DOMParser — a
938
+ * web-platform API, not a React dependency; see this module's header
939
+ * for why that's still "framework-agnostic core" the same way
940
+ * core/calendar.ts's use of Intl/Date is. Never throws; returns an
941
+ * empty string if DOMParser isn't available rather than passing
942
+ * unsanitized markup through.
943
+ */
944
+ declare function sanitizeHtml(html: string): string;
945
+ interface RichTextHistory {
946
+ past: string[];
947
+ future: string[];
948
+ }
949
+ declare function createHistory(): RichTextHistory;
950
+ /** Records `previousValue` as a checkpoint to return to. Caller decides checkpoint granularity (e.g. word boundaries). */
951
+ declare function pushHistory(history: RichTextHistory, previousValue: string): RichTextHistory;
952
+ declare function undoHistory(history: RichTextHistory, currentValue: string): {
953
+ history: RichTextHistory;
954
+ value: string;
955
+ } | null;
956
+ declare function redoHistory(history: RichTextHistory, currentValue: string): {
957
+ history: RichTextHistory;
958
+ value: string;
959
+ } | null;
960
+ interface RichTextEditorCoreProps {
961
+ disabled?: boolean;
962
+ readOnly?: boolean;
963
+ placeholder?: string;
964
+ size?: Size;
965
+ }
966
+
967
+ type ImageFit = "cover" | "contain" | "fill" | "none" | "scale-down";
968
+ interface ImageCoreProps {
969
+ fit?: ImageFit;
970
+ /** Raw CSS aspect-ratio value, e.g. "16/9", "1/1", "4/3". No aspect-ratio lock when omitted — the image sizes naturally. */
971
+ aspectRatio?: string;
972
+ /** Raw CSS radius override, same shape as Card/Skeleton's `radius` prop (a CSS value, not an enum). */
973
+ radius?: string;
974
+ }
975
+
976
+ interface LightboxCoreProps {
977
+ /** Wrap past the last image back to the first (and vice versa) with prev/next. Default true — unlike Carousel, a lightbox is normally an unbounded browse, not a bounded set of slides. */
978
+ loop?: boolean;
979
+ }
980
+
981
+ type GalleryLayout = "grid" | "masonry" | "justified";
982
+ interface GalleryCoreProps {
983
+ layout?: GalleryLayout;
984
+ /** Column count for "grid" and "masonry". Default 3. Ignored by "justified", which fills rows by width instead. */
985
+ columns?: number;
986
+ /** CSS gap value between items. Default undefined (falls back to the CSS file's own token default). */
987
+ gap?: string;
988
+ /** Target row height in px for "justified". Default 220. */
989
+ targetRowHeight?: number;
990
+ }
991
+ /** An item with no known dimensions is treated as a 1:1 square — a reasonable default that keeps the row-packing math well-defined rather than throwing on missing data. */
992
+ declare function aspectRatioFromDims(width?: number, height?: number): number;
993
+ interface JustifiedRow {
994
+ /** Indices into the original items array, in order. */
995
+ indices: number[];
996
+ /** Shared row height in px, after scaling to fill the container width. */
997
+ height: number;
998
+ /** Each item's rendered width in px, same order/length as `indices`. */
999
+ widths: number[];
1000
+ }
1001
+ /**
1002
+ * Classic row-packing: accumulate items into a row at `targetRowHeight`
1003
+ * until the row's natural width (plus gaps) reaches the container
1004
+ * width, then scale the whole row (height and every item's width) by
1005
+ * the ratio needed to make it land exactly on `containerWidth`. The
1006
+ * last row is left at `targetRowHeight`, unscaled, unless it would
1007
+ * need to be scaled DOWN (i.e. it already overflows) — a short final
1008
+ * row of 1-2 images stretched to fill the full width looks broken,
1009
+ * which is the standard justified-gallery convention (Flickr does
1010
+ * the same).
1011
+ */
1012
+ declare function computeJustifiedRows(aspectRatios: number[], containerWidth: number, targetRowHeight: number, gap: number): JustifiedRow[];
1013
+
1014
+ declare const PLAYBACK_RATES: readonly [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
1015
+ type PlaybackRate = (typeof PLAYBACK_RATES)[number];
1016
+ /** mm:ss, or h:mm:ss once the duration crosses an hour. NaN/Infinity/negative all render as "0:00" rather than "NaN:NaN" — happens routinely before metadata has loaded. */
1017
+ declare function formatMediaTime(seconds: number): string;
1018
+ /** Seconds each seek-back/seek-forward button press moves by, when the consumer doesn't say otherwise. */
1019
+ declare const SKIP_SECONDS = 10;
1020
+ /**
1021
+ * The skip amounts that have a dedicated, number-bearing seek icon
1022
+ * (`seek-minus-ten`, `seek-plus-thirty`, ...). Any other amount is
1023
+ * still perfectly valid — it just falls back to the unnumbered
1024
+ * `seek-minus`/`seek-plus` pair, so `skipSeconds={7}` never renders a
1025
+ * button whose icon claims "10".
1026
+ */
1027
+ declare const LABELED_SKIP_SECONDS: readonly [5, 10, 15, 30];
1028
+ type LabeledSkipSeconds = (typeof LABELED_SKIP_SECONDS)[number];
1029
+ /** Whether `seconds` is one of the amounts with a numbered seek icon — the icon lookup in the React layer is a `hasLabeledSkipIcon` check plus a map, so the "which icon" decision stays testable here rather than living only inside JSX. */
1030
+ declare function hasLabeledSkipIcon(seconds: number): seconds is LabeledSkipSeconds;
1031
+ /** A skip amount is always a positive, finite number of seconds; anything else (0, negative, NaN, Infinity) would render a button that visibly does nothing, so it falls back to the default rather than being honored. Direction comes from which button was pressed, never from the sign of this prop. */
1032
+ declare function resolveSkipSeconds(skipSeconds?: number): number;
1033
+ interface MediaTransportProps {
1034
+ /** Seconds each seek-back/seek-forward press moves by. Default 10. Positive number; direction comes from the button, not the sign. */
1035
+ skipSeconds?: number;
1036
+ /** Called when the next-track button is pressed. Omit and no next-track button is rendered at all. */
1037
+ onNext?: () => void;
1038
+ /** Called when the previous-track button is pressed. Omit and no previous-track button is rendered at all. */
1039
+ onPrevious?: () => void;
1040
+ /** Whether a next track exists. Default true. False keeps the button in place but disables it. */
1041
+ hasNext?: boolean;
1042
+ /** Whether a previous track exists. Default true. False keeps the button in place but disables it. */
1043
+ hasPrevious?: boolean;
1044
+ }
1045
+ interface MediaTransportState {
1046
+ skipSeconds: number;
1047
+ showNext: boolean;
1048
+ showPrevious: boolean;
1049
+ nextDisabled: boolean;
1050
+ previousDisabled: boolean;
1051
+ }
1052
+ declare function resolveMediaTransport(props: MediaTransportProps): MediaTransportState;
1053
+ type MediaKeyAction = "toggle-play" | "seek-back" | "seek-forward" | "volume-up" | "volume-down";
1054
+ /** Maps a KeyboardEvent.key to the player-wide action it triggers, or null for a key this layer doesn't own. "Spacebar" is IE11/old-Edge's name for the same key " " reports everywhere else. */
1055
+ declare function getMediaKeyAction(key: string): MediaKeyAction | null;
1056
+
1057
+ interface VideoPlayerCoreProps extends MediaTransportProps {
1058
+ /** Show the built-in control bar over the video. Default true — set false to render a bare, unstyled <video> (e.g. to build fully custom controls against the forwarded ref). */
1059
+ controls?: boolean;
1060
+ /** Rates offered in the playback-speed menu. Default [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]. */
1061
+ playbackRates?: readonly number[];
1062
+ }
1063
+
1064
+ interface AudioPlayerCoreProps extends MediaTransportProps {
1065
+ /** Rates offered in the playback-speed menu. Default [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]. */
1066
+ playbackRates?: readonly number[];
1067
+ }
1068
+
1069
+ interface PdfViewerCoreProps {
1070
+ /** Page to open on first render. Default 1. */
1071
+ initialPage?: number;
1072
+ /** Zoom level to open at, where 1 = 100%. Left unset, the viewer opens fit-to-width instead of a fixed percentage — see initialScale on PdfViewerState. */
1073
+ initialScale?: number;
1074
+ minScale?: number;
1075
+ maxScale?: number;
1076
+ /** How much each zoom-in/out step changes the scale. Default 0.25. */
1077
+ scaleStep?: number;
1078
+ }
1079
+ /**
1080
+ * "auto" means fit-to-width (the PDF open-parameters spec's own
1081
+ * `zoom=page-width`) rather than a fixed percentage — it's the
1082
+ * default so a page opens fully visible instead of at a literal 100%
1083
+ * that's wider than the viewer and gets clipped, forcing a manual
1084
+ * zoom-out just to see the page. It only ever applies before the
1085
+ * first zoom interaction: clicking zoom in/out always resolves to a
1086
+ * concrete percentage from there (see zoomIn/zoomOut below), since
1087
+ * "step in/out from fit-to-width" isn't a well-defined percentage.
1088
+ */
1089
+ type PdfZoom = number | "auto";
1090
+ declare function formatZoomPercent(scale: PdfZoom): string;
1091
+
1092
+ export { LANGUAGE_LABELS as $, type AccentDefinition as A, type BadgeVariant as B, type CalendarDay as C, type DropdownItemVariant as D, DEFAULT_PRESETS as E, DRAG_START_THRESHOLD_PX as F, type DatePickerCoreProps as G, type DividerOrientation as H, type DrawerSide as I, type DrawerSize as J, type EditorEngine as K, type FieldProps as L, type FieldState as M, type FileVerdict as N, type GalleryCoreProps as O, type GalleryLayout as P, type HighlightEngine as Q, type ImageCoreProps as R, type ImageFit as S, type ThemeTokens as T, type JustifiedRow as U, type KanbanBoardValue as V, type KanbanCardLocation as W, type KanbanColumnValue as X, type KanbanCoreProps as Y, type KeyboardMoveDirection as Z, LABELED_SKIP_SECONDS as _, type AccordionType as a, type ToastVariant as a$, type LabeledSkipSeconds as a0, type LightboxCoreProps as a1, type MediaKeyAction as a2, type MediaTransportProps as a3, type MediaTransportState as a4, type MenuPoint as a5, type ModalSize as a6, type MoveCardTarget as a7, type MoveColumnTarget as a8, type OTPInputCoreProps as a9, type SemanticColor as aA, type SidebarCoreProps as aB, type Size as aC, type SkeletonAnimation as aD, type SkeletonVariant as aE, type SliderValue as aF, type SortDirection as aG, type SpeedDialCoreProps as aH, type SpinnerVariant as aI, type StarFill as aJ, type StepStatus as aK, type StepWizardOrientation as aL, type StepWizardStepDef as aM, type StepWizardVariant as aN, TOKEN_CATEGORIES as aO, type TableCoreProps as aP, type TabsActivationMode as aQ, type TabsOrientation as aR, type TabsVariant as aS, type TimePickerCoreProps as aT, type TimeValue as aU, type TimelineAlign as aV, type TimelineCoreProps as aW, type TimelineItemCoreProps as aX, type TimelineOrientation as aY, type TimelineStatus as aZ, type ToastPosition as a_, type OTPInputType as aa, PLAYBACK_RATES as ab, type PaginationItem as ac, type PanelConstraints as ad, type PanelGroupDirection as ae, type PdfViewerCoreProps as af, type PhoneCountry as ag, type PhoneInputCoreProps as ah, type Placement as ai, type PlaybackRate as aj, type PopoverCoreProps as ak, type ProgressVariant as al, REQUIRED_TOKEN_PATHS as am, type RatingCoreProps as an, type RectLike as ao, type RichTextBlock as ap, type RichTextCommand as aq, type RichTextEditorCoreProps as ar, type RichTextHistory as as, type RichTextMark as at, SKIP_SECONDS as au, type ScrollAreaOrientation as av, type ScrollbarVisibility as aw, type SearchSuggestion as ax, type SelectAllState as ay, type SelectOptionItem as az, type AlertVariant as b, type Variant as b0, type VideoPlayerCoreProps as b1, type WeekStart as b2, aspectRatioFromDims as b3, computeColumnDropIndex as b4, computeDropColumn as b5, computeDropIndex as b6, computeJustifiedRows as b7, createHistory as b8, defineTheme as b9, undoHistory as bA, type BadgeCoreProps as bB, type AvatarCoreProps as bC, type SpinnerCoreProps as bD, type DividerCoreProps as bE, type CardCoreProps as bF, type ScrollAreaCoreProps as bG, type AlertCoreProps as bH, type ModalCoreProps as bI, type ProgressCoreProps as bJ, type TabsCoreProps as bK, type AccordionCoreProps as bL, type DropdownCoreProps as bM, type SelectCoreProps as bN, type StepWizardCoreProps as bO, type SliderCoreProps as bP, type ComboboxCoreProps as bQ, type SearchBarCoreProps as bR, type TimePanelMode as bS, type ChatBubbleReaction as bT, type FileUploadCoreProps as bU, type PaginationCoreProps as bV, type BreadcrumbCoreProps as bW, type SkeletonCoreProps as bX, type DrawerCoreProps as bY, type ContextMenuCoreProps as bZ, DEFAULT_ACCENT as b_, execRichTextCommand as ba, findCardLocation as bb, findMissingTokenPaths as bc, formatMediaTime as bd, formatZoomPercent as be, getAccent as bf, getActiveCommands as bg, getAdjacentColumnId as bh, getColumnKeyboardMoveTarget as bi, getKeyboardMoveTarget as bj, getMediaKeyAction as bk, getNextSortDirection as bl, getSelectAllState as bm, hasLabeledSkipIcon as bn, listAccents as bo, moveCard as bp, moveColumn as bq, nuvoxHighlight as br, pushHistory as bs, redoHistory as bt, registerAccent as bu, removeCard as bv, removeColumn as bw, resolveMediaTransport as bx, resolveSkipSeconds as by, sanitizeHtml as bz, type Alignment as c, type AudioPlayerCoreProps as d, type AvatarShape as e, type AvatarSize as f, type AvatarStatus as g, type BaseComponentProps as h, type BreadcrumbSlot as i, type CardLayout as j, type CardPadding as k, type CardVariant as l, type CarouselCoreProps as m, type CarouselOrientation as n, type ChatBubbleAlign as o, type ChatBubbleCoreProps as p, type ChatBubbleStatus as q, type CodeBlockCoreProps as r, type CodeLine as s, type CodeToken as t, type ColorPickerCoreProps as u, type ColorScale as v, type ColumnKeyboardMoveDirection as w, type ComboboxOption as x, type CommandGroup as y, type CommandItem as z };