@brycks/core-front 0.3.1 → 0.3.2

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 (109) hide show
  1. package/dist/components/data/List/List.cjs +1 -1
  2. package/dist/components/data/List/List.cjs.map +1 -1
  3. package/dist/components/data/List/List.js +92 -88
  4. package/dist/components/data/List/List.js.map +1 -1
  5. package/dist/components/data/Table/Table.cjs +1 -1
  6. package/dist/components/data/Table/Table.cjs.map +1 -1
  7. package/dist/components/data/Table/Table.js +129 -125
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +2 -0
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -0
  11. package/dist/components/data/TreeView/TreeView.js +256 -0
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -0
  13. package/dist/components/data/VirtualList/VirtualList.cjs +2 -0
  14. package/dist/components/data/VirtualList/VirtualList.cjs.map +1 -0
  15. package/dist/components/data/VirtualList/VirtualList.js +186 -0
  16. package/dist/components/data/VirtualList/VirtualList.js.map +1 -0
  17. package/dist/components/data.cjs +1 -1
  18. package/dist/components/data.js +21 -16
  19. package/dist/components/data.js.map +1 -1
  20. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  21. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  22. package/dist/components/feedback/Modal/Modal.js +81 -77
  23. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  24. package/dist/components/form/Combobox/Combobox.cjs +7 -0
  25. package/dist/components/form/Combobox/Combobox.cjs.map +1 -0
  26. package/dist/components/form/Combobox/Combobox.js +338 -0
  27. package/dist/components/form/Combobox/Combobox.js.map +1 -0
  28. package/dist/components/form/DateRangePicker/DateRangePicker.cjs +2 -0
  29. package/dist/components/form/DateRangePicker/DateRangePicker.cjs.map +1 -0
  30. package/dist/components/form/DateRangePicker/DateRangePicker.js +372 -0
  31. package/dist/components/form/DateRangePicker/DateRangePicker.js.map +1 -0
  32. package/dist/components/form/MultiSelect/MultiSelect.cjs +2 -0
  33. package/dist/components/form/MultiSelect/MultiSelect.cjs.map +1 -0
  34. package/dist/components/form/MultiSelect/MultiSelect.js +393 -0
  35. package/dist/components/form/MultiSelect/MultiSelect.js.map +1 -0
  36. package/dist/components/form/Rating/Rating.cjs +2 -0
  37. package/dist/components/form/Rating/Rating.cjs.map +1 -0
  38. package/dist/components/form/Rating/Rating.js +163 -0
  39. package/dist/components/form/Rating/Rating.js.map +1 -0
  40. package/dist/components/form/Slider/Slider.cjs +1 -1
  41. package/dist/components/form/Slider/Slider.cjs.map +1 -1
  42. package/dist/components/form/Slider/Slider.js +120 -85
  43. package/dist/components/form/Slider/Slider.js.map +1 -1
  44. package/dist/components/form/TagInput/TagInput.cjs +2 -0
  45. package/dist/components/form/TagInput/TagInput.cjs.map +1 -0
  46. package/dist/components/form/TagInput/TagInput.js +286 -0
  47. package/dist/components/form/TagInput/TagInput.js.map +1 -0
  48. package/dist/components/form/TimePicker/TimePicker.cjs +2 -0
  49. package/dist/components/form/TimePicker/TimePicker.cjs.map +1 -0
  50. package/dist/components/form/TimePicker/TimePicker.js +328 -0
  51. package/dist/components/form/TimePicker/TimePicker.js.map +1 -0
  52. package/dist/components/form.cjs +1 -1
  53. package/dist/components/form.js +34 -22
  54. package/dist/components/form.js.map +1 -1
  55. package/dist/components/layout/Card/Card.cjs +1 -1
  56. package/dist/components/layout/Card/Card.cjs.map +1 -1
  57. package/dist/components/layout/Card/Card.js +62 -59
  58. package/dist/components/layout/Card/Card.js.map +1 -1
  59. package/dist/components/layout/Collapse/Collapse.cjs +2 -0
  60. package/dist/components/layout/Collapse/Collapse.cjs.map +1 -0
  61. package/dist/components/layout/Collapse/Collapse.js +140 -0
  62. package/dist/components/layout/Collapse/Collapse.js.map +1 -0
  63. package/dist/components/layout.cjs +1 -1
  64. package/dist/components/layout.js +27 -24
  65. package/dist/components/layout.js.map +1 -1
  66. package/dist/components/navigation/Breadcrumb/Breadcrumb.cjs +1 -1
  67. package/dist/components/navigation/Breadcrumb/Breadcrumb.cjs.map +1 -1
  68. package/dist/components/navigation/Breadcrumb/Breadcrumb.js +66 -62
  69. package/dist/components/navigation/Breadcrumb/Breadcrumb.js.map +1 -1
  70. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +2 -0
  71. package/dist/components/navigation/ContextMenu/ContextMenu.cjs.map +1 -0
  72. package/dist/components/navigation/ContextMenu/ContextMenu.js +227 -0
  73. package/dist/components/navigation/ContextMenu/ContextMenu.js.map +1 -0
  74. package/dist/components/navigation/Dropdown/Dropdown.cjs +2 -2
  75. package/dist/components/navigation/Dropdown/Dropdown.cjs.map +1 -1
  76. package/dist/components/navigation/Dropdown/Dropdown.js +84 -80
  77. package/dist/components/navigation/Dropdown/Dropdown.js.map +1 -1
  78. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  79. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  80. package/dist/components/navigation/Menu/Menu.js +132 -94
  81. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  82. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  83. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  84. package/dist/components/navigation/Pagination/Pagination.js +111 -107
  85. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  86. package/dist/components/navigation/Stepper/Stepper.cjs +2 -0
  87. package/dist/components/navigation/Stepper/Stepper.cjs.map +1 -0
  88. package/dist/components/navigation/Stepper/Stepper.js +187 -0
  89. package/dist/components/navigation/Stepper/Stepper.js.map +1 -0
  90. package/dist/components/navigation.cjs +1 -1
  91. package/dist/components/navigation.js +27 -21
  92. package/dist/components/navigation.js.map +1 -1
  93. package/dist/components/utility/Badge/Badge.cjs +1 -1
  94. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  95. package/dist/components/utility/Badge/Badge.js +38 -35
  96. package/dist/components/utility/Badge/Badge.js.map +1 -1
  97. package/dist/data.d.ts +116 -0
  98. package/dist/form.d.ts +316 -0
  99. package/dist/hooks/useInteractionState.cjs +2 -0
  100. package/dist/hooks/useInteractionState.cjs.map +1 -0
  101. package/dist/hooks/useInteractionState.js +67 -0
  102. package/dist/hooks/useInteractionState.js.map +1 -0
  103. package/dist/hooks.cjs +1 -1
  104. package/dist/hooks.d.ts +87 -0
  105. package/dist/hooks.js +16 -14
  106. package/dist/hooks.js.map +1 -1
  107. package/dist/layout.d.ts +44 -0
  108. package/dist/navigation.d.ts +88 -0
  109. package/package.json +1 -1
package/dist/form.d.ts CHANGED
@@ -31,6 +31,64 @@ export declare interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInpu
31
31
 
32
32
  export declare type CheckboxSize = 'sm' | 'md' | 'lg';
33
33
 
34
+ export declare const Combobox: ForwardRefExoticComponent<ComboboxProps & RefAttributes<HTMLInputElement>>;
35
+
36
+ export declare interface ComboboxOption {
37
+ /** Unique identifier for the option */
38
+ value: string;
39
+ /** Display label */
40
+ label: string;
41
+ /** Optional description */
42
+ description?: string;
43
+ /** Optional icon */
44
+ icon?: ReactNode;
45
+ /** Whether the option is disabled */
46
+ disabled?: boolean;
47
+ }
48
+
49
+ export declare interface ComboboxProps {
50
+ /** Available options */
51
+ options: ComboboxOption[];
52
+ /** Currently selected value (controlled) */
53
+ value?: string | null;
54
+ /** Default selected value (uncontrolled) */
55
+ defaultValue?: string | null;
56
+ /** Callback when selection changes */
57
+ onChange?: (value: string | null) => void;
58
+ /** Callback when input value changes */
59
+ onInputChange?: (value: string) => void;
60
+ /** Placeholder text */
61
+ placeholder?: string;
62
+ /** Component size */
63
+ size?: ComboboxSize;
64
+ /** Whether the combobox is disabled */
65
+ disabled?: boolean;
66
+ /** Whether the combobox is invalid */
67
+ isInvalid?: boolean;
68
+ /** Whether the combobox is required */
69
+ required?: boolean;
70
+ /** Whether to allow clearing the selection */
71
+ clearable?: boolean;
72
+ /** Label for accessibility */
73
+ 'aria-label'?: string;
74
+ /** ID of element that labels this combobox */
75
+ 'aria-labelledby'?: string;
76
+ /** Custom filter function */
77
+ filterFn?: (option: ComboboxOption, inputValue: string) => boolean;
78
+ /** Text to show when no options match */
79
+ emptyText?: string;
80
+ /** Whether to allow creating new options */
81
+ creatable?: boolean;
82
+ /** Callback when creating new option */
83
+ onCreate?: (inputValue: string) => void;
84
+ /** Custom class name */
85
+ className?: string;
86
+ /** Test ID */
87
+ testId?: string;
88
+ }
89
+
90
+ export declare type ComboboxSize = 'sm' | 'md' | 'lg';
91
+
34
92
  export declare const DateInput: ForwardRefExoticComponent<DateInputProps & RefAttributes<HTMLInputElement>>;
35
93
 
36
94
  export declare interface DateInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {
@@ -62,6 +120,61 @@ export declare type DateInputType = 'date' | 'datetime-local' | 'time' | 'month'
62
120
 
63
121
  export declare type DateInputVariant = 'outline' | 'filled' | 'flushed';
64
122
 
123
+ export declare interface DateRange {
124
+ start: Date | null;
125
+ end: Date | null;
126
+ }
127
+
128
+ export declare const DateRangePicker: ForwardRefExoticComponent<DateRangePickerProps & RefAttributes<HTMLDivElement>>;
129
+
130
+ export declare interface DateRangePickerProps {
131
+ /** Current date range value */
132
+ value?: DateRange;
133
+ /** Default date range value (uncontrolled) */
134
+ defaultValue?: DateRange;
135
+ /** Callback when date range changes */
136
+ onChange?: (value: DateRange) => void;
137
+ /** Component size */
138
+ size?: DateRangePickerSize;
139
+ /** Minimum selectable date */
140
+ minDate?: Date;
141
+ /** Maximum selectable date */
142
+ maxDate?: Date;
143
+ /** Placeholder text */
144
+ placeholder?: string;
145
+ /** Whether the input is disabled */
146
+ disabled?: boolean;
147
+ /** Whether the input is invalid */
148
+ isInvalid?: boolean;
149
+ /** Whether to allow clearing */
150
+ clearable?: boolean;
151
+ /** Preset date ranges */
152
+ presets?: DateRangePreset[];
153
+ /** Date format display */
154
+ dateFormat?: (date: Date) => string;
155
+ /** Label for accessibility */
156
+ 'aria-label'?: string;
157
+ /** Custom class name */
158
+ className?: string;
159
+ /** Test ID */
160
+ testId?: string;
161
+ }
162
+
163
+ /**
164
+ * DateRangePicker Component
165
+ *
166
+ * A date range selection component with calendar UI.
167
+ * Supports preset ranges and custom date selection.
168
+ *
169
+ * @module components/form/DateRangePicker
170
+ */
171
+ export declare type DateRangePickerSize = 'sm' | 'md' | 'lg';
172
+
173
+ export declare interface DateRangePreset {
174
+ label: string;
175
+ getValue: () => DateRange;
176
+ }
177
+
65
178
  export declare const FieldError: ForwardRefExoticComponent<FieldErrorProps & RefAttributes<HTMLSpanElement>>;
66
179
 
67
180
  export declare interface FieldErrorProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
@@ -245,6 +358,62 @@ export declare type InputSize = 'sm' | 'md' | 'lg';
245
358
 
246
359
  export declare type InputVariant = 'outline' | 'filled' | 'flushed';
247
360
 
361
+ export declare const MultiSelect: ForwardRefExoticComponent<MultiSelectProps & RefAttributes<HTMLDivElement>>;
362
+
363
+ export declare interface MultiSelectOption {
364
+ /** Unique identifier */
365
+ value: string;
366
+ /** Display label */
367
+ label: string;
368
+ /** Optional description */
369
+ description?: string;
370
+ /** Optional icon */
371
+ icon?: ReactNode;
372
+ /** Whether the option is disabled */
373
+ disabled?: boolean;
374
+ /** Optional group */
375
+ group?: string;
376
+ }
377
+
378
+ export declare interface MultiSelectProps {
379
+ /** Available options */
380
+ options: MultiSelectOption[];
381
+ /** Selected values (controlled) */
382
+ value?: string[];
383
+ /** Default selected values (uncontrolled) */
384
+ defaultValue?: string[];
385
+ /** Callback when selection changes */
386
+ onChange?: (values: string[]) => void;
387
+ /** Placeholder text */
388
+ placeholder?: string;
389
+ /** Component size */
390
+ size?: MultiSelectSize;
391
+ /** Maximum selections allowed */
392
+ maxSelections?: number;
393
+ /** Whether the select is searchable */
394
+ searchable?: boolean;
395
+ /** Whether the select is disabled */
396
+ disabled?: boolean;
397
+ /** Whether the select is invalid */
398
+ isInvalid?: boolean;
399
+ /** Whether to allow clearing all */
400
+ clearable?: boolean;
401
+ /** Text when no options match search */
402
+ emptyText?: string;
403
+ /** Whether to close on select */
404
+ closeOnSelect?: boolean;
405
+ /** Label for accessibility */
406
+ 'aria-label'?: string;
407
+ /** ID of element that labels this select */
408
+ 'aria-labelledby'?: string;
409
+ /** Custom class name */
410
+ className?: string;
411
+ /** Test ID */
412
+ testId?: string;
413
+ }
414
+
415
+ export declare type MultiSelectSize = 'sm' | 'md' | 'lg';
416
+
248
417
  export declare const Radio: ForwardRefExoticComponent<RadioProps & RefAttributes<HTMLInputElement>>;
249
418
 
250
419
  export declare function RadioGroup({ name, value: controlledValue, defaultValue, onChange, disabled, size, orientation, gap, children, className, style, }: RadioGroupProps): JSX.Element;
@@ -295,6 +464,45 @@ export declare interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputEl
295
464
 
296
465
  export declare type RadioSize = 'sm' | 'md' | 'lg';
297
466
 
467
+ export declare const Rating: ForwardRefExoticComponent<RatingProps & RefAttributes<HTMLDivElement>>;
468
+
469
+ export declare interface RatingProps {
470
+ /** Current rating value */
471
+ value?: number;
472
+ /** Default rating value (uncontrolled) */
473
+ defaultValue?: number;
474
+ /** Callback when rating changes */
475
+ onChange?: (value: number) => void;
476
+ /** Maximum rating (number of stars) */
477
+ max?: number;
478
+ /** Component size */
479
+ size?: RatingSize;
480
+ /** Whether to allow half stars */
481
+ allowHalf?: boolean;
482
+ /** Whether the rating is read-only */
483
+ readOnly?: boolean;
484
+ /** Whether the rating is disabled */
485
+ disabled?: boolean;
486
+ /** Whether to allow clearing (clicking same value again) */
487
+ allowClear?: boolean;
488
+ /** Custom filled icon */
489
+ filledIcon?: ReactNode;
490
+ /** Custom empty icon */
491
+ emptyIcon?: ReactNode;
492
+ /** Custom half-filled icon */
493
+ halfIcon?: ReactNode;
494
+ /** Color for filled stars */
495
+ color?: string;
496
+ /** Label for accessibility */
497
+ 'aria-label'?: string;
498
+ /** Custom class name */
499
+ className?: string;
500
+ /** Test ID */
501
+ testId?: string;
502
+ }
503
+
504
+ export declare type RatingSize = 'sm' | 'md' | 'lg' | 'xl';
505
+
298
506
  export declare const Select: ForwardRefExoticComponent<SelectProps & RefAttributes<HTMLSelectElement>>;
299
507
 
300
508
  export declare interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> {
@@ -368,6 +576,58 @@ export declare interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputE
368
576
 
369
577
  export declare type SwitchSize = 'sm' | 'md' | 'lg';
370
578
 
579
+ export declare const TagInput: ForwardRefExoticComponent<TagInputProps & RefAttributes<HTMLInputElement>>;
580
+
581
+ export declare interface TagInputProps {
582
+ /** Current tags */
583
+ value?: TagItem[];
584
+ /** Default tags (uncontrolled) */
585
+ defaultValue?: TagItem[];
586
+ /** Callback when tags change */
587
+ onChange?: (tags: TagItem[]) => void;
588
+ /** Placeholder text */
589
+ placeholder?: string;
590
+ /** Component size */
591
+ size?: TagInputSize;
592
+ /** Maximum number of tags */
593
+ maxTags?: number;
594
+ /** Whether to allow duplicates */
595
+ allowDuplicates?: boolean;
596
+ /** Delimiter keys to create tag (default: Enter, comma) */
597
+ delimiters?: string[];
598
+ /** Whether the input is disabled */
599
+ disabled?: boolean;
600
+ /** Whether the input is invalid */
601
+ isInvalid?: boolean;
602
+ /** Whether the input is read-only */
603
+ readOnly?: boolean;
604
+ /** Validation function for new tags */
605
+ validateTag?: (value: string) => boolean | string;
606
+ /** Transform function for new tag value */
607
+ transformTag?: (value: string) => string;
608
+ /** Suggested tags for autocomplete */
609
+ suggestions?: TagItem[];
610
+ /** Custom tag renderer */
611
+ renderTag?: (tag: TagItem, onRemove: () => void) => ReactNode;
612
+ /** Label for accessibility */
613
+ 'aria-label'?: string;
614
+ /** Custom class name */
615
+ className?: string;
616
+ /** Test ID */
617
+ testId?: string;
618
+ }
619
+
620
+ export declare type TagInputSize = 'sm' | 'md' | 'lg';
621
+
622
+ export declare interface TagItem {
623
+ /** Unique identifier */
624
+ id: string;
625
+ /** Display label */
626
+ label: string;
627
+ /** Optional color */
628
+ color?: string;
629
+ }
630
+
371
631
  export declare const Textarea: ForwardRefExoticComponent<TextareaProps & RefAttributes<HTMLTextAreaElement>>;
372
632
 
373
633
  export declare interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'size'> {
@@ -412,4 +672,60 @@ export declare interface TextFieldProps extends InputProps {
412
672
  hideLabel?: boolean;
413
673
  }
414
674
 
675
+ export declare type TimeFormat = '12h' | '24h';
676
+
677
+ export declare const TimePicker: ForwardRefExoticComponent<TimePickerProps & RefAttributes<HTMLInputElement>>;
678
+
679
+ export declare interface TimePickerProps {
680
+ /** Current time value */
681
+ value?: TimeValue | null;
682
+ /** Default time value (uncontrolled) */
683
+ defaultValue?: TimeValue | null;
684
+ /** Callback when time changes */
685
+ onChange?: (value: TimeValue | null) => void;
686
+ /** Time format */
687
+ format?: TimeFormat;
688
+ /** Component size */
689
+ size?: TimePickerSize;
690
+ /** Minute step interval */
691
+ minuteStep?: number;
692
+ /** Minimum selectable time */
693
+ minTime?: TimeValue;
694
+ /** Maximum selectable time */
695
+ maxTime?: TimeValue;
696
+ /** Placeholder text */
697
+ placeholder?: string;
698
+ /** Whether the input is disabled */
699
+ disabled?: boolean;
700
+ /** Whether the input is invalid */
701
+ isInvalid?: boolean;
702
+ /** Whether to allow clearing */
703
+ clearable?: boolean;
704
+ /** Label for accessibility */
705
+ 'aria-label'?: string;
706
+ /** Custom class name */
707
+ className?: string;
708
+ /** Test ID */
709
+ testId?: string;
710
+ }
711
+
712
+ /**
713
+ * TimePicker Component
714
+ *
715
+ * A time selection component with hour, minute, and optional period (AM/PM).
716
+ * Supports keyboard navigation and manual input.
717
+ *
718
+ * @module components/form/TimePicker
719
+ */
720
+ export declare type TimePickerSize = 'sm' | 'md' | 'lg';
721
+
722
+ export declare interface TimeValue {
723
+ /** Hours (0-23 for 24h, 1-12 for 12h) */
724
+ hours: number;
725
+ /** Minutes (0-59) */
726
+ minutes: number;
727
+ /** Period for 12h format */
728
+ period?: 'AM' | 'PM';
729
+ }
730
+
415
731
  export { }
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react");function I(b={}){const{onFocusChange:t,onHoverChange:a,onPressedChange:u,onFocus:c,onBlur:d,onMouseEnter:f,onMouseLeave:M,onMouseDown:i,onMouseUp:h,disabled:n=!1}=b,[C,l]=s.useState(!1),[v,r]=s.useState(!1),[F,o]=s.useState(!1),O=s.useCallback(e=>{n||(l(!0),t?.(!0),c?.(e))},[n,t,c]),S=s.useCallback(e=>{l(!1),o(!1),t?.(!1),d?.(e)},[t,d]),k=s.useCallback(e=>{n||(r(!0),a?.(!0),f?.(e))},[n,a,f]),x=s.useCallback(e=>{r(!1),o(!1),a?.(!1),M?.(e)},[a,M]),g=s.useCallback(e=>{n||(o(!0),u?.(!0),i?.(e))},[n,u,i]),p=s.useCallback(e=>{o(!1),u?.(!1),h?.(e)},[u,h]);return{state:{isFocused:C,isHovered:v,isPressed:F},handlers:{onFocus:O,onBlur:S,onMouseEnter:k,onMouseLeave:x,onMouseDown:g,onMouseUp:p},setIsFocused:l,setIsHovered:r,setIsPressed:o}}exports.useInteractionState=I;
2
+ //# sourceMappingURL=useInteractionState.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInteractionState.cjs","sources":["../../src/hooks/useInteractionState.ts"],"sourcesContent":["/**\n * useInteractionState Hook\n *\n * Manages common interaction states (focus, hover, pressed) for interactive components.\n * Eliminates duplicate state management across form components.\n */\n\nimport { useState, useCallback, type FocusEvent, type MouseEvent } from 'react'\n\nexport interface InteractionState {\n /** Whether the element is currently focused */\n isFocused: boolean\n /** Whether the element is currently hovered */\n isHovered: boolean\n /** Whether the element is currently pressed */\n isPressed: boolean\n}\n\nexport interface InteractionHandlers<T extends HTMLElement = HTMLElement> {\n /** Handler for focus events */\n onFocus: (event: FocusEvent<T>) => void\n /** Handler for blur events */\n onBlur: (event: FocusEvent<T>) => void\n /** Handler for mouse enter events */\n onMouseEnter: (event: MouseEvent<T>) => void\n /** Handler for mouse leave events */\n onMouseLeave: (event: MouseEvent<T>) => void\n /** Handler for mouse down events */\n onMouseDown: (event: MouseEvent<T>) => void\n /** Handler for mouse up events */\n onMouseUp: (event: MouseEvent<T>) => void\n}\n\nexport interface UseInteractionStateOptions<T extends HTMLElement = HTMLElement> {\n /** Callback when focus state changes */\n onFocusChange?: (isFocused: boolean) => void\n /** Callback when hover state changes */\n onHoverChange?: (isHovered: boolean) => void\n /** Callback when pressed state changes */\n onPressedChange?: (isPressed: boolean) => void\n /** External focus handler to merge */\n onFocus?: (event: FocusEvent<T>) => void\n /** External blur handler to merge */\n onBlur?: (event: FocusEvent<T>) => void\n /** External mouse enter handler to merge */\n onMouseEnter?: (event: MouseEvent<T>) => void\n /** External mouse leave handler to merge */\n onMouseLeave?: (event: MouseEvent<T>) => void\n /** External mouse down handler to merge */\n onMouseDown?: (event: MouseEvent<T>) => void\n /** External mouse up handler to merge */\n onMouseUp?: (event: MouseEvent<T>) => void\n /** Whether the element is disabled (disables all interactions) */\n disabled?: boolean\n}\n\nexport interface UseInteractionStateReturn<T extends HTMLElement = HTMLElement> {\n /** Current interaction state */\n state: InteractionState\n /** Event handlers to spread onto the element */\n handlers: InteractionHandlers<T>\n /** Manually set focus state */\n setIsFocused: (value: boolean) => void\n /** Manually set hover state */\n setIsHovered: (value: boolean) => void\n /** Manually set pressed state */\n setIsPressed: (value: boolean) => void\n}\n\n/**\n * Hook for managing interactive states in form components.\n *\n * @example\n * ```tsx\n * function MyInput(props) {\n * const { state, handlers } = useInteractionState({\n * disabled: props.disabled,\n * onFocus: props.onFocus,\n * onBlur: props.onBlur,\n * })\n *\n * return (\n * <input\n * {...handlers}\n * style={{\n * borderColor: state.isFocused ? 'blue' : 'gray',\n * }}\n * />\n * )\n * }\n * ```\n */\nexport function useInteractionState<T extends HTMLElement = HTMLElement>(\n options: UseInteractionStateOptions<T> = {}\n): UseInteractionStateReturn<T> {\n const {\n onFocusChange,\n onHoverChange,\n onPressedChange,\n onFocus: externalOnFocus,\n onBlur: externalOnBlur,\n onMouseEnter: externalOnMouseEnter,\n onMouseLeave: externalOnMouseLeave,\n onMouseDown: externalOnMouseDown,\n onMouseUp: externalOnMouseUp,\n disabled = false,\n } = options\n\n const [isFocused, setIsFocused] = useState(false)\n const [isHovered, setIsHovered] = useState(false)\n const [isPressed, setIsPressed] = useState(false)\n\n const handleFocus = useCallback(\n (event: FocusEvent<T>) => {\n if (disabled) return\n setIsFocused(true)\n onFocusChange?.(true)\n externalOnFocus?.(event)\n },\n [disabled, onFocusChange, externalOnFocus]\n )\n\n const handleBlur = useCallback(\n (event: FocusEvent<T>) => {\n setIsFocused(false)\n setIsPressed(false)\n onFocusChange?.(false)\n externalOnBlur?.(event)\n },\n [onFocusChange, externalOnBlur]\n )\n\n const handleMouseEnter = useCallback(\n (event: MouseEvent<T>) => {\n if (disabled) return\n setIsHovered(true)\n onHoverChange?.(true)\n externalOnMouseEnter?.(event)\n },\n [disabled, onHoverChange, externalOnMouseEnter]\n )\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent<T>) => {\n setIsHovered(false)\n setIsPressed(false)\n onHoverChange?.(false)\n externalOnMouseLeave?.(event)\n },\n [onHoverChange, externalOnMouseLeave]\n )\n\n const handleMouseDown = useCallback(\n (event: MouseEvent<T>) => {\n if (disabled) return\n setIsPressed(true)\n onPressedChange?.(true)\n externalOnMouseDown?.(event)\n },\n [disabled, onPressedChange, externalOnMouseDown]\n )\n\n const handleMouseUp = useCallback(\n (event: MouseEvent<T>) => {\n setIsPressed(false)\n onPressedChange?.(false)\n externalOnMouseUp?.(event)\n },\n [onPressedChange, externalOnMouseUp]\n )\n\n return {\n state: {\n isFocused,\n isHovered,\n isPressed,\n },\n handlers: {\n onFocus: handleFocus,\n onBlur: handleBlur,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n onMouseDown: handleMouseDown,\n onMouseUp: handleMouseUp,\n },\n setIsFocused,\n setIsHovered,\n setIsPressed,\n }\n}\n"],"names":["useInteractionState","options","onFocusChange","onHoverChange","onPressedChange","externalOnFocus","externalOnBlur","externalOnMouseEnter","externalOnMouseLeave","externalOnMouseDown","externalOnMouseUp","disabled","isFocused","setIsFocused","useState","isHovered","setIsHovered","isPressed","setIsPressed","handleFocus","useCallback","event","handleBlur","handleMouseEnter","handleMouseLeave","handleMouseDown","handleMouseUp"],"mappings":"yGA4FO,SAASA,EACdC,EAAyC,GACX,CAC9B,KAAM,CACJ,cAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,QAASC,EACT,OAAQC,EACR,aAAcC,EACd,aAAcC,EACd,YAAaC,EACb,UAAWC,EACX,SAAAC,EAAW,EAAA,EACTV,EAEE,CAACW,EAAWC,CAAY,EAAIC,EAAAA,SAAS,EAAK,EAC1C,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAK,EAC1C,CAACG,EAAWC,CAAY,EAAIJ,EAAAA,SAAS,EAAK,EAE1CK,EAAcC,EAAAA,YACjBC,GAAyB,CACpBV,IACJE,EAAa,EAAI,EACjBX,IAAgB,EAAI,EACpBG,IAAkBgB,CAAK,EACzB,EACA,CAACV,EAAUT,EAAeG,CAAe,CAAA,EAGrCiB,EAAaF,EAAAA,YAChBC,GAAyB,CACxBR,EAAa,EAAK,EAClBK,EAAa,EAAK,EAClBhB,IAAgB,EAAK,EACrBI,IAAiBe,CAAK,CACxB,EACA,CAACnB,EAAeI,CAAc,CAAA,EAG1BiB,EAAmBH,EAAAA,YACtBC,GAAyB,CACpBV,IACJK,EAAa,EAAI,EACjBb,IAAgB,EAAI,EACpBI,IAAuBc,CAAK,EAC9B,EACA,CAACV,EAAUR,EAAeI,CAAoB,CAAA,EAG1CiB,EAAmBJ,EAAAA,YACtBC,GAAyB,CACxBL,EAAa,EAAK,EAClBE,EAAa,EAAK,EAClBf,IAAgB,EAAK,EACrBK,IAAuBa,CAAK,CAC9B,EACA,CAAClB,EAAeK,CAAoB,CAAA,EAGhCiB,EAAkBL,EAAAA,YACrBC,GAAyB,CACpBV,IACJO,EAAa,EAAI,EACjBd,IAAkB,EAAI,EACtBK,IAAsBY,CAAK,EAC7B,EACA,CAACV,EAAUP,EAAiBK,CAAmB,CAAA,EAG3CiB,EAAgBN,EAAAA,YACnBC,GAAyB,CACxBH,EAAa,EAAK,EAClBd,IAAkB,EAAK,EACvBM,IAAoBW,CAAK,CAC3B,EACA,CAACjB,EAAiBM,CAAiB,CAAA,EAGrC,MAAO,CACL,MAAO,CACL,UAAAE,EACA,UAAAG,EACA,UAAAE,CAAA,EAEF,SAAU,CACR,QAASE,EACT,OAAQG,EACR,aAAcC,EACd,aAAcC,EACd,YAAaC,EACb,UAAWC,CAAA,EAEb,aAAAb,EACA,aAAAG,EACA,aAAAE,CAAA,CAEJ"}
@@ -0,0 +1,67 @@
1
+ import { useState as c, useCallback as n } from "react";
2
+ function U(x = {}) {
3
+ const {
4
+ onFocusChange: t,
5
+ onHoverChange: u,
6
+ onPressedChange: a,
7
+ onFocus: f,
8
+ onBlur: d,
9
+ onMouseEnter: M,
10
+ onMouseLeave: h,
11
+ onMouseDown: i,
12
+ onMouseUp: v,
13
+ disabled: s = !1
14
+ } = x, [F, r] = c(!1), [p, l] = c(!1), [O, o] = c(!1), w = n(
15
+ (e) => {
16
+ s || (r(!0), t?.(!0), f?.(e));
17
+ },
18
+ [s, t, f]
19
+ ), B = n(
20
+ (e) => {
21
+ r(!1), o(!1), t?.(!1), d?.(e);
22
+ },
23
+ [t, d]
24
+ ), C = n(
25
+ (e) => {
26
+ s || (l(!0), u?.(!0), M?.(e));
27
+ },
28
+ [s, u, M]
29
+ ), D = n(
30
+ (e) => {
31
+ l(!1), o(!1), u?.(!1), h?.(e);
32
+ },
33
+ [u, h]
34
+ ), E = n(
35
+ (e) => {
36
+ s || (o(!0), a?.(!0), i?.(e));
37
+ },
38
+ [s, a, i]
39
+ ), I = n(
40
+ (e) => {
41
+ o(!1), a?.(!1), v?.(e);
42
+ },
43
+ [a, v]
44
+ );
45
+ return {
46
+ state: {
47
+ isFocused: F,
48
+ isHovered: p,
49
+ isPressed: O
50
+ },
51
+ handlers: {
52
+ onFocus: w,
53
+ onBlur: B,
54
+ onMouseEnter: C,
55
+ onMouseLeave: D,
56
+ onMouseDown: E,
57
+ onMouseUp: I
58
+ },
59
+ setIsFocused: r,
60
+ setIsHovered: l,
61
+ setIsPressed: o
62
+ };
63
+ }
64
+ export {
65
+ U as useInteractionState
66
+ };
67
+ //# sourceMappingURL=useInteractionState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInteractionState.js","sources":["../../src/hooks/useInteractionState.ts"],"sourcesContent":["/**\n * useInteractionState Hook\n *\n * Manages common interaction states (focus, hover, pressed) for interactive components.\n * Eliminates duplicate state management across form components.\n */\n\nimport { useState, useCallback, type FocusEvent, type MouseEvent } from 'react'\n\nexport interface InteractionState {\n /** Whether the element is currently focused */\n isFocused: boolean\n /** Whether the element is currently hovered */\n isHovered: boolean\n /** Whether the element is currently pressed */\n isPressed: boolean\n}\n\nexport interface InteractionHandlers<T extends HTMLElement = HTMLElement> {\n /** Handler for focus events */\n onFocus: (event: FocusEvent<T>) => void\n /** Handler for blur events */\n onBlur: (event: FocusEvent<T>) => void\n /** Handler for mouse enter events */\n onMouseEnter: (event: MouseEvent<T>) => void\n /** Handler for mouse leave events */\n onMouseLeave: (event: MouseEvent<T>) => void\n /** Handler for mouse down events */\n onMouseDown: (event: MouseEvent<T>) => void\n /** Handler for mouse up events */\n onMouseUp: (event: MouseEvent<T>) => void\n}\n\nexport interface UseInteractionStateOptions<T extends HTMLElement = HTMLElement> {\n /** Callback when focus state changes */\n onFocusChange?: (isFocused: boolean) => void\n /** Callback when hover state changes */\n onHoverChange?: (isHovered: boolean) => void\n /** Callback when pressed state changes */\n onPressedChange?: (isPressed: boolean) => void\n /** External focus handler to merge */\n onFocus?: (event: FocusEvent<T>) => void\n /** External blur handler to merge */\n onBlur?: (event: FocusEvent<T>) => void\n /** External mouse enter handler to merge */\n onMouseEnter?: (event: MouseEvent<T>) => void\n /** External mouse leave handler to merge */\n onMouseLeave?: (event: MouseEvent<T>) => void\n /** External mouse down handler to merge */\n onMouseDown?: (event: MouseEvent<T>) => void\n /** External mouse up handler to merge */\n onMouseUp?: (event: MouseEvent<T>) => void\n /** Whether the element is disabled (disables all interactions) */\n disabled?: boolean\n}\n\nexport interface UseInteractionStateReturn<T extends HTMLElement = HTMLElement> {\n /** Current interaction state */\n state: InteractionState\n /** Event handlers to spread onto the element */\n handlers: InteractionHandlers<T>\n /** Manually set focus state */\n setIsFocused: (value: boolean) => void\n /** Manually set hover state */\n setIsHovered: (value: boolean) => void\n /** Manually set pressed state */\n setIsPressed: (value: boolean) => void\n}\n\n/**\n * Hook for managing interactive states in form components.\n *\n * @example\n * ```tsx\n * function MyInput(props) {\n * const { state, handlers } = useInteractionState({\n * disabled: props.disabled,\n * onFocus: props.onFocus,\n * onBlur: props.onBlur,\n * })\n *\n * return (\n * <input\n * {...handlers}\n * style={{\n * borderColor: state.isFocused ? 'blue' : 'gray',\n * }}\n * />\n * )\n * }\n * ```\n */\nexport function useInteractionState<T extends HTMLElement = HTMLElement>(\n options: UseInteractionStateOptions<T> = {}\n): UseInteractionStateReturn<T> {\n const {\n onFocusChange,\n onHoverChange,\n onPressedChange,\n onFocus: externalOnFocus,\n onBlur: externalOnBlur,\n onMouseEnter: externalOnMouseEnter,\n onMouseLeave: externalOnMouseLeave,\n onMouseDown: externalOnMouseDown,\n onMouseUp: externalOnMouseUp,\n disabled = false,\n } = options\n\n const [isFocused, setIsFocused] = useState(false)\n const [isHovered, setIsHovered] = useState(false)\n const [isPressed, setIsPressed] = useState(false)\n\n const handleFocus = useCallback(\n (event: FocusEvent<T>) => {\n if (disabled) return\n setIsFocused(true)\n onFocusChange?.(true)\n externalOnFocus?.(event)\n },\n [disabled, onFocusChange, externalOnFocus]\n )\n\n const handleBlur = useCallback(\n (event: FocusEvent<T>) => {\n setIsFocused(false)\n setIsPressed(false)\n onFocusChange?.(false)\n externalOnBlur?.(event)\n },\n [onFocusChange, externalOnBlur]\n )\n\n const handleMouseEnter = useCallback(\n (event: MouseEvent<T>) => {\n if (disabled) return\n setIsHovered(true)\n onHoverChange?.(true)\n externalOnMouseEnter?.(event)\n },\n [disabled, onHoverChange, externalOnMouseEnter]\n )\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent<T>) => {\n setIsHovered(false)\n setIsPressed(false)\n onHoverChange?.(false)\n externalOnMouseLeave?.(event)\n },\n [onHoverChange, externalOnMouseLeave]\n )\n\n const handleMouseDown = useCallback(\n (event: MouseEvent<T>) => {\n if (disabled) return\n setIsPressed(true)\n onPressedChange?.(true)\n externalOnMouseDown?.(event)\n },\n [disabled, onPressedChange, externalOnMouseDown]\n )\n\n const handleMouseUp = useCallback(\n (event: MouseEvent<T>) => {\n setIsPressed(false)\n onPressedChange?.(false)\n externalOnMouseUp?.(event)\n },\n [onPressedChange, externalOnMouseUp]\n )\n\n return {\n state: {\n isFocused,\n isHovered,\n isPressed,\n },\n handlers: {\n onFocus: handleFocus,\n onBlur: handleBlur,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n onMouseDown: handleMouseDown,\n onMouseUp: handleMouseUp,\n },\n setIsFocused,\n setIsHovered,\n setIsPressed,\n }\n}\n"],"names":["useInteractionState","options","onFocusChange","onHoverChange","onPressedChange","externalOnFocus","externalOnBlur","externalOnMouseEnter","externalOnMouseLeave","externalOnMouseDown","externalOnMouseUp","disabled","isFocused","setIsFocused","useState","isHovered","setIsHovered","isPressed","setIsPressed","handleFocus","useCallback","event","handleBlur","handleMouseEnter","handleMouseLeave","handleMouseDown","handleMouseUp"],"mappings":";AA4FO,SAASA,EACdC,IAAyC,IACX;AAC9B,QAAM;AAAA,IACJ,eAAAC;AAAA,IACA,eAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,SAASC;AAAA,IACT,QAAQC;AAAA,IACR,cAAcC;AAAA,IACd,cAAcC;AAAA,IACd,aAAaC;AAAA,IACb,WAAWC;AAAA,IACX,UAAAC,IAAW;AAAA,EAAA,IACTV,GAEE,CAACW,GAAWC,CAAY,IAAIC,EAAS,EAAK,GAC1C,CAACC,GAAWC,CAAY,IAAIF,EAAS,EAAK,GAC1C,CAACG,GAAWC,CAAY,IAAIJ,EAAS,EAAK,GAE1CK,IAAcC;AAAA,IAClB,CAACC,MAAyB;AACxB,MAAIV,MACJE,EAAa,EAAI,GACjBX,IAAgB,EAAI,GACpBG,IAAkBgB,CAAK;AAAA,IACzB;AAAA,IACA,CAACV,GAAUT,GAAeG,CAAe;AAAA,EAAA,GAGrCiB,IAAaF;AAAA,IACjB,CAACC,MAAyB;AACxB,MAAAR,EAAa,EAAK,GAClBK,EAAa,EAAK,GAClBhB,IAAgB,EAAK,GACrBI,IAAiBe,CAAK;AAAA,IACxB;AAAA,IACA,CAACnB,GAAeI,CAAc;AAAA,EAAA,GAG1BiB,IAAmBH;AAAA,IACvB,CAACC,MAAyB;AACxB,MAAIV,MACJK,EAAa,EAAI,GACjBb,IAAgB,EAAI,GACpBI,IAAuBc,CAAK;AAAA,IAC9B;AAAA,IACA,CAACV,GAAUR,GAAeI,CAAoB;AAAA,EAAA,GAG1CiB,IAAmBJ;AAAA,IACvB,CAACC,MAAyB;AACxB,MAAAL,EAAa,EAAK,GAClBE,EAAa,EAAK,GAClBf,IAAgB,EAAK,GACrBK,IAAuBa,CAAK;AAAA,IAC9B;AAAA,IACA,CAAClB,GAAeK,CAAoB;AAAA,EAAA,GAGhCiB,IAAkBL;AAAA,IACtB,CAACC,MAAyB;AACxB,MAAIV,MACJO,EAAa,EAAI,GACjBd,IAAkB,EAAI,GACtBK,IAAsBY,CAAK;AAAA,IAC7B;AAAA,IACA,CAACV,GAAUP,GAAiBK,CAAmB;AAAA,EAAA,GAG3CiB,IAAgBN;AAAA,IACpB,CAACC,MAAyB;AACxB,MAAAH,EAAa,EAAK,GAClBd,IAAkB,EAAK,GACvBM,IAAoBW,CAAK;AAAA,IAC3B;AAAA,IACA,CAACjB,GAAiBM,CAAiB;AAAA,EAAA;AAGrC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,WAAAE;AAAA,MACA,WAAAG;AAAA,MACA,WAAAE;AAAA,IAAA;AAAA,IAEF,UAAU;AAAA,MACR,SAASE;AAAA,MACT,QAAQG;AAAA,MACR,cAAcC;AAAA,MACd,cAAcC;AAAA,MACd,aAAaC;AAAA,MACb,WAAWC;AAAA,IAAA;AAAA,IAEb,cAAAb;AAAA,IACA,cAAAG;AAAA,IACA,cAAAE;AAAA,EAAA;AAEJ;"}
package/dist/hooks.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./hooks/useMediaQuery.cjs"),u=require("./hooks/useDisclosure.cjs"),r=require("./hooks/useClickOutside.cjs"),o=require("./hooks/useKeyboardNavigation.cjs"),i=require("./hooks/useFocusTrap.cjs"),s=require("./hooks/useId.cjs"),t=require("./hooks/useControllable.cjs");exports.useIsDesktop=e.useIsDesktop;exports.useIsMobile=e.useIsMobile;exports.useIsTablet=e.useIsTablet;exports.useMediaQuery=e.useMediaQuery;exports.usePrefersDarkMode=e.usePrefersDarkMode;exports.usePrefersReducedMotion=e.usePrefersReducedMotion;exports.useDisclosure=u.useDisclosure;exports.useClickOutside=r.useClickOutside;exports.useKeyboardNavigation=o.useKeyboardNavigation;exports.useFocusTrap=i.useFocusTrap;exports.useId=s.useId;exports.useIds=s.useIds;exports.useControllable=t.useControllable;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./hooks/useMediaQuery.cjs"),u=require("./hooks/useDisclosure.cjs"),r=require("./hooks/useClickOutside.cjs"),o=require("./hooks/useKeyboardNavigation.cjs"),t=require("./hooks/useFocusTrap.cjs"),s=require("./hooks/useId.cjs"),i=require("./hooks/useControllable.cjs"),a=require("./hooks/useInteractionState.cjs");exports.useIsDesktop=e.useIsDesktop;exports.useIsMobile=e.useIsMobile;exports.useIsTablet=e.useIsTablet;exports.useMediaQuery=e.useMediaQuery;exports.usePrefersDarkMode=e.usePrefersDarkMode;exports.usePrefersReducedMotion=e.usePrefersReducedMotion;exports.useDisclosure=u.useDisclosure;exports.useClickOutside=r.useClickOutside;exports.useKeyboardNavigation=o.useKeyboardNavigation;exports.useFocusTrap=t.useFocusTrap;exports.useId=s.useId;exports.useIds=s.useIds;exports.useControllable=i.useControllable;exports.useInteractionState=a.useInteractionState;
2
2
  //# sourceMappingURL=hooks.cjs.map
package/dist/hooks.d.ts CHANGED
@@ -1,5 +1,31 @@
1
+ import { FocusEvent as FocusEvent_2 } from 'react';
2
+ import { MouseEvent as MouseEvent_2 } from 'react';
1
3
  import { RefObject } from 'react';
2
4
 
5
+ export declare interface InteractionHandlers<T extends HTMLElement = HTMLElement> {
6
+ /** Handler for focus events */
7
+ onFocus: (event: FocusEvent_2<T>) => void;
8
+ /** Handler for blur events */
9
+ onBlur: (event: FocusEvent_2<T>) => void;
10
+ /** Handler for mouse enter events */
11
+ onMouseEnter: (event: MouseEvent_2<T>) => void;
12
+ /** Handler for mouse leave events */
13
+ onMouseLeave: (event: MouseEvent_2<T>) => void;
14
+ /** Handler for mouse down events */
15
+ onMouseDown: (event: MouseEvent_2<T>) => void;
16
+ /** Handler for mouse up events */
17
+ onMouseUp: (event: MouseEvent_2<T>) => void;
18
+ }
19
+
20
+ export declare interface InteractionState {
21
+ /** Whether the element is currently focused */
22
+ isFocused: boolean;
23
+ /** Whether the element is currently hovered */
24
+ isHovered: boolean;
25
+ /** Whether the element is currently pressed */
26
+ isPressed: boolean;
27
+ }
28
+
3
29
  export declare function useClickOutside<T extends HTMLElement = HTMLElement>(handler: (event: MouseEvent | TouchEvent) => void, options?: UseClickOutsideOptions): RefObject<T | null>;
4
30
 
5
31
  export declare interface UseClickOutsideOptions {
@@ -88,6 +114,67 @@ export declare function useId(prefix?: string): string;
88
114
 
89
115
  export declare function useIds(count: number, prefix?: string): string[];
90
116
 
117
+ /**
118
+ * Hook for managing interactive states in form components.
119
+ *
120
+ * @example
121
+ * ```tsx
122
+ * function MyInput(props) {
123
+ * const { state, handlers } = useInteractionState({
124
+ * disabled: props.disabled,
125
+ * onFocus: props.onFocus,
126
+ * onBlur: props.onBlur,
127
+ * })
128
+ *
129
+ * return (
130
+ * <input
131
+ * {...handlers}
132
+ * style={{
133
+ * borderColor: state.isFocused ? 'blue' : 'gray',
134
+ * }}
135
+ * />
136
+ * )
137
+ * }
138
+ * ```
139
+ */
140
+ export declare function useInteractionState<T extends HTMLElement = HTMLElement>(options?: UseInteractionStateOptions<T>): UseInteractionStateReturn<T>;
141
+
142
+ export declare interface UseInteractionStateOptions<T extends HTMLElement = HTMLElement> {
143
+ /** Callback when focus state changes */
144
+ onFocusChange?: (isFocused: boolean) => void;
145
+ /** Callback when hover state changes */
146
+ onHoverChange?: (isHovered: boolean) => void;
147
+ /** Callback when pressed state changes */
148
+ onPressedChange?: (isPressed: boolean) => void;
149
+ /** External focus handler to merge */
150
+ onFocus?: (event: FocusEvent_2<T>) => void;
151
+ /** External blur handler to merge */
152
+ onBlur?: (event: FocusEvent_2<T>) => void;
153
+ /** External mouse enter handler to merge */
154
+ onMouseEnter?: (event: MouseEvent_2<T>) => void;
155
+ /** External mouse leave handler to merge */
156
+ onMouseLeave?: (event: MouseEvent_2<T>) => void;
157
+ /** External mouse down handler to merge */
158
+ onMouseDown?: (event: MouseEvent_2<T>) => void;
159
+ /** External mouse up handler to merge */
160
+ onMouseUp?: (event: MouseEvent_2<T>) => void;
161
+ /** Whether the element is disabled (disables all interactions) */
162
+ disabled?: boolean;
163
+ }
164
+
165
+ export declare interface UseInteractionStateReturn<T extends HTMLElement = HTMLElement> {
166
+ /** Current interaction state */
167
+ state: InteractionState;
168
+ /** Event handlers to spread onto the element */
169
+ handlers: InteractionHandlers<T>;
170
+ /** Manually set focus state */
171
+ setIsFocused: (value: boolean) => void;
172
+ /** Manually set hover state */
173
+ setIsHovered: (value: boolean) => void;
174
+ /** Manually set pressed state */
175
+ setIsPressed: (value: boolean) => void;
176
+ }
177
+
91
178
  export declare function useIsDesktop(): boolean;
92
179
 
93
180
  /** Pre-built responsive hooks */
package/dist/hooks.js CHANGED
@@ -1,23 +1,25 @@
1
- import { useIsDesktop as r, useIsMobile as s, useIsTablet as u, useMediaQuery as t, usePrefersDarkMode as f, usePrefersReducedMotion as p } from "./hooks/useMediaQuery.js";
2
- import { useDisclosure as d } from "./hooks/useDisclosure.js";
3
- import { useClickOutside as l } from "./hooks/useClickOutside.js";
4
- import { useKeyboardNavigation as x } from "./hooks/useKeyboardNavigation.js";
5
- import { useFocusTrap as b } from "./hooks/useFocusTrap.js";
6
- import { useId as M, useIds as k } from "./hooks/useId.js";
1
+ import { useIsDesktop as r, useIsMobile as s, useIsTablet as u, useMediaQuery as t, usePrefersDarkMode as a, usePrefersReducedMotion as f } from "./hooks/useMediaQuery.js";
2
+ import { useDisclosure as i } from "./hooks/useDisclosure.js";
3
+ import { useClickOutside as m } from "./hooks/useClickOutside.js";
4
+ import { useKeyboardNavigation as l } from "./hooks/useKeyboardNavigation.js";
5
+ import { useFocusTrap as c } from "./hooks/useFocusTrap.js";
6
+ import { useId as b, useIds as M } from "./hooks/useId.js";
7
7
  import { useControllable as D } from "./hooks/useControllable.js";
8
+ import { useInteractionState as C } from "./hooks/useInteractionState.js";
8
9
  export {
9
- l as useClickOutside,
10
+ m as useClickOutside,
10
11
  D as useControllable,
11
- d as useDisclosure,
12
- b as useFocusTrap,
13
- M as useId,
14
- k as useIds,
12
+ i as useDisclosure,
13
+ c as useFocusTrap,
14
+ b as useId,
15
+ M as useIds,
16
+ C as useInteractionState,
15
17
  r as useIsDesktop,
16
18
  s as useIsMobile,
17
19
  u as useIsTablet,
18
- x as useKeyboardNavigation,
20
+ l as useKeyboardNavigation,
19
21
  t as useMediaQuery,
20
- f as usePrefersDarkMode,
21
- p as usePrefersReducedMotion
22
+ a as usePrefersDarkMode,
23
+ f as usePrefersReducedMotion
22
24
  };
23
25
  //# sourceMappingURL=hooks.js.map
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
1
+ {"version":3,"file":"hooks.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
package/dist/layout.d.ts CHANGED
@@ -132,6 +132,50 @@ export declare interface CardProps extends HTMLAttributes<HTMLDivElement> {
132
132
 
133
133
  export declare type CardVariant = 'elevated' | 'outline' | 'filled' | 'ghost';
134
134
 
135
+ export declare const Collapse: ForwardRefExoticComponent<CollapseProps & RefAttributes<HTMLDivElement>>;
136
+
137
+ export declare interface CollapseProps {
138
+ /** Whether the content is expanded (controlled) */
139
+ isOpen?: boolean;
140
+ /** Default expanded state (uncontrolled) */
141
+ defaultIsOpen?: boolean;
142
+ /** Content to show when collapsed */
143
+ children: ReactNode;
144
+ /** Animation duration in milliseconds */
145
+ duration?: number;
146
+ /** Easing function */
147
+ easing?: string;
148
+ /** Whether to animate on initial render */
149
+ animateOnMount?: boolean;
150
+ /** Whether to unmount content when collapsed */
151
+ unmountOnCollapse?: boolean;
152
+ /** Custom class name */
153
+ className?: string;
154
+ /** Test ID */
155
+ testId?: string;
156
+ }
157
+
158
+ export declare const Collapsible: ForwardRefExoticComponent<CollapsibleProps & RefAttributes<HTMLDivElement>>;
159
+
160
+ export declare interface CollapsibleProps {
161
+ /** Header content (always visible) */
162
+ header: ReactNode;
163
+ /** Collapsible content */
164
+ children: ReactNode;
165
+ /** Whether expanded (controlled) */
166
+ isOpen?: boolean;
167
+ /** Default expanded state (uncontrolled) */
168
+ defaultIsOpen?: boolean;
169
+ /** Callback when expanded state changes */
170
+ onToggle?: (isOpen: boolean) => void;
171
+ /** Whether the collapsible is disabled */
172
+ disabled?: boolean;
173
+ /** Custom class name */
174
+ className?: string;
175
+ /** Test ID */
176
+ testId?: string;
177
+ }
178
+
135
179
  export declare const Container: ContainerComponent;
136
180
 
137
181
  declare interface ContainerComponent {