mtrl-addons 0.5.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,32 +1,592 @@
1
1
  # mtrl-addons
2
2
 
3
- Additional components and utilities for the mtrl library, featuring specialized elements, and extended functionality for modern applications.
3
+ > Extended components and utilities for the [mtrl](https://github.com/nicholasgriffintn/mtrl) Material Design 3 component library
4
+
5
+ mtrl-addons provides high-performance, specialized components and core systems that extend mtrl's capabilities for building modern web applications. Built with the same functional composition philosophy and zero external dependencies (except mtrl as a peer dependency).
6
+
7
+ ## Features
8
+
9
+ - 🚀 **Virtual Scrolling** - Handle millions of items with smooth 60fps scrolling
10
+ - 📝 **Form Builder** - Declarative form creation with validation and state management
11
+ - 🎨 **Color Picker** - Full-featured HSV picker with swatches, pipette, and variants
12
+ - 📐 **Layout System** - Flexible array-based layout schemas with JSX support
13
+ - 👆 **Gesture Recognition** - Touch and mouse gesture detection (tap, swipe, pinch, etc.)
14
+ - 🎯 **Viewport System** - Composable virtual scrolling foundation
15
+ - 🌳 **Tree-Shaking Optimized** - Import only what you need
4
16
 
5
17
  ## Installation
6
18
 
7
19
  ```bash
8
- npm install mtrl-addons
20
+ # npm
21
+ npm install mtrl-addons mtrl
22
+
23
+ # yarn
24
+ yarn add mtrl-addons mtrl
25
+
26
+ # bun
27
+ bun add mtrl-addons mtrl
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ```javascript
33
+ import { createVList, createForm, createColorPicker } from 'mtrl-addons';
34
+ ```
35
+
36
+ ## Tree-Shaking Optimized Imports
37
+
38
+ mtrl-addons is optimized for tree-shaking. Constants are exported separately from component creators to minimize bundle size.
39
+
40
+ ### Import Patterns
41
+
42
+ | Import Type | Path |
43
+ |-------------|------|
44
+ | Component creators | `import { createColorPicker } from 'mtrl-addons'` |
45
+ | ColorPicker constants | `import { COLORPICKER_EVENTS } from 'mtrl-addons/components/colorpicker/constants'` |
46
+ | Form constants | `import { FORM_EVENTS, DATA_STATE } from 'mtrl-addons/components/form/constants'` |
47
+ | VList constants | `import { VLIST_CLASSES } from 'mtrl-addons/components/vlist/constants'` |
48
+ | Color utilities | `import { hsvToRgb, rgbToHex } from 'mtrl-addons'` |
49
+ | Layout system | `import { createLayout } from 'mtrl-addons/layout'` |
50
+ | Viewport system | `import { createViewport } from 'mtrl-addons/viewport'` |
51
+ | Gestures | `import { createGestureManager } from 'mtrl-addons/gestures'` |
52
+
53
+ ---
54
+
55
+ ## Components
56
+
57
+ ### VList (Virtual List)
58
+
59
+ High-performance virtual scrolling list for large datasets. Renders only visible items while maintaining smooth scrolling with millions of rows.
60
+
61
+ #### Features
62
+ - 📊 Handles 100,000+ items efficiently
63
+ - 🔍 Built-in search with debouncing
64
+ - 🎛️ Filter panel integration
65
+ - ⌨️ Keyboard navigation
66
+ - 📍 Scroll position restoration
67
+ - 🎯 Item selection (single/multi)
68
+ - 📈 Stats tracking (render time, visible items)
69
+ - ⚡ Velocity-based scroll optimization
70
+
71
+ #### Basic Usage
72
+
73
+ ```javascript
74
+ import { createVList } from 'mtrl-addons';
75
+
76
+ const vlist = createVList({
77
+ container: '#my-list',
78
+ template: (item) => ({
79
+ class: 'list-item',
80
+ children: [
81
+ { tag: 'span', class: 'name', text: item.name },
82
+ { tag: 'span', class: 'email', text: item.email }
83
+ ]
84
+ }),
85
+ collection: {
86
+ adapter: {
87
+ read: async ({ page, limit }) => {
88
+ const response = await fetch(`/api/users?page=${page}&limit=${limit}`);
89
+ return response.json();
90
+ }
91
+ }
92
+ }
93
+ });
94
+ ```
95
+
96
+ #### With Layout, Search & Filters
97
+
98
+ ```javascript
99
+ import { createVList } from 'mtrl-addons';
100
+ import { createIconButton, createSearch, createSelect } from 'mtrl';
101
+
102
+ const vlist = createVList({
103
+ container: '#users-list',
104
+ class: 'users',
105
+
106
+ // Layout schema - declarative UI structure
107
+ layout: [
108
+ ['head', { class: 'list-head' },
109
+ [createIconButton, 'searchBtn', { icon: iconSearch, toggle: true }],
110
+ [createIconButton, 'filterBtn', { icon: iconFilter, toggle: true }]
111
+ ],
112
+ ['filter-panel', { class: 'filter-panel' },
113
+ [createSelect, 'country', { label: 'Country', options: countries }],
114
+ [createSelect, 'role', { label: 'Role', options: roles }]
115
+ ],
116
+ [createSearch, 'searchBar', { placeholder: 'Search users...' }],
117
+ ['viewport'], // Virtual scrolling area
118
+ ['foot', { class: 'list-foot' },
119
+ ['stats', { text: 'Loading...' }]
120
+ ]
121
+ ],
122
+
123
+ // Search configuration
124
+ search: {
125
+ toggleButton: 'searchBtn',
126
+ searchBar: 'searchBar',
127
+ debounce: 300
128
+ },
129
+
130
+ // Filter configuration
131
+ filter: {
132
+ toggleButton: 'filterBtn',
133
+ panel: 'filter-panel',
134
+ controls: {
135
+ country: 'country',
136
+ role: 'role'
137
+ }
138
+ },
139
+
140
+ // Stats display
141
+ stats: {
142
+ element: 'stats',
143
+ format: ({ total, rendered }) => `${rendered} of ${total} users`
144
+ },
145
+
146
+ template: userTemplate,
147
+ collection: {
148
+ adapter: {
149
+ read: async ({ page, limit, search, filters }) => {
150
+ // search and filters are automatically populated
151
+ return fetchUsers({ page, limit, search, ...filters });
152
+ }
153
+ }
154
+ }
155
+ });
156
+
157
+ // Events
158
+ vlist.on('search:change', ({ query }) => console.log('Search:', query));
159
+ vlist.on('filter:change', ({ filters }) => console.log('Filters:', filters));
160
+ vlist.on('item:select', ({ item }) => console.log('Selected:', item));
161
+
162
+ // API
163
+ vlist.search('john');
164
+ vlist.setFilter('country', 'US');
165
+ vlist.scrollToIndex(50);
166
+ vlist.refresh();
167
+ ```
168
+
169
+ ---
170
+
171
+ ### Form
172
+
173
+ Functional form builder with declarative field configuration, validation, and state management.
174
+
175
+ #### Features
176
+ - 📋 Declarative field definitions
177
+ - ✅ Built-in validation rules
178
+ - 🔄 Dirty/pristine state tracking
179
+ - 🛡️ Unsaved changes protection
180
+ - 📤 Submit handling with loading states
181
+ - 🎯 Field-level error handling
182
+
183
+ #### Basic Usage
184
+
185
+ ```javascript
186
+ import { createForm } from 'mtrl-addons';
187
+ import { FORM_EVENTS, DATA_STATE } from 'mtrl-addons/components/form/constants';
188
+
189
+ const form = createForm({
190
+ fields: [
191
+ { name: 'email', type: 'email', label: 'Email', required: true },
192
+ { name: 'password', type: 'password', label: 'Password', required: true },
193
+ { name: 'remember', type: 'checkbox', label: 'Remember me' }
194
+ ],
195
+
196
+ // Protect unsaved changes
197
+ protectChanges: {
198
+ beforeUnload: true, // Warn on page close
199
+ onDataOverwrite: true // Emit event when setData() called with changes
200
+ },
201
+
202
+ onSubmit: async (data) => {
203
+ await api.login(data);
204
+ }
205
+ });
206
+
207
+ // Mount to container
208
+ document.getElementById('login-form').appendChild(form.element);
209
+
210
+ // Events
211
+ form.on(FORM_EVENTS.CHANGE, ({ field, value }) => {
212
+ console.log(`${field} changed to:`, value);
213
+ });
214
+
215
+ form.on(FORM_EVENTS.STATE_CHANGE, ({ state }) => {
216
+ if (state === DATA_STATE.DIRTY) {
217
+ console.log('Form has unsaved changes');
218
+ }
219
+ });
220
+
221
+ form.on(FORM_EVENTS.SUBMIT, (data) => {
222
+ console.log('Form submitted:', data);
223
+ });
224
+
225
+ form.on(FORM_EVENTS.DATA_CONFLICT, ({ currentData, newData, cancel, proceed }) => {
226
+ if (confirm('Discard unsaved changes?')) {
227
+ proceed();
228
+ } else {
229
+ cancel();
230
+ }
231
+ });
232
+
233
+ // API
234
+ form.setData({ email: 'user@example.com' });
235
+ const data = form.getData();
236
+ const isValid = form.validate();
237
+ form.reset();
238
+ form.disable();
239
+ form.enable();
9
240
  ```
10
241
 
11
- ## Usage
242
+ ---
243
+
244
+ ### ColorPicker
245
+
246
+ Full-featured color picker with HSV color area, hue slider, swatches, and multiple display variants.
247
+
248
+ #### Features
249
+ - 🎨 HSV color area with saturation/brightness
250
+ - 📊 Hue slider
251
+ - 🔲 Opacity/alpha slider (optional)
252
+ - 💎 Color swatches with add/remove
253
+ - 💉 Pipette/eyedropper (native API or canvas sampling)
254
+ - 📝 Hex input field
255
+ - 🖼️ Multiple variants: inline, dropdown, dialog
256
+ - 📱 Compact density mode
257
+
258
+ #### Basic Usage
12
259
 
13
260
  ```javascript
14
- import { version } from 'mtrl-addons';
261
+ import { createColorPicker } from 'mtrl-addons';
262
+ import { COLORPICKER_EVENTS, COLORPICKER_VARIANTS } from 'mtrl-addons/components/colorpicker/constants';
263
+
264
+ // Inline picker (always visible)
265
+ const picker = createColorPicker({
266
+ value: '#6200ee',
267
+ showSwatches: true,
268
+ swatches: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff']
269
+ });
270
+
271
+ document.getElementById('color-picker').appendChild(picker.element);
272
+
273
+ // Events
274
+ picker.on(COLORPICKER_EVENTS.CHANGE, ({ value }) => {
275
+ console.log('Color selected:', value);
276
+ });
277
+
278
+ picker.on(COLORPICKER_EVENTS.INPUT, ({ value }) => {
279
+ // Live preview during drag
280
+ document.body.style.backgroundColor = value;
281
+ });
282
+
283
+ // API
284
+ picker.setValue('#ff5722');
285
+ const hex = picker.getValue(); // '#ff5722'
286
+ const hsv = picker.getHSV(); // { h: 14, s: 86, v: 100 }
287
+ const rgb = picker.getRGB(); // { r: 255, g: 87, b: 34 }
288
+
289
+ picker.addSwatch('#9c27b0', 'Purple');
290
+ picker.setOpacity(0.5);
15
291
  ```
16
292
 
293
+ #### Dropdown Variant
294
+
295
+ ```javascript
296
+ const trigger = document.getElementById('color-button');
297
+
298
+ const picker = createColorPicker({
299
+ value: '#6200ee',
300
+ variant: COLORPICKER_VARIANTS.DROPDOWN,
301
+ trigger: trigger,
302
+ closeOnSelect: true
303
+ });
304
+
305
+ // Toggle programmatically
306
+ picker.open();
307
+ picker.close();
308
+ picker.toggle();
309
+ ```
310
+
311
+ #### With Pipette (Color Sampling)
312
+
313
+ ```javascript
314
+ const picker = createColorPicker({
315
+ value: '#ffffff',
316
+ showPipette: true,
317
+ // Optional: provide image for canvas-based sampling
318
+ imageSource: document.getElementById('my-image'),
319
+
320
+ onPipetteStart: () => console.log('Sampling started'),
321
+ onPipetteEnd: (color) => console.log('Picked:', color)
322
+ });
323
+
324
+ // Trigger programmatically
325
+ const pickedColor = await picker.pickColor();
326
+ ```
327
+
328
+ ---
329
+
330
+ ## Core Systems
331
+
332
+ ### Layout System
333
+
334
+ Flexible array-based layout schemas for declarative UI construction. Supports mtrl components, HTML elements, and nested structures.
335
+
336
+ ```javascript
337
+ import { createLayout } from 'mtrl-addons/layout';
338
+ import { createButton, createTextField } from 'mtrl';
339
+
340
+ // Array-based schema
341
+ const layout = createLayout([
342
+ 'div', { class: 'form-container' },
343
+ [
344
+ ['header', { class: 'form-header' },
345
+ ['h2', { text: 'Contact Form' }]
346
+ ],
347
+ ['main', { class: 'form-body' },
348
+ [createTextField, 'name', { label: 'Name' }],
349
+ [createTextField, 'email', { label: 'Email', type: 'email' }],
350
+ [createTextField, 'message', { label: 'Message', multiline: true }]
351
+ ],
352
+ ['footer', { class: 'form-footer' },
353
+ [createButton, 'submit', { text: 'Send', variant: 'filled' }],
354
+ [createButton, 'cancel', { text: 'Cancel', variant: 'outlined' }]
355
+ ]
356
+ ]
357
+ ]);
358
+
359
+ // Access named components
360
+ layout.name.setValue('John Doe');
361
+ layout.submit.on('click', handleSubmit);
362
+
363
+ // Append to DOM
364
+ document.body.appendChild(layout.element);
365
+ ```
366
+
367
+ #### Convenience Functions
368
+
369
+ ```javascript
370
+ import { layout, row, stack, grid } from 'mtrl-addons/layout';
371
+
372
+ // Vertical stack
373
+ const stackLayout = stack({ gap: '1rem' });
374
+
375
+ // Horizontal row (mobile-stacks automatically)
376
+ const rowLayout = row({ gap: '1rem', mobileStack: true });
377
+
378
+ // Responsive grid
379
+ const gridLayout = grid('auto-fit', { gap: '1rem' });
380
+ ```
381
+
382
+ ---
383
+
384
+ ### Viewport System
385
+
386
+ Low-level composable virtual scrolling foundation. Used internally by VList but available for custom implementations.
387
+
388
+ ```javascript
389
+ import { createViewport } from 'mtrl-addons/viewport';
390
+
391
+ const viewport = createViewport({
392
+ container: document.getElementById('scroll-container'),
393
+ itemCount: 100000,
394
+ estimatedItemSize: 48,
395
+ overscan: 5, // Extra items to render outside viewport
396
+
397
+ renderItem: (index) => {
398
+ const div = document.createElement('div');
399
+ div.textContent = `Item ${index}`;
400
+ return div;
401
+ },
402
+
403
+ onRangeChange: ({ start, end }) => {
404
+ console.log(`Rendering items ${start} to ${end}`);
405
+ }
406
+ });
407
+
408
+ // API
409
+ viewport.scrollToIndex(500);
410
+ viewport.refresh();
411
+ viewport.destroy();
412
+ ```
413
+
414
+ #### Feature Composition
415
+
416
+ ```javascript
417
+ import {
418
+ withBase,
419
+ withVirtual,
420
+ withScrolling,
421
+ withRendering
422
+ } from 'mtrl-addons/viewport';
423
+
424
+ // Build custom viewport with specific features
425
+ const customViewport = pipe(
426
+ withBase,
427
+ withVirtual,
428
+ withScrolling,
429
+ withRendering
430
+ )(config);
431
+ ```
432
+
433
+ ---
434
+
435
+ ### Gesture System
436
+
437
+ Touch and mouse gesture recognition with support for tap, swipe, long-press, pinch, rotate, and pan.
438
+
439
+ ```javascript
440
+ import { createGestureManager } from 'mtrl-addons/gestures';
441
+
442
+ const gestures = createGestureManager(element, {
443
+ // Tap detection
444
+ onTap: ({ x, y, target }) => {
445
+ console.log('Tapped at', x, y);
446
+ },
447
+
448
+ // Swipe detection
449
+ onSwipe: ({ direction, velocity, distance }) => {
450
+ console.log(`Swiped ${direction} with velocity ${velocity}`);
451
+ },
452
+
453
+ // Long press
454
+ onLongPress: ({ x, y, duration }) => {
455
+ console.log('Long pressed for', duration, 'ms');
456
+ },
457
+
458
+ // Pinch (zoom)
459
+ onPinch: ({ scale, center }) => {
460
+ element.style.transform = `scale(${scale})`;
461
+ },
462
+
463
+ // Rotation
464
+ onRotate: ({ angle, center }) => {
465
+ element.style.transform = `rotate(${angle}deg)`;
466
+ },
467
+
468
+ // Pan (drag)
469
+ onPan: ({ deltaX, deltaY, state }) => {
470
+ if (state === 'move') {
471
+ element.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
472
+ }
473
+ }
474
+ });
475
+
476
+ // Configuration
477
+ const gestures = createGestureManager(element, {
478
+ tap: { maxDuration: 300 },
479
+ swipe: { minDistance: 50, minVelocity: 0.3 },
480
+ longPress: { duration: 500 },
481
+ pinch: { minScale: 0.5, maxScale: 3 }
482
+ });
483
+
484
+ // Cleanup
485
+ gestures.destroy();
486
+ ```
487
+
488
+ #### Individual Gesture Detectors
489
+
490
+ ```javascript
491
+ import { detectTap, detectSwipe, detectPinch } from 'mtrl-addons/gestures';
492
+
493
+ // Use specific detectors for lighter bundles
494
+ const tapDetector = detectTap(element, { onTap: handleTap });
495
+ const swipeDetector = detectSwipe(element, { onSwipe: handleSwipe });
496
+ ```
497
+
498
+ ---
499
+
500
+ ## Color Utilities
501
+
502
+ Pure functions for color conversion (tree-shakeable, included in main bundle).
503
+
504
+ ```javascript
505
+ import {
506
+ hsvToRgb,
507
+ rgbToHsv,
508
+ hsvToHex,
509
+ hexToHsv,
510
+ rgbToHex,
511
+ hexToRgb,
512
+ isValidHex,
513
+ normalizeHex,
514
+ getContrastColor
515
+ } from 'mtrl-addons';
516
+
517
+ // HSV ↔ RGB
518
+ const rgb = hsvToRgb({ h: 200, s: 80, v: 90 }); // { r: 46, g: 184, b: 230 }
519
+ const hsv = rgbToHsv({ r: 255, g: 128, b: 0 }); // { h: 30, s: 100, v: 100 }
520
+
521
+ // Hex conversions
522
+ const hex = rgbToHex({ r: 255, g: 0, b: 128 }); // '#ff0080'
523
+ const rgb2 = hexToRgb('#ff0080'); // { r: 255, g: 0, b: 128 }
524
+
525
+ // Validation & normalization
526
+ isValidHex('#ff0080'); // true
527
+ isValidHex('ff0080'); // true
528
+ normalizeHex('f00'); // '#ff0000'
529
+ normalizeHex('#F00'); // '#ff0000'
530
+
531
+ // Contrast color (for text on colored backgrounds)
532
+ getContrastColor('#ffffff'); // '#000000'
533
+ getContrastColor('#000000'); // '#ffffff'
534
+ ```
535
+
536
+ ---
537
+
17
538
  ## Development
18
539
 
19
540
  ```bash
20
541
  # Install dependencies
21
542
  bun install
22
543
 
23
- # Build
544
+ # Build package (for distribution)
24
545
  bun run build
25
546
 
26
- # Test
547
+ # Build for mtrl-app integration
548
+ bun run build:app
549
+
550
+ # Run tests
27
551
  bun test
552
+
553
+ # Watch mode
554
+ bun run dev
555
+
556
+ # Link mtrl for local development
557
+ bun run link:mtrl
28
558
  ```
29
559
 
560
+ ## Browser Support
561
+
562
+ mtrl-addons supports modern browsers:
563
+
564
+ - Chrome (latest)
565
+ - Firefox (latest)
566
+ - Safari (latest)
567
+ - Edge (latest)
568
+
569
+ ## Peer Dependencies
570
+
571
+ - `mtrl` ^0.6.2 - Core Material Design 3 component library
572
+
573
+ ## Related Packages
574
+
575
+ - [mtrl](https://github.com/floor/mtrl) - Core Material Design 3 component library
576
+ - [mtrl-app](https://github.com/floor/mtrl-app) - Documentation and showcase application
577
+
30
578
  ## License
31
579
 
32
- MIT
580
+ MIT
581
+
582
+ ## Contributing
583
+
584
+ Contributions are welcome! Please follow the existing code style and include tests for new features.
585
+
586
+ ```bash
587
+ # Run tests before submitting
588
+ bun test
589
+
590
+ # Build to verify no errors
591
+ bun run build
592
+ ```
@@ -24,20 +24,27 @@ export declare const getFieldValue: (field: FormField) => FieldValue;
24
24
  */
25
25
  export declare const setFieldValue: (field: FormField, value: FieldValue, silent?: boolean) => void;
26
26
  /**
27
- * Updates the tracked value for a field
28
- * Called when setData is used with silent=true to keep deduplication in sync
27
+ * Binds change and input events to fields
28
+ * Calls the provided callback when any field changes
29
+ *
30
+ * Listens to both 'input' (for immediate feedback while typing)
31
+ * and 'change' (for components that only emit on blur/selection)
32
+ *
33
+ * Deduplicates events to prevent double-firing when both input and change
34
+ * emit for the same value (e.g., textfield input followed by blur)
29
35
  */
30
- export declare const updateTrackedFieldValue: (name: string, value: FieldValue) => void;
31
36
  /**
32
- * Updates all tracked field values from a fields registry
33
- * Called after silent setData to sync deduplication state
37
+ * Updates the tracked value for a field in the given tracker
34
38
  */
35
- export declare const syncTrackedFieldValues: (fields: FormFieldRegistry) => void;
39
+ export declare const updateTrackedFieldValue: (name: string, value: FieldValue, tracker?: Map<string, FieldValue>) => void;
36
40
  /**
37
- * Resets the field value tracker for a new form
38
- * Should be called at the start of withFields before bindFieldEvents
41
+ * Updates all tracked field values from a fields registry
42
+ * Called after silent setData to sync deduplication state
43
+ *
44
+ * @param fields - The form's field registry
45
+ * @param tracker - The per-form tracker map (stored on the component as _fieldValueTracker)
39
46
  */
40
- export declare const resetFieldValueTracker: () => void;
47
+ export declare const syncTrackedFieldValues: (fields: FormFieldRegistry, tracker?: Map<string, FieldValue>) => void;
41
48
  /**
42
49
  * withFields feature
43
50
  * Adds field extraction and registry management to the form
@@ -3,7 +3,7 @@
3
3
  * Each feature adds specific capabilities to the form component
4
4
  */
5
5
  export { withLayout } from "./layout";
6
- export { withFields, getFieldValue, setFieldValue, updateTrackedFieldValue, syncTrackedFieldValues, resetFieldValueTracker, } from "./fields";
6
+ export { withFields, getFieldValue, setFieldValue, updateTrackedFieldValue, syncTrackedFieldValues, } from "./fields";
7
7
  export { withData, flatToNested, getNestedValue, setNestedValue } from "./data";
8
8
  export { withController } from "./controller";
9
9
  export { withSubmit, validateData, performRequest } from "./submit";
@@ -1,14 +1,18 @@
1
1
  /**
2
2
  * Components Module Exports
3
3
  *
4
- * Central export point for all components
4
+ * Central export point for all components.
5
+ *
6
+ * NOTE: Constants are NOT exported here to enable tree-shaking.
7
+ * Import constants directly from the component's constants file:
8
+ * import { COLORPICKER_EVENTS } from 'mtrl-addons/components/colorpicker/constants'
9
+ * import { FORM_EVENTS } from 'mtrl-addons/components/form/constants'
10
+ * import { VLIST_CLASSES } from 'mtrl-addons/components/vlist/constants'
5
11
  */
6
12
  export { createVList } from "./vlist";
7
13
  export type { VListConfig, VListComponent } from "./vlist/types";
8
14
  export { createForm } from "./form";
9
15
  export type { FormConfig, FormComponent, FormField, FormData, DataState, FormState, FormValidationRule, FormValidationResult, FormSubmitOptions, FormEventHandlers, FieldValue, SubmitHandler, CancelHandler, } from "./form/types";
10
- export { DATA_STATE, FORM_EVENTS, FORM_CLASSES, FORM_DEFAULTS, } from "./form/constants";
11
16
  export { createColorPicker } from "./colorpicker";
12
17
  export type { ColorPickerConfig, ColorPickerComponent, HSVColor, RGBColor, ColorSwatch, } from "./colorpicker/types";
13
- export { COLORPICKER_EVENTS, COLORPICKER_SIZES, COLORPICKER_VARIANTS, COLORPICKER_CLASSES, COLORPICKER_DEFAULTS, SWATCH_SIZES, PALETTE_SWATCH_ORDER, } from "./colorpicker/constants";
14
18
  export { hsvToRgb, rgbToHsv, hsvToHex, hexToHsv, rgbToHex, hexToRgb, isValidHex, normalizeHex, getContrastColor, } from "./colorpicker/utils";