@asymmetric-effort/specifyjs 0.0.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/dist/specifyjs-client.cjs.js +2 -0
  3. package/dist/specifyjs-client.cjs.js.map +1 -0
  4. package/dist/specifyjs-client.d.ts +159 -0
  5. package/dist/specifyjs-client.esm.js +2 -0
  6. package/dist/specifyjs-client.esm.js.map +1 -0
  7. package/dist/specifyjs-components.cjs.js +2 -0
  8. package/dist/specifyjs-components.cjs.js.map +1 -0
  9. package/dist/specifyjs-components.d.ts +2094 -0
  10. package/dist/specifyjs-components.esm.js +2 -0
  11. package/dist/specifyjs-components.esm.js.map +1 -0
  12. package/dist/specifyjs-dom.cjs.js +2 -0
  13. package/dist/specifyjs-dom.cjs.js.map +1 -0
  14. package/dist/specifyjs-dom.d.ts +103 -0
  15. package/dist/specifyjs-dom.esm.js +2 -0
  16. package/dist/specifyjs-dom.esm.js.map +1 -0
  17. package/dist/specifyjs-jsx-dev-runtime.cjs.js +2 -0
  18. package/dist/specifyjs-jsx-dev-runtime.cjs.js.map +1 -0
  19. package/dist/specifyjs-jsx-dev-runtime.esm.js +2 -0
  20. package/dist/specifyjs-jsx-dev-runtime.esm.js.map +1 -0
  21. package/dist/specifyjs-jsx-runtime.cjs.js +2 -0
  22. package/dist/specifyjs-jsx-runtime.cjs.js.map +1 -0
  23. package/dist/specifyjs-jsx-runtime.esm.js +2 -0
  24. package/dist/specifyjs-jsx-runtime.esm.js.map +1 -0
  25. package/dist/specifyjs-server.cjs.js +2 -0
  26. package/dist/specifyjs-server.cjs.js.map +1 -0
  27. package/dist/specifyjs-server.d.ts +132 -0
  28. package/dist/specifyjs-server.esm.js +2 -0
  29. package/dist/specifyjs-server.esm.js.map +1 -0
  30. package/dist/specifyjs-telemetry.cjs.js +2 -0
  31. package/dist/specifyjs-telemetry.cjs.js.map +1 -0
  32. package/dist/specifyjs-telemetry.d.ts +165 -0
  33. package/dist/specifyjs-telemetry.esm.js +2 -0
  34. package/dist/specifyjs-telemetry.esm.js.map +1 -0
  35. package/dist/specifyjs.cjs.js +2 -0
  36. package/dist/specifyjs.cjs.js.map +1 -0
  37. package/dist/specifyjs.d.ts +577 -0
  38. package/dist/specifyjs.esm.js +2 -0
  39. package/dist/specifyjs.esm.js.map +1 -0
  40. package/package.json +113 -0
@@ -0,0 +1,2094 @@
1
+ import * as specifyjs_shared_types from 'specifyjs/shared/types';
2
+
3
+ interface AnalogClockProps {
4
+ /** Display format: '12h' or '24h' — in 24h, show 0-23 hour numbers */
5
+ format?: '12h' | '24h';
6
+ /** Clock face size in pixels */
7
+ size?: number;
8
+ /** Show date below the clock */
9
+ showDate?: boolean;
10
+ /** Date format: 'short' (MM/DD/YYYY), 'long' (Month DD, YYYY), 'iso' (YYYY-MM-DD) */
11
+ dateFormat?: 'short' | 'long' | 'iso';
12
+ /** Show second hand */
13
+ showSeconds?: boolean;
14
+ /** Custom timezone */
15
+ timezone?: string;
16
+ /** CSS className */
17
+ className?: string;
18
+ }
19
+ declare function AnalogClock(props: AnalogClockProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
20
+
21
+ interface AvatarProps {
22
+ /** Image source URL */
23
+ src?: string;
24
+ /** Alt text for image */
25
+ alt?: string;
26
+ /** User's name (used to generate initials fallback) */
27
+ name?: string;
28
+ /** Size preset or pixel number */
29
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;
30
+ /** Shape of the avatar */
31
+ shape?: 'circle' | 'square';
32
+ /** Background color for initials/fallback */
33
+ fallbackColor?: string;
34
+ /** Online status indicator */
35
+ status?: 'online' | 'offline' | 'busy' | 'away';
36
+ /** Position of the status dot */
37
+ statusPosition?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
38
+ }
39
+ declare function Avatar(props: AvatarProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
40
+
41
+ interface BadgeProps {
42
+ /** Numeric count to display */
43
+ count?: number;
44
+ /** Maximum count before showing "N+" */
45
+ max?: number;
46
+ /** Show a dot instead of a count */
47
+ dot?: boolean;
48
+ /** Badge color */
49
+ color?: string;
50
+ /** Size preset */
51
+ size?: 'sm' | 'md' | 'lg';
52
+ /** Visual variant */
53
+ variant?: 'solid' | 'outline';
54
+ /** Child element to overlay the badge on */
55
+ children?: unknown;
56
+ }
57
+ declare function Badge(props: BadgeProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
58
+
59
+ interface DataGridColumn {
60
+ /** Property key in the row data */
61
+ key: string;
62
+ /** Display header text */
63
+ header: string;
64
+ /** Column width (CSS value) */
65
+ width?: string;
66
+ /** Whether this column is sortable */
67
+ sortable?: boolean;
68
+ /** Whether this column shows a filter input */
69
+ filterable?: boolean;
70
+ /** Custom cell renderer */
71
+ render?: (value: unknown, row: Record<string, unknown>) => unknown;
72
+ }
73
+ interface DataGridProps {
74
+ /** Column definitions */
75
+ columns: DataGridColumn[];
76
+ /** Row data */
77
+ data: Record<string, unknown>[];
78
+ /** Rows per page (enables pagination when set) */
79
+ pageSize?: number;
80
+ /** Current page index (0-based) */
81
+ currentPage?: number;
82
+ /** Page change handler */
83
+ onPageChange?: (page: number) => void;
84
+ /** Current sort column key */
85
+ sortBy?: string;
86
+ /** Sort direction */
87
+ sortDir?: 'asc' | 'desc';
88
+ /** Sort change handler */
89
+ onSort?: (columnKey: string, direction: 'asc' | 'desc') => void;
90
+ /** Enable row selection checkboxes */
91
+ selectable?: boolean;
92
+ /** Currently selected row indices */
93
+ selectedRows?: number[];
94
+ /** Selection change handler */
95
+ onSelectionChange?: (selectedIndices: number[]) => void;
96
+ /** Alternate row background colors */
97
+ striped?: boolean;
98
+ /** Show cell borders */
99
+ bordered?: boolean;
100
+ /** Compact row height */
101
+ compact?: boolean;
102
+ /** Sticky header on scroll */
103
+ stickyHeader?: boolean;
104
+ }
105
+ declare function DataGrid(props: DataGridProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
106
+
107
+ interface DigitalClockProps {
108
+ /** Display format: '12h' for AM/PM or '24h' for 24-hour */
109
+ format?: '12h' | '24h';
110
+ /** Show date display */
111
+ showDate?: boolean;
112
+ /** Date format: 'short' (MM/DD/YYYY), 'long' (Month DD, YYYY), 'iso' (YYYY-MM-DD) */
113
+ dateFormat?: 'short' | 'long' | 'iso';
114
+ /** Show seconds */
115
+ showSeconds?: boolean;
116
+ /** Custom timezone (e.g., 'America/New_York') */
117
+ timezone?: string;
118
+ /** CSS className */
119
+ className?: string;
120
+ }
121
+ declare function DigitalClock(props: DigitalClockProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
122
+
123
+ interface ListViewProps {
124
+ /** Array of items to render */
125
+ items: unknown[];
126
+ /** Render function for each item */
127
+ renderItem: (item: unknown, index: number) => unknown;
128
+ /** Unique key extractor per item */
129
+ keyExtractor: (item: unknown, index: number) => string;
130
+ /** Show divider between items */
131
+ divider?: boolean;
132
+ /** Highlight items on hover */
133
+ hoverable?: boolean;
134
+ /** Currently selected item index */
135
+ selectedIndex?: number;
136
+ /** Selection handler */
137
+ onSelect?: (index: number) => void;
138
+ /** Message shown when items is empty */
139
+ emptyMessage?: string;
140
+ /** Optional header element */
141
+ header?: unknown;
142
+ /** Optional footer element */
143
+ footer?: unknown;
144
+ }
145
+ declare function ListView(props: ListViewProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
146
+
147
+ interface TagProps {
148
+ /** Tag label text */
149
+ label: string;
150
+ /** Color theme (CSS color or named color) */
151
+ color?: string;
152
+ /** Visual variant */
153
+ variant?: 'solid' | 'outline' | 'subtle';
154
+ /** Size preset */
155
+ size?: 'sm' | 'md' | 'lg';
156
+ /** Show remove/close button */
157
+ removable?: boolean;
158
+ /** Remove button handler */
159
+ onRemove?: () => void;
160
+ /** Leading icon element */
161
+ icon?: unknown;
162
+ /** Click handler (makes tag interactive) */
163
+ onClick?: () => void;
164
+ /** Disabled state */
165
+ disabled?: boolean;
166
+ }
167
+ declare function Tag(props: TagProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
168
+
169
+ interface VirtualScrollProps {
170
+ /** Full array of items */
171
+ items: unknown[];
172
+ /** Render function for a single item */
173
+ renderItem: (item: unknown, index: number) => unknown;
174
+ /** Fixed height of each item in pixels */
175
+ itemHeight: number;
176
+ /** Extra items rendered above/below the viewport */
177
+ overscan?: number;
178
+ /** Container height (CSS value, e.g. '400px' or '100%') */
179
+ height: string;
180
+ }
181
+ declare function VirtualScroll(props: VirtualScrollProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
182
+
183
+ interface AlertAction {
184
+ label: string;
185
+ onClick: () => void;
186
+ }
187
+ interface AlertProps {
188
+ /** Alert severity type */
189
+ type?: 'info' | 'success' | 'warning' | 'error';
190
+ /** Alert title */
191
+ title?: string;
192
+ /** Alert message (children) */
193
+ message?: unknown;
194
+ /** Children alias for message */
195
+ children?: unknown;
196
+ /** Show close button */
197
+ closable?: boolean;
198
+ /** Close callback */
199
+ onClose?: () => void;
200
+ /** Custom icon text/emoji; auto-selected by type if omitted */
201
+ icon?: string;
202
+ /** Style variant */
203
+ variant?: 'filled' | 'outline' | 'subtle';
204
+ /** Optional action button */
205
+ action?: AlertAction;
206
+ }
207
+ declare function Alert(props: AlertProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props> | null;
208
+
209
+ interface EmptyStateAction {
210
+ label: string;
211
+ onClick: () => void;
212
+ }
213
+ interface EmptyStateProps {
214
+ /** Large icon or emoji displayed at the top */
215
+ icon?: string;
216
+ /** Title text */
217
+ title?: string;
218
+ /** Description text */
219
+ description?: string;
220
+ /** Call-to-action button */
221
+ action?: EmptyStateAction;
222
+ /** Image URL displayed instead of / above the icon */
223
+ image?: string;
224
+ }
225
+ declare function EmptyState(props: EmptyStateProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
226
+
227
+ interface ProgressBarProps {
228
+ /** Current progress value (0-100) */
229
+ value?: number;
230
+ /** Maximum value (default: 100) */
231
+ max?: number;
232
+ /** Fill color */
233
+ color?: string;
234
+ /** Track background color */
235
+ backgroundColor?: string;
236
+ /** Bar height (CSS value) */
237
+ height?: string;
238
+ /** Show percentage label */
239
+ showLabel?: boolean;
240
+ /** Enable shimmer animation on the filled portion */
241
+ animated?: boolean;
242
+ /** Display variant */
243
+ variant?: 'bar' | 'circular';
244
+ /** Size for circular variant or bar height shorthand */
245
+ size?: number | string;
246
+ /** Indeterminate mode -- animated without a specific value */
247
+ indeterminate?: boolean;
248
+ }
249
+ declare function ProgressBar(props: ProgressBarProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
250
+
251
+ interface SkeletonProps {
252
+ /** Shape variant */
253
+ variant?: 'text' | 'circular' | 'rectangular';
254
+ /** Width (CSS value) */
255
+ width?: string | number;
256
+ /** Height (CSS value) */
257
+ height?: string | number;
258
+ /** Number of text lines to render (text variant only) */
259
+ lines?: number;
260
+ /** Enable shimmer animation (default: true) */
261
+ animated?: boolean;
262
+ /** Border radius (CSS value) */
263
+ borderRadius?: string;
264
+ }
265
+ declare function Skeleton(props: SkeletonProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
266
+
267
+ interface SpinnerProps {
268
+ /** Spinner size: preset name or pixel number */
269
+ size?: 'sm' | 'md' | 'lg' | number;
270
+ /** Spinner color */
271
+ color?: string;
272
+ /** Stroke thickness in pixels */
273
+ thickness?: number;
274
+ /** Animation speed */
275
+ speed?: 'slow' | 'normal' | 'fast';
276
+ /** Accessible label for screen readers */
277
+ label?: string;
278
+ }
279
+ declare function Spinner(props: SpinnerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
280
+
281
+ interface CheckboxProps {
282
+ /** Whether checkbox is checked */
283
+ checked: boolean;
284
+ /** Change handler */
285
+ onChange: (checked: boolean) => void;
286
+ /** Label text */
287
+ label?: string;
288
+ /** Indeterminate state (overrides checkmark display) */
289
+ indeterminate?: boolean;
290
+ /** Disabled state */
291
+ disabled?: boolean;
292
+ /** Error message */
293
+ error?: string;
294
+ /** Size variant */
295
+ size?: 'sm' | 'md' | 'lg';
296
+ }
297
+ declare function Checkbox(props: CheckboxProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
298
+
299
+ interface ColorPickerProps {
300
+ /** Current color value as hex string (e.g. '#ff0000') */
301
+ value: string;
302
+ /** Change handler, receives hex string */
303
+ onChange: (value: string) => void;
304
+ /** Preset color swatches */
305
+ presets?: string[];
306
+ /** Show hex text input */
307
+ showInput?: boolean;
308
+ /** Show alpha/opacity slider (future: reserved) */
309
+ showAlpha?: boolean;
310
+ /** Disabled state */
311
+ disabled?: boolean;
312
+ /** Label text */
313
+ label?: string;
314
+ }
315
+ declare function ColorPicker(props: ColorPickerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
316
+
317
+ interface ColorWheelProps {
318
+ /** Current color value (hex string) */
319
+ value?: string;
320
+ /** Called when color changes */
321
+ onChange?: (color: string) => void;
322
+ /** Swatch size in pixels (default: 32) */
323
+ size?: number;
324
+ /** Whether to show hex label below swatch (default: true) */
325
+ showLabel?: boolean;
326
+ /** Disabled state */
327
+ disabled?: boolean;
328
+ /** Label text */
329
+ label?: string;
330
+ }
331
+ declare function ColorWheel(props: ColorWheelProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
332
+
333
+ interface DatePickerProps {
334
+ /** Current value (Date object or 'YYYY-MM-DD' string) */
335
+ value: Date | string | null;
336
+ /** Change handler, receives ISO date string */
337
+ onChange: (value: string) => void;
338
+ /** Display format (default 'YYYY-MM-DD') */
339
+ format?: string;
340
+ /** Earliest selectable date */
341
+ minDate?: Date | string;
342
+ /** Latest selectable date */
343
+ maxDate?: Date | string;
344
+ /** Disabled state */
345
+ disabled?: boolean;
346
+ /** Placeholder text */
347
+ placeholder?: string;
348
+ /** Label text */
349
+ label?: string;
350
+ /** Error message */
351
+ error?: string;
352
+ }
353
+ declare function DatePicker(props: DatePickerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
354
+
355
+ interface FileUploadProps {
356
+ /** Change handler, receives array of selected files */
357
+ onChange: (files: File[]) => void;
358
+ /** Accepted file types (e.g. 'image/*,.pdf') */
359
+ accept?: string;
360
+ /** Allow multiple file selection */
361
+ multiple?: boolean;
362
+ /** Maximum file size in bytes */
363
+ maxSize?: number;
364
+ /** Disabled state */
365
+ disabled?: boolean;
366
+ /** Label text */
367
+ label?: string;
368
+ /** Help text */
369
+ helpText?: string;
370
+ }
371
+ declare function FileUpload(props: FileUploadProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
372
+
373
+ interface FormFieldWrapperStyle {
374
+ /** Container font family */
375
+ fontFamily?: string;
376
+ /** Container font size (default: '14px') */
377
+ fontSize?: string;
378
+ /** Label color (default: '#374151') */
379
+ labelColor?: string;
380
+ /** Label font weight (default: '500') */
381
+ labelFontWeight?: string;
382
+ /** Label font size (default: '14px') */
383
+ labelFontSize?: string;
384
+ /** Help text color (default: '#6b7280') */
385
+ helpColor?: string;
386
+ /** Error text color (default: '#ef4444') */
387
+ errorColor?: string;
388
+ /** Error border color applied to child (default: '#ef4444') */
389
+ errorBorderColor?: string;
390
+ /** Focus border color hint (default: '#3b82f6') */
391
+ focusBorderColor?: string;
392
+ /** Gap between label/field/help (default: '4px') */
393
+ gap?: string;
394
+ /** Width (default: '100%') */
395
+ width?: string | number;
396
+ /** Custom overrides */
397
+ custom?: Record<string, string>;
398
+ }
399
+ interface FormFieldWrapperProps {
400
+ /** Label text */
401
+ label?: string;
402
+ /** HTML id to link label to input via htmlFor */
403
+ htmlFor?: string;
404
+ /** Help / description text shown below the field */
405
+ helpText?: string;
406
+ /** Error message — when set, field enters error state */
407
+ error?: string;
408
+ /** Show required asterisk (default: false) */
409
+ required?: boolean;
410
+ /** Disabled state (default: false) */
411
+ disabled?: boolean;
412
+ /** Styling */
413
+ styling?: FormFieldWrapperStyle;
414
+ /** Extra class */
415
+ className?: string;
416
+ /** The form control (children) */
417
+ children?: unknown;
418
+ }
419
+ declare function FormFieldWrapper(props: FormFieldWrapperProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
420
+ /**
421
+ * Shared input styling builder used by textfield, multiline, texteditor.
422
+ */
423
+ interface InputBaseStyle {
424
+ padding?: string;
425
+ border?: string;
426
+ borderRadius?: string;
427
+ fontSize?: string;
428
+ fontFamily?: string;
429
+ backgroundColor?: string;
430
+ color?: string;
431
+ focusBorderColor?: string;
432
+ errorBorderColor?: string;
433
+ transition?: string;
434
+ custom?: Record<string, string>;
435
+ }
436
+ declare function buildInputStyle(s: InputBaseStyle, state: {
437
+ focused: boolean;
438
+ error: boolean;
439
+ }): Record<string, string>;
440
+
441
+ interface MultilineFieldProps {
442
+ /** Current value (controlled) */
443
+ value?: string;
444
+ /** Default value (uncontrolled) */
445
+ defaultValue?: string;
446
+ /** Change handler */
447
+ onChange?: (value: string) => void;
448
+ /** Blur handler */
449
+ onBlur?: (value: string) => void;
450
+ /** Placeholder */
451
+ placeholder?: string;
452
+ /** HTML name */
453
+ name?: string;
454
+ /** HTML id */
455
+ id?: string;
456
+ /** Number of visible rows (default: 4) */
457
+ rows?: number;
458
+ /** Max length */
459
+ maxLength?: number;
460
+ /** Auto-resize to fit content (default: false) */
461
+ autoResize?: boolean;
462
+ /** Min height when auto-resizing */
463
+ minHeight?: string;
464
+ /** Max height when auto-resizing */
465
+ maxHeight?: string;
466
+ /** Read-only */
467
+ readOnly?: boolean;
468
+ /** Disabled */
469
+ disabled?: boolean;
470
+ /** Show character count (default: false) */
471
+ showCount?: boolean;
472
+ label?: string;
473
+ helpText?: string;
474
+ error?: string;
475
+ required?: boolean;
476
+ wrapperStyle?: FormFieldWrapperStyle;
477
+ inputStyle?: InputBaseStyle;
478
+ className?: string;
479
+ }
480
+ declare function MultilineField(props: MultilineFieldProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
481
+
482
+ interface NumberSpinnerProps {
483
+ /** Current numeric value */
484
+ value: number;
485
+ /** Change handler */
486
+ onChange: (value: number) => void;
487
+ /** Minimum allowed value */
488
+ min?: number;
489
+ /** Maximum allowed value */
490
+ max?: number;
491
+ /** Step increment */
492
+ step?: number;
493
+ /** Disabled state */
494
+ disabled?: boolean;
495
+ /** Prefix text (e.g. '$') */
496
+ prefix?: string;
497
+ /** Suffix text (e.g. 'kg') */
498
+ suffix?: string;
499
+ /** Label text */
500
+ label?: string;
501
+ /** Error message */
502
+ error?: string;
503
+ }
504
+ declare function NumberSpinner(props: NumberSpinnerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
505
+
506
+ interface RadioOption {
507
+ value: string;
508
+ label: string;
509
+ disabled?: boolean;
510
+ }
511
+ interface RadioGroupProps {
512
+ /** Available options */
513
+ options: RadioOption[];
514
+ /** Currently selected value */
515
+ value: string;
516
+ /** Change handler */
517
+ onChange: (value: string) => void;
518
+ /** Name attribute for the radio group */
519
+ name: string;
520
+ /** Layout direction */
521
+ direction?: 'horizontal' | 'vertical';
522
+ /** Disabled state for entire group */
523
+ disabled?: boolean;
524
+ /** Error message */
525
+ error?: string;
526
+ /** Label for the group */
527
+ label?: string;
528
+ }
529
+ declare function RadioGroup(props: RadioGroupProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
530
+
531
+ interface SelectOption {
532
+ value: string;
533
+ label: string;
534
+ disabled?: boolean;
535
+ group?: string;
536
+ }
537
+ interface SelectProps {
538
+ /** Available options */
539
+ options: SelectOption[];
540
+ /** Current selected value (string for single, string[] for multiple) */
541
+ value: string | string[];
542
+ /** Change handler */
543
+ onChange: (value: string | string[]) => void;
544
+ /** Placeholder text */
545
+ placeholder?: string;
546
+ /** Enable search/filter by typing */
547
+ searchable?: boolean;
548
+ /** Allow multiple selection */
549
+ multiple?: boolean;
550
+ /** Show clear button */
551
+ clearable?: boolean;
552
+ /** Disabled state */
553
+ disabled?: boolean;
554
+ /** Error message */
555
+ error?: string;
556
+ /** Label text */
557
+ label?: string;
558
+ /** Help text */
559
+ helpText?: string;
560
+ }
561
+ declare function Select(props: SelectProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
562
+
563
+ interface SliderMark {
564
+ value: number;
565
+ label: string;
566
+ }
567
+ interface SliderProps {
568
+ /** Current value (number for single, [number, number] for range) */
569
+ value: number | [number, number];
570
+ /** Change handler */
571
+ onChange: (value: number | [number, number]) => void;
572
+ /** Minimum value */
573
+ min?: number;
574
+ /** Maximum value */
575
+ max?: number;
576
+ /** Step increment */
577
+ step?: number;
578
+ /** Show current value label above thumb */
579
+ showValue?: boolean;
580
+ /** Show tick marks at each step */
581
+ showTicks?: boolean;
582
+ /** Disabled state */
583
+ disabled?: boolean;
584
+ /** Named marks along the track */
585
+ marks?: SliderMark[];
586
+ /** Enable range mode (dual handles) */
587
+ range?: boolean;
588
+ /** Label text */
589
+ label?: string;
590
+ /** Error message */
591
+ error?: string;
592
+ }
593
+ declare function Slider(props: SliderProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
594
+
595
+ interface TextEditorProps {
596
+ /** Initial HTML content */
597
+ value?: string;
598
+ /** Change handler — receives HTML string */
599
+ onChange?: (html: string) => void;
600
+ /** Blur handler */
601
+ onBlur?: (html: string) => void;
602
+ /** Placeholder text */
603
+ placeholder?: string;
604
+ /** Minimum height of editing area (default: '200px') */
605
+ minHeight?: string;
606
+ /** Maximum height (default: none — grows to fit) */
607
+ maxHeight?: string;
608
+ /** Read-only */
609
+ readOnly?: boolean;
610
+ /** Disabled */
611
+ disabled?: boolean;
612
+ /** Which toolbar buttons to show (default: all) */
613
+ toolbar?: ToolbarButton[];
614
+ /** HTML id */
615
+ id?: string;
616
+ toolbarStyle?: {
617
+ backgroundColor?: string;
618
+ borderBottom?: string;
619
+ buttonColor?: string;
620
+ buttonHoverBackground?: string;
621
+ buttonActiveBackground?: string;
622
+ buttonSize?: string;
623
+ };
624
+ editorStyle?: {
625
+ padding?: string;
626
+ backgroundColor?: string;
627
+ color?: string;
628
+ fontFamily?: string;
629
+ fontSize?: string;
630
+ lineHeight?: string;
631
+ };
632
+ label?: string;
633
+ helpText?: string;
634
+ error?: string;
635
+ required?: boolean;
636
+ wrapperStyle?: FormFieldWrapperStyle;
637
+ }
638
+ type ToolbarButton = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'heading1' | 'heading2' | 'heading3' | 'bulletList' | 'orderedList' | 'blockquote' | 'link' | 'unlink' | 'insertHR' | 'removeFormat' | 'undo' | 'redo';
639
+ declare function TextEditor(props: TextEditorProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
640
+
641
+ interface TextFieldProps {
642
+ /** Current value (controlled) */
643
+ value?: string;
644
+ /** Default value (uncontrolled) */
645
+ defaultValue?: string;
646
+ /** Change handler */
647
+ onChange?: (value: string) => void;
648
+ /** Input event handler (fires on every keystroke) */
649
+ onInput?: (value: string) => void;
650
+ /** Blur handler */
651
+ onBlur?: (value: string) => void;
652
+ /** Enter key handler */
653
+ onEnter?: (value: string) => void;
654
+ /** Placeholder text */
655
+ placeholder?: string;
656
+ /** Input type (default: 'text') */
657
+ type?: 'text' | 'password' | 'email' | 'url' | 'tel' | 'search' | 'number';
658
+ /** HTML name attribute */
659
+ name?: string;
660
+ /** HTML id */
661
+ id?: string;
662
+ /** Max length */
663
+ maxLength?: number;
664
+ /** Pattern for validation */
665
+ pattern?: string;
666
+ /** Auto-complete hint */
667
+ autoComplete?: string;
668
+ /** Autofocus on mount */
669
+ autoFocus?: boolean;
670
+ /** Read-only */
671
+ readOnly?: boolean;
672
+ /** Disabled */
673
+ disabled?: boolean;
674
+ /** Prefix element (icon, text) */
675
+ prefix?: unknown;
676
+ /** Suffix element (icon, button) */
677
+ suffix?: unknown;
678
+ label?: string;
679
+ helpText?: string;
680
+ error?: string;
681
+ required?: boolean;
682
+ wrapperStyle?: FormFieldWrapperStyle;
683
+ inputStyle?: InputBaseStyle;
684
+ /** Extra class on the input */
685
+ className?: string;
686
+ }
687
+ declare function TextField(props: TextFieldProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
688
+
689
+ interface TimePickerProps {
690
+ /** Current value in 'HH:MM' or 'HH:MM:SS' format (24h) */
691
+ value: string;
692
+ /** Change handler, receives 'HH:MM' or 'HH:MM:SS' string in 24h format */
693
+ onChange: (value: string) => void;
694
+ /** Display format */
695
+ format?: '12h' | '24h';
696
+ /** Minute increment step */
697
+ minuteStep?: number;
698
+ /** Disabled state */
699
+ disabled?: boolean;
700
+ /** Label text */
701
+ label?: string;
702
+ /** Error message */
703
+ error?: string;
704
+ /** When true, show a seconds spinner (default false) */
705
+ showSeconds?: boolean;
706
+ /** If provided, display a timezone label next to the time */
707
+ timezone?: string;
708
+ /** When true, show a timezone dropdown selector (default false) */
709
+ showTimezone?: boolean;
710
+ /** List of timezone strings for the dropdown */
711
+ timezones?: string[];
712
+ /** Callback when timezone changes */
713
+ onTimezoneChange?: (tz: string) => void;
714
+ }
715
+ declare function TimePicker(props: TimePickerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
716
+
717
+ interface ToggleProps {
718
+ /** Whether toggle is on */
719
+ checked: boolean;
720
+ /** Change handler */
721
+ onChange: (checked: boolean) => void;
722
+ /** Label text */
723
+ label?: string;
724
+ /** Label position relative to toggle */
725
+ labelPosition?: 'left' | 'right';
726
+ /** Disabled state */
727
+ disabled?: boolean;
728
+ /** Size variant */
729
+ size?: 'sm' | 'md' | 'lg';
730
+ /** Track color when on */
731
+ onColor?: string;
732
+ /** Track color when off */
733
+ offColor?: string;
734
+ }
735
+ declare function Toggle(props: ToggleProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
736
+
737
+ interface CardProps {
738
+ /** Card title displayed in the header */
739
+ title?: string;
740
+ /** Subtitle shown below the title */
741
+ subtitle?: string;
742
+ /** Slot rendered at the trailing edge of the header (e.g. action button) */
743
+ headerAction?: unknown;
744
+ /** Slot rendered as the card footer */
745
+ footer?: unknown;
746
+ /** URL for a top image */
747
+ image?: string;
748
+ /** Alt text for the top image */
749
+ imageAlt?: string;
750
+ /** Enable hover elevation effect (default: false) */
751
+ hoverable?: boolean;
752
+ /** Show border (default: true) */
753
+ bordered?: boolean;
754
+ /** Shadow level: 'none' | 'sm' | 'md' | 'lg' (default: 'sm') */
755
+ shadow?: 'none' | 'sm' | 'md' | 'lg';
756
+ /** Inner padding (CSS value, default: '16px') */
757
+ padding?: string;
758
+ /** Border radius (CSS value, default: '8px') */
759
+ borderRadius?: string;
760
+ /** Extra inline styles */
761
+ style?: Record<string, string>;
762
+ /** Extra class name */
763
+ className?: string;
764
+ /** Body content */
765
+ children?: unknown;
766
+ }
767
+ declare function Card(props: CardProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
768
+
769
+ interface FlexContainerProps {
770
+ /** flex-direction (default: 'row') */
771
+ direction?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
772
+ /** flex-wrap (default: 'nowrap') */
773
+ wrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
774
+ /** Gap between items (CSS value) */
775
+ gap?: string;
776
+ /** CSS align-items */
777
+ alignItems?: string;
778
+ /** CSS justify-content */
779
+ justifyContent?: string;
780
+ /** Use inline-flex instead of flex */
781
+ inline?: boolean;
782
+ /** Extra inline styles */
783
+ style?: Record<string, string>;
784
+ /** Extra class name */
785
+ className?: string;
786
+ /** Children */
787
+ children?: unknown;
788
+ }
789
+ interface FlexItemProps {
790
+ /** Shorthand flex property (e.g. '1 1 auto') */
791
+ flex?: string;
792
+ /** flex-grow */
793
+ grow?: number;
794
+ /** flex-shrink */
795
+ shrink?: number;
796
+ /** flex-basis */
797
+ basis?: string;
798
+ /** align-self override */
799
+ alignSelf?: string;
800
+ /** order */
801
+ order?: number;
802
+ /** Extra inline styles */
803
+ style?: Record<string, string>;
804
+ /** Extra class name */
805
+ className?: string;
806
+ /** Children */
807
+ children?: unknown;
808
+ }
809
+ declare function FlexContainer(props: FlexContainerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
810
+ declare function FlexItem(props: FlexItemProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
811
+
812
+ interface GridBreakpoint {
813
+ /** Min-width media query value (e.g. '768px') */
814
+ minWidth: string;
815
+ /** Column template override at this breakpoint */
816
+ columns?: number | string;
817
+ /** Row template override */
818
+ rows?: string;
819
+ /** Gap override */
820
+ gap?: string;
821
+ }
822
+ interface GridProps {
823
+ /** Number of equal columns or a CSS grid-template-columns string */
824
+ columns?: number | string;
825
+ /** CSS grid-template-rows value */
826
+ rows?: string;
827
+ /** Gap between grid cells (CSS value, e.g. '16px' or '1rem 2rem') */
828
+ gap?: string;
829
+ /** CSS align-items for the grid container */
830
+ alignItems?: string;
831
+ /** CSS justify-items for the grid container */
832
+ justifyItems?: string;
833
+ /** When set, uses auto-fit with minmax(minColWidth, 1fr) */
834
+ minColWidth?: string;
835
+ /** Named grid areas (grid-template-areas lines) */
836
+ areas?: string[];
837
+ /** Responsive breakpoints — rendered as inline style overrides via CSS custom properties */
838
+ responsive?: GridBreakpoint[];
839
+ /** Extra inline styles */
840
+ style?: Record<string, string>;
841
+ /** Extra class name */
842
+ className?: string;
843
+ /** Children */
844
+ children?: unknown;
845
+ }
846
+ interface GridItemProps {
847
+ /** grid-column value (e.g. 'span 2', '1 / 3') */
848
+ gridColumn?: string;
849
+ /** grid-row value */
850
+ gridRow?: string;
851
+ /** grid-area name */
852
+ gridArea?: string;
853
+ /** CSS align-self */
854
+ alignSelf?: string;
855
+ /** CSS justify-self */
856
+ justifySelf?: string;
857
+ /** Extra inline styles */
858
+ style?: Record<string, string>;
859
+ /** Extra class name */
860
+ className?: string;
861
+ /** Children */
862
+ children?: unknown;
863
+ }
864
+ declare function Grid(props: GridProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
865
+ declare function GridItem(props: GridItemProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
866
+
867
+ interface PanelProps {
868
+ /** Panel title */
869
+ title?: string;
870
+ /** Whether the panel can be collapsed (default: false) */
871
+ collapsible?: boolean;
872
+ /** Initial collapsed state when collapsible (default: false) */
873
+ defaultCollapsed?: boolean;
874
+ /** Icon element rendered before the title */
875
+ icon?: unknown;
876
+ /** Slot rendered at the trailing edge of the header */
877
+ headerRight?: unknown;
878
+ /** Show border (default: true) */
879
+ bordered?: boolean;
880
+ /** Shadow: 'none' | 'sm' | 'md' (default: 'none') */
881
+ shadow?: 'none' | 'sm' | 'md';
882
+ /** Extra inline styles */
883
+ style?: Record<string, string>;
884
+ /** Extra class name */
885
+ className?: string;
886
+ /** Body content */
887
+ children?: unknown;
888
+ }
889
+ declare function Panel(props: PanelProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
890
+
891
+ interface ScrollContainerProps {
892
+ /** Maximum height (CSS value) */
893
+ maxHeight?: string;
894
+ /** Maximum width (CSS value) */
895
+ maxWidth?: string;
896
+ /** Scroll direction (default: 'vertical') */
897
+ direction?: 'vertical' | 'horizontal' | 'both';
898
+ /** Scrollbar visibility (default: 'auto') */
899
+ showScrollbar?: 'auto' | 'always' | 'hover' | 'never';
900
+ /** Inner padding (CSS value) */
901
+ padding?: string;
902
+ /** Show inset shadow at scroll edges to hint overflow (default: false) */
903
+ shadow?: boolean;
904
+ /** Extra inline styles */
905
+ style?: Record<string, string>;
906
+ /** Extra class name */
907
+ className?: string;
908
+ /** Children */
909
+ children?: unknown;
910
+ }
911
+ declare function ScrollContainer(props: ScrollContainerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
912
+
913
+ interface SplitterProps {
914
+ /** Split direction (default: 'horizontal' — left|right panes) */
915
+ direction?: 'horizontal' | 'vertical';
916
+ /** Initial split percentage for the first pane (default: 50) */
917
+ initialSplit?: number;
918
+ /** Minimum size of either pane in px (default: 50) */
919
+ minSize?: number;
920
+ /** Maximum size of the first pane in px */
921
+ maxSize?: number;
922
+ /** Divider bar width/height in px (default: 6) */
923
+ dividerSize?: number;
924
+ /** Extra inline styles for the container */
925
+ style?: Record<string, string>;
926
+ /** Extra class name */
927
+ className?: string;
928
+ /** Exactly two children */
929
+ children?: unknown[];
930
+ }
931
+ declare function Splitter(props: SplitterProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
932
+
933
+ interface TabDefinition {
934
+ /** Unique tab identifier */
935
+ id: string;
936
+ /** Display label */
937
+ label: string;
938
+ /** Optional icon element */
939
+ icon?: unknown;
940
+ /** Disabled state */
941
+ disabled?: boolean;
942
+ /** Tab panel content */
943
+ content: unknown;
944
+ }
945
+ interface TabsProps {
946
+ /** Tab definitions */
947
+ tabs: TabDefinition[];
948
+ /** Controlled active tab id */
949
+ activeTab?: string;
950
+ /** Change handler (receives tab id) */
951
+ onChange?: (tabId: string) => void;
952
+ /** Tab list position (default: 'top') */
953
+ position?: 'top' | 'bottom' | 'left' | 'right';
954
+ /** Visual variant (default: 'line') */
955
+ variant?: 'line' | 'card' | 'pill';
956
+ /** Extra inline styles */
957
+ style?: Record<string, string>;
958
+ /** Extra class name */
959
+ className?: string;
960
+ }
961
+ declare function Tabs(props: TabsProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
962
+
963
+ interface CarouselItem {
964
+ content: unknown;
965
+ caption?: string;
966
+ }
967
+ interface CarouselProps {
968
+ /** Carousel items */
969
+ items: CarouselItem[];
970
+ /** Enable auto-advance */
971
+ autoPlay?: boolean;
972
+ /** Auto-advance interval in ms (default: 5000) */
973
+ interval?: number;
974
+ /** Show dot indicators (default: true) */
975
+ showDots?: boolean;
976
+ /** Show prev/next arrows (default: true) */
977
+ showArrows?: boolean;
978
+ /** Loop from last to first (default: true) */
979
+ loop?: boolean;
980
+ /** Transition animation type */
981
+ animation?: 'slide' | 'fade';
982
+ /** Called when the active index changes */
983
+ onChange?: (index: number) => void;
984
+ }
985
+ declare function Carousel(props: CarouselProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
986
+
987
+ interface ImageProps {
988
+ /** Image source URL */
989
+ src: string;
990
+ /** Alt text */
991
+ alt?: string;
992
+ /** Width (CSS value or number) */
993
+ width?: string | number;
994
+ /** Height (CSS value or number) */
995
+ height?: string | number;
996
+ /** Fallback URL or element shown on error */
997
+ fallback?: string | unknown;
998
+ /** Placeholder shown while loading: 'blur', 'skeleton', or element */
999
+ placeholder?: 'blur' | 'skeleton' | unknown;
1000
+ /** Enable lazy loading (default: true) */
1001
+ lazy?: boolean;
1002
+ /** CSS object-fit value */
1003
+ objectFit?: string;
1004
+ /** CSS border-radius value */
1005
+ borderRadius?: string;
1006
+ /** Caption text rendered below the image */
1007
+ caption?: string;
1008
+ }
1009
+ declare function Image(props: ImageProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1010
+
1011
+ interface VideoPlayerProps {
1012
+ /** Video source URL */
1013
+ src: string;
1014
+ /** Poster image URL */
1015
+ poster?: string;
1016
+ /** Width (CSS value or number) */
1017
+ width?: string | number;
1018
+ /** Height (CSS value or number) */
1019
+ height?: string | number;
1020
+ /** Auto-play video */
1021
+ autoPlay?: boolean;
1022
+ /** Loop playback */
1023
+ loop?: boolean;
1024
+ /** Muted */
1025
+ muted?: boolean;
1026
+ /** Show custom controls (default: true) */
1027
+ controls?: boolean;
1028
+ /** Play callback */
1029
+ onPlay?: () => void;
1030
+ /** Pause callback */
1031
+ onPause?: () => void;
1032
+ /** Ended callback */
1033
+ onEnded?: () => void;
1034
+ /** Time update callback */
1035
+ onTimeUpdate?: (currentTime: number, duration: number) => void;
1036
+ }
1037
+ declare function VideoPlayer(props: VideoPlayerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1038
+
1039
+ type NavOrientation = 'horizontal' | 'vertical';
1040
+ interface NavWrapperStyle {
1041
+ /** Background color (default: '#ffffff') */
1042
+ backgroundColor?: string;
1043
+ /** Text color (default: '#1f2937') */
1044
+ color?: string;
1045
+ /** Font family (default: inherit) */
1046
+ fontFamily?: string;
1047
+ /** Font size (default: '14px') */
1048
+ fontSize?: string;
1049
+ /** Border (default: '1px solid #e5e7eb') */
1050
+ border?: string;
1051
+ /** Border radius (default: '8px') */
1052
+ borderRadius?: string;
1053
+ /** Padding (default: '0') */
1054
+ padding?: string;
1055
+ /** Box shadow (default: none) */
1056
+ boxShadow?: string;
1057
+ /** Width (default: 'auto') */
1058
+ width?: string | number;
1059
+ /** Max height for scrollable content (default: none) */
1060
+ maxHeight?: string | number;
1061
+ /** Custom inline styles merged last */
1062
+ custom?: Record<string, string>;
1063
+ }
1064
+ interface NavWrapperProps {
1065
+ /** Orientation of child items (default: 'vertical') */
1066
+ orientation?: NavOrientation;
1067
+ /** ARIA role (default: 'navigation') */
1068
+ role?: string;
1069
+ /** ARIA label */
1070
+ ariaLabel?: string;
1071
+ /** Styling configuration */
1072
+ styling?: NavWrapperStyle;
1073
+ /** Extra CSS class name */
1074
+ className?: string;
1075
+ /** Enable keyboard navigation with arrow keys (default: true) */
1076
+ keyboardNav?: boolean;
1077
+ /** Children */
1078
+ children?: unknown;
1079
+ }
1080
+ declare function NavWrapper(props: NavWrapperProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1081
+ interface NavItemStyle {
1082
+ /** Padding (default: '10px 16px') */
1083
+ padding?: string;
1084
+ /** Hover background (default: '#f3f4f6') */
1085
+ hoverBackground?: string;
1086
+ /** Active/selected background (default: '#eff6ff') */
1087
+ activeBackground?: string;
1088
+ /** Active text color (default: '#2563eb') */
1089
+ activeColor?: string;
1090
+ /** Border bottom between items (default: none) */
1091
+ separator?: string;
1092
+ /** Cursor (default: 'pointer') */
1093
+ cursor?: string;
1094
+ /** Transition (default: 'background-color 0.15s') */
1095
+ transition?: string;
1096
+ }
1097
+ /**
1098
+ * Build common inline styles for a navigation item.
1099
+ */
1100
+ declare function buildNavItemStyle(s: NavItemStyle, state: {
1101
+ hover: boolean;
1102
+ active: boolean;
1103
+ }): Record<string, string>;
1104
+ /**
1105
+ * useHover — simple hover state hook for nav items.
1106
+ */
1107
+ declare function useHover(): {
1108
+ hover: boolean;
1109
+ onMouseEnter: () => void;
1110
+ onMouseLeave: () => void;
1111
+ };
1112
+
1113
+ interface AccordionSection {
1114
+ /** Unique identifier for the section */
1115
+ id: string;
1116
+ /** Text displayed in the section header */
1117
+ header: string;
1118
+ /** Content rendered when the section is expanded */
1119
+ content: unknown;
1120
+ /** Optional icon displayed in the header */
1121
+ icon?: string;
1122
+ /** When true, section cannot be toggled */
1123
+ disabled?: boolean;
1124
+ }
1125
+ interface AccordionHeaderStyle {
1126
+ padding?: string;
1127
+ backgroundColor?: string;
1128
+ hoverBackground?: string;
1129
+ color?: string;
1130
+ fontWeight?: string;
1131
+ fontSize?: string;
1132
+ borderBottom?: string;
1133
+ }
1134
+ interface AccordionContentStyle {
1135
+ padding?: string;
1136
+ backgroundColor?: string;
1137
+ borderBottom?: string;
1138
+ }
1139
+ interface AccordionProps {
1140
+ /** Array of sections to render */
1141
+ sections: AccordionSection[];
1142
+ /** IDs of sections that should be expanded on initial render */
1143
+ defaultExpanded?: string[];
1144
+ /** Allow multiple sections to be open at the same time (default: false) */
1145
+ allowMultiple?: boolean;
1146
+ /** Styling for section headers */
1147
+ headerStyle?: AccordionHeaderStyle;
1148
+ /** Styling for section content panels */
1149
+ contentStyle?: AccordionContentStyle;
1150
+ /** Styling passed through to the NavWrapper container */
1151
+ wrapperStyle?: NavWrapperStyle;
1152
+ /** Icon shown on collapsed sections (default: '+') */
1153
+ expandIcon?: string;
1154
+ /** Icon shown on expanded sections (default: '\u2212') */
1155
+ collapseIcon?: string;
1156
+ /** Position of the expand/collapse icon (default: 'right') */
1157
+ iconPosition?: 'left' | 'right';
1158
+ /** Enable smooth open/close animation via max-height transition (default: true) */
1159
+ animated?: boolean;
1160
+ /** Callback fired with the array of currently expanded section IDs */
1161
+ onChange?: (expandedIds: string[]) => void;
1162
+ }
1163
+ declare function Accordion(props: AccordionProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1164
+
1165
+ interface BreadcrumbItem {
1166
+ /** Display label */
1167
+ label: string;
1168
+ /** Optional link href — if omitted, rendered as plain text */
1169
+ href?: string;
1170
+ /** Optional click handler */
1171
+ onClick?: () => void;
1172
+ }
1173
+ type BreadcrumbSize = 'sm' | 'md' | 'lg';
1174
+ interface BreadcrumbProps {
1175
+ /** Ordered list of breadcrumb items (first = root, last = current page) */
1176
+ items: BreadcrumbItem[];
1177
+ /** Separator between items (default: '/') */
1178
+ separator?: string | unknown;
1179
+ /** When set, collapses middle items to '...' if items exceed this count */
1180
+ maxItems?: number;
1181
+ /** Size variant (default: 'md') */
1182
+ size?: BreadcrumbSize;
1183
+ }
1184
+ declare function Breadcrumb(props: BreadcrumbProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1185
+
1186
+ interface DropdownItem {
1187
+ /** Unique identifier for the item */
1188
+ id: string;
1189
+ /** Display label */
1190
+ label: string;
1191
+ /** Optional icon rendered as a text span before the label (emoji or text) */
1192
+ icon?: string;
1193
+ /** Whether the item is disabled (grayed out, non-interactive) */
1194
+ disabled?: boolean;
1195
+ /** Render as a thin horizontal divider instead of a menu item */
1196
+ divider?: boolean;
1197
+ /** Click handler */
1198
+ onClick?: () => void;
1199
+ /** Nested submenu items — shows a right chevron and expands on hover */
1200
+ children?: DropdownItem[];
1201
+ }
1202
+ interface DropdownProps {
1203
+ /** Trigger button text */
1204
+ label: string;
1205
+ /** Menu items */
1206
+ items: DropdownItem[];
1207
+ /** Custom styles for the trigger button */
1208
+ triggerStyle?: Record<string, string>;
1209
+ /** Styling passed to NavWrapper for the dropdown panel */
1210
+ menuStyle?: NavWrapperStyle;
1211
+ /** Styling for menu items */
1212
+ itemStyle?: NavItemStyle;
1213
+ /** Placement of the dropdown relative to the trigger (default: 'bottom-start') */
1214
+ placement?: 'bottom-start' | 'bottom-end';
1215
+ /** Close the dropdown when an item is selected (default: true) */
1216
+ closeOnSelect?: boolean;
1217
+ /** Width of the dropdown panel (default: '220px') */
1218
+ width?: string | number;
1219
+ }
1220
+ declare function Dropdown(props: DropdownProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1221
+
1222
+ interface MenuItem {
1223
+ /** Display label */
1224
+ label: string;
1225
+ /** Click handler */
1226
+ onClick?: () => void;
1227
+ /** Keyboard shortcut hint (e.g. 'Ctrl+S') */
1228
+ shortcut?: string;
1229
+ /** Icon text (emoji or character) */
1230
+ icon?: string;
1231
+ /** Render as a divider line */
1232
+ divider?: boolean;
1233
+ /** Whether the item is disabled */
1234
+ disabled?: boolean;
1235
+ /** Nested submenu items */
1236
+ children?: MenuItem[];
1237
+ }
1238
+ interface MenuDefinition {
1239
+ /** Top-level menu label */
1240
+ label: string;
1241
+ /** Items in this menu */
1242
+ items: MenuItem[];
1243
+ }
1244
+ interface MenubarProps {
1245
+ /** Array of top-level menu definitions */
1246
+ menus: MenuDefinition[];
1247
+ }
1248
+ declare function Menubar(props: MenubarProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1249
+
1250
+ interface PaginationProps {
1251
+ /** Total number of items */
1252
+ total: number;
1253
+ /** Items per page */
1254
+ pageSize: number;
1255
+ /** Current active page (1-based) */
1256
+ currentPage: number;
1257
+ /** Called when page changes */
1258
+ onChange: (page: number) => void;
1259
+ /** Number of sibling pages shown around the current page (default: 1) */
1260
+ siblingCount?: number;
1261
+ /** Show First/Last buttons (default: true) */
1262
+ showFirstLast?: boolean;
1263
+ /** Show Prev/Next buttons (default: true) */
1264
+ showPrevNext?: boolean;
1265
+ /** Disable all controls */
1266
+ disabled?: boolean;
1267
+ }
1268
+ declare function Pagination(props: PaginationProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1269
+
1270
+ interface SidebarItem {
1271
+ /** Unique identifier */
1272
+ id: string;
1273
+ /** Display label */
1274
+ label: string;
1275
+ /** Optional icon (emoji or text character) */
1276
+ icon?: string;
1277
+ /** Nested child items */
1278
+ children?: SidebarItem[];
1279
+ /** Optional badge text (e.g. count) */
1280
+ badge?: string;
1281
+ }
1282
+ interface SidebarProps {
1283
+ /** Navigation items */
1284
+ items: SidebarItem[];
1285
+ /** Whether the sidebar is collapsed to icon-only mode */
1286
+ collapsed?: boolean;
1287
+ /** Called to toggle collapse state */
1288
+ onToggleCollapse?: () => void;
1289
+ /** Currently selected item id */
1290
+ selectedId?: string;
1291
+ /** Called when an item is selected */
1292
+ onSelect?: (id: string) => void;
1293
+ /** Expanded width (default: '240px') */
1294
+ width?: string | number;
1295
+ /** Collapsed width (default: '56px') */
1296
+ collapsedWidth?: string | number;
1297
+ }
1298
+ declare function Sidebar(props: SidebarProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1299
+
1300
+ interface StepItem {
1301
+ /** Step label */
1302
+ label: string;
1303
+ /** Optional description shown below the label */
1304
+ description?: string;
1305
+ /** Optional icon text (emoji or character) shown inside the circle */
1306
+ icon?: string;
1307
+ }
1308
+ type StepperOrientation = 'horizontal' | 'vertical';
1309
+ type StepperVariant = 'circle' | 'dot';
1310
+ interface StepperProps {
1311
+ /** Array of step definitions */
1312
+ steps: StepItem[];
1313
+ /** Current active step (0-based index) */
1314
+ currentStep: number;
1315
+ /** Orientation (default: 'horizontal') */
1316
+ orientation?: StepperOrientation;
1317
+ /** Called when a step is clicked — receives the step index */
1318
+ onChange?: (step: number) => void;
1319
+ /** Whether steps are clickable (default: false) */
1320
+ clickable?: boolean;
1321
+ /** Visual variant (default: 'circle') */
1322
+ variant?: StepperVariant;
1323
+ }
1324
+ declare function Stepper(props: StepperProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1325
+
1326
+ interface ToolbarItem {
1327
+ /** Unique identifier */
1328
+ id: string;
1329
+ /** Display label (optional if icon provided) */
1330
+ label?: string;
1331
+ /** Icon text (emoji or character) */
1332
+ icon?: string;
1333
+ /** Item type */
1334
+ type: 'button' | 'separator' | 'dropdown' | 'spacer';
1335
+ /** Click handler */
1336
+ onClick?: () => void;
1337
+ /** Whether the item is disabled */
1338
+ disabled?: boolean;
1339
+ /** Whether the item is in an active/pressed state */
1340
+ active?: boolean;
1341
+ }
1342
+ type ToolbarSize = 'sm' | 'md' | 'lg';
1343
+ type ToolbarVariant = 'flat' | 'raised';
1344
+ interface ToolbarProps {
1345
+ /** Toolbar items */
1346
+ items: ToolbarItem[];
1347
+ /** Size (default: 'md') */
1348
+ size?: ToolbarSize;
1349
+ /** Visual variant (default: 'flat') */
1350
+ variant?: ToolbarVariant;
1351
+ }
1352
+ declare function Toolbar(props: ToolbarProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1353
+
1354
+ /**
1355
+ * TreeNode — Extensible data model for tree navigation nodes.
1356
+ *
1357
+ * Represents a single node in a hierarchical tree structure. Supports
1358
+ * arbitrary metadata for extensibility, parent/child traversal, and
1359
+ * expand/collapse state management. Developers can subclass TreeNode or
1360
+ * attach custom data via the `metadata` field.
1361
+ */
1362
+ interface TreeNodeData {
1363
+ /** Unique identifier for the node */
1364
+ id: string;
1365
+ /** Display label */
1366
+ label: string;
1367
+ /** Nested child nodes */
1368
+ children?: TreeNodeData[];
1369
+ /** Whether the node starts expanded (default: false) */
1370
+ expanded?: boolean;
1371
+ /** Text or emoji icon displayed alongside the label */
1372
+ icon?: string;
1373
+ /** Extensible payload — attach arbitrary data here */
1374
+ metadata?: Record<string, unknown>;
1375
+ }
1376
+ declare class TreeNode {
1377
+ id: string;
1378
+ label: string;
1379
+ children: TreeNode[];
1380
+ expanded: boolean;
1381
+ icon: string | null;
1382
+ metadata: Record<string, unknown>;
1383
+ parent: TreeNode | null;
1384
+ depth: number;
1385
+ constructor(data: TreeNodeData, parent?: TreeNode);
1386
+ /**
1387
+ * Build a full TreeNode tree from nested data.
1388
+ */
1389
+ static fromData(data: TreeNodeData): TreeNode;
1390
+ /**
1391
+ * Returns true if the node has no children.
1392
+ */
1393
+ isLeaf(): boolean;
1394
+ /**
1395
+ * Returns true if the node has no parent (root of the tree).
1396
+ */
1397
+ isRoot(): boolean;
1398
+ /**
1399
+ * Depth-first walk of this node and all descendants.
1400
+ * The callback receives each node and its depth.
1401
+ */
1402
+ walk(fn: (node: TreeNode, depth: number) => void): void;
1403
+ /**
1404
+ * Find a descendant (or self) by id. Returns null if not found.
1405
+ */
1406
+ find(id: string): TreeNode | null;
1407
+ /**
1408
+ * Toggle the expanded/collapsed state.
1409
+ */
1410
+ toggle(): void;
1411
+ /**
1412
+ * Expand this node (show children).
1413
+ */
1414
+ expand(): void;
1415
+ /**
1416
+ * Collapse this node (hide children).
1417
+ */
1418
+ collapse(): void;
1419
+ /**
1420
+ * Add a child node from data. Returns the newly created TreeNode.
1421
+ */
1422
+ addChild(data: TreeNodeData): TreeNode;
1423
+ /**
1424
+ * Remove a direct child by id. Returns true if a child was removed.
1425
+ */
1426
+ removeChild(id: string): boolean;
1427
+ }
1428
+
1429
+ interface TreeNavProps {
1430
+ /** Tree data structure */
1431
+ root: TreeNodeData;
1432
+ /** Fired when a node label is clicked */
1433
+ onNodeClick?: (node: TreeNode) => void;
1434
+ /** Fired when a node is expanded */
1435
+ onNodeExpand?: (node: TreeNode) => void;
1436
+ /** Fired when a node is collapsed */
1437
+ onNodeCollapse?: (node: TreeNode) => void;
1438
+ /** Id of the currently selected node */
1439
+ selectedId?: string;
1440
+ /** Start with all nodes expanded (default: false) */
1441
+ expandAll?: boolean;
1442
+ /** Color of connector lines (default: '#000') */
1443
+ lineColor?: string;
1444
+ /** Width of connector lines in px (default: 1) */
1445
+ lineWidth?: number;
1446
+ /** Pixels of indentation per depth level (default: 20) */
1447
+ indentPx?: number;
1448
+ /** Icon shown for expanded non-leaf nodes (default: '\u2212') */
1449
+ iconExpanded?: string;
1450
+ /** Icon shown for collapsed non-leaf nodes (default: '+') */
1451
+ iconCollapsed?: string;
1452
+ /** Styling for individual node items */
1453
+ nodeStyle?: NavItemStyle;
1454
+ /** Styling for the outer NavWrapper */
1455
+ wrapperStyle?: NavWrapperStyle;
1456
+ /** Custom node renderer for full control over node appearance */
1457
+ renderNode?: (node: TreeNode, isSelected: boolean) => unknown;
1458
+ }
1459
+ declare function TreeNav(props: TreeNavProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1460
+
1461
+ interface ContextMenuItem {
1462
+ /** Display label */
1463
+ label?: string;
1464
+ /** Click handler */
1465
+ onClick?: () => void;
1466
+ /** Optional icon (rendered as text/emoji) */
1467
+ icon?: string;
1468
+ /** Disabled state */
1469
+ disabled?: boolean;
1470
+ /** Render as a divider instead of a menu item */
1471
+ divider?: boolean;
1472
+ /** Nested submenu items */
1473
+ children?: ContextMenuItem[];
1474
+ }
1475
+ interface ContextMenuProps {
1476
+ /** Menu item definitions */
1477
+ items: ContextMenuItem[];
1478
+ /** Trigger area children */
1479
+ children?: unknown;
1480
+ }
1481
+ declare function ContextMenu(props: ContextMenuProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1482
+
1483
+ type DrawerPosition = 'left' | 'right' | 'top' | 'bottom';
1484
+ interface DrawerProps {
1485
+ /** Whether the drawer is open */
1486
+ open: boolean;
1487
+ /** Called when the drawer requests to close */
1488
+ onClose: () => void;
1489
+ /** Edge the drawer slides in from */
1490
+ position?: DrawerPosition;
1491
+ /** Width (left/right) or height (top/bottom) in px or % */
1492
+ size?: string;
1493
+ /** Drawer title */
1494
+ title?: string;
1495
+ /** Show overlay backdrop behind the drawer */
1496
+ overlay?: boolean;
1497
+ /** Close when clicking the overlay */
1498
+ closeOnOverlay?: boolean;
1499
+ /** Close on Escape key */
1500
+ closeOnEscape?: boolean;
1501
+ /** Drawer body children */
1502
+ children?: unknown;
1503
+ }
1504
+ declare function Drawer(props: DrawerProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props> | null;
1505
+
1506
+ type ModalSize = 'sm' | 'md' | 'lg' | 'full';
1507
+ interface ModalProps {
1508
+ /** Whether the modal is open */
1509
+ open: boolean;
1510
+ /** Called when the modal requests to close */
1511
+ onClose: () => void;
1512
+ /** Modal title rendered in the header */
1513
+ title?: string;
1514
+ /** Modal width preset */
1515
+ size?: ModalSize;
1516
+ /** Close when clicking the overlay backdrop (default true) */
1517
+ closeOnOverlay?: boolean;
1518
+ /** Close when pressing Escape (default true) */
1519
+ closeOnEscape?: boolean;
1520
+ /** Footer slot content */
1521
+ footer?: unknown;
1522
+ /** Show the X close button in the header (default true) */
1523
+ showCloseButton?: boolean;
1524
+ /** Modal body children */
1525
+ children?: unknown;
1526
+ }
1527
+ declare function Modal(props: ModalProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props> | null;
1528
+
1529
+ type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
1530
+ interface PopoverProps {
1531
+ /** Trigger element slot */
1532
+ trigger: unknown;
1533
+ /** Popover content slot */
1534
+ content: unknown;
1535
+ /** Controlled open state (if provided, disables auto-toggle) */
1536
+ open?: boolean;
1537
+ /** Placement relative to trigger */
1538
+ placement?: PopoverPlacement;
1539
+ /** Offset from trigger in px */
1540
+ offset?: number;
1541
+ /** Show an arrow pointing to the trigger */
1542
+ arrow?: boolean;
1543
+ /** Close when clicking outside the popover */
1544
+ closeOnClickOutside?: boolean;
1545
+ /** Callback when open state changes (for controlled mode) */
1546
+ onOpenChange?: (open: boolean) => void;
1547
+ }
1548
+ declare function Popover(props: PopoverProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1549
+
1550
+ type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
1551
+ type ToastType = 'info' | 'success' | 'warning' | 'error';
1552
+ interface ToastAction {
1553
+ label: string;
1554
+ onClick: () => void;
1555
+ }
1556
+ interface ToastOptions {
1557
+ /** Toast type for styling */
1558
+ type?: ToastType;
1559
+ /** Duration in ms before auto-dismiss (0 = persistent) */
1560
+ duration?: number;
1561
+ /** Optional action button */
1562
+ action?: ToastAction;
1563
+ }
1564
+ interface ToasterConfig {
1565
+ /** Position of the toast stack */
1566
+ position?: ToastPosition;
1567
+ /** Maximum visible toasts */
1568
+ maxToasts?: number;
1569
+ /** Default auto-dismiss duration in ms */
1570
+ defaultDuration?: number;
1571
+ }
1572
+ interface ToastItem {
1573
+ id: string;
1574
+ message: string;
1575
+ type: ToastType;
1576
+ duration: number;
1577
+ action?: ToastAction;
1578
+ createdAt: number;
1579
+ }
1580
+ interface Toaster {
1581
+ toast: (message: string, opts?: ToastOptions) => string;
1582
+ dismiss: (id: string) => void;
1583
+ dismissAll: () => void;
1584
+ subscribe: (listener: () => void) => () => void;
1585
+ getToasts: () => ToastItem[];
1586
+ config: Required<ToasterConfig>;
1587
+ }
1588
+ /**
1589
+ * Creates a toaster instance that manages toast state externally.
1590
+ */
1591
+ declare function createToaster(config?: ToasterConfig): Toaster;
1592
+ /**
1593
+ * ToastContainer — Renders all toasts from a given toaster.
1594
+ */
1595
+ declare function ToastContainer(props: {
1596
+ toaster: Toaster;
1597
+ }): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props> | null;
1598
+ /**
1599
+ * useToast — Hook that creates a toaster and returns toast() + ToastContainer.
1600
+ */
1601
+ declare function useToast(config?: ToasterConfig): {
1602
+ toast: (message: string, opts?: ToastOptions) => string;
1603
+ dismiss: (id: string) => void;
1604
+ dismissAll: () => void;
1605
+ ToastContainer: () => specifyjs_shared_types.SpecElement<{
1606
+ toaster: Toaster;
1607
+ }>;
1608
+ };
1609
+
1610
+ type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
1611
+ interface TooltipProps {
1612
+ /** Tooltip text content */
1613
+ text: string;
1614
+ /** Placement relative to the trigger */
1615
+ placement?: TooltipPlacement;
1616
+ /** Delay in ms before showing (default 200) */
1617
+ delay?: number;
1618
+ /** Max width of the tooltip */
1619
+ maxWidth?: string;
1620
+ /** Trigger element(s) */
1621
+ children?: unknown;
1622
+ }
1623
+ declare function Tooltip(props: TooltipProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1624
+
1625
+ interface BarDatum {
1626
+ label: string;
1627
+ value: number;
1628
+ color?: string;
1629
+ }
1630
+ interface StackedBarDatum {
1631
+ label: string;
1632
+ values: {
1633
+ category: string;
1634
+ value: number;
1635
+ color?: string;
1636
+ }[];
1637
+ }
1638
+ interface BarGraphProps {
1639
+ /** Simple bar data */
1640
+ data: BarDatum[];
1641
+ /** SVG width in pixels (default: 600) */
1642
+ width?: number;
1643
+ /** SVG height in pixels (default: 400) */
1644
+ height?: number;
1645
+ /** Bar orientation (default: 'vertical') */
1646
+ orientation?: 'vertical' | 'horizontal';
1647
+ /** Default bar fill color (default: '#3b82f6') */
1648
+ barColor?: string;
1649
+ /** Gap between bars in px (default: 8) */
1650
+ barGap?: number;
1651
+ /** Border radius on bar tops (default: 4) */
1652
+ barRadius?: number;
1653
+ /** Show value labels on bars (default: true) */
1654
+ showValues?: boolean;
1655
+ /** Show grid lines perpendicular to bars (default: true) */
1656
+ showGrid?: boolean;
1657
+ /** Grid line color (default: '#e5e7eb') */
1658
+ gridColor?: string;
1659
+ /** Chart title */
1660
+ title?: string;
1661
+ /** Padding around chart area in px (default: 50) */
1662
+ padding?: number;
1663
+ /** Enable animation (default: false) */
1664
+ animate?: boolean;
1665
+ /** Stacked bar data — overrides `data` when provided */
1666
+ stacked?: StackedBarDatum[];
1667
+ /** Grouped mode — side-by-side bars when using stacked data (default: false) */
1668
+ grouped?: boolean;
1669
+ }
1670
+ interface BarGraphScales {
1671
+ /** Maps a value to a pixel length along the value axis */
1672
+ valueScale: (v: number) => number;
1673
+ /** Maps a category index to a pixel position along the category axis */
1674
+ categoryScale: (i: number) => number;
1675
+ /** Width/thickness of a single bar in px */
1676
+ barThickness: number;
1677
+ /** Maximum data value (used for scale domain) */
1678
+ maxValue: number;
1679
+ /** Length of the value axis in px */
1680
+ valueAxisLength: number;
1681
+ /** Length of the category axis in px */
1682
+ categoryAxisLength: number;
1683
+ }
1684
+ declare function useBarGraphScales(count: number, maxValue: number, axisLength: number, categoryAxisLength: number, barGap: number): BarGraphScales;
1685
+ declare function BarGraph(props: BarGraphProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1686
+
1687
+ interface PointEvent {
1688
+ x: number;
1689
+ y: number;
1690
+ index: number;
1691
+ event: Event;
1692
+ }
1693
+ interface CartesianGraph2DProps {
1694
+ width?: number;
1695
+ height?: number;
1696
+ points?: {
1697
+ x: number;
1698
+ y: number;
1699
+ }[];
1700
+ plotFunction?: (x: number) => number;
1701
+ plotResolution?: number;
1702
+ xRange?: [number, number];
1703
+ yRange?: [number, number];
1704
+ showGrid?: boolean;
1705
+ showAxes?: boolean;
1706
+ pointRadius?: number;
1707
+ pointColor?: string;
1708
+ curveColor?: string;
1709
+ gridColor?: string;
1710
+ axisColor?: string;
1711
+ onPointClick?: (info: PointEvent) => void;
1712
+ onPointDoubleClick?: (info: PointEvent) => void;
1713
+ onPointContextMenu?: (info: PointEvent) => void;
1714
+ onPointHover?: (info: PointEvent) => void;
1715
+ }
1716
+ declare function CartesianGraph2D(props: CartesianGraph2DProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1717
+
1718
+ interface ComplexPointInfo {
1719
+ re: number;
1720
+ im: number;
1721
+ iterations: number;
1722
+ event: Event;
1723
+ }
1724
+ interface ComplexGraph2DProps {
1725
+ width?: number;
1726
+ height?: number;
1727
+ realRange?: [number, number];
1728
+ imagRange?: [number, number];
1729
+ maxIterations?: number;
1730
+ colorScheme?: 'classic' | 'fire' | 'ocean';
1731
+ computeFunction?: (re: number, im: number, maxIter: number) => number;
1732
+ onPointClick?: (info: ComplexPointInfo) => void;
1733
+ onPointHover?: (info: ComplexPointInfo) => void;
1734
+ onPointDoubleClick?: (info: ComplexPointInfo) => void;
1735
+ onPointContextMenu?: (info: ComplexPointInfo) => void;
1736
+ }
1737
+ declare function ComplexGraph2D(props: ComplexGraph2DProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1738
+
1739
+ interface Point {
1740
+ x: number;
1741
+ y: number;
1742
+ }
1743
+ interface LineSeries {
1744
+ data: Point[];
1745
+ color: string;
1746
+ label?: string;
1747
+ }
1748
+ interface LineGraphProps {
1749
+ data: Point[];
1750
+ width?: number;
1751
+ height?: number;
1752
+ lineColor?: string;
1753
+ lineWidth?: number;
1754
+ pointRadius?: number;
1755
+ pointColor?: string;
1756
+ showPoints?: boolean;
1757
+ showGrid?: boolean;
1758
+ showArea?: boolean;
1759
+ areaColor?: string;
1760
+ xLabel?: string;
1761
+ yLabel?: string;
1762
+ title?: string;
1763
+ padding?: number;
1764
+ animate?: boolean;
1765
+ multiLine?: LineSeries[];
1766
+ }
1767
+ interface ScaleResult {
1768
+ xScale: (v: number) => number;
1769
+ yScale: (v: number) => number;
1770
+ xTicks: number[];
1771
+ yTicks: number[];
1772
+ xMin: number;
1773
+ xMax: number;
1774
+ yMin: number;
1775
+ yMax: number;
1776
+ }
1777
+ declare function useLineGraphScales(data: Point[], width: number, height: number, padding: number): ScaleResult;
1778
+ declare function LineGraph(props: LineGraphProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1779
+
1780
+ /** Unique symbol to identify SpecifyJS elements */
1781
+ declare const SPEC_ELEMENT_TYPE: unique symbol;
1782
+ /** A key used for reconciliation */
1783
+ type Key = string | number | null;
1784
+ /** A ref can be a callback, an object, or null */
1785
+ type Ref<T = unknown> = RefCallback<T> | RefObject<T> | null;
1786
+ type RefCallback<T> = (instance: T | null) => void;
1787
+ interface RefObject<T> {
1788
+ current: T | null;
1789
+ }
1790
+ /** Props are an arbitrary key-value map */
1791
+ type Props = Record<string, unknown> & {
1792
+ children?: SpecNode;
1793
+ key?: Key;
1794
+ ref?: Ref;
1795
+ };
1796
+ /** Valid child types in a SpecifyJS tree */
1797
+ type SpecChild = SpecElement | string | number | boolean | null | undefined;
1798
+ type SpecNode = SpecChild | SpecNode[];
1799
+ /** A functional component */
1800
+ type FunctionComponent<P extends Props = Props> = (props: P) => SpecNode;
1801
+ /** A class component constructor */
1802
+ interface ClassComponentConstructor<P extends Props = Props, S = unknown> {
1803
+ new (props: P): ClassComponentInstance<P, S>;
1804
+ getDerivedStateFromProps?(props: P, state: S): Partial<S> | null;
1805
+ getDerivedStateFromError?(error: unknown): Partial<S> | null;
1806
+ }
1807
+ /** Instance of a class component */
1808
+ interface ClassComponentInstance<P extends Props = Props, S = unknown> {
1809
+ props: P;
1810
+ state: S;
1811
+ setState(updater: Partial<S> | ((prevState: S, props: P) => Partial<S> | null)): void;
1812
+ forceUpdate(callback?: () => void): void;
1813
+ render(): SpecNode;
1814
+ componentDidMount?(): void;
1815
+ componentDidUpdate?(prevProps: P, prevState: S, snapshot?: unknown): void;
1816
+ componentWillUnmount?(): void;
1817
+ shouldComponentUpdate?(nextProps: P, nextState: S): boolean;
1818
+ getSnapshotBeforeUpdate?(prevProps: P, prevState: S): unknown;
1819
+ componentDidCatch?(error: unknown, info: ErrorInfo): void;
1820
+ }
1821
+ interface ErrorInfo {
1822
+ componentStack: string;
1823
+ }
1824
+ /** A component type can be a function, a class, or a special symbol type */
1825
+ type ComponentType<P extends Props = Props> = FunctionComponent<P> | ClassComponentConstructor<P> | string | symbol;
1826
+ /** The core element structure — equivalent to React.Element */
1827
+ interface SpecElement<P extends Props = Props> {
1828
+ $$typeof: typeof SPEC_ELEMENT_TYPE;
1829
+ type: ComponentType<P>;
1830
+ props: P;
1831
+ key: Key;
1832
+ ref: Ref;
1833
+ }
1834
+
1835
+ interface PieSliceDatum {
1836
+ label: string;
1837
+ value: number;
1838
+ color?: string;
1839
+ }
1840
+ interface ComputedSlice {
1841
+ label: string;
1842
+ value: number;
1843
+ startAngle: number;
1844
+ endAngle: number;
1845
+ percentage: number;
1846
+ color: string;
1847
+ }
1848
+ interface PieGraphProps {
1849
+ data: PieSliceDatum[];
1850
+ width?: number;
1851
+ height?: number;
1852
+ innerRadius?: number;
1853
+ outerRadius?: number;
1854
+ padAngle?: number;
1855
+ showLabels?: boolean;
1856
+ showValues?: boolean;
1857
+ showLegend?: boolean;
1858
+ legendPosition?: 'right' | 'bottom';
1859
+ title?: string;
1860
+ centerLabel?: string;
1861
+ colors?: string[];
1862
+ strokeColor?: string;
1863
+ strokeWidth?: number;
1864
+ }
1865
+ /**
1866
+ * Build an SVG path `d` string for an arc (or annular sector).
1867
+ *
1868
+ * Angles are in **radians**, measured clockwise from 12-o'clock
1869
+ * (i.e. -PI/2 offset so 0 rad = top).
1870
+ *
1871
+ * Exported as a public utility so consumers can draw custom arcs.
1872
+ */
1873
+ declare function describeArc(cx: number, cy: number, innerR: number, outerR: number, startAngle: number, endAngle: number): string;
1874
+ /**
1875
+ * Given raw data, compute start/end angles, percentages, and resolved colors.
1876
+ */
1877
+ declare function computeSlices(data: PieSliceDatum[], options?: {
1878
+ padAngle?: number;
1879
+ colors?: string[];
1880
+ }): ComputedSlice[];
1881
+ declare function PieGraph(props: PieGraphProps): SpecElement;
1882
+
1883
+ interface PolarPointInfo {
1884
+ r: number;
1885
+ theta: number;
1886
+ index: number;
1887
+ event: Event;
1888
+ }
1889
+ interface PolarGraph2DProps {
1890
+ width?: number;
1891
+ height?: number;
1892
+ rRange?: [number, number];
1893
+ plotFunction?: (theta: number) => number;
1894
+ plotResolution?: number;
1895
+ points?: {
1896
+ r: number;
1897
+ theta: number;
1898
+ }[];
1899
+ showGrid?: boolean;
1900
+ pointRadius?: number;
1901
+ pointColor?: string;
1902
+ curveColor?: string;
1903
+ onPointClick?: (info: PolarPointInfo) => void;
1904
+ onPointDoubleClick?: (info: PolarPointInfo) => void;
1905
+ onPointContextMenu?: (info: PolarPointInfo) => void;
1906
+ onPointHover?: (info: PolarPointInfo) => void;
1907
+ }
1908
+ declare function PolarGraph2D(props: PolarGraph2DProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
1909
+
1910
+ /**
1911
+ * Hypercube math engine.
1912
+ *
1913
+ * Generates vertices and edges for an N-dimensional hypercube and projects
1914
+ * them to 2D via configurable rotation + orthographic projection.
1915
+ */
1916
+ interface Vec {
1917
+ /** N-dimensional coordinates */
1918
+ coords: number[];
1919
+ }
1920
+ interface Vertex {
1921
+ id: number;
1922
+ /** Original N-dimensional position (each coord 0 or 1) */
1923
+ position: Vec;
1924
+ /** Projected 2D position after rotation */
1925
+ x: number;
1926
+ y: number;
1927
+ /** Projected depth for z-ordering */
1928
+ depth: number;
1929
+ }
1930
+ interface Edge {
1931
+ source: number;
1932
+ target: number;
1933
+ }
1934
+ interface HypercubeData {
1935
+ vertices: Vertex[];
1936
+ edges: Edge[];
1937
+ dimension: number;
1938
+ }
1939
+ /**
1940
+ * Generate all 2^n vertices of an n-dimensional hypercube.
1941
+ * Each vertex is a binary vector of length n, centered at the origin
1942
+ * (coords mapped from {0,1} to {-1,+1}).
1943
+ */
1944
+ declare function generateVertices(dimension: number): Vec[];
1945
+ /**
1946
+ * Generate edges connecting vertices that differ in exactly one coordinate
1947
+ * (Hamming distance 1).
1948
+ */
1949
+ declare function generateEdges(dimension: number): Edge[];
1950
+ /**
1951
+ * Build an N×N rotation matrix that applies rotations in each pair of
1952
+ * coordinate planes. `angles` is an array of rotation angles (radians),
1953
+ * one per plane pair: (0,1), (0,2), (1,2), (0,3), (1,3), (2,3), ...
1954
+ */
1955
+ declare function buildRotationMatrix(dimension: number, angles: number[]): number[][];
1956
+ /**
1957
+ * Apply an N×N matrix to an N-dimensional vector.
1958
+ */
1959
+ declare function transformVec(matrix: number[][], v: Vec): number[];
1960
+ /**
1961
+ * Project an N-dimensional point to 2D using orthographic projection
1962
+ * (just take the first two coordinates) with optional perspective scaling
1963
+ * based on depth (average of remaining coordinates).
1964
+ */
1965
+ declare function projectTo2D(transformed: number[], perspective?: number): {
1966
+ x: number;
1967
+ y: number;
1968
+ depth: number;
1969
+ };
1970
+ /**
1971
+ * Generate a complete projected hypercube.
1972
+ *
1973
+ * @param dimension Number of dimensions (2 = square, 3 = cube, 4 = tesseract, ...)
1974
+ * @param angles Rotation angles for each plane pair
1975
+ * @param perspective Perspective strength (0 = orthographic)
1976
+ * @param scale Scaling factor for output coordinates
1977
+ */
1978
+ declare function generateHypercube(dimension: number, angles?: number[], perspective?: number, scale?: number): HypercubeData;
1979
+ /**
1980
+ * Number of rotation plane-pairs for a given dimension.
1981
+ * This is C(n,2) = n*(n-1)/2.
1982
+ */
1983
+ declare function numRotationAngles(dimension: number): number;
1984
+ /**
1985
+ * Generate a palette of distinct colors for vertices.
1986
+ */
1987
+ declare function generatePalette(count: number, saturation?: number, lightness?: number): string[];
1988
+
1989
+ interface HypercubeGraphProps {
1990
+ /** Number of dimensions (default: 4) */
1991
+ dimension?: number;
1992
+ /** SVG width in pixels (default: 600) */
1993
+ width?: number;
1994
+ /** SVG height in pixels (default: 600) */
1995
+ height?: number;
1996
+ /** Vertex radius in pixels (default: 10) */
1997
+ vertexRadius?: number;
1998
+ /** Edge stroke width (default: 3) */
1999
+ edgeWidth?: number;
2000
+ /** Edge color (default: '#111') */
2001
+ edgeColor?: string;
2002
+ /** Array of vertex colors, or 'auto' for generated palette (default: 'auto') */
2003
+ vertexColors?: string[] | 'auto';
2004
+ /** Perspective strength, 0 = orthographic (default: 0.25) */
2005
+ perspective?: number;
2006
+ /** Auto-rotation speed (radians/frame). 0 = no rotation (default: 0.008) */
2007
+ rotationSpeed?: number;
2008
+ /** Whether to show vertex labels (default: false) */
2009
+ showLabels?: boolean;
2010
+ /** Background color (default: 'transparent') */
2011
+ backgroundColor?: string;
2012
+ /** Scale factor (default: auto-fit) */
2013
+ scale?: number;
2014
+ }
2015
+ declare function HypercubeGraph(props: HypercubeGraphProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
2016
+ interface UseHypercubeOptions {
2017
+ dimension?: number;
2018
+ rotationSpeed?: number;
2019
+ perspective?: number;
2020
+ scale?: number;
2021
+ }
2022
+ /**
2023
+ * Hook that provides hypercube data with auto-animated rotation angles.
2024
+ * Useful for headless rendering or custom SVG layouts.
2025
+ */
2026
+ declare function useHypercube(opts?: UseHypercubeOptions): {
2027
+ data: HypercubeData;
2028
+ angles: number[];
2029
+ setAngles: (action: number[] | ((prev: number[]) => number[])) => void;
2030
+ };
2031
+
2032
+ type Position = 'top' | 'bottom' | 'left' | 'right';
2033
+ interface LegendItem {
2034
+ label: string;
2035
+ color: string;
2036
+ /** Optional dash pattern for line charts (e.g. '5,3') */
2037
+ dash?: string;
2038
+ /** Shape: circle, square, line (default: circle) */
2039
+ shape?: 'circle' | 'square' | 'line';
2040
+ }
2041
+ interface VizWrapperProps {
2042
+ /** Title text */
2043
+ title?: string;
2044
+ /** Position of the title relative to content (default: 'top') */
2045
+ titlePosition?: Position;
2046
+ /** Title alignment: 'start' | 'center' | 'end' (default: 'center') */
2047
+ titleAlign?: 'start' | 'center' | 'end';
2048
+ /** Title font size (default: '16px') */
2049
+ titleFontSize?: string;
2050
+ /** Title font weight (default: '600') */
2051
+ titleFontWeight?: string;
2052
+ /** Title color (default: '#1f2937') */
2053
+ titleColor?: string;
2054
+ /** Legend items */
2055
+ legend?: LegendItem[];
2056
+ /** Position of the legend relative to content (default: 'bottom') */
2057
+ legendPosition?: Position;
2058
+ /** Legend alignment: 'start' | 'center' | 'end' (default: 'center') */
2059
+ legendAlign?: 'start' | 'center' | 'end';
2060
+ /** Legend font size (default: '12px') */
2061
+ legendFontSize?: string;
2062
+ /** Legend item spacing in px (default: 16) */
2063
+ legendGap?: number;
2064
+ /** Container width (default: 'auto') */
2065
+ width?: string | number;
2066
+ /** Container height (default: 'auto') */
2067
+ height?: string | number;
2068
+ /** Background color (default: '#ffffff') */
2069
+ backgroundColor?: string;
2070
+ /** Border (default: '1px solid #e5e7eb') */
2071
+ border?: string;
2072
+ /** Border radius (default: '8px') */
2073
+ borderRadius?: string;
2074
+ /** Padding around the entire wrapper (default: '16px') */
2075
+ padding?: string;
2076
+ /** Gap between title/legend/content (default: '12px') */
2077
+ gap?: string;
2078
+ /** Box shadow (default: none) */
2079
+ boxShadow?: string;
2080
+ /** Font family (default: inherit) */
2081
+ fontFamily?: string;
2082
+ /** CSS contain value for isolation (default: 'layout style paint') */
2083
+ contain?: string;
2084
+ /** Extra className on the outer container */
2085
+ className?: string;
2086
+ /** Extra inline style on the outer container */
2087
+ style?: Record<string, string>;
2088
+ /** The visualization content (children) */
2089
+ children?: unknown;
2090
+ }
2091
+ declare function VizWrapper(props: VizWrapperProps): specifyjs_shared_types.SpecElement<specifyjs_shared_types.Props>;
2092
+
2093
+ export { Accordion, Alert, AnalogClock, Avatar, Badge, BarGraph, Breadcrumb, Card, Carousel, CartesianGraph2D, Checkbox, ColorPicker, ColorWheel, ComplexGraph2D, ContextMenu, DataGrid, DatePicker, DigitalClock, Drawer, Dropdown, EmptyState, FileUpload, FlexContainer, FlexItem, FormFieldWrapper, Grid, GridItem, HypercubeGraph, Image, LineGraph, ListView, Menubar, Modal, MultilineField, NavWrapper, NumberSpinner, Pagination, Panel, PieGraph, PolarGraph2D, Popover, ProgressBar, RadioGroup, ScrollContainer, Select, Sidebar, Skeleton, Slider, Spinner, Splitter, Stepper, Tabs, Tag, TextEditor, TextField, TimePicker, ToastContainer, Toggle, Toolbar, Tooltip, TreeNav, TreeNode, VideoPlayer, VirtualScroll, VizWrapper, buildInputStyle, buildNavItemStyle, buildRotationMatrix, computeSlices, createToaster, describeArc, generateEdges, generateHypercube, generatePalette, generateVertices, numRotationAngles, projectTo2D, transformVec, useBarGraphScales, useHover, useHypercube, useLineGraphScales, useToast };
2094
+ export type { AccordionContentStyle, AccordionHeaderStyle, AccordionProps, AccordionSection, AlertProps, AnalogClockProps, AvatarProps, BadgeProps, BarDatum, BarGraphProps, BarGraphScales, BreadcrumbItem, BreadcrumbProps, BreadcrumbSize, CardProps, CarouselProps, CartesianGraph2DProps, CheckboxProps, ColorPickerProps, ColorWheelProps, ComplexGraph2DProps, ComplexPointInfo, ComputedSlice, ContextMenuItem, ContextMenuProps, DataGridColumn, DataGridProps, DatePickerProps, DigitalClockProps, DrawerPosition, DrawerProps, DropdownItem, DropdownProps, Edge, EmptyStateProps, FileUploadProps, FlexContainerProps, FlexItemProps, FormFieldWrapperProps, FormFieldWrapperStyle, GridBreakpoint, GridItemProps, GridProps, HypercubeData, HypercubeGraphProps, ImageProps, InputBaseStyle, LegendItem, LineGraphProps, LineSeries, ListViewProps, MenuDefinition, MenuItem, MenubarProps, ModalProps, ModalSize, MultilineFieldProps, NavItemStyle, NavOrientation, NavWrapperProps, NavWrapperStyle, NumberSpinnerProps, PaginationProps, PanelProps, PieGraphProps, PieSliceDatum, Point, PointEvent, PolarGraph2DProps, PolarPointInfo, PopoverPlacement, PopoverProps, Position, ProgressBarProps, RadioGroupProps, RadioOption, ScrollContainerProps, SelectOption, SelectProps, SidebarItem, SidebarProps, SkeletonProps, SliderMark, SliderProps, SpinnerProps, SplitterProps, StackedBarDatum, StepItem, StepperOrientation, StepperProps, StepperVariant, TabDefinition, TabsProps, TagProps, TextEditorProps, TextFieldProps, TimePickerProps, ToastAction, ToastItem, ToastOptions, ToastPosition, ToastType, Toaster, ToasterConfig, ToggleProps, ToolbarButton, ToolbarItem, ToolbarProps, ToolbarSize, ToolbarVariant, TooltipPlacement, TooltipProps, TreeNavProps, TreeNodeData, UseHypercubeOptions, Vec, Vertex, VideoPlayerProps, VirtualScrollProps, VizWrapperProps };