flexium 0.8.14

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 (154) hide show
  1. package/README.md +219 -0
  2. package/dist/DrawText-CeXBL8Ev.d.ts +309 -0
  3. package/dist/DrawText-JB58mpQT.d.cts +309 -0
  4. package/dist/Motion-BrOAJzgH.d.cts +87 -0
  5. package/dist/Motion-BrOAJzgH.d.ts +87 -0
  6. package/dist/advanced.d.cts +30 -0
  7. package/dist/advanced.d.ts +30 -0
  8. package/dist/advanced.js +2 -0
  9. package/dist/advanced.js.map +1 -0
  10. package/dist/advanced.mjs +2 -0
  11. package/dist/advanced.mjs.map +1 -0
  12. package/dist/canvas.d.cts +22 -0
  13. package/dist/canvas.d.ts +22 -0
  14. package/dist/canvas.js +2 -0
  15. package/dist/canvas.js.map +1 -0
  16. package/dist/canvas.mjs +2 -0
  17. package/dist/canvas.mjs.map +1 -0
  18. package/dist/chunk-2MVKTSFR.mjs +3 -0
  19. package/dist/chunk-2MVKTSFR.mjs.map +1 -0
  20. package/dist/chunk-2U4DW375.mjs +2 -0
  21. package/dist/chunk-2U4DW375.mjs.map +1 -0
  22. package/dist/chunk-3P6DMEGB.js +2 -0
  23. package/dist/chunk-3P6DMEGB.js.map +1 -0
  24. package/dist/chunk-5S3ZQ2LB.mjs +3 -0
  25. package/dist/chunk-5S3ZQ2LB.mjs.map +1 -0
  26. package/dist/chunk-CNY6FPKJ.js +2 -0
  27. package/dist/chunk-CNY6FPKJ.js.map +1 -0
  28. package/dist/chunk-CZYIK6FD.mjs +2 -0
  29. package/dist/chunk-CZYIK6FD.mjs.map +1 -0
  30. package/dist/chunk-DOGIWSDA.js +2 -0
  31. package/dist/chunk-DOGIWSDA.js.map +1 -0
  32. package/dist/chunk-EX2GURH5.mjs +3 -0
  33. package/dist/chunk-EX2GURH5.mjs.map +1 -0
  34. package/dist/chunk-GDBJ322I.js +2 -0
  35. package/dist/chunk-GDBJ322I.js.map +1 -0
  36. package/dist/chunk-I7UCVARB.js +2 -0
  37. package/dist/chunk-I7UCVARB.js.map +1 -0
  38. package/dist/chunk-KNF5ERPK.mjs +2 -0
  39. package/dist/chunk-KNF5ERPK.mjs.map +1 -0
  40. package/dist/chunk-MLZTCKTH.mjs +2 -0
  41. package/dist/chunk-MLZTCKTH.mjs.map +1 -0
  42. package/dist/chunk-OPAQ4R4M.mjs +2 -0
  43. package/dist/chunk-OPAQ4R4M.mjs.map +1 -0
  44. package/dist/chunk-Q7IWDVJ4.js +2 -0
  45. package/dist/chunk-Q7IWDVJ4.js.map +1 -0
  46. package/dist/chunk-R5CS7UZG.mjs +2 -0
  47. package/dist/chunk-R5CS7UZG.mjs.map +1 -0
  48. package/dist/chunk-REETNY2Z.js +3 -0
  49. package/dist/chunk-REETNY2Z.js.map +1 -0
  50. package/dist/chunk-ROYFUJN5.js +3 -0
  51. package/dist/chunk-ROYFUJN5.js.map +1 -0
  52. package/dist/chunk-U6C6VDVZ.js +2 -0
  53. package/dist/chunk-U6C6VDVZ.js.map +1 -0
  54. package/dist/chunk-V4K6WOXN.js +3 -0
  55. package/dist/chunk-V4K6WOXN.js.map +1 -0
  56. package/dist/chunk-WQFQO5LK.js +2 -0
  57. package/dist/chunk-WQFQO5LK.js.map +1 -0
  58. package/dist/chunk-WVEJT7HD.mjs +2 -0
  59. package/dist/chunk-WVEJT7HD.mjs.map +1 -0
  60. package/dist/chunk-ZNPYN2TZ.mjs +2 -0
  61. package/dist/chunk-ZNPYN2TZ.mjs.map +1 -0
  62. package/dist/core.d.cts +24 -0
  63. package/dist/core.d.ts +24 -0
  64. package/dist/core.js +2 -0
  65. package/dist/core.js.map +1 -0
  66. package/dist/core.mjs +2 -0
  67. package/dist/core.mjs.map +1 -0
  68. package/dist/dom.d.cts +36 -0
  69. package/dist/dom.d.ts +36 -0
  70. package/dist/dom.js +2 -0
  71. package/dist/dom.js.map +1 -0
  72. package/dist/dom.mjs +2 -0
  73. package/dist/dom.mjs.map +1 -0
  74. package/dist/index.d.cts +26 -0
  75. package/dist/index.d.ts +26 -0
  76. package/dist/index.js +2 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/index.mjs +2 -0
  79. package/dist/index.mjs.map +1 -0
  80. package/dist/interactive.d.cts +161 -0
  81. package/dist/interactive.d.ts +161 -0
  82. package/dist/interactive.js +2 -0
  83. package/dist/interactive.js.map +1 -0
  84. package/dist/interactive.mjs +2 -0
  85. package/dist/interactive.mjs.map +1 -0
  86. package/dist/jsx-dev-runtime.d.cts +2 -0
  87. package/dist/jsx-dev-runtime.d.ts +2 -0
  88. package/dist/jsx-dev-runtime.js +2 -0
  89. package/dist/jsx-dev-runtime.js.map +1 -0
  90. package/dist/jsx-dev-runtime.mjs +2 -0
  91. package/dist/jsx-dev-runtime.mjs.map +1 -0
  92. package/dist/jsx-runtime.d.cts +78 -0
  93. package/dist/jsx-runtime.d.ts +78 -0
  94. package/dist/jsx-runtime.js +2 -0
  95. package/dist/jsx-runtime.js.map +1 -0
  96. package/dist/jsx-runtime.mjs +2 -0
  97. package/dist/jsx-runtime.mjs.map +1 -0
  98. package/dist/metafile-cjs.json +1 -0
  99. package/dist/metafile-esm.json +1 -0
  100. package/dist/portal-BpcIlK9y.d.cts +206 -0
  101. package/dist/portal-DBwz7gD0.d.ts +206 -0
  102. package/dist/primitives/layout.d.cts +295 -0
  103. package/dist/primitives/layout.d.ts +295 -0
  104. package/dist/primitives/layout.js +2 -0
  105. package/dist/primitives/layout.js.map +1 -0
  106. package/dist/primitives/layout.mjs +2 -0
  107. package/dist/primitives/layout.mjs.map +1 -0
  108. package/dist/primitives/motion.d.cts +230 -0
  109. package/dist/primitives/motion.d.ts +230 -0
  110. package/dist/primitives/motion.js +2 -0
  111. package/dist/primitives/motion.js.map +1 -0
  112. package/dist/primitives/motion.mjs +2 -0
  113. package/dist/primitives/motion.mjs.map +1 -0
  114. package/dist/primitives/ui.d.cts +81 -0
  115. package/dist/primitives/ui.d.ts +81 -0
  116. package/dist/primitives/ui.js +2 -0
  117. package/dist/primitives/ui.js.map +1 -0
  118. package/dist/primitives/ui.mjs +2 -0
  119. package/dist/primitives/ui.mjs.map +1 -0
  120. package/dist/primitives.d.cts +92 -0
  121. package/dist/primitives.d.ts +92 -0
  122. package/dist/primitives.js +2 -0
  123. package/dist/primitives.js.map +1 -0
  124. package/dist/primitives.mjs +2 -0
  125. package/dist/primitives.mjs.map +1 -0
  126. package/dist/renderer-DSLb-FGg.d.cts +135 -0
  127. package/dist/renderer-DSLb-FGg.d.ts +135 -0
  128. package/dist/router.d.cts +126 -0
  129. package/dist/router.d.ts +126 -0
  130. package/dist/router.js +2 -0
  131. package/dist/router.js.map +1 -0
  132. package/dist/router.mjs +2 -0
  133. package/dist/router.mjs.map +1 -0
  134. package/dist/server.d.cts +3 -0
  135. package/dist/server.d.ts +3 -0
  136. package/dist/server.js +2 -0
  137. package/dist/server.js.map +1 -0
  138. package/dist/server.mjs +2 -0
  139. package/dist/server.mjs.map +1 -0
  140. package/dist/signal-PWBIM6JV.mjs +2 -0
  141. package/dist/signal-PWBIM6JV.mjs.map +1 -0
  142. package/dist/signal-XZXQ4VYQ.js +2 -0
  143. package/dist/signal-XZXQ4VYQ.js.map +1 -0
  144. package/dist/signal-mNtlF8-v.d.cts +158 -0
  145. package/dist/signal-mNtlF8-v.d.ts +158 -0
  146. package/dist/state-kK9sQh9s.d.cts +73 -0
  147. package/dist/state-kK9sQh9s.d.ts +73 -0
  148. package/dist/test-exports.d.cts +17 -0
  149. package/dist/test-exports.d.ts +17 -0
  150. package/dist/test-exports.js +2 -0
  151. package/dist/test-exports.js.map +1 -0
  152. package/dist/test-exports.mjs +2 -0
  153. package/dist/test-exports.mjs.map +1 -0
  154. package/package.json +173 -0
@@ -0,0 +1,230 @@
1
+ import { A as AnimatableProps } from '../Motion-BrOAJzgH.js';
2
+ export { M as MotionController, a as MotionProps, S as SpringConfig, c as cleanupMotionState } from '../Motion-BrOAJzgH.js';
3
+ import { F as FNode } from '../renderer-DSLb-FGg.js';
4
+
5
+ /**
6
+ * Preset animation types
7
+ */
8
+ type TransitionPreset = 'fade' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'scale' | 'scale-fade';
9
+ /**
10
+ * Transition timing configuration
11
+ */
12
+ interface TransitionTiming {
13
+ duration?: number;
14
+ delay?: number;
15
+ easing?: string;
16
+ }
17
+ /**
18
+ * Transition component props
19
+ */
20
+ interface TransitionProps {
21
+ /** Use a preset animation */
22
+ preset?: TransitionPreset;
23
+ /** Custom enter animation (from state) */
24
+ enter?: AnimatableProps;
25
+ /** Custom enter animation (to state) */
26
+ enterTo?: AnimatableProps;
27
+ /** Custom exit animation (to state) */
28
+ exit?: AnimatableProps;
29
+ /** Enter timing */
30
+ enterTiming?: TransitionTiming;
31
+ /** Exit timing */
32
+ exitTiming?: TransitionTiming;
33
+ /** Callback when enter animation starts */
34
+ onEnterStart?: () => void;
35
+ /** Callback when enter animation completes */
36
+ onEnterComplete?: () => void;
37
+ /** Callback when exit animation starts */
38
+ onExitStart?: () => void;
39
+ /** Callback when exit animation completes */
40
+ onExitComplete?: () => void;
41
+ /** Children to animate */
42
+ children: any;
43
+ }
44
+ /**
45
+ * Transition component for animated enter/exit
46
+ *
47
+ * @example
48
+ * {() => visible() && (
49
+ * <Transition preset="fade">
50
+ * <div>Content appears with fade</div>
51
+ * </Transition>
52
+ * )}
53
+ *
54
+ * @example
55
+ * <Transition
56
+ * enter={{ opacity: 0, y: 50 }}
57
+ * enterTo={{ opacity: 1, y: 0 }}
58
+ * exit={{ opacity: 0, y: -50 }}
59
+ * enterTiming={{ duration: 300, easing: 'ease-out' }}
60
+ * exitTiming={{ duration: 200, easing: 'ease-in' }}
61
+ * >
62
+ * <div>Custom animated content</div>
63
+ * </Transition>
64
+ */
65
+ declare function Transition(props: TransitionProps): FNode;
66
+ /**
67
+ * TransitionGroup props
68
+ */
69
+ interface TransitionGroupProps {
70
+ /** Delay between each child animation (stagger effect) */
71
+ stagger?: number;
72
+ /** Children (should contain Transition components) */
73
+ children: any;
74
+ }
75
+ /**
76
+ * TransitionGroup component for staggered animations
77
+ *
78
+ * @example
79
+ * <TransitionGroup stagger={50}>
80
+ * <For each={items}>
81
+ * {(item) => (
82
+ * <Transition preset="slide-up">
83
+ * <div>{item.name}</div>
84
+ * </Transition>
85
+ * )}
86
+ * </For>
87
+ * </TransitionGroup>
88
+ */
89
+ declare function TransitionGroup(props: TransitionGroupProps): () => any;
90
+ /**
91
+ * Preset transition configurations
92
+ */
93
+ declare const transitions: {
94
+ fade: {
95
+ preset: "fade";
96
+ };
97
+ slideUp: {
98
+ preset: "slide-up";
99
+ };
100
+ slideDown: {
101
+ preset: "slide-down";
102
+ };
103
+ slideLeft: {
104
+ preset: "slide-left";
105
+ };
106
+ slideRight: {
107
+ preset: "slide-right";
108
+ };
109
+ scale: {
110
+ preset: "scale";
111
+ };
112
+ scaleFade: {
113
+ preset: "scale-fade";
114
+ };
115
+ modal: {
116
+ enter: {
117
+ opacity: number;
118
+ scale: number;
119
+ y: number;
120
+ };
121
+ enterTo: {
122
+ opacity: number;
123
+ scale: number;
124
+ y: number;
125
+ };
126
+ exit: {
127
+ opacity: number;
128
+ scale: number;
129
+ y: number;
130
+ };
131
+ enterTiming: {
132
+ duration: number;
133
+ easing: string;
134
+ };
135
+ exitTiming: {
136
+ duration: number;
137
+ easing: string;
138
+ };
139
+ };
140
+ dropdown: {
141
+ enter: {
142
+ opacity: number;
143
+ y: number;
144
+ scale: number;
145
+ };
146
+ enterTo: {
147
+ opacity: number;
148
+ y: number;
149
+ scale: number;
150
+ };
151
+ exit: {
152
+ opacity: number;
153
+ y: number;
154
+ scale: number;
155
+ };
156
+ enterTiming: {
157
+ duration: number;
158
+ easing: string;
159
+ };
160
+ exitTiming: {
161
+ duration: number;
162
+ easing: string;
163
+ };
164
+ };
165
+ tooltip: {
166
+ enter: {
167
+ opacity: number;
168
+ scale: number;
169
+ };
170
+ enterTo: {
171
+ opacity: number;
172
+ scale: number;
173
+ };
174
+ exit: {
175
+ opacity: number;
176
+ scale: number;
177
+ };
178
+ enterTiming: {
179
+ duration: number;
180
+ easing: string;
181
+ };
182
+ exitTiming: {
183
+ duration: number;
184
+ easing: string;
185
+ };
186
+ };
187
+ notification: {
188
+ enter: {
189
+ opacity: number;
190
+ x: number;
191
+ };
192
+ enterTo: {
193
+ opacity: number;
194
+ x: number;
195
+ };
196
+ exit: {
197
+ opacity: number;
198
+ x: number;
199
+ };
200
+ enterTiming: {
201
+ duration: number;
202
+ easing: string;
203
+ };
204
+ exitTiming: {
205
+ duration: number;
206
+ easing: string;
207
+ };
208
+ };
209
+ page: {
210
+ enter: {
211
+ opacity: number;
212
+ };
213
+ enterTo: {
214
+ opacity: number;
215
+ };
216
+ exit: {
217
+ opacity: number;
218
+ };
219
+ enterTiming: {
220
+ duration: number;
221
+ easing: string;
222
+ };
223
+ exitTiming: {
224
+ duration: number;
225
+ easing: string;
226
+ };
227
+ };
228
+ };
229
+
230
+ export { AnimatableProps, Transition, TransitionGroup, type TransitionGroupProps, type TransitionPreset, type TransitionProps, type TransitionTiming, transitions };
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkDOGIWSDA_js=require('../chunk-DOGIWSDA.js');require('../chunk-Q7IWDVJ4.js'),require('../chunk-WQFQO5LK.js'),require('../chunk-ROYFUJN5.js');Object.defineProperty(exports,"MotionController",{enumerable:true,get:function(){return chunkDOGIWSDA_js.b}});Object.defineProperty(exports,"Transition",{enumerable:true,get:function(){return chunkDOGIWSDA_js.c}});Object.defineProperty(exports,"TransitionGroup",{enumerable:true,get:function(){return chunkDOGIWSDA_js.d}});Object.defineProperty(exports,"cleanupMotionState",{enumerable:true,get:function(){return chunkDOGIWSDA_js.a}});Object.defineProperty(exports,"transitions",{enumerable:true,get:function(){return chunkDOGIWSDA_js.e}});//# sourceMappingURL=motion.js.map
2
+ //# sourceMappingURL=motion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"motion.js"}
@@ -0,0 +1,2 @@
1
+ export{b as MotionController,c as Transition,d as TransitionGroup,a as cleanupMotionState,e as transitions}from'../chunk-MLZTCKTH.mjs';import'../chunk-WVEJT7HD.mjs';import'../chunk-KNF5ERPK.mjs';import'../chunk-5S3ZQ2LB.mjs';//# sourceMappingURL=motion.mjs.map
2
+ //# sourceMappingURL=motion.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"motion.mjs"}
@@ -0,0 +1,81 @@
1
+ import { S as Signal } from '../signal-mNtlF8-v.cjs';
2
+ import { F as FNode } from '../renderer-DSLb-FGg.cjs';
3
+
4
+ /**
5
+ * Button Component - Accessible button with unified touch/click handler
6
+ *
7
+ * Provides onPress handler that works consistently across mouse, touch, and keyboard
8
+ * Includes full ARIA support and style props
9
+ */
10
+
11
+ /**
12
+ * Button variants
13
+ */
14
+ type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
15
+ /**
16
+ * Button sizes
17
+ */
18
+ type ButtonSize = 'sm' | 'md' | 'lg';
19
+ /**
20
+ * Button type attribute
21
+ */
22
+ type ButtonType = 'button' | 'submit' | 'reset';
23
+ /**
24
+ * Button component props
25
+ */
26
+ interface ButtonProps {
27
+ type?: ButtonType;
28
+ variant?: ButtonVariant;
29
+ size?: ButtonSize;
30
+ disabled?: Signal<boolean> | boolean;
31
+ loading?: Signal<boolean> | boolean;
32
+ fullWidth?: boolean;
33
+ children?: any;
34
+ leftIcon?: any;
35
+ rightIcon?: any;
36
+ loadingText?: string;
37
+ className?: string;
38
+ style?: Partial<CSSStyleDeclaration>;
39
+ id?: string;
40
+ role?: string;
41
+ ariaLabel?: string;
42
+ ariaDescribedby?: string;
43
+ ariaExpanded?: boolean;
44
+ ariaPressed?: boolean;
45
+ ariaControls?: string;
46
+ onPress?: (event: Event) => void | Promise<void>;
47
+ onPressStart?: (event: PointerEvent) => void;
48
+ onPressEnd?: (event: PointerEvent) => void;
49
+ onFocus?: (event: FocusEvent) => void;
50
+ onBlur?: (event: FocusEvent) => void;
51
+ onKeyDown?: (event: KeyboardEvent) => void;
52
+ }
53
+ /**
54
+ * Button component - Accessible button with unified touch/click handler
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * <Button variant="primary" onPress={() => console.log('clicked')}>
59
+ * Click me
60
+ * </Button>
61
+ *
62
+ * const loading = signal(false)
63
+ * <Button loading={loading} loadingText="Saving...">
64
+ * Save
65
+ * </Button>
66
+ * ```
67
+ */
68
+ declare function Button(props: ButtonProps): FNode;
69
+ /**
70
+ * IconButton component - Button with only an icon
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <IconButton icon={<i class="icon-close" />} ariaLabel="Close" onPress={handleClose} />
75
+ * ```
76
+ */
77
+ declare function IconButton(props: ButtonProps & {
78
+ icon: any;
79
+ }): FNode;
80
+
81
+ export { Button, type ButtonProps, type ButtonSize, type ButtonType, type ButtonVariant, IconButton };
@@ -0,0 +1,81 @@
1
+ import { S as Signal } from '../signal-mNtlF8-v.js';
2
+ import { F as FNode } from '../renderer-DSLb-FGg.js';
3
+
4
+ /**
5
+ * Button Component - Accessible button with unified touch/click handler
6
+ *
7
+ * Provides onPress handler that works consistently across mouse, touch, and keyboard
8
+ * Includes full ARIA support and style props
9
+ */
10
+
11
+ /**
12
+ * Button variants
13
+ */
14
+ type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
15
+ /**
16
+ * Button sizes
17
+ */
18
+ type ButtonSize = 'sm' | 'md' | 'lg';
19
+ /**
20
+ * Button type attribute
21
+ */
22
+ type ButtonType = 'button' | 'submit' | 'reset';
23
+ /**
24
+ * Button component props
25
+ */
26
+ interface ButtonProps {
27
+ type?: ButtonType;
28
+ variant?: ButtonVariant;
29
+ size?: ButtonSize;
30
+ disabled?: Signal<boolean> | boolean;
31
+ loading?: Signal<boolean> | boolean;
32
+ fullWidth?: boolean;
33
+ children?: any;
34
+ leftIcon?: any;
35
+ rightIcon?: any;
36
+ loadingText?: string;
37
+ className?: string;
38
+ style?: Partial<CSSStyleDeclaration>;
39
+ id?: string;
40
+ role?: string;
41
+ ariaLabel?: string;
42
+ ariaDescribedby?: string;
43
+ ariaExpanded?: boolean;
44
+ ariaPressed?: boolean;
45
+ ariaControls?: string;
46
+ onPress?: (event: Event) => void | Promise<void>;
47
+ onPressStart?: (event: PointerEvent) => void;
48
+ onPressEnd?: (event: PointerEvent) => void;
49
+ onFocus?: (event: FocusEvent) => void;
50
+ onBlur?: (event: FocusEvent) => void;
51
+ onKeyDown?: (event: KeyboardEvent) => void;
52
+ }
53
+ /**
54
+ * Button component - Accessible button with unified touch/click handler
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * <Button variant="primary" onPress={() => console.log('clicked')}>
59
+ * Click me
60
+ * </Button>
61
+ *
62
+ * const loading = signal(false)
63
+ * <Button loading={loading} loadingText="Saving...">
64
+ * Save
65
+ * </Button>
66
+ * ```
67
+ */
68
+ declare function Button(props: ButtonProps): FNode;
69
+ /**
70
+ * IconButton component - Button with only an icon
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <IconButton icon={<i class="icon-close" />} ariaLabel="Close" onPress={handleClose} />
75
+ * ```
76
+ */
77
+ declare function IconButton(props: ButtonProps & {
78
+ icon: any;
79
+ }): FNode;
80
+
81
+ export { Button, type ButtonProps, type ButtonSize, type ButtonType, type ButtonVariant, IconButton };
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkQ7IWDVJ4_js=require('../chunk-Q7IWDVJ4.js');require('../chunk-WQFQO5LK.js');var chunkROYFUJN5_js=require('../chunk-ROYFUJN5.js');function O(u){let{type:y="button",variant:s="primary",size:v="md",disabled:o=false,loading:E=false,fullWidth:j=false,children:b,leftIcon:x,rightIcon:T,loadingText:k="Loading...",className:D="",style:G,id:C,role:N,ariaLabel:w,ariaDescribedby:I,ariaExpanded:A,ariaPressed:F,ariaControls:K,onPress:z,onPressStart:a,onPressEnd:l,onFocus:m,onBlur:L,onKeyDown:H}=u,g=["button",`button-${s}`,`button-${v}`];j&&g.push("button-full-width"),D&&g.push(D);let t={type:y,class:g.join(" "),style:G};C&&(t.id=C),N&&(t.role=N),w&&(t["aria-label"]=w),I&&(t["aria-describedby"]=I),A!==void 0&&(t["aria-expanded"]=A),F!==void 0&&(t["aria-pressed"]=F),K&&(t["aria-controls"]=K),t.ref=e=>{if(!e)return;let M=typeof o=="boolean"?chunkROYFUJN5_js.h(o):o,Q=typeof E=="boolean"?chunkROYFUJN5_js.h(E):E,d=e.querySelector(".button-content"),c=e.querySelector(".button-spinner"),p=e.querySelector(".button-text");if(chunkROYFUJN5_js.j(()=>{e.disabled=M.value,M.value?e.setAttribute("aria-disabled","true"):e.removeAttribute("aria-disabled");}),chunkROYFUJN5_js.j(()=>{Q.value?(c&&(c.style.display="inline-block"),d&&(d.style.visibility="hidden"),k&&p&&(p.textContent=k),e.disabled=true,e.setAttribute("aria-busy","true")):(c&&(c.style.display="none"),d&&(d.style.visibility="visible"),typeof b=="string"&&p&&(p.textContent=b),e.removeAttribute("aria-busy"));}),z){let i=false,_=n=>{e.disabled||(i=true,e.classList.add("button-pressed"),a&&a(n));},U=n=>{i&&(i=false,e.classList.remove("button-pressed"),l&&l(n));},B=async n=>{if(e.disabled){n.preventDefault();return}try{await z(n);}catch(X){chunkROYFUJN5_js.b(chunkROYFUJN5_js.a.BUTTON_HANDLER_FAILED,void 0,X);}},W=n=>{e.disabled||((n.key==="Enter"||n.key===" ")&&(n.preventDefault(),i=true,e.classList.add("button-pressed"),a&&a(n)),H&&H(n));},q=n=>{e.disabled||(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),i=false,e.classList.remove("button-pressed"),l&&l(n),B(n));},R=()=>{i=false,e.classList.remove("button-pressed");};e.addEventListener("pointerdown",_),e.addEventListener("pointerup",U),e.addEventListener("click",B),e.addEventListener("keydown",W),e.addEventListener("keyup",q),e.addEventListener("pointercancel",R),chunkROYFUJN5_js.o(()=>{e.removeEventListener("pointerdown",_),e.removeEventListener("pointerup",U),e.removeEventListener("click",B),e.removeEventListener("keydown",W),e.removeEventListener("keyup",q),e.removeEventListener("pointercancel",R);});}m&&(e.addEventListener("focus",m),chunkROYFUJN5_js.o(()=>e.removeEventListener("focus",m))),L&&(e.addEventListener("blur",L),chunkROYFUJN5_js.o(()=>e.removeEventListener("blur",L)));};let J=[chunkQ7IWDVJ4_js.a("span",{class:"button-spinner","aria-hidden":"true",style:{display:"none"}}),chunkQ7IWDVJ4_js.a("span",{class:"button-content"},[x&&chunkQ7IWDVJ4_js.a("span",{class:"button-icon button-icon-left"},x),chunkQ7IWDVJ4_js.a("span",{class:"button-text"},b),T&&chunkQ7IWDVJ4_js.a("span",{class:"button-icon button-icon-right"},T)].filter(Boolean))];return chunkQ7IWDVJ4_js.a("button",t,J)}function Y(u){let{icon:y,ariaLabel:s,className:v,...o}=u;return s||chunkROYFUJN5_js.c(chunkROYFUJN5_js.a.BUTTON_MISSING_ARIA_LABEL),O({...o,children:y,ariaLabel:s,className:`icon-button ${v||""}`})}exports.Button=O;exports.IconButton=Y;//# sourceMappingURL=ui.js.map
2
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/ui/Button.ts"],"names":["Button","props","type","variant","size","disabled","loading","fullWidth","children","leftIcon","rightIcon","loadingText","className","style","id","role","ariaLabel","ariaDescribedby","ariaExpanded","ariaPressed","ariaControls","onPress","onPressStart","onPressEnd","onFocus","onBlur","onKeyDown","classes","buttonProps","button","disabledSignal","signal","loadingSignal","contentWrapper","loadingSpinner","textContent","effect","isPressing","handlePointerDown","e","handlePointerUp","handleClick","error","logError","ErrorCodes","handleKeyDown","handleKeyUp","handlePointerCancel","onCleanup","buttonChildren","f","IconButton","icon","logWarning"],"mappings":"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","file":"ui.js","sourcesContent":["/**\n * Button Component - Accessible button with unified touch/click handler\n *\n * Provides onPress handler that works consistently across mouse, touch, and keyboard\n * Includes full ARIA support and style props\n */\n\nimport { signal, effect, onCleanup, type Signal } from '../../core/signal'\nimport { ErrorCodes, logError, logWarning } from '../../core/errors'\nimport { f } from '../../renderers/dom/f'\nimport type { FNode } from '../../core/renderer'\n\n/**\n * Button variants\n */\nexport type ButtonVariant =\n | 'primary'\n | 'secondary'\n | 'outline'\n | 'ghost'\n | 'danger'\n\n/**\n * Button sizes\n */\nexport type ButtonSize = 'sm' | 'md' | 'lg'\n\n/**\n * Button type attribute\n */\nexport type ButtonType = 'button' | 'submit' | 'reset'\n\n/**\n * Button component props\n */\nexport interface ButtonProps {\n type?: ButtonType\n variant?: ButtonVariant\n size?: ButtonSize\n disabled?: Signal<boolean> | boolean\n loading?: Signal<boolean> | boolean\n fullWidth?: boolean\n\n // Content\n children?: any\n leftIcon?: any\n rightIcon?: any\n loadingText?: string\n\n // Styling\n className?: string\n style?: Partial<CSSStyleDeclaration>\n\n // Accessibility\n id?: string\n role?: string\n ariaLabel?: string\n ariaDescribedby?: string\n ariaExpanded?: boolean\n ariaPressed?: boolean\n ariaControls?: string\n\n // Event handlers\n onPress?: (event: Event) => void | Promise<void>\n onPressStart?: (event: PointerEvent) => void\n onPressEnd?: (event: PointerEvent) => void\n onFocus?: (event: FocusEvent) => void\n onBlur?: (event: FocusEvent) => void\n onKeyDown?: (event: KeyboardEvent) => void\n}\n\n/**\n * Button component - Accessible button with unified touch/click handler\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\" onPress={() => console.log('clicked')}>\n * Click me\n * </Button>\n *\n * const loading = signal(false)\n * <Button loading={loading} loadingText=\"Saving...\">\n * Save\n * </Button>\n * ```\n */\nexport function Button(props: ButtonProps): FNode {\n const {\n type = 'button',\n variant = 'primary',\n size = 'md',\n disabled = false,\n loading = false,\n fullWidth = false,\n children,\n leftIcon,\n rightIcon,\n loadingText = 'Loading...',\n className = '',\n style,\n id,\n role,\n ariaLabel,\n ariaDescribedby,\n ariaExpanded,\n ariaPressed,\n ariaControls,\n onPress,\n onPressStart,\n onPressEnd,\n onFocus,\n onBlur,\n onKeyDown,\n } = props\n\n // Build class names\n const classes = ['button', `button-${variant}`, `button-${size}`]\n if (fullWidth) classes.push('button-full-width')\n if (className) classes.push(className)\n\n // Build props for the button element\n const buttonProps: Record<string, any> = {\n type,\n class: classes.join(' '),\n style,\n }\n\n if (id) buttonProps.id = id\n if (role) buttonProps.role = role\n if (ariaLabel) buttonProps['aria-label'] = ariaLabel\n if (ariaDescribedby) buttonProps['aria-describedby'] = ariaDescribedby\n if (ariaExpanded !== undefined) buttonProps['aria-expanded'] = ariaExpanded\n if (ariaPressed !== undefined) buttonProps['aria-pressed'] = ariaPressed\n if (ariaControls) buttonProps['aria-controls'] = ariaControls\n\n // Add ref callback to set up reactive behavior\n buttonProps.ref = (button: HTMLButtonElement | null) => {\n if (!button) return\n\n // Convert disabled/loading to signals if needed\n const disabledSignal =\n typeof disabled === 'boolean' ? signal(disabled) : disabled\n const loadingSignal = typeof loading === 'boolean' ? signal(loading) : loading\n\n // Find content elements after mount\n const contentWrapper = button.querySelector('.button-content') as HTMLElement\n const loadingSpinner = button.querySelector('.button-spinner') as HTMLElement\n const textContent = button.querySelector('.button-text') as HTMLElement\n\n // Handle disabled state\n effect(() => {\n button.disabled = disabledSignal.value\n if (disabledSignal.value) {\n button.setAttribute('aria-disabled', 'true')\n } else {\n button.removeAttribute('aria-disabled')\n }\n })\n\n // Handle loading state\n effect(() => {\n const isLoading = loadingSignal.value\n\n if (isLoading) {\n // Show spinner\n if (loadingSpinner) loadingSpinner.style.display = 'inline-block'\n if (contentWrapper) contentWrapper.style.visibility = 'hidden'\n\n // Update text for screen readers\n if (loadingText && textContent) {\n textContent.textContent = loadingText\n }\n\n // Disable button during loading\n button.disabled = true\n button.setAttribute('aria-busy', 'true')\n } else {\n // Hide spinner\n if (loadingSpinner) loadingSpinner.style.display = 'none'\n if (contentWrapper) contentWrapper.style.visibility = 'visible'\n\n // Restore original text\n if (typeof children === 'string' && textContent) {\n textContent.textContent = children\n }\n\n button.removeAttribute('aria-busy')\n }\n })\n\n // Unified press handler (works for mouse, touch, and keyboard)\n if (onPress) {\n let isPressing = false\n\n // Pointer down (mouse/touch start)\n const handlePointerDown = (e: PointerEvent) => {\n if (button.disabled) return\n\n isPressing = true\n button.classList.add('button-pressed')\n\n if (onPressStart) {\n onPressStart(e)\n }\n }\n\n // Pointer up (mouse/touch end)\n const handlePointerUp = (e: PointerEvent) => {\n if (!isPressing) return\n\n isPressing = false\n button.classList.remove('button-pressed')\n\n if (onPressEnd) {\n onPressEnd(e)\n }\n }\n\n // Click (fires after pointer up)\n const handleClick = async (e: Event) => {\n if (button.disabled) {\n e.preventDefault()\n return\n }\n\n try {\n await onPress(e)\n } catch (error) {\n logError(ErrorCodes.BUTTON_HANDLER_FAILED, undefined, error)\n }\n }\n\n // Keyboard (Enter/Space)\n const handleKeyDown = (e: KeyboardEvent) => {\n if (button.disabled) return\n\n // Enter or Space triggers press\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n isPressing = true\n button.classList.add('button-pressed')\n\n if (onPressStart) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onPressStart(e as any)\n }\n }\n\n // Custom keydown handler\n if (onKeyDown) {\n onKeyDown(e)\n }\n }\n\n const handleKeyUp = (e: KeyboardEvent) => {\n if (button.disabled) return\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n isPressing = false\n button.classList.remove('button-pressed')\n\n if (onPressEnd) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onPressEnd(e as any)\n }\n\n // Trigger press\n handleClick(e)\n }\n }\n\n // Pointer cancel (touch interrupted)\n const handlePointerCancel = () => {\n isPressing = false\n button.classList.remove('button-pressed')\n }\n\n button.addEventListener('pointerdown', handlePointerDown)\n button.addEventListener('pointerup', handlePointerUp)\n button.addEventListener('click', handleClick)\n button.addEventListener('keydown', handleKeyDown)\n button.addEventListener('keyup', handleKeyUp)\n button.addEventListener('pointercancel', handlePointerCancel)\n\n onCleanup(() => {\n button.removeEventListener('pointerdown', handlePointerDown)\n button.removeEventListener('pointerup', handlePointerUp)\n button.removeEventListener('click', handleClick)\n button.removeEventListener('keydown', handleKeyDown)\n button.removeEventListener('keyup', handleKeyUp)\n button.removeEventListener('pointercancel', handlePointerCancel)\n })\n }\n\n // Focus/blur handlers\n if (onFocus) {\n button.addEventListener('focus', onFocus)\n onCleanup(() => button.removeEventListener('focus', onFocus))\n }\n\n if (onBlur) {\n button.addEventListener('blur', onBlur)\n onCleanup(() => button.removeEventListener('blur', onBlur))\n }\n }\n\n // Build button content structure\n const buttonChildren = [\n // Loading spinner\n f('span', {\n class: 'button-spinner',\n 'aria-hidden': 'true',\n style: { display: 'none' },\n }),\n // Content wrapper with icons and text\n f(\n 'span',\n { class: 'button-content' },\n [\n leftIcon && f('span', { class: 'button-icon button-icon-left' }, leftIcon),\n f('span', { class: 'button-text' }, children),\n rightIcon &&\n f('span', { class: 'button-icon button-icon-right' }, rightIcon),\n ].filter(Boolean)\n ),\n ]\n\n return f('button', buttonProps, buttonChildren)\n}\n\n/**\n * IconButton component - Button with only an icon\n *\n * @example\n * ```tsx\n * <IconButton icon={<i class=\"icon-close\" />} ariaLabel=\"Close\" onPress={handleClose} />\n * ```\n */\nexport function IconButton(props: ButtonProps & { icon: any }): FNode {\n const { icon, ariaLabel, className, ...buttonProps } = props\n\n if (!ariaLabel) {\n logWarning(ErrorCodes.BUTTON_MISSING_ARIA_LABEL)\n }\n\n return Button({\n ...buttonProps,\n children: icon,\n ariaLabel,\n className: `icon-button ${className || ''}`,\n })\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import {a}from'../chunk-WVEJT7HD.mjs';import'../chunk-KNF5ERPK.mjs';import {c,a as a$1,h,j,o,b}from'../chunk-5S3ZQ2LB.mjs';function O(u){let{type:y="button",variant:s="primary",size:v="md",disabled:o$1=false,loading:E=false,fullWidth:j$1=false,children:b$1,leftIcon:x,rightIcon:T,loadingText:k="Loading...",className:D="",style:G,id:C,role:N,ariaLabel:w,ariaDescribedby:I,ariaExpanded:A,ariaPressed:F,ariaControls:K,onPress:z,onPressStart:a$2,onPressEnd:l,onFocus:m,onBlur:L,onKeyDown:H}=u,g=["button",`button-${s}`,`button-${v}`];j$1&&g.push("button-full-width"),D&&g.push(D);let t={type:y,class:g.join(" "),style:G};C&&(t.id=C),N&&(t.role=N),w&&(t["aria-label"]=w),I&&(t["aria-describedby"]=I),A!==void 0&&(t["aria-expanded"]=A),F!==void 0&&(t["aria-pressed"]=F),K&&(t["aria-controls"]=K),t.ref=e=>{if(!e)return;let M=typeof o$1=="boolean"?h(o$1):o$1,Q=typeof E=="boolean"?h(E):E,d=e.querySelector(".button-content"),c=e.querySelector(".button-spinner"),p=e.querySelector(".button-text");if(j(()=>{e.disabled=M.value,M.value?e.setAttribute("aria-disabled","true"):e.removeAttribute("aria-disabled");}),j(()=>{Q.value?(c&&(c.style.display="inline-block"),d&&(d.style.visibility="hidden"),k&&p&&(p.textContent=k),e.disabled=true,e.setAttribute("aria-busy","true")):(c&&(c.style.display="none"),d&&(d.style.visibility="visible"),typeof b$1=="string"&&p&&(p.textContent=b$1),e.removeAttribute("aria-busy"));}),z){let i=false,_=n=>{e.disabled||(i=true,e.classList.add("button-pressed"),a$2&&a$2(n));},U=n=>{i&&(i=false,e.classList.remove("button-pressed"),l&&l(n));},B=async n=>{if(e.disabled){n.preventDefault();return}try{await z(n);}catch(X){b(a$1.BUTTON_HANDLER_FAILED,void 0,X);}},W=n=>{e.disabled||((n.key==="Enter"||n.key===" ")&&(n.preventDefault(),i=true,e.classList.add("button-pressed"),a$2&&a$2(n)),H&&H(n));},q=n=>{e.disabled||(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),i=false,e.classList.remove("button-pressed"),l&&l(n),B(n));},R=()=>{i=false,e.classList.remove("button-pressed");};e.addEventListener("pointerdown",_),e.addEventListener("pointerup",U),e.addEventListener("click",B),e.addEventListener("keydown",W),e.addEventListener("keyup",q),e.addEventListener("pointercancel",R),o(()=>{e.removeEventListener("pointerdown",_),e.removeEventListener("pointerup",U),e.removeEventListener("click",B),e.removeEventListener("keydown",W),e.removeEventListener("keyup",q),e.removeEventListener("pointercancel",R);});}m&&(e.addEventListener("focus",m),o(()=>e.removeEventListener("focus",m))),L&&(e.addEventListener("blur",L),o(()=>e.removeEventListener("blur",L)));};let J=[a("span",{class:"button-spinner","aria-hidden":"true",style:{display:"none"}}),a("span",{class:"button-content"},[x&&a("span",{class:"button-icon button-icon-left"},x),a("span",{class:"button-text"},b$1),T&&a("span",{class:"button-icon button-icon-right"},T)].filter(Boolean))];return a("button",t,J)}function Y(u){let{icon:y,ariaLabel:s,className:v,...o}=u;return s||c(a$1.BUTTON_MISSING_ARIA_LABEL),O({...o,children:y,ariaLabel:s,className:`icon-button ${v||""}`})}export{O as Button,Y as IconButton};//# sourceMappingURL=ui.mjs.map
2
+ //# sourceMappingURL=ui.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/ui/Button.ts"],"names":["Button","props","type","variant","size","disabled","loading","fullWidth","children","leftIcon","rightIcon","loadingText","className","style","id","role","ariaLabel","ariaDescribedby","ariaExpanded","ariaPressed","ariaControls","onPress","onPressStart","onPressEnd","onFocus","onBlur","onKeyDown","classes","buttonProps","button","disabledSignal","signal","loadingSignal","contentWrapper","loadingSpinner","textContent","effect","isPressing","handlePointerDown","e","handlePointerUp","handleClick","error","logError","ErrorCodes","handleKeyDown","handleKeyUp","handlePointerCancel","onCleanup","buttonChildren","f","IconButton","icon","logWarning"],"mappings":"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","file":"ui.mjs","sourcesContent":["/**\n * Button Component - Accessible button with unified touch/click handler\n *\n * Provides onPress handler that works consistently across mouse, touch, and keyboard\n * Includes full ARIA support and style props\n */\n\nimport { signal, effect, onCleanup, type Signal } from '../../core/signal'\nimport { ErrorCodes, logError, logWarning } from '../../core/errors'\nimport { f } from '../../renderers/dom/f'\nimport type { FNode } from '../../core/renderer'\n\n/**\n * Button variants\n */\nexport type ButtonVariant =\n | 'primary'\n | 'secondary'\n | 'outline'\n | 'ghost'\n | 'danger'\n\n/**\n * Button sizes\n */\nexport type ButtonSize = 'sm' | 'md' | 'lg'\n\n/**\n * Button type attribute\n */\nexport type ButtonType = 'button' | 'submit' | 'reset'\n\n/**\n * Button component props\n */\nexport interface ButtonProps {\n type?: ButtonType\n variant?: ButtonVariant\n size?: ButtonSize\n disabled?: Signal<boolean> | boolean\n loading?: Signal<boolean> | boolean\n fullWidth?: boolean\n\n // Content\n children?: any\n leftIcon?: any\n rightIcon?: any\n loadingText?: string\n\n // Styling\n className?: string\n style?: Partial<CSSStyleDeclaration>\n\n // Accessibility\n id?: string\n role?: string\n ariaLabel?: string\n ariaDescribedby?: string\n ariaExpanded?: boolean\n ariaPressed?: boolean\n ariaControls?: string\n\n // Event handlers\n onPress?: (event: Event) => void | Promise<void>\n onPressStart?: (event: PointerEvent) => void\n onPressEnd?: (event: PointerEvent) => void\n onFocus?: (event: FocusEvent) => void\n onBlur?: (event: FocusEvent) => void\n onKeyDown?: (event: KeyboardEvent) => void\n}\n\n/**\n * Button component - Accessible button with unified touch/click handler\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\" onPress={() => console.log('clicked')}>\n * Click me\n * </Button>\n *\n * const loading = signal(false)\n * <Button loading={loading} loadingText=\"Saving...\">\n * Save\n * </Button>\n * ```\n */\nexport function Button(props: ButtonProps): FNode {\n const {\n type = 'button',\n variant = 'primary',\n size = 'md',\n disabled = false,\n loading = false,\n fullWidth = false,\n children,\n leftIcon,\n rightIcon,\n loadingText = 'Loading...',\n className = '',\n style,\n id,\n role,\n ariaLabel,\n ariaDescribedby,\n ariaExpanded,\n ariaPressed,\n ariaControls,\n onPress,\n onPressStart,\n onPressEnd,\n onFocus,\n onBlur,\n onKeyDown,\n } = props\n\n // Build class names\n const classes = ['button', `button-${variant}`, `button-${size}`]\n if (fullWidth) classes.push('button-full-width')\n if (className) classes.push(className)\n\n // Build props for the button element\n const buttonProps: Record<string, any> = {\n type,\n class: classes.join(' '),\n style,\n }\n\n if (id) buttonProps.id = id\n if (role) buttonProps.role = role\n if (ariaLabel) buttonProps['aria-label'] = ariaLabel\n if (ariaDescribedby) buttonProps['aria-describedby'] = ariaDescribedby\n if (ariaExpanded !== undefined) buttonProps['aria-expanded'] = ariaExpanded\n if (ariaPressed !== undefined) buttonProps['aria-pressed'] = ariaPressed\n if (ariaControls) buttonProps['aria-controls'] = ariaControls\n\n // Add ref callback to set up reactive behavior\n buttonProps.ref = (button: HTMLButtonElement | null) => {\n if (!button) return\n\n // Convert disabled/loading to signals if needed\n const disabledSignal =\n typeof disabled === 'boolean' ? signal(disabled) : disabled\n const loadingSignal = typeof loading === 'boolean' ? signal(loading) : loading\n\n // Find content elements after mount\n const contentWrapper = button.querySelector('.button-content') as HTMLElement\n const loadingSpinner = button.querySelector('.button-spinner') as HTMLElement\n const textContent = button.querySelector('.button-text') as HTMLElement\n\n // Handle disabled state\n effect(() => {\n button.disabled = disabledSignal.value\n if (disabledSignal.value) {\n button.setAttribute('aria-disabled', 'true')\n } else {\n button.removeAttribute('aria-disabled')\n }\n })\n\n // Handle loading state\n effect(() => {\n const isLoading = loadingSignal.value\n\n if (isLoading) {\n // Show spinner\n if (loadingSpinner) loadingSpinner.style.display = 'inline-block'\n if (contentWrapper) contentWrapper.style.visibility = 'hidden'\n\n // Update text for screen readers\n if (loadingText && textContent) {\n textContent.textContent = loadingText\n }\n\n // Disable button during loading\n button.disabled = true\n button.setAttribute('aria-busy', 'true')\n } else {\n // Hide spinner\n if (loadingSpinner) loadingSpinner.style.display = 'none'\n if (contentWrapper) contentWrapper.style.visibility = 'visible'\n\n // Restore original text\n if (typeof children === 'string' && textContent) {\n textContent.textContent = children\n }\n\n button.removeAttribute('aria-busy')\n }\n })\n\n // Unified press handler (works for mouse, touch, and keyboard)\n if (onPress) {\n let isPressing = false\n\n // Pointer down (mouse/touch start)\n const handlePointerDown = (e: PointerEvent) => {\n if (button.disabled) return\n\n isPressing = true\n button.classList.add('button-pressed')\n\n if (onPressStart) {\n onPressStart(e)\n }\n }\n\n // Pointer up (mouse/touch end)\n const handlePointerUp = (e: PointerEvent) => {\n if (!isPressing) return\n\n isPressing = false\n button.classList.remove('button-pressed')\n\n if (onPressEnd) {\n onPressEnd(e)\n }\n }\n\n // Click (fires after pointer up)\n const handleClick = async (e: Event) => {\n if (button.disabled) {\n e.preventDefault()\n return\n }\n\n try {\n await onPress(e)\n } catch (error) {\n logError(ErrorCodes.BUTTON_HANDLER_FAILED, undefined, error)\n }\n }\n\n // Keyboard (Enter/Space)\n const handleKeyDown = (e: KeyboardEvent) => {\n if (button.disabled) return\n\n // Enter or Space triggers press\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n isPressing = true\n button.classList.add('button-pressed')\n\n if (onPressStart) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onPressStart(e as any)\n }\n }\n\n // Custom keydown handler\n if (onKeyDown) {\n onKeyDown(e)\n }\n }\n\n const handleKeyUp = (e: KeyboardEvent) => {\n if (button.disabled) return\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n isPressing = false\n button.classList.remove('button-pressed')\n\n if (onPressEnd) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onPressEnd(e as any)\n }\n\n // Trigger press\n handleClick(e)\n }\n }\n\n // Pointer cancel (touch interrupted)\n const handlePointerCancel = () => {\n isPressing = false\n button.classList.remove('button-pressed')\n }\n\n button.addEventListener('pointerdown', handlePointerDown)\n button.addEventListener('pointerup', handlePointerUp)\n button.addEventListener('click', handleClick)\n button.addEventListener('keydown', handleKeyDown)\n button.addEventListener('keyup', handleKeyUp)\n button.addEventListener('pointercancel', handlePointerCancel)\n\n onCleanup(() => {\n button.removeEventListener('pointerdown', handlePointerDown)\n button.removeEventListener('pointerup', handlePointerUp)\n button.removeEventListener('click', handleClick)\n button.removeEventListener('keydown', handleKeyDown)\n button.removeEventListener('keyup', handleKeyUp)\n button.removeEventListener('pointercancel', handlePointerCancel)\n })\n }\n\n // Focus/blur handlers\n if (onFocus) {\n button.addEventListener('focus', onFocus)\n onCleanup(() => button.removeEventListener('focus', onFocus))\n }\n\n if (onBlur) {\n button.addEventListener('blur', onBlur)\n onCleanup(() => button.removeEventListener('blur', onBlur))\n }\n }\n\n // Build button content structure\n const buttonChildren = [\n // Loading spinner\n f('span', {\n class: 'button-spinner',\n 'aria-hidden': 'true',\n style: { display: 'none' },\n }),\n // Content wrapper with icons and text\n f(\n 'span',\n { class: 'button-content' },\n [\n leftIcon && f('span', { class: 'button-icon button-icon-left' }, leftIcon),\n f('span', { class: 'button-text' }, children),\n rightIcon &&\n f('span', { class: 'button-icon button-icon-right' }, rightIcon),\n ].filter(Boolean)\n ),\n ]\n\n return f('button', buttonProps, buttonChildren)\n}\n\n/**\n * IconButton component - Button with only an icon\n *\n * @example\n * ```tsx\n * <IconButton icon={<i class=\"icon-close\" />} ariaLabel=\"Close\" onPress={handleClose} />\n * ```\n */\nexport function IconButton(props: ButtonProps & { icon: any }): FNode {\n const { icon, ariaLabel, className, ...buttonProps } = props\n\n if (!ariaLabel) {\n logWarning(ErrorCodes.BUTTON_MISSING_ARIA_LABEL)\n }\n\n return Button({\n ...buttonProps,\n children: icon,\n ariaLabel,\n className: `icon-button ${className || ''}`,\n })\n}\n"]}
@@ -0,0 +1,92 @@
1
+ export { e as effect, r as root } from './signal-mNtlF8-v.cjs';
2
+ export { _ as state } from './state-kK9sQh9s.cjs';
3
+ export { CommonStyle as BaseStyleProps, Column, ColumnProps, CommonStyle, Grid, GridProps, Row, RowProps, Spacer, SpacerProps, Stack, StackProps } from './primitives/layout.cjs';
4
+ import { T as TextProps, F as FNode, I as ImageProps, P as PressableProps, S as ScrollViewProps, m as CommonStyle, n as TextStyle } from './DrawText-JB58mpQT.cjs';
5
+ export { C as Canvas, f as CanvasProps, b as DrawArc, i as DrawArcProps, a as DrawCircle, h as DrawCircleProps, c as DrawLine, j as DrawLineProps, d as DrawPath, k as DrawPathProps, D as DrawRect, g as DrawRectProps, e as DrawText, l as DrawTextProps } from './DrawText-JB58mpQT.cjs';
6
+ import './renderer-DSLb-FGg.cjs';
7
+
8
+ /**
9
+ * Text - Universal text display component
10
+ *
11
+ * Maps to:
12
+ * - Web: <span>
13
+ * - React Native: <Text>
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <Text style={{ color: 'blue', fontSize: 16 }}>
18
+ * Hello World
19
+ * </Text>
20
+ * ```
21
+ */
22
+
23
+ declare function Text(props: TextProps): FNode;
24
+
25
+ /**
26
+ * Image - Universal image component
27
+ *
28
+ * Maps to:
29
+ * - Web: <img>
30
+ * - React Native: <Image>
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * <Image
35
+ * src="/logo.png"
36
+ * alt="Logo"
37
+ * width={100}
38
+ * height={100}
39
+ * />
40
+ * ```
41
+ */
42
+
43
+ declare function Image(props: ImageProps): FNode;
44
+
45
+ /**
46
+ * Pressable - Universal touchable/clickable component
47
+ *
48
+ * Maps to:
49
+ * - Web: <button>
50
+ * - React Native: <Pressable>
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * <Pressable
55
+ * onPress={() => console.log('pressed')}
56
+ * style={{ padding: 10 }}
57
+ * >
58
+ * <Text>Click Me</Text>
59
+ * </Pressable>
60
+ * ```
61
+ */
62
+
63
+ declare function Pressable(props: PressableProps): FNode;
64
+
65
+ /**
66
+ * ScrollView - Universal scrollable container
67
+ *
68
+ * Maps to:
69
+ * - Web: <div style="overflow: scroll">
70
+ * - React Native: <ScrollView>
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <ScrollView style={{ height: 300 }}>
75
+ * <Column>...</Column>
76
+ * <Column>...</Column>
77
+ * </ScrollView>
78
+ * ```
79
+ */
80
+
81
+ declare function ScrollView(props: ScrollViewProps): FNode;
82
+
83
+ /**
84
+ * Primitive utilities
85
+ */
86
+
87
+ /**
88
+ * Normalize CommonStyle to CSS properties
89
+ */
90
+ declare function normalizeStyle(style?: CommonStyle | TextStyle): Record<string, any>;
91
+
92
+ export { Image, ImageProps, Pressable, PressableProps, ScrollView, ScrollViewProps, Text, TextProps, TextStyle, normalizeStyle };