@shohojdhara/atomix 0.3.4 → 0.3.5

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 (114) hide show
  1. package/dist/atomix.css +9 -10
  2. package/dist/atomix.css.map +1 -0
  3. package/dist/atomix.min.css +15108 -11
  4. package/dist/atomix.min.css.map +1 -0
  5. package/dist/charts.d.ts +1929 -0
  6. package/dist/charts.js +6482 -0
  7. package/dist/charts.js.map +1 -0
  8. package/dist/core.d.ts +1289 -0
  9. package/dist/core.js +3357 -0
  10. package/dist/core.js.map +1 -0
  11. package/dist/forms.d.ts +1085 -0
  12. package/dist/forms.js +2450 -0
  13. package/dist/forms.js.map +1 -0
  14. package/dist/heavy.d.ts +636 -0
  15. package/dist/heavy.js +4550 -0
  16. package/dist/heavy.js.map +1 -0
  17. package/dist/index.d.ts +5161 -4990
  18. package/dist/index.esm.js +1457 -784
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/index.js +1473 -790
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.min.js +1 -1
  23. package/dist/index.min.js.map +1 -1
  24. package/dist/layout.d.ts +300 -0
  25. package/dist/layout.js +336 -0
  26. package/dist/layout.js.map +1 -0
  27. package/dist/theme.d.ts +1992 -0
  28. package/dist/theme.js +5348 -0
  29. package/dist/theme.js.map +1 -0
  30. package/package.json +66 -20
  31. package/scripts/atomix-cli.js +544 -16
  32. package/scripts/cli/__tests__/cli-commands.test.js +204 -0
  33. package/scripts/cli/__tests__/utils.test.js +201 -0
  34. package/scripts/cli/__tests__/vitest.config.js +26 -0
  35. package/scripts/cli/interactive-init.js +1 -1
  36. package/scripts/cli/token-manager.js +32 -7
  37. package/scripts/cli/utils.js +347 -0
  38. package/src/components/Accordion/Accordion.tsx +5 -54
  39. package/src/components/Accordion/index.ts +1 -1
  40. package/src/components/Avatar/Avatar.tsx +3 -3
  41. package/src/components/Badge/Badge.tsx +3 -3
  42. package/src/components/Breadcrumb/Breadcrumb.tsx +3 -3
  43. package/src/components/Card/ElevationCard.tsx +1 -1
  44. package/src/components/Chart/AnimatedChart.tsx +19 -17
  45. package/src/components/Chart/AreaChart.tsx +5 -1
  46. package/src/components/Chart/BarChart.tsx +1 -0
  47. package/src/components/Chart/BubbleChart.tsx +6 -5
  48. package/src/components/Chart/ChartToolbar.tsx +1 -0
  49. package/src/components/Chart/FunnelChart.tsx +1 -1
  50. package/src/components/Chart/RadarChart.tsx +19 -12
  51. package/src/components/Chart/ScatterChart.tsx +3 -3
  52. package/src/components/Chart/TreemapChart.tsx +2 -1
  53. package/src/components/Chart/WaterfallChart.tsx +0 -1
  54. package/src/components/Chart/types.ts +12 -2
  55. package/src/components/Chart/utils.ts +4 -3
  56. package/src/components/DataTable/DataTable.tsx +3 -3
  57. package/src/components/Dropdown/Dropdown.tsx +12 -9
  58. package/src/components/Footer/FooterSection.tsx +3 -3
  59. package/src/components/Form/Checkbox.tsx +3 -3
  60. package/src/components/Form/Input.tsx +4 -2
  61. package/src/components/Form/Radio.tsx +3 -3
  62. package/src/components/Form/Select.tsx +3 -3
  63. package/src/components/Form/Textarea.tsx +4 -2
  64. package/src/components/List/List.stories.tsx +3 -3
  65. package/src/components/List/List.tsx +3 -3
  66. package/src/components/List/ListGroup.tsx +3 -1
  67. package/src/components/Modal/Modal.tsx +3 -3
  68. package/src/components/Navigation/Menu/MegaMenu.tsx +9 -3
  69. package/src/components/Navigation/Menu/Menu.tsx +9 -3
  70. package/src/components/Pagination/Pagination.tsx +6 -5
  71. package/src/components/PhotoViewer/PhotoViewerImage.tsx +2 -2
  72. package/src/components/Popover/Popover.tsx +4 -4
  73. package/src/components/Progress/Progress.tsx +6 -2
  74. package/src/components/Rating/Rating.tsx +5 -2
  75. package/src/components/Slider/Slider.tsx +10 -9
  76. package/src/components/Spinner/Spinner.tsx +3 -3
  77. package/src/components/Tabs/Tabs.tsx +3 -3
  78. package/src/components/Tooltip/Tooltip.tsx +3 -3
  79. package/src/components/index.ts +5 -2
  80. package/src/layouts/MasonryGrid/MasonryGrid.tsx +2 -2
  81. package/src/lib/composables/useChartPerformance.ts +102 -78
  82. package/src/lib/composables/useChartScale.ts +10 -0
  83. package/src/lib/composables/useHero.ts +9 -2
  84. package/src/lib/composables/useHeroBackgroundSlider.ts +5 -3
  85. package/src/lib/composables/useSideMenu.ts +1 -0
  86. package/src/lib/composables/useVideoPlayer.ts +3 -2
  87. package/src/lib/config/loader.ts +55 -13
  88. package/src/lib/hooks/index.ts +0 -1
  89. package/src/lib/hooks/useComponentCustomization.ts +10 -14
  90. package/src/lib/hooks/usePerformanceMonitor.ts +149 -0
  91. package/src/lib/patterns/index.ts +2 -2
  92. package/src/lib/patterns/slots.tsx +2 -2
  93. package/src/lib/theme/composeTheme.ts +1 -1
  94. package/src/lib/theme/core/ThemeEngine.ts +8 -0
  95. package/src/lib/theme/core/ThemeValidator.ts +5 -2
  96. package/src/lib/theme/devtools/Inspector.tsx +1 -1
  97. package/src/lib/theme/devtools/LiveEditor.tsx +11 -5
  98. package/src/lib/theme/generateCSSVariables.ts +1 -1
  99. package/src/lib/theme/i18n/rtl.ts +2 -1
  100. package/src/lib/theme/runtime/ThemeApplicator.ts +28 -11
  101. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +3 -3
  102. package/src/lib/theme/runtime/ThemeManager.ts +4 -0
  103. package/src/lib/theme-tools.ts +1 -1
  104. package/src/lib/types/components.ts +183 -34
  105. package/src/lib/types/partProps.ts +0 -16
  106. package/src/lib/utils/fontPreloader.ts +148 -0
  107. package/src/lib/utils/index.ts +11 -0
  108. package/src/lib/utils/memoryMonitor.ts +189 -0
  109. package/src/styles/01-settings/_settings.fonts.scss +2 -5
  110. package/src/styles/03-generic/_generated-root.css +22 -1
  111. package/src/styles/06-components/_components.navbar.scss +0 -6
  112. package/src/themes/themes.config.js +37 -4
  113. package/scripts/build-themes.js +0 -208
  114. package/src/components/AtomixGlass/atomixGLass.old.tsx +0 -1263
package/dist/forms.js ADDED
@@ -0,0 +1,2450 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+
3
+ import React, { useRef, useEffect, memo, forwardRef, useId, useState, useMemo, useCallback } from "react";
4
+
5
+ // Define checkbox class constants
6
+ const FORM_CLASSES_BASE = "c-form", FORM_CLASSES_DISABLED = "c-form--disabled", FORM_GROUP_CLASSES_BASE = "c-form-group", FORM_GROUP_CLASSES_SMALL = "c-form-group--sm", FORM_GROUP_CLASSES_LARGE = "c-form-group--lg", FORM_GROUP_CLASSES_INVALID = "c-form-group--invalid", FORM_GROUP_CLASSES_VALID = "c-form-group--valid", FORM_GROUP_CLASSES_DISABLED = "c-form-group--disabled", INPUT_CLASSES_BASE = "c-input", INPUT_CLASSES_SMALL = "c-input--sm", INPUT_CLASSES_LARGE = "c-input--lg", INPUT_CLASSES_INVALID = "is-invalid", INPUT_CLASSES_VALID = "is-valid", INPUT_CLASSES_DISABLED = "is-disabled", INPUT_CLASSES_FULL_WIDTH = "c-input--full-width", INPUT_CLASSES_PREFIX_ICON = "c-input--prefix-icon", INPUT_CLASSES_SUFFIX_ICON = "c-input--suffix-icon", INPUT_CLASSES_CLEARABLE = "c-input--clearable", INPUT_CLASSES_WITH_COUNTER = "c-input--with-counter", INPUT_CLASSES_PASSWORD_TOGGLE = "c-input--password-toggle", INPUT_ELEMENTS_WRAPPER = "c-input-wrapper", RADIO_CLASSES_BASE = "c-radio", RADIO_CLASSES_INVALID = "is-error", RADIO_CLASSES_VALID = "is-valid", RADIO_CLASSES_DISABLED = "is-disabled", SELECT_CLASSES_BASE = "c-select", SELECT_CLASSES_SELECTED = "c-select__selected", SELECT_CLASSES_SELECT_BODY = "c-select__body", SELECT_CLASSES_SELECT_PANEL = "c-select__panel", SELECT_CLASSES_SELECT_ITEMS = "c-select__items", SELECT_CLASSES_SELECT_ITEM = "c-select__item", SELECT_CLASSES_TOGGLE_ICON = "c-select__toggle-icon", SELECT_CLASSES_ICON_CARET = "icon-atomix-caret-down", SELECT_CLASSES_SMALL = "c-select--sm", SELECT_CLASSES_LARGE = "c-select--lg", SELECT_CLASSES_INVALID = "is-invalid", SELECT_CLASSES_VALID = "is-valid", SELECT_CLASSES_DISABLED = "is-disabled", SELECT_CLASSES_IS_OPEN = "is-open", TEXTAREA_CLASSES_BASE = "c-input c-input--textarea", TEXTAREA_CLASSES_SMALL = "c-input--sm", TEXTAREA_CLASSES_LARGE = "c-input--lg", TEXTAREA_CLASSES_INVALID = "is-invalid", TEXTAREA_CLASSES_VALID = "is-valid", TEXTAREA_CLASSES_DISABLED = "is-disabled", ATOMIX_GLASS = {
7
+ BASE_CLASS: "c-atomix-glass",
8
+ CONTAINER_CLASS: "c-atomix-glass__container",
9
+ INNER_CLASS: "c-atomix-glass__inner",
10
+ FILTER_CLASS: "c-atomix-glass__filter",
11
+ FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
12
+ FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
13
+ CONTENT_CLASS: "c-atomix-glass__content",
14
+ BORDER_1_CLASS: "c-atomix-glass__border-1",
15
+ BORDER_2_CLASS: "c-atomix-glass__border-2",
16
+ HOVER_1_CLASS: "c-atomix-glass__hover-1",
17
+ HOVER_2_CLASS: "c-atomix-glass__hover-2",
18
+ HOVER_3_CLASS: "c-atomix-glass__hover-3",
19
+ BASE_LAYER_CLASS: "c-atomix-glass__base",
20
+ OVERLAY_LAYER_CLASS: "c-atomix-glass__overlay",
21
+ OVERLAY_HIGHLIGHT_CLASS: "c-atomix-glass__overlay-highlight",
22
+ BACKGROUND_LAYER_CLASS: "c-atomix-glass__background-layer",
23
+ BACKGROUND_LAYER_DARK_CLASS: "c-atomix-glass__background-layer--dark",
24
+ BACKGROUND_LAYER_BLACK_CLASS: "c-atomix-glass__background-layer--black",
25
+ BACKGROUND_LAYER_OVER_LIGHT_CLASS: "c-atomix-glass__background-layer--over-light",
26
+ BACKGROUND_LAYER_HIDDEN_CLASS: "c-atomix-glass__background-layer--hidden",
27
+ VARIANT_PREFIX: "c-atomix-glass--",
28
+ MODE_PREFIX: "c-atomix-glass--",
29
+ CLASSES: {
30
+ BASE: "c-atomix-glass",
31
+ CONTAINER: "c-atomix-glass__container",
32
+ INNER: "c-atomix-glass__inner",
33
+ FILTER: "c-atomix-glass__filter",
34
+ CONTENT: "c-atomix-glass__content",
35
+ ACTIVE: "active",
36
+ OVER_LIGHT: "c-atomix-glass__container--over-light",
37
+ // Mode variants
38
+ STANDARD: "c-atomix-glass--standard",
39
+ POLAR: "c-atomix-glass--polar",
40
+ PROMINENT: "c-atomix-glass--prominent",
41
+ SHADER: "c-atomix-glass--shader"
42
+ },
43
+ DEFAULTS: {
44
+ DISPLACEMENT_SCALE: 20,
45
+ BLUR_AMOUNT: 1,
46
+ SATURATION: 140,
47
+ ABERRATION_INTENSITY: 2.5,
48
+ ELASTICITY: .05,
49
+ CORNER_RADIUS: 16,
50
+ // Default border-radius matching design system
51
+ PADDING: "0 0",
52
+ MODE: "standard",
53
+ OVER_LIGHT: !1,
54
+ ENABLE_OVER_LIGHT_LAYERS: !0
55
+ },
56
+ CONSTANTS: {
57
+ ACTIVATION_ZONE: 200,
58
+ MIN_BLUR: .1,
59
+ MOUSE_INFLUENCE_DIVISOR: 100,
60
+ EDGE_FADE_PIXELS: 2,
61
+ DEFAULT_CORNER_RADIUS: 16,
62
+ // Fallback value matching design system
63
+ MAX_SIZE: 4096,
64
+ // Maximum width/height for glass size
65
+ // Gradient calculation constants
66
+ GRADIENT: {
67
+ BASE_ANGLE: 135,
68
+ // Base angle for border gradients (degrees)
69
+ ANGLE_MULTIPLIER: 1.2,
70
+ // Multiplier for mouse influence on angle
71
+ BORDER_STOP_1: {
72
+ MIN: 10,
73
+ // Minimum percentage for border stop 1
74
+ BASE: 33,
75
+ // Base percentage for border stop 1
76
+ MULTIPLIER: .3
77
+ },
78
+ BORDER_STOP_2: {
79
+ MAX: 90,
80
+ // Maximum percentage for border stop 2
81
+ BASE: 66,
82
+ // Base percentage for border stop 2
83
+ MULTIPLIER: .4
84
+ },
85
+ BORDER_OPACITY: {
86
+ BASE_1: .12,
87
+ // Base opacity for border gradient 1
88
+ BASE_2: .4,
89
+ // Base opacity for border gradient 2
90
+ BASE_3: .32,
91
+ // Base opacity for border gradient 3
92
+ BASE_4: .6,
93
+ // Base opacity for border gradient 4
94
+ MULTIPLIER_LOW: .008,
95
+ // Low multiplier for mouse influence on opacity
96
+ MULTIPLIER_HIGH: .012
97
+ },
98
+ CENTER_POSITION: 50,
99
+ // Center position percentage (50%)
100
+ HOVER_POSITION: {
101
+ DIVISOR_1: 2,
102
+ // Divisor for hover 1 position calculation
103
+ DIVISOR_2: 1.5,
104
+ // Divisor for hover 2 position calculation
105
+ MULTIPLIER_3: 1
106
+ },
107
+ BASE_LAYER_MULTIPLIER: .5
108
+ },
109
+ // Gradient opacity values for hover effects
110
+ GRADIENT_OPACITY: {
111
+ HOVER_1: {
112
+ BLACK_START: .3,
113
+ // Start opacity for black hover 1
114
+ BLACK_MID: .1,
115
+ // Mid opacity for black hover 1
116
+ BLACK_STOP: 30,
117
+ // Stop percentage for black hover 1
118
+ BLACK_END: 60,
119
+ // End percentage for black hover 1
120
+ WHITE_START: .5,
121
+ // Start opacity for white hover 1
122
+ WHITE_STOP: 50
123
+ },
124
+ HOVER_2: {
125
+ BLACK_START: .4,
126
+ // Start opacity for black hover 2
127
+ BLACK_MID: .15,
128
+ // Mid opacity for black hover 2
129
+ BLACK_STOP: 40,
130
+ // Stop percentage for black hover 2
131
+ BLACK_END: 80,
132
+ // End percentage for black hover 2
133
+ WHITE_START: 1,
134
+ // Start opacity for white hover 2
135
+ WHITE_STOP: 80
136
+ },
137
+ HOVER_3: {
138
+ BLACK_START: .5,
139
+ // Start opacity for black hover 3
140
+ BLACK_MID: .2,
141
+ // Mid opacity for black hover 3
142
+ BLACK_STOP: 50,
143
+ // Stop percentage for black hover 3
144
+ BLACK_END: 100,
145
+ // End percentage for black hover 3
146
+ WHITE_START: 1,
147
+ // Start opacity for white hover 3
148
+ WHITE_STOP: 100
149
+ }
150
+ },
151
+ // Base and overlay gradient constants
152
+ BASE_GRADIENT: {
153
+ ANGLE: 135,
154
+ // Gradient angle in degrees
155
+ BLACK_START_BASE: .15,
156
+ // Base start opacity for black
157
+ BLACK_START_MULTIPLIER: .003,
158
+ // Multiplier for mouse X influence on start
159
+ BLACK_MID_BASE: .1,
160
+ // Base mid opacity for black
161
+ BLACK_MID_MULTIPLIER: .002,
162
+ // Multiplier for mouse Y influence on mid
163
+ BLACK_MID_STOP: 50,
164
+ // Mid stop percentage
165
+ BLACK_END_BASE: .18,
166
+ // Base end opacity for black
167
+ BLACK_END_MULTIPLIER: .004,
168
+ // Multiplier for mouse X influence on end
169
+ WHITE_OPACITY: .1
170
+ },
171
+ OVERLAY_GRADIENT: {
172
+ BLACK_START_BASE: .12,
173
+ // Base start opacity for black overlay
174
+ BLACK_START_MULTIPLIER: .003,
175
+ // Multiplier for mouse X influence on start
176
+ BLACK_MID: .06,
177
+ // Mid opacity for black overlay
178
+ BLACK_MID_STOP: 40,
179
+ // Mid stop percentage
180
+ BLACK_END_BASE: .15,
181
+ // Base end opacity for black overlay
182
+ BLACK_END_MULTIPLIER: .003,
183
+ // Multiplier for mouse Y influence on end
184
+ WHITE_OPACITY: .05
185
+ },
186
+ // Overlay highlight constants
187
+ OVERLAY_HIGHLIGHT: {
188
+ POSITION_X: 20,
189
+ // X position percentage
190
+ POSITION_Y: 20,
191
+ // Y position percentage
192
+ WHITE_OPACITY: .4,
193
+ // White opacity in gradient
194
+ STOP: 60,
195
+ // Stop percentage
196
+ OPACITY_MULTIPLIER: .7
197
+ },
198
+ // Displacement and aberration multipliers
199
+ MULTIPLIERS: {
200
+ SHADER_DISPLACEMENT: .8,
201
+ // Displacement scale multiplier for shader mode
202
+ OVER_LIGHT_DISPLACEMENT: .6,
203
+ // Displacement scale multiplier for over-light mode
204
+ SHADER_ABERRATION: .7
205
+ },
206
+ // Saturation constants
207
+ SATURATION: {
208
+ HIGH_CONTRAST: 200
209
+ }
210
+ }
211
+ }, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2) => {
212
+ if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
213
+ const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
214
+ return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
215
+ }, calculateElementCenter = rect => rect ? {
216
+ x: rect.left + rect.width / 2,
217
+ y: rect.top + rect.height / 2
218
+ } : {
219
+ x: 0,
220
+ y: 0
221
+ }, calculateMouseInfluence = mouseOffset => {
222
+ if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
223
+ // More responsive calculation for overlight effects
224
+ const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$1.MOUSE_INFLUENCE_DIVISOR;
225
+ return Math.min(1.5, influence);
226
+ // Cap influence for better control
227
+ }, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$1.MIN_BLUR : Math.max(CONSTANTS$1.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$1.MAX_SIZE && size.height <= CONSTANTS$1.MAX_SIZE, parseBorderRadiusValue = value => {
228
+ if ("number" == typeof value) return Math.max(0, value);
229
+ if ("string" != typeof value || !value.trim()) return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
230
+ const trimmedValue = value.trim();
231
+ // Handle px values
232
+ if (trimmedValue.endsWith("px")) {
233
+ const parsed = parseFloat(trimmedValue);
234
+ return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
235
+ }
236
+ // Handle rem values (assume 16px = 1rem)
237
+ if (trimmedValue.endsWith("rem")) {
238
+ const parsed = parseFloat(trimmedValue);
239
+ return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
240
+ }
241
+ // Handle em values (assume 16px = 1em for simplicity)
242
+ if (trimmedValue.endsWith("em")) {
243
+ const parsed = parseFloat(trimmedValue);
244
+ return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
245
+ }
246
+ // Handle percentage (convert to approximate px value, assuming 200px container)
247
+ if (trimmedValue.endsWith("%")) {
248
+ const parsed = parseFloat(trimmedValue);
249
+ return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
250
+ }
251
+ // Handle unitless numbers
252
+ const numValue = parseFloat(trimmedValue);
253
+ return isNaN(numValue) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
254
+ }, extractBorderRadiusFromElement = element => {
255
+ if (!element || !element.props) return null;
256
+ // Check inline styles first (highest priority)
257
+ if (element.props.style) {
258
+ const radiusFromStyle = (style => {
259
+ if (!style) return null;
260
+ // Check various border-radius properties
261
+ const borderRadius = style.borderRadius || style.borderTopLeftRadius || style.borderTopRightRadius || style.borderBottomLeftRadius || style.borderBottomRightRadius;
262
+ return void 0 !== borderRadius ? parseBorderRadiusValue(borderRadius) : null;
263
+ })(element.props.style);
264
+ if (null !== radiusFromStyle && radiusFromStyle > 0) return radiusFromStyle;
265
+ }
266
+ // If element has children, recursively check them
267
+ if (element.props.children) {
268
+ const childRadius = extractBorderRadiusFromChildren(element.props.children);
269
+ if (childRadius > 0 && childRadius !== CONSTANTS$1.DEFAULT_CORNER_RADIUS) return childRadius;
270
+ }
271
+ return null;
272
+ }, extractBorderRadiusFromChildren = children => {
273
+ if (!children) return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
274
+ try {
275
+ const childArray = React.Children.toArray(children);
276
+ for (let i = 0; i < childArray.length; i++) {
277
+ const child = childArray[i];
278
+ if ( React.isValidElement(child)) {
279
+ const radius = extractBorderRadiusFromElement(child);
280
+ if (null !== radius) return radius;
281
+ }
282
+ }
283
+ } catch (error) {
284
+ // Silently handle errors
285
+ }
286
+ return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
287
+ }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
288
+ switch (mode) {
289
+ case "standard":
290
+ return displacementMap;
291
+
292
+ case "polar":
293
+ return polarDisplacementMap;
294
+
295
+ case "prominent":
296
+ return prominentDisplacementMap;
297
+
298
+ case "shader":
299
+ return shaderMapUrl || displacementMap;
300
+
301
+ default:
302
+ return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
303
+ }
304
+ }, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
305
+ style: {
306
+ position: "absolute",
307
+ width: "100%",
308
+ height: "100%",
309
+ inset: 0
310
+ },
311
+ "aria-hidden": "true",
312
+ suppressHydrationWarning: !0,
313
+ children: jsxs("defs", {
314
+ children: [ jsxs("radialGradient", {
315
+ id: `${id}-edge-mask`,
316
+ cx: "50%",
317
+ cy: "50%",
318
+ r: "50%",
319
+ children: [ jsx("stop", {
320
+ offset: "0%",
321
+ stopColor: "black",
322
+ stopOpacity: "0"
323
+ }), jsx("stop", {
324
+ offset: `${Math.max(30, 80 - 2 * aberrationIntensity)}%`,
325
+ stopColor: "black",
326
+ stopOpacity: "0"
327
+ }), jsx("stop", {
328
+ offset: "100%",
329
+ stopColor: "white",
330
+ stopOpacity: "1"
331
+ }) ]
332
+ }), jsxs("filter", {
333
+ id: id,
334
+ x: "-35%",
335
+ y: "-35%",
336
+ width: "170%",
337
+ height: "170%",
338
+ colorInterpolationFilters: "sRGB",
339
+ children: [ jsx("feImage", {
340
+ id: "feimage",
341
+ x: "0",
342
+ y: "0",
343
+ width: "100%",
344
+ height: "100%",
345
+ result: "DISPLACEMENT_MAP",
346
+ href: getDisplacementMap(mode, "data:image/jpeg;base64,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cUAUAkEkziomgGgkoxZGgxZFQFQlYnQHRdPfj/10KCSCKESCNiVkViPSLpD0h6I0Q0I0A2IoBWBIJIBKBIJoJIJ2R2J0JWBUJ0JUB0XTv479dFZDYiglYigkhEgjZFQjRFQjRFQjQigFYigHYigmgEgmglYlYnQlQlYlQHQlQnQ9P/kf1yVkNiNCNkNiVENiNiViNEViNkVCVgKCViViViSCViSCVgdCViVCViVCdgVCVCdD1D+U/XBWQ2I0I2Q2JUQ2I0JWQ0I2JUQ2JUI2JUI2J0JWJWJWA2R0BWJ0I2JUJ2BUJUJ0P//EABkQAQEBAQEBAAAAAAAAAAAAAAECABEDEP/aAAgBAQABAgB1atWrVq1atWrVq1atWrVq1atWrVq1atWrVq+OrVq1atWrVq1atWrVq1atWrVq1atWrVq1atXxVppppppdWrVq1atWrVq1NNNNNNNNNNNPVWmmmmms6tWrVq1atWpppppppppppppp6q0000uc51atWrVq1ammmmmmmmmmmmmt1Vpppc5znVq1atWrVqaaaaaaaaaaaaaeqtNLnOc51atWrVq1ammmmmmmmmmmmmnqrS5znOc6tWrVq16222mmmmmmlVppp6tKuc5znOrVq1a9TbbbbTTTTTSq000qtLnOc5zq1atWrW0222200000qqqtKqrnOc5zq1atTbbbbbbbbTTTSqqqqqq5znOc6tTTTbbbbbbbbTTTSqqqqrlVznOctNNNtttttttttNNNNKqqqrqznKqrTTTTbbbbbbbbbTTTSqqqqrqznOc5aaaabbbbbbbbbaaaaVVVVVdWc5znVq1NNttttttttttNNKqqqqudWc5znVq16tbbbbbbbbbbTTSqqqq5XVnOc6tWrVrb1tttttttttNNKqqqqrWrK5VWmmm2230bbbbbbaaaXOc5zlVa1KuVVppptttt9G22222mmlzlVznK6tWVVWmmmm2222222222mlznOc5znLWppVVWmmm22222229bTWrOc5znOcq1qaaVpWmm222222229erVqznOc5znKtatStK0rTbTTbbbberXr1as5znOc5aVpppppWlabaabbbb1ta9WrVnOc5znU0rTTTTTTTTTbTTbbbTWvVq1as5znOdTTStNNNNNNNNNtNNtttN6tWvVq1ZznOrU00rTTTTTTTTTTTTTbTWvVq1atWrOc6tTTTStNNNNNNNNNNtNNtNa9WrVq1Z1Z1NNNNNK1q1NNNNNNNNNNNtNatWrVq1atWrU00000rWrVq1atWrVq1alaaa1atWrVq1NNNammmmla1atWrVq1aterVq16tWrVnVqa1NK1qaaaVX/xAAWEAADAAAAAAAAAAAAAAAAAAAhgJD/2gAIAQEAAz8AaExf/8QAGhEBAQEBAQEBAAAAAAAAAAAAAQISEQADEP/aAAgBAgEBAgDx48ePHjx48ePHjx48ePHjx48ePHjx48ePHj86IiIiIiInjx48ePHjx48IiIiIj0oooooooooRERER73ve60UUUUUUVrWiiiiiihERERER73ve97ooooorRWiiiiihKERERER73ve973RRRRWtFFFFFFCIiIiIiPe973ve60UUVrRRRRRRQiIlCIiI973ve973pRRWiiiiiiiiiiiiiiihEe973ve973RRWtFFFFFFFFFFFFFFFFFFa13ve973WitaKKKKKKKKKKKKKKKKKK1rWtd1rutFa1oooooooooooosssooorWta1rWta1rRRRRRRRRRRZZZZZZZZZWta1rWta1rRRRRRRRRZZZZZZZZZZZZe9a1rWta1rWitaKLLLLLLLLLLLLLLLLL3rWta1rWtFbLLLLLLLLLLLLLLLLLLLL3vWta1rWita1ssssssss+hZZZZZZZZe961rWta0Vre97LLLLLLLLLLLPoWWWWWXrWta1oorWta3ssss+hZZZZ9Cyyyyyyyyiita1orWta1ve9llllllllllllllllFFa0VorWta1ve9llllllllllllllllllFFFaK1rWta1rWiyyyyyyyyyyyyiiiiiiitFFa1rWta1oosoosssssoooosoooorRRRWta1rWta0UUUUUWUUUUUUUUUUUVoooorWta1rWtaKKKKKKmiiiiiiiiiiiiiiitd73ve61oSiiipoqaKKKKKKKKKK0UUUVrve973vREREZoSihEooooorRRRRWtd73ve9EREREREoSiiiiitFllllla73ve9ERERERESiiiiiitH0PoWWWWVrXe96IiIiMoiJRRRRRRWjwlFFllllFFd6IiIiIlCUUUUUUUUUePHjx48ePCIiIiIiIiUUUUUUUUUUUePHjx48ePHjx48ePHjx48IiUUUUUUJRRRX//xAAWEQADAAAAAAAAAAAAAAAAAAABYJD/2gAIAQIBAz8AtEV7/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAECEP/aAAgBAwEBAgCtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcrTTTTTTTTTTTTTTTTTTTTTTTTTTTTTXKrTTTTTTTU000000000000000000001FVpppppqampqaaaaaaaaaaaaaaaaaaaa5Vaaaaampqampqammmmmmmmmmmlaaaaaaiq0001NTU1NTU1NTTTTTTTTTTSqqtNNNcqtNNSyzU1LNTU1NTTTTTTTTTSqqq001ytNLLLLNTU1NTU1NTbbbTTTTTSqqq001ytNLLLLLNTU1NTU3NttttNNNNNKqq001KrSyyyyyzU1NTU3Nzc02220000qqqqrSqqyyyyyzU1NTU3Nzc3NttttNNNKqqqqqqssssss1NTU3Nzc3NzbbbbTTTSqqqqqqrLLLLLNTU1Nzc3Nzc22220000qqqqqqqqssss1NTU3Nzc3NzbbbbbTTSqqqqqqqqqqzU1NTc3Nzc3Nzbc22000qqqqqqqqqqqtTU3Nzc3Nzc3NtzbTTSqqqqrKqqqqqtNNzc23Nzc3Nzc3NTU1KqqqrKqqqqqtNNNNttzc3Nzc3NzU1NLLLLLKqqqqqqqq0022223Nzc3NzU1NSyyyyyyqqqqqqqrTTbbbbc3Nzc3NTU1LLLLLLKsqqqqqqrTTTTbbbc3Nzc1NTUsssssssqqqqqqrTTTTTbbbTc3NTU1NTUsssssqqqqqqqq0000222023NTU1NTUsssssqqqqqqqq000000003NTU1NTU1LLLLLNKrTSqqqqtNNNNNNtNNTU1NSzUssss00qq0qqqqrTTTTTTTTTU1NTUs1LLLNNNKrTTTSqqq00000000001NTU1LNTU0000qtNNNKqqqtNNNNNNNNTU1NTUs1NNNNNKss1NNNK00qtK0000001NNTU0s000000qq000001NKrStNNNNK1NNNNStNNNNNKqtNNNNNNNK0000000rU0000rTTTTTSq00000rTTTTTTTTTTTTTTTTStNNNNKr/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k=", "data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/2wCEAAYEBAQFBAYFBQYJBgUGCQsIBgYICwwKCgsKCgwQDAwMDAwMEAwODxAPDgwTExQUExMcGxsbHB8fHx8fHx8fHx8BBwcHDQwNGBAQGBoVERUaHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fH//CABEIAQABAAMBEQACEQEDEQH/xAAxAAADAQEBAAAAAAAAAAAAAAABAgMABAcBAAMBAQEBAAAAAAAAAAAAAAIDBAEABQb/2gAMAwEAAhADEAAAAPG/tfu93bu3bs7d27t3bu2du7d27h3bs3du7d27t3bc3du7d27tvbu3du7d27T3E+2du05u7tm7O2cM7d2zt3Du2YOzbw7N3bcHZt7dm3tvbeO9u7dx3d3Ht3cS05pzd24dOds0Z2HdnDsGdswdg7hw7cHYNzbg3NvbcO9izbx3TvbtPae09pLTmnCObh3ZuHcO4eGcM4ZgzB2DhHYOEbg0QWbcxZtzFmLjvEuO6e07p4jmsWnCOERIiWHcO4NA8M4DwzBmLgjsXRHCNEEI0QQ4sxZjwlxLjvEtPa2keJuJt04bCREsJECw6A3BoHFHhmKIrmLwjQXRGgpCCHEIMcWE8x4S1i4lraR7W02wnIiJsJkTIFg3AWXoHgGqGAcXBTBXhXgXQUgBADAGIMceE8J4T4lrFraTaT6TYbabiZFjAeAissBBegNAcq8UcXBXATBXVpoKQAlqYBg4wzMx4WYx8T1i1yJtN+NsN9NxYwmVmQZlllllaA1V8oYoYoimAnAmrXVoS1MAawwAwcwSzCzCfMzXLWIn035j8b6xwYwMIMKjKzyiCyCuVfKGKAoIpgJgJq0JSEtTWprDQzAzRzBZvFnMfOZORuRvzHw6a1wYwMZbSphUeUQUQXqqxF4gCgCmAnLnykJaGpTUrFhqw0M0S0S3GZrM52E5HTTfm0xlNY4OYGMtrJZlMKSCiVOqrkWKAKACCE+XPVTJSGlGKDFq1YcvNEuFm4zeZmuwqEb6ymspja61wcymutpS0pPJMJIJ1FcqsRYTAJ4ueKkSpkpDSjFK1StVnBnAXCXYzeduuwqEyhMrrKY6nNoDnU5lNZLSlmQYQap1U4ihRYzBcxXLlS1MyVNiUYlWqVyg9ecBeDO5nc7dowqGyhMrzaY6vOoDnU50uZLihmQwIJUaqcRIzUEwXIVy5UtTI0zYhGKRyVckPXnrLxZ+O7naVGlQ2VJtebXH151AdRT2S9kNM7chgnJUaqMRIooJLXIVR5UiREkzaibEq9CuUKFZ6zQLPxn9RpUadWHXW111cfbn0W+inuh7IcZ26dgnJZ9WfESM0hIFRFUuTHUxNEmIm5COQtCQ9WoWaRZ+O/qOKjTqxlibXnWx9efVdFE0Oh7ocZnadgmNZ9WYUSMkrktcRTHkw1EWIkxE3To9CUJFCdSs0C9AvRtHbVrKsZUnW11sotj6roommiHtM8zu0zBMYl1ZxnOM1LipUBTHkwJETni2eTkI+daULSnUrakGox6Oq8qtZVjLG6+vsNFuoqqmqKHRQ8zzM7TNWUhLqzYk4ySuC1RFMMRAp4Mni2eT50fOlKBSnVKNIPTj09V5VayzWWJ99fbKb5RVVNUU0noaahpnCVokMS8suTnGSVxUnnFMMRAp+dk0XTyfNOidKZxUnVKNQPSNKdq8qvZZjbm6/UXym2U2VTVFVJ6XleZX6RolMScsuTmCKFwUqAo5+RzlNBk0HTRfMlMyUoWpGrU1QNUNKetQdXsu1tyffaLjVfKbKqsiqk1LS0NI7SOEhiPllyUwRQuCk84I5+RzlNzslg6aNEs6ZkqnFaNWo1rerKVdag6vO7XdB0X6joyq+U2TXZFVJanloMjzG4RmI+STJzBGdfOpPOE/N0/MU3O2WDpo0yzplSqda0axLVrasa1bWkrvZdrrnR0bT0ZV0DVdNdZ66zVPJSY36NwjPRckeSmCM6udKeYEc3Tcxzc7JOd8saZZVSpVMLEaxJsW9Y0r21JXey7X9DKOnaega+garpstPXSWp5KWjo0ThEeh5I8lKEJ1c6k8oT82Tcxy8zZOd8sKZJ1SpXMts+sSbVvWNa+tUV3t6HP6Do6dq6Br6Mr6EWWmsrLU8lTRUaJwhPQ8keRkXCdfMlHME/Lk3KcvM2TnojhTJKuVLJVsn1qWtU9mVs61RXob0Nf0sp6eq6Mr6Rs6EWWmsrLXSOow06J2gPQ8kWRkXzzK5kp5Qn5cl5Tk5XSc9EcKo5VyzslFswtS1yntGtfXqO9Lel1HSdPTtXSNnSNnQi281lZK3iraKjQv0B7z+SLIyL5plcyE8i5uTpeU5OV0fPTHCqONciWyLbPrkG5VLgrZt6jvS3pdR1HT07X05Z1Bb0ItvNbWOukVbQ06F+8895/JDkI180yuZCONc3JkvIyTmdFzUx89cUrJJ2yLdNrp2vW9wVs69bOmlvS6jpZV1bX1Db0qt6VW3mttHa8NbQ06B7ecY8/pwDGMOaVXIhHGqbk6TkZHyvi5qYueuKNsc7ZFvm1yGvTS8a29es+ml3S+jqOvq2vpXb1Ku6lXXnttHbSGtoKt57z5x7z+nAMIg5pU8k6OJM3IcnI2LkbFzUxc9cMbY53SLfLr0N6CXuGt2dFh9NL+p9PUyrqG3pXb/8QAGxAAAwEBAQEBAAAAAAAAAAAAAAECEQMwECD/2gAIAQEAAQIAMzMzMzM/W7u7u745mZmZnhu7u7u+GZmZmZ4bu7u7vhmZmZmeG7u7u7+l8zMzMzBjGMY/m7u7u6IQhCEISzMzMxjGMYxje7u7u6hCEIQhJLMzMxjGMYxjGN7u7upoQhCEIQlmZmY0xjGMYxje7vzU0IQhCEISzMzMaYxjGMYxtvd3dQhCEIQhCEszMaaYxjGMYxtvd1NNCEIQhCEISzMxppjGMYxjG293U000IQhCJEISzMxppjTVKiihjG93U000IkkkkkQklmZjTTVFFFFFDG2291NNNOSSSSSRCSSWY0001SoooooY223upppoRJJJJJIkklmNNNNUqVFFFFDbbe6mmnJJJJJJJIkklmNNNNUUUUWUMbbb3U005JJJJJJJJSSWY001SpUqLKKKKbbe6mmnJJJJJJJJKSSzGmmqVFFllllFNtvdTTlySSQQSSSSkksxrGqVK1ZZZZRTbb3U05ckkEEEEkkpJLMaxqlSsssssoptt7qacuSSCCCCSSUklmNY1Sssssssoptt7qacuSSCCCCCSUklmNY1StWdCyyyim23uppy5JIIIIIIJUpLMxpqlZZZZ0LLKbbe6mnLkggggggglSkszGqVK1Z0LOh0LKdNvdTly4IIIIIIIJSSWZjVK1a6HQ6HQ6Flum3upy5cuCDmcyCCCUklmY1StWdDodDodCy3Tb3U5cuHBBzOZBBBKlJZmNUrVrodDodCyy3Tb3U5cuCDmczmQQQSpSWYk1StdDodDodDoWWU291OXDgg5nM5nM5kEqUlmY1StdDodTodDoWW6be6nLhwczmczmczmQSpSWZjVK10Op1Oh0OhZbpt7qckOHzOZzOZzOZBClJZiTVKzodTqdDqdDoW6be6nLhwczmczmczmcyFKSzBq10XRdTqdTqdDo7dNvdRJD5vmczkczmf/8QAFhAAAwAAAAAAAAAAAAAAAAAAMXCQ/9oACAEBAAM/AK3FJf/EABsRAAMBAQEBAQAAAAAAAAAAAAABAhEDIBAw/9oACAECAQECAMzM9bu7u7u+szMzMzPw3d3d3fwzMzMzPD8bu7u7vlfczMzMzw/G7u7u75X3MzMzMGMYxj+bu7u7ohCEIXzMzMzMYxjGMYzd3d3U0IQhCEISzMzMaaYxjGMY3u7u6mmhCEIQhLMzMxppjGMYxjbe7u6mhCEIQhCSWZmY0xjGMYxjG93d1NCEIQhCEkszMxpjGMYxjGN7u7qaEIQhCEJJZmY00xjGUMYxjbe7qaaESIRIhCSWZmNNMZRRRRQxjbe7qaaESSSSSIQklmY00xlFFFFDG2293U000SSSSSSISSzMaaaooooooZTbb3U0005JJJJJJEkkszGmqVFFFFFFDbbe6mmmiSSSSSSRJJLMxpqiiiiiiim223upppySSSSSSSISSzGmmqKKKKKKKKbbe6mmnJJJJJJJJKSSzGmmqKKLLKKKdNtvdTTTkkkgkkkklJJZjTVKiiiyyiinTbb3U05cuSSCSCSSUkkljTVKiiiyyyyinTb3U05cuSCCCCSSUklmNNUqVFllllllOm3uppy5JIIIIIJJUpLMaapUqLLLLLLKbbe6mnLkkgggggklSksxpqlSsssssssp0291OXLkggggggklSksxpqlRZZZZ0LLdOm3upy5cEEEEEEEEqUkljTVKiyyzodDoW6dNvdTly4IIIOZBBBKlJJY01Ssss6HQ6HQt26bbepy5cOCCDmcyCCVKSSxqlStWWdDodDoW7dNtvU5cuCCDmczmQQSpSSWNUqVqzodDodDoW7dNtvU5cOHBzOZzOZzIIUqUljVKlas6HQ6HQ6Fu3Tpt6nLhwQczmczmcyCFKSSxplK1Z0Oh0Op0Ojt06bey5cOHBzOZzOZzIUKUkljGUWdDodDodTodHbp0200S4cPmczmczmczmQpSSTGMZZ0Oh0Op1Op0du3TbRJJD5vmczmcjmczmoUpJJjP/8QAFBEBAAAAAAAAAAAAAAAAAAAAoP/aAAgBAgEDPwAAH//EABsRAAMBAQEBAQAAAAAAAAAAAAABAhEDEDAg/9oACAEDAQECAPzmZmZnx3d3d3fjmZmZ8d3d3d+OZmZmfHd3d3fjmZmZmfDd3d3d9Qhe5mZmZ4xjGP3d3d3dEIQhCEZmZmZjGMYxjGbu7u6IQhCEIXmZhmMYxjGMYzd3d3UIQhCEIQlmZhjGMYxjGMfu7uoQhCEIQhLMzMGmMYxjGMZu7uppoQhCEIQklmZjTGMYxjGMbb3d1NCEIQhCEISzMxpjGMYxjGMb3d1NCEIkQhCEkszGmMYyihjGMbb3d1NCESSIkQhJLMxppjGUUUMYxtvd1NNNCJJESIQklmY0xjKKKKKGMbb3dTTTRJJJJJIhJLMxpjGUUUUUUMbb3dTTQiSSSSSRCSWZjTTGUUUUUUMbb3dTTRJJJJJJJIklmY0xjKKKKKKKG293U005JJJJJJJEkksaaaaoooooooobbb3U05JJJJJJJJEkksaaZRRRRRRRRQ223uppySSSSSSSSIQkNNMoooooooooptt7qackkkkkEEkiEksGmqKKLLKLKKKbbe6mnJJJBBBBJJKSSxpplFFFllllFFNtvdTTkkkggggkklJZjTTVFFFlllllFDbe6mnLkggggggkkSzGmUUUUWWWWWUUU291NOSSCCCCCCSRLMaaZRRRZZZZZRRTb3U5ckkEEEEEEkpLMaaaoossssssop0291OXJBBBBBBBBKSzGmMossssssssp0291OXJBBBzOZBBBKlZjTVFFllllllllOm3upy5cEEHM5kEEEqVmNNUUWWWWdCyyynTb1NOXLggg5nMggglSvGmUqLLOhZ0LLLKdNm6nLgggg5nMggglSsxpqlRZZ0Oh0OhZZTpt7qcuHBzOZzOZzOZBKleNNUUWWdDodDodCynQxmy5cEHM5n/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k=", "data:image/png;base64,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", shaderMapUrl),
347
+ preserveAspectRatio: "xMidYMid slice"
348
+ }), jsx("feColorMatrix", {
349
+ in: "DISPLACEMENT_MAP",
350
+ type: "matrix",
351
+ values: "0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0 0 0 1 0",
352
+ result: "EDGE_INTENSITY"
353
+ }), jsx("feComponentTransfer", {
354
+ in: "EDGE_INTENSITY",
355
+ result: "EDGE_MASK",
356
+ children: jsx("feFuncA", {
357
+ type: "discrete",
358
+ tableValues: `0 ${.05 * aberrationIntensity} 1`
359
+ })
360
+ }), jsx("feOffset", {
361
+ in: "SourceGraphic",
362
+ dx: "0",
363
+ dy: "0",
364
+ result: "CENTER_ORIGINAL"
365
+ }), jsx("feDisplacementMap", {
366
+ in: "SourceGraphic",
367
+ in2: "DISPLACEMENT_MAP",
368
+ scale: displacementScale * ("shader" === mode ? 1 : -1),
369
+ xChannelSelector: "R",
370
+ yChannelSelector: "B",
371
+ result: "RED_DISPLACED"
372
+ }), jsx("feColorMatrix", {
373
+ in: "RED_DISPLACED",
374
+ type: "matrix",
375
+ values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
376
+ result: "RED_CHANNEL"
377
+ }), jsx("feDisplacementMap", {
378
+ in: "SourceGraphic",
379
+ in2: "DISPLACEMENT_MAP",
380
+ scale: displacementScale * (("shader" === mode ? 1 : -1) - .02 * aberrationIntensity),
381
+ xChannelSelector: "R",
382
+ yChannelSelector: "B",
383
+ result: "GREEN_DISPLACED"
384
+ }), jsx("feColorMatrix", {
385
+ in: "GREEN_DISPLACED",
386
+ type: "matrix",
387
+ values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
388
+ result: "GREEN_CHANNEL"
389
+ }), jsx("feDisplacementMap", {
390
+ in: "SourceGraphic",
391
+ in2: "DISPLACEMENT_MAP",
392
+ scale: displacementScale * (("shader" === mode ? 1 : -1) - .03 * aberrationIntensity),
393
+ xChannelSelector: "R",
394
+ yChannelSelector: "B",
395
+ result: "BLUE_DISPLACED"
396
+ }), jsx("feColorMatrix", {
397
+ in: "BLUE_DISPLACED",
398
+ type: "matrix",
399
+ values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0",
400
+ result: "BLUE_CHANNEL"
401
+ }), jsx("feBlend", {
402
+ in: "GREEN_CHANNEL",
403
+ in2: "BLUE_CHANNEL",
404
+ mode: "screen",
405
+ result: "GB_COMBINED"
406
+ }), jsx("feBlend", {
407
+ in: "RED_CHANNEL",
408
+ in2: "GB_COMBINED",
409
+ mode: "screen",
410
+ result: "RGB_COMBINED"
411
+ }), jsx("feGaussianBlur", {
412
+ in: "RGB_COMBINED",
413
+ result: "ABERRATED_BLURRED",
414
+ stdDeviation: blurAmount * aberrationIntensity * .05
415
+ }), jsx("feComposite", {
416
+ in: "ABERRATED_BLURRED",
417
+ in2: "EDGE_MASK",
418
+ operator: "in",
419
+ result: "EDGE_ABERRATION"
420
+ }), jsx("feComponentTransfer", {
421
+ in: "EDGE_MASK",
422
+ result: "INVERTED_MASK",
423
+ children: jsx("feFuncA", {
424
+ type: "table",
425
+ tableValues: "1 0"
426
+ })
427
+ }), jsx("feComposite", {
428
+ in: "CENTER_ORIGINAL",
429
+ in2: "INVERTED_MASK",
430
+ operator: "in",
431
+ result: "CENTER_CLEAN"
432
+ }), jsx("feComposite", {
433
+ in: "EDGE_ABERRATION",
434
+ in2: "CENTER_CLEAN",
435
+ operator: "over"
436
+ }) ]
437
+ }) ]
438
+ })
439
+ });
440
+
441
+ /**
442
+ * Checkbox state and functionality
443
+ * @param initialProps - Initial checkbox properties
444
+ * @returns Checkbox state and methods
445
+ */ GlassFilterComponent.displayName = "GlassFilter";
446
+
447
+ // Memoize component to prevent unnecessary re-renders
448
+ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
449
+ x: 0,
450
+ y: 0
451
+ }, globalMousePosition: globalMousePosition = {
452
+ x: 0,
453
+ y: 0
454
+ }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, active: active = !1, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, cornerRadius: cornerRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
455
+ width: 0,
456
+ height: 0
457
+ }, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
458
+ // Use React's useId() for SSR compatibility
459
+ // Note: In Next.js, IDs may differ between server and client
460
+ // We'll suppress hydration warnings on elements that use this ID
461
+ const filterId = useId(), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
462
+ // Lazy load shader utilities only when shader mode is needed
463
+ useEffect((() => {
464
+ "shader" === mode ?
465
+ // Dynamic import shader utilities
466
+ Promise.resolve().then((() => shaderUtils)).then((shaderUtils => {
467
+ shaderUtilsRef.current = {
468
+ ShaderDisplacementGenerator: shaderUtils.ShaderDisplacementGenerator,
469
+ fragmentShaders: shaderUtils.fragmentShaders
470
+ };
471
+ })).catch((error => {
472
+ console.warn("AtomixGlassContainer: Error loading shader utilities", error);
473
+ })) :
474
+ // Clear shader utils when not in shader mode to free memory
475
+ shaderUtilsRef.current = null;
476
+ }), [ mode ]),
477
+ // Generate shader map with debouncing and caching
478
+ useEffect((() => {
479
+ // Enhanced validation for shader mode
480
+ if ("shader" === mode && glassSize && validateGlassSize(glassSize) && shaderUtilsRef.current) {
481
+ // Create cache key from size and variant
482
+ const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
483
+ const entry = sharedShaderCache.get(key);
484
+ return entry ? (
485
+ // Update access timestamp for LRU
486
+ entry.timestamp = Date.now(), entry.url) : null;
487
+ })(cacheKey);
488
+ // Check shared cache first
489
+ if (cachedUrl) return void setShaderMapUrl(cachedUrl);
490
+ // Clear any pending debounce
491
+ shaderDebounceTimeoutRef.current && clearTimeout(shaderDebounceTimeoutRef.current);
492
+ // Debounce shader generation to avoid blocking on rapid size changes
493
+ const generateShader = () => {
494
+ if (shaderUtilsRef.current) try {
495
+ const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
496
+ shaderGeneratorRef.current?.destroy();
497
+ const selectedShader = fragmentShaders[shaderVariant] || fragmentShaders.liquidGlass;
498
+ shaderGeneratorRef.current = new ShaderDisplacementGenerator({
499
+ width: glassSize.width,
500
+ height: glassSize.height,
501
+ fragment: selectedShader
502
+ });
503
+ // Use requestIdleCallback if available for non-blocking generation
504
+ const generate = () => {
505
+ const url = shaderGeneratorRef.current?.updateShader() || "";
506
+ ((key, url) => {
507
+ // Evict oldest entries if at capacity
508
+ if (sharedShaderCache.size >= 15) {
509
+ const entries = Array.from(sharedShaderCache.entries());
510
+ // Sort by timestamp (oldest first)
511
+ entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
512
+ // Remove oldest entry
513
+ const oldestEntry = entries[0];
514
+ oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
515
+ }
516
+ sharedShaderCache.set(key, {
517
+ url: url,
518
+ timestamp: Date.now()
519
+ }),
520
+ // Development mode: log cache size
521
+ "production" !== process.env.NODE_ENV && sharedShaderCache.size;
522
+ })(cacheKey, url), setShaderMapUrl(url);
523
+ };
524
+ "undefined" != typeof requestIdleCallback ? requestIdleCallback(generate, {
525
+ timeout: 1e3
526
+ }) :
527
+ // Fallback to setTimeout for browsers without requestIdleCallback
528
+ setTimeout(generate, 0);
529
+ } catch (error) {
530
+ console.warn("AtomixGlassContainer: Error generating shader map", error), setShaderMapUrl("");
531
+ } else
532
+ // Shader utils not loaded yet, retry after a short delay
533
+ shaderDebounceTimeoutRef.current = setTimeout(generateShader, 100);
534
+ };
535
+ // Debounce with 300ms delay
536
+ shaderDebounceTimeoutRef.current = setTimeout(generateShader, 300);
537
+ } else
538
+ // Not in shader mode, clear URL
539
+ setShaderMapUrl("");
540
+ // Cleanup function with error handling
541
+ return () => {
542
+ shaderDebounceTimeoutRef.current && (clearTimeout(shaderDebounceTimeoutRef.current),
543
+ shaderDebounceTimeoutRef.current = null);
544
+ try {
545
+ shaderGeneratorRef.current?.destroy();
546
+ } catch (error) {
547
+ console.warn("AtomixGlassContainer: Error during shader cleanup", error);
548
+ } finally {
549
+ shaderGeneratorRef.current = null;
550
+ }
551
+ };
552
+ }), [ mode, glassSize, shaderVariant ]);
553
+ // Removed forced reflow to avoid layout thrash and potential feedback sizing loops
554
+ const [rectCache, setRectCache] = useState(null);
555
+ useEffect((() => {
556
+ if (!ref || "function" == typeof ref) return;
557
+ const element = ref.current;
558
+ if (element) try {
559
+ setRectCache(element.getBoundingClientRect());
560
+ } catch (error) {
561
+ console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
562
+ }
563
+ }), [ ref, glassSize ]);
564
+ // Pre-calculate static multipliers outside useMemo
565
+ const liquidBlur = useMemo((() => {
566
+ const defaultBlur = {
567
+ baseBlur: blurAmount,
568
+ edgeBlur: 1.25 * blurAmount,
569
+ centerBlur: 1.1 * blurAmount,
570
+ flowBlur: 1.2 * blurAmount
571
+ };
572
+ // Enhanced validation for liquid blur
573
+ if (!enableLiquidBlur || !rectCache || !globalMousePosition || "number" != typeof globalMousePosition.x || "number" != typeof globalMousePosition.y || isNaN(globalMousePosition.x) || isNaN(globalMousePosition.y)) return defaultBlur;
574
+ try {
575
+ // Cache center and distance calculations
576
+ const center = calculateElementCenter(rectCache), distance = calculateDistance(globalMousePosition, center), maxDistance = Math.sqrt(rectCache.width * rectCache.width + rectCache.height * rectCache.height) / 2, normalizedDistance = Math.min(distance / maxDistance, 1), mouseInfluence = calculateMouseInfluence(mouseOffset), baseBlur = blurAmount + mouseInfluence * blurAmount * .4, edgeBlur = baseBlur * (.8 + .6 * (1.5 * normalizedDistance + .3 * mouseInfluence)), centerBlur = baseBlur * (.3 + .4 * (.3 * (1 - normalizedDistance) + .2 * mouseInfluence)), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, flowDirection = Math.atan2(deltaY, deltaX), flowBlur = baseBlur * (.4 + .6 * (.5 * Math.sin(flowDirection + mouseInfluence * Math.PI) + .5)), stateMultiplier = (isHovered ? 1.2 : 1) * (isActive ? 1.4 : 1);
577
+ return {
578
+ baseBlur: clampBlur(baseBlur * stateMultiplier),
579
+ edgeBlur: clampBlur(edgeBlur * stateMultiplier),
580
+ centerBlur: clampBlur(centerBlur * stateMultiplier),
581
+ flowBlur: clampBlur(flowBlur * stateMultiplier)
582
+ };
583
+ } catch (error) {
584
+ return console.warn("AtomixGlassContainer: Error calculating liquid blur", error),
585
+ defaultBlur;
586
+ }
587
+ }), [ enableLiquidBlur, blurAmount, globalMousePosition, mouseOffset, isHovered, isActive, rectCache, style, glassSize ]), backdropStyle = useMemo((() => {
588
+ try {
589
+ const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), validatedBaseBlur = "number" != typeof liquidBlur.baseBlur || isNaN(liquidBlur.baseBlur) ? 0 : liquidBlur.baseBlur, validatedEdgeBlur = "number" != typeof liquidBlur.edgeBlur || isNaN(liquidBlur.edgeBlur) ? 0 : liquidBlur.edgeBlur, validatedCenterBlur = "number" != typeof liquidBlur.centerBlur || isNaN(liquidBlur.centerBlur) ? 0 : liquidBlur.centerBlur, validatedFlowBlur = "number" != typeof liquidBlur.flowBlur || isNaN(liquidBlur.flowBlur) ? 0 : liquidBlur.flowBlur, area = rectCache ? rectCache.width * rectCache.height : 0;
590
+ // Validate blur values before using them
591
+ return !enableLiquidBlur || effectiveReducedMotion || effectiveDisableEffects || area > 18e4 ? {
592
+ backdropFilter: `blur(${clampBlur(Math.max(validatedBaseBlur, .8 * validatedEdgeBlur, 1.1 * validatedCenterBlur, .9 * validatedFlowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(1.05) brightness(1.05)`
593
+ } : {
594
+ backdropFilter: `${[ `blur(${validatedBaseBlur}px)`, `blur(${validatedEdgeBlur}px)`, `blur(${validatedCenterBlur}px)`, `blur(${validatedFlowBlur}px)` ].join(" ")} saturate(${Math.min(dynamicSaturation, 200)}%) contrast(1.05) brightness(1.05)`
595
+ };
596
+ // Single-pass fallback: stronger radius to match perceived blur of multi-pass
597
+ } catch (error) {
598
+ return console.warn("AtomixGlassContainer: Error calculating backdrop style", error),
599
+ {
600
+ backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
601
+ };
602
+ }
603
+ }), [ filterId, liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveDisableEffects, enableLiquidBlur ]), containerVars = useMemo((() => {
604
+ try {
605
+ // Safe extraction of mouse offset values
606
+ const mx = mouseOffset && "number" == typeof mouseOffset.x && !isNaN(mouseOffset.x) ? mouseOffset.x : 0, my = mouseOffset && "number" == typeof mouseOffset.y && !isNaN(mouseOffset.y) ? mouseOffset.y : 0;
607
+ return {
608
+ "--atomix-glass-container-width": `${glassSize?.width}`,
609
+ "--atomix-glass-container-height": `${glassSize?.height}`,
610
+ "--atomix-glass-container-padding": padding || "0 0",
611
+ "--atomix-glass-container-radius": `${"number" != typeof cornerRadius || isNaN(cornerRadius) ? 0 : cornerRadius}px`,
612
+ "--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
613
+ "--atomix-glass-container-shadow": overLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${.4 + .002 * mx})`, `inset 0 -1px 0 rgba(0, 0, 0, ${.2 + .001 * Math.abs(my)})`, `inset 0 0 20px rgba(0, 0, 0, ${.08 + .001 * Math.abs(mx + my)})`, `0 2px 12px rgba(0, 0, 0, ${.12 + .002 * Math.abs(my)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset",
614
+ "--atomix-glass-container-shadow-opacity": effectiveDisableEffects ? 0 : 1,
615
+ // Background and shadow values use design token-aligned RGB values
616
+ "--atomix-glass-container-bg": overLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none",
617
+ "--atomix-glass-container-text-shadow": overLight ? "0px 2px 12px rgba(0, 0, 0, 0)" : "0px 2px 12px rgba(0, 0, 0, 0.4)",
618
+ "--atomix-glass-container-box-shadow": overLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)"
619
+ };
620
+ } catch (error) {
621
+ return console.warn("AtomixGlassContainer: Error generating container variables", error),
622
+ {
623
+ "--atomix-glass-container-padding": "0 0",
624
+ "--atomix-glass-container-radius": "0px",
625
+ "--atomix-glass-container-backdrop": "none",
626
+ "--atomix-glass-container-shadow": "none",
627
+ "--atomix-glass-container-shadow-opacity": 1,
628
+ "--atomix-glass-container-bg": "none",
629
+ "--atomix-glass-container-text-shadow": "none"
630
+ };
631
+ }
632
+ }), [ glassSize, padding, cornerRadius, backdropStyle, mouseOffset, overLight, effectiveDisableEffects ]);
633
+ return jsx("div", {
634
+ ref: ref,
635
+ className: `${ATOMIX_GLASS.CONTAINER_CLASS} ${className} ${active ? ATOMIX_GLASS.CLASSES.ACTIVE : ""} ${overLight ? ATOMIX_GLASS.CLASSES.OVER_LIGHT : ""}`,
636
+ style: {
637
+ ...style,
638
+ ...containerVars
639
+ },
640
+ onClick: onClick,
641
+ children: jsxs("div", {
642
+ className: ATOMIX_GLASS.INNER_CLASS,
643
+ style: {
644
+ padding: "var(--atomix-glass-container-padding)",
645
+ boxShadow: "var(--atomix-glass-container-box-shadow)"
646
+ },
647
+ onMouseEnter: onMouseEnter,
648
+ onMouseLeave: onMouseLeave,
649
+ onMouseDown: onMouseDown,
650
+ onMouseUp: onMouseUp,
651
+ children: [ jsxs("div", {
652
+ className: ATOMIX_GLASS.FILTER_CLASS,
653
+ children: [ jsx(GlassFilter, {
654
+ blurAmount: blurAmount,
655
+ mode: mode,
656
+ id: filterId,
657
+ displacementScale: "number" != typeof displacementScale || isNaN(displacementScale) ? 0 : displacementScale,
658
+ aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
659
+ shaderMapUrl: shaderMapUrl
660
+ }), jsx("div", {
661
+ className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
662
+ suppressHydrationWarning: !0,
663
+ style: {
664
+ filter: `url(#${filterId})`,
665
+ backdropFilter: "var(--atomix-glass-container-backdrop)",
666
+ borderRadius: "var(--atomix-glass-container-radius)"
667
+ }
668
+ }), jsx("div", {
669
+ className: ATOMIX_GLASS.FILTER_SHADOW_CLASS,
670
+ style: {
671
+ boxShadow: "var(--atomix-glass-container-shadow)",
672
+ opacity: "var(--atomix-glass-container-shadow-opacity)",
673
+ background: "var(--atomix-glass-container-bg)",
674
+ borderRadius: "var(--atomix-glass-container-radius)"
675
+ }
676
+ }) ]
677
+ }), jsx("div", {
678
+ ref: contentRef,
679
+ className: ATOMIX_GLASS.CONTENT_CLASS,
680
+ style: {
681
+ position: "relative",
682
+ textShadow: "var(--atomix-glass-container-text-shadow)",
683
+ ...elasticity > 0 ? {
684
+ zIndex: 100
685
+ } : {}
686
+ },
687
+ children: children
688
+ }) ]
689
+ })
690
+ });
691
+ }));
692
+
693
+ // Module-level shared shader cache with LRU eviction
694
+ AtomixGlassContainer.displayName = "AtomixGlassContainer";
695
+
696
+ // Singleton instance
697
+ const globalMouseTracker = new
698
+ /**
699
+ * Global mouse tracker singleton
700
+ * Tracks mouse position at document level and distributes to subscribers
701
+ * Reduces event processing overhead when multiple AtomixGlass instances are present
702
+ */
703
+ class {
704
+ constructor() {
705
+ this.listeners = new Set, this.position = {
706
+ x: 0,
707
+ y: 0
708
+ }, this.rafId = null, this.lastEvent = null, this.isTracking = !1,
709
+ /**
710
+ * Handle mouse move event
711
+ */
712
+ this.handleMouseMove = e => {
713
+ this.lastEvent = e,
714
+ // Use requestAnimationFrame to throttle updates
715
+ null === this.rafId && (this.rafId = requestAnimationFrame((() => {
716
+ this.lastEvent && (this.position = {
717
+ x: this.lastEvent.clientX,
718
+ y: this.lastEvent.clientY
719
+ },
720
+ // Notify all subscribers
721
+ this.listeners.forEach((callback => {
722
+ try {
723
+ callback(this.position);
724
+ } catch (error) {
725
+ console.error("GlobalMouseTracker: Error in subscriber callback", error);
726
+ }
727
+ }))), this.rafId = null;
728
+ })));
729
+ };
730
+ }
731
+ /**
732
+ * Subscribe to mouse position updates
733
+ * @param callback Function to call when mouse position changes
734
+ * @returns Unsubscribe function
735
+ */ subscribe(callback) {
736
+ // Return unsubscribe function
737
+ return this.listeners.add(callback),
738
+ // Start tracking if this is the first subscriber
739
+ 1 === this.listeners.size && this.startTracking(),
740
+ // Immediately notify with current position
741
+ callback(this.position), () => {
742
+ this.unsubscribe(callback);
743
+ };
744
+ }
745
+ /**
746
+ * Unsubscribe from mouse position updates
747
+ */ unsubscribe(callback) {
748
+ this.listeners.delete(callback),
749
+ // Stop tracking if no more subscribers
750
+ 0 === this.listeners.size && this.stopTracking();
751
+ }
752
+ /**
753
+ * Start tracking mouse movement
754
+ */ startTracking() {
755
+ this.isTracking || (this.isTracking = !0,
756
+ // Use document-level listener for global tracking
757
+ document.addEventListener("mousemove", this.handleMouseMove, {
758
+ passive: !0
759
+ }));
760
+ }
761
+ /**
762
+ * Stop tracking mouse movement
763
+ */ stopTracking() {
764
+ this.isTracking && (this.isTracking = !1, document.removeEventListener("mousemove", this.handleMouseMove),
765
+ // Cancel any pending RAF
766
+ null !== this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = null), this.lastEvent = null);
767
+ }
768
+ /**
769
+ * Get current mouse position (synchronous)
770
+ */ getPosition() {
771
+ return {
772
+ ...this.position
773
+ };
774
+ }
775
+ /**
776
+ * Get number of active subscribers (for debugging)
777
+ */ getSubscriberCount() {
778
+ return this.listeners.size;
779
+ }
780
+ }, {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
781
+ parentElement && backgroundDetectionCache.set(parentElement, {
782
+ result: result,
783
+ timestamp: Date.now(),
784
+ config: overLightConfig,
785
+ threshold: threshold
786
+ });
787
+ };
788
+
789
+ /**
790
+ * Composable hook for AtomixGlass component logic
791
+ * Manages all state, calculations, and event handlers
792
+ */
793
+ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadius: cornerRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, disableEffects: disableEffects = !1, elasticity: elasticity = .05, onClick: onClick, debugCornerRadius: debugCornerRadius = !1, debugOverLight: debugOverLight = !1, enablePerformanceMonitoring: enablePerformanceMonitoring = !1, children: children}) {
794
+ // State
795
+ const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), [glassSize, setGlassSize] = useState({
796
+ width: 270,
797
+ height: 69
798
+ }), [internalGlobalMousePosition, setInternalGlobalMousePosition] = useState({
799
+ x: 0,
800
+ y: 0
801
+ }), [internalMouseOffset, setInternalMouseOffset] = useState({
802
+ x: 0,
803
+ y: 0
804
+ }), [dynamicCornerRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveCornerRadius = useMemo((() => void 0 !== cornerRadius ? Math.max(0, cornerRadius) : Math.max(0, dynamicCornerRadius)), [ cornerRadius, dynamicCornerRadius, debugCornerRadius ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveDisableEffects = useMemo((() => disableEffects || effectiveReducedMotion), [ disableEffects, effectiveReducedMotion ]), globalMousePosition = useMemo((() => externalGlobalMousePosition || internalGlobalMousePosition), [ externalGlobalMousePosition, internalGlobalMousePosition ]), mouseOffset = useMemo((() => externalMouseOffset || internalMouseOffset), [ externalMouseOffset, internalMouseOffset ]);
805
+ // Extract border-radius from children
806
+ useEffect((() => {
807
+ const extractRadius = () => {
808
+ try {
809
+ let extractedRadius = null, extractionSource = "default";
810
+ if (contentRef.current) {
811
+ const firstChild = contentRef.current.firstElementChild;
812
+ if (firstChild) {
813
+ const domRadius = (element => {
814
+ if (!element || "undefined" == typeof window) return null;
815
+ try {
816
+ const computedStyles = window.getComputedStyle(element), borderRadius = computedStyles.borderRadius || computedStyles.borderTopLeftRadius || computedStyles.borderTopRightRadius || computedStyles.borderBottomLeftRadius || computedStyles.borderBottomRightRadius;
817
+ if (borderRadius && "0px" !== borderRadius && "auto" !== borderRadius) {
818
+ const parsed = parseBorderRadiusValue(borderRadius);
819
+ return parsed > 0 ? parsed : null;
820
+ }
821
+ return null;
822
+ } catch (error) {
823
+ return null;
824
+ }
825
+ })(firstChild);
826
+ null !== domRadius && domRadius > 0 && (extractedRadius = domRadius, extractionSource = "DOM element");
827
+ }
828
+ }
829
+ if (null === extractedRadius) {
830
+ const childRadius = extractBorderRadiusFromChildren(children);
831
+ childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius,
832
+ extractionSource = "React children");
833
+ }
834
+ null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : process.env.NODE_ENV;
835
+ } catch (error) {
836
+ "production" !== process.env.NODE_ENV && debugCornerRadius && console.error("[AtomixGlass] Error extracting corner radius:", error);
837
+ }
838
+ };
839
+ extractRadius();
840
+ const timeoutId = setTimeout(extractRadius, 100);
841
+ return () => clearTimeout(timeoutId);
842
+ }), [ children, debugCornerRadius, contentRef ]),
843
+ // Media query handlers and background detection
844
+ useEffect((() => {
845
+ if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
846
+ const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
847
+ if (!parentElement) return null;
848
+ const cached = backgroundDetectionCache.get(parentElement);
849
+ return cached && ((config1, config2) => {
850
+ // Primitive comparison for boolean and 'auto'
851
+ if ("object" != typeof config1 || null === config1) return config1 === config2;
852
+ // Both must be objects at this point
853
+ if ("object" != typeof config2 || null === config2) return !1;
854
+ const obj1 = config1, obj2 = config2, props = [ "threshold", "opacity", "contrast", "brightness", "saturationBoost" ];
855
+ for (const prop of props) {
856
+ const val1 = obj1[prop], val2 = obj2[prop];
857
+ // If both are undefined, they're equal for this property
858
+ if (void 0 !== val1 || void 0 !== val2) {
859
+ // If one is undefined and the other isn't, they're different
860
+ if (void 0 === val1 || void 0 === val2) return !1;
861
+ // Compare numeric values (handle NaN and floating point precision)
862
+ if ("number" == typeof val1 && "number" == typeof val2) {
863
+ // Use Number.isNaN for proper NaN comparison
864
+ if (Number.isNaN(val1) && Number.isNaN(val2)) continue;
865
+ if (Number.isNaN(val1) || Number.isNaN(val2)) return !1;
866
+ // Compare with small epsilon for floating point numbers
867
+ if (Math.abs(val1 - val2) > Number.EPSILON) return !1;
868
+ } else if (val1 !== val2) return !1;
869
+ }
870
+ }
871
+ return !0;
872
+ })(cached.config, overLightConfig) ? (
873
+ // Update timestamp for LRU-like behavior (though WeakMap doesn't support LRU)
874
+ cached.timestamp = Date.now(), cached.result) : null;
875
+ })(element.parentElement, overLight);
876
+ if (null !== cachedResult) return void setDetectedOverLight(cachedResult);
877
+ const timeoutId = setTimeout((() => {
878
+ try {
879
+ if (!element) return void setDetectedOverLight(!1);
880
+ // Validate window context
881
+ if ("undefined" == typeof window || "function" != typeof window.getComputedStyle) return void setDetectedOverLight(!1);
882
+ let totalLuminance = 0, validSamples = 0, hasValidBackground = !1, currentElement = element.parentElement, depth = 0;
883
+ const maxDepth = 20, maxSamples = 10;
884
+ // Limit traversal depth to prevent infinite loops and performance issues
885
+ for (;currentElement && validSamples < maxSamples && depth < maxDepth; ) {
886
+ try {
887
+ const computedStyle = window.getComputedStyle(currentElement);
888
+ if (!computedStyle) {
889
+ currentElement = currentElement.parentElement, depth++;
890
+ continue;
891
+ }
892
+ const bgColor = computedStyle.backgroundColor, bgImage = computedStyle.backgroundImage;
893
+ // Check for solid color backgrounds
894
+ if (bgColor && "rgba(0, 0, 0, 0)" !== bgColor && "transparent" !== bgColor && "initial" !== bgColor && "none" !== bgColor) {
895
+ const rgb = bgColor.match(/\d+/g);
896
+ if (rgb && rgb.length >= 3) {
897
+ const r = Number(rgb[0]), g = Number(rgb[1]), b = Number(rgb[2]);
898
+ // Validate RGB values are valid numbers
899
+ if (!isNaN(r) && !isNaN(g) && !isNaN(b) && isFinite(r) && isFinite(g) && isFinite(b) && r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && (r > 10 || g > 10 || b > 10)) {
900
+ const luminance = (.299 * r + .587 * g + .114 * b) / 255;
901
+ !isNaN(luminance) && isFinite(luminance) && (totalLuminance += luminance, validSamples++,
902
+ hasValidBackground = !0);
903
+ }
904
+ }
905
+ }
906
+ // Check for image backgrounds
907
+ bgImage && "none" !== bgImage && "initial" !== bgImage && (
908
+ // For image backgrounds, assume medium luminance
909
+ totalLuminance += .5, validSamples++, hasValidBackground = !0);
910
+ } catch (styleError) {
911
+ process.env.NODE_ENV;
912
+ }
913
+ // Move to parent element for next iteration
914
+ if (!currentElement) break;
915
+ // Exit loop if currentElement becomes null
916
+ currentElement = currentElement.parentElement, depth++;
917
+ }
918
+ // More conservative detection with better error handling
919
+ if (hasValidBackground && validSamples > 0) {
920
+ const avgLuminance = totalLuminance / validSamples;
921
+ if (!isNaN(avgLuminance) && isFinite(avgLuminance)) {
922
+ let threshold = .7;
923
+ // Conservative threshold for overlight
924
+ // If overLight is an object, use its threshold property with validation
925
+ if ("object" == typeof overLight && null !== overLight) {
926
+ const objConfig = overLight;
927
+ if (void 0 !== objConfig.threshold) {
928
+ const configThreshold = "number" == typeof objConfig.threshold && !isNaN(objConfig.threshold) && isFinite(objConfig.threshold) ? objConfig.threshold : .7;
929
+ threshold = Math.min(.9, Math.max(.1, configThreshold));
930
+ }
931
+ }
932
+ const isOverLightDetected = avgLuminance > threshold;
933
+ // Cache the result in shared cache
934
+ setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold),
935
+ setDetectedOverLight(isOverLightDetected);
936
+ } else {
937
+ // Invalid luminance calculation, default to false
938
+ const result = !1, threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
939
+ setCachedBackgroundDetection(element.parentElement, overLight, result, threshold),
940
+ setDetectedOverLight(result);
941
+ }
942
+ } else {
943
+ // Default to false if no valid background found
944
+ const result = !1, threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
945
+ setCachedBackgroundDetection(element.parentElement, overLight, result, threshold),
946
+ setDetectedOverLight(result);
947
+ }
948
+ } catch (error) {
949
+ // Enhanced error logging with context
950
+ "development" === process.env.NODE_ENV && console.warn("AtomixGlass: Error detecting background brightness:", error);
951
+ const result = !1;
952
+ if (element && element.parentElement) {
953
+ const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
954
+ setCachedBackgroundDetection(element.parentElement, overLight, result, threshold);
955
+ }
956
+ setDetectedOverLight(result);
957
+ }
958
+ }), 150);
959
+ return () => clearTimeout(timeoutId);
960
+ }
961
+ if ("boolean" == typeof overLight &&
962
+ // For boolean values, disable auto-detection
963
+ // Cache is automatically managed by WeakMap (no manual clearing needed)
964
+ setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
965
+ const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
966
+ setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
967
+ const handleReducedMotionChange = e => {
968
+ setUserPrefersReducedMotion(e.matches);
969
+ }, handleHighContrastChange = e => {
970
+ setUserPrefersHighContrast(e.matches);
971
+ };
972
+ return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
973
+ mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
974
+ mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
975
+ try {
976
+ mediaQueryReducedMotion.removeEventListener ? (mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
977
+ mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.removeListener && (mediaQueryReducedMotion.removeListener(handleReducedMotionChange),
978
+ mediaQueryHighContrast.removeListener(handleHighContrastChange));
979
+ } catch (cleanupError) {
980
+ console.error("AtomixGlass: Error cleaning up media query listeners:", cleanupError);
981
+ }
982
+ };
983
+ } catch (error) {
984
+ return void console.error("AtomixGlass: Error setting up media queries:", error);
985
+ }
986
+ }), [ overLight, glassRef, debugOverLight ]);
987
+ // Mouse tracking using shared global tracker
988
+ // Cache bounding rect to avoid repeated getBoundingClientRect calls
989
+ const cachedRectRef = useRef(null), updateRectRef = useRef(null), handleGlobalMousePosition = useCallback((globalPos => {
990
+ if (externalGlobalMousePosition && externalMouseOffset)
991
+ // External mouse position provided, skip internal tracking
992
+ return;
993
+ if (effectiveDisableEffects) return;
994
+ const container = mouseContainer?.current || glassRef.current;
995
+ if (!container) return;
996
+ enablePerformanceMonitoring && performance.now();
997
+ // Use cached rect if available, otherwise get new one
998
+ let rect = cachedRectRef.current;
999
+ if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
1000
+ cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
1001
+ const center = calculateElementCenter(rect), newOffset = {
1002
+ x: (globalPos.x - center.x) / rect.width * 100,
1003
+ y: (globalPos.y - center.y) / rect.height * 100
1004
+ };
1005
+ // Calculate offset relative to this container
1006
+ // React 18 automatically batches these updates
1007
+ setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "production" !== process.env.NODE_ENV && enablePerformanceMonitoring && performance.now();
1008
+ }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects, enablePerformanceMonitoring ]);
1009
+ // Subscribe to shared mouse tracker
1010
+ useEffect((() => {
1011
+ if (externalGlobalMousePosition && externalMouseOffset)
1012
+ // External mouse position provided, don't subscribe
1013
+ return;
1014
+ if (effectiveDisableEffects)
1015
+ // Effects disabled, don't subscribe
1016
+ return;
1017
+ // Subscribe to shared tracker
1018
+ const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
1019
+ // Update cached rect when container size changes
1020
+ let resizeObserver = null;
1021
+ return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
1022
+ null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
1023
+ const container = mouseContainer?.current || glassRef.current;
1024
+ container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
1025
+ }));
1026
+ })), resizeObserver.observe(container)), () => {
1027
+ unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1028
+ updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
1029
+ };
1030
+ }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects ]);
1031
+ // Transform calculations
1032
+ const calculateDirectionalScale = useCallback((() => {
1033
+ if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
1034
+ const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
1035
+ x: edgeDistanceX,
1036
+ y: edgeDistanceY
1037
+ }, {
1038
+ x: 0,
1039
+ y: 0
1040
+ });
1041
+ if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
1042
+ const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
1043
+ if (0 === centerDistance) return "scale(1)";
1044
+ const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15;
1045
+ return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
1046
+ }), [ globalMousePosition, elasticity, glassSize, glassRef ]), calculateFadeInFactor = useCallback((() => {
1047
+ if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
1048
+ const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
1049
+ x: edgeDistanceX,
1050
+ y: edgeDistanceY
1051
+ }, {
1052
+ x: 0,
1053
+ y: 0
1054
+ });
1055
+ return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
1056
+ }), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = useCallback((() => {
1057
+ if (!glassRef.current) return {
1058
+ x: 0,
1059
+ y: 0
1060
+ };
1061
+ const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
1062
+ return {
1063
+ x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
1064
+ y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
1065
+ };
1066
+ }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveDisableEffects ? {
1067
+ x: 0,
1068
+ y: 0
1069
+ } : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveDisableEffects ]), directionalScale = useMemo((() => effectiveDisableEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveDisableEffects ]), transformStyle = useMemo((() => effectiveDisableEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`), [ elasticTranslation, isActive, onClick, directionalScale, effectiveDisableEffects ]);
1070
+ // Size management
1071
+ useEffect((() => {
1072
+ const isValidElement = element => null !== element && element instanceof HTMLElement && element.isConnected;
1073
+ let rafId = null, lastSize = {
1074
+ width: 0,
1075
+ height: 0
1076
+ }, lastCornerRadius = effectiveCornerRadius;
1077
+ const updateGlassSize = (forceUpdate = !1) => {
1078
+ null !== rafId && cancelAnimationFrame(rafId), rafId = requestAnimationFrame((() => {
1079
+ if (!isValidElement(glassRef.current)) return void (rafId = null);
1080
+ const rect = glassRef.current.getBoundingClientRect();
1081
+ if (rect.width <= 0 || rect.height <= 0) return void (rafId = null);
1082
+ // Measure actual rendered size without artificial offsets to avoid feedback loops
1083
+ const newSize = {
1084
+ width: Math.round(rect.width),
1085
+ height: Math.round(rect.height)
1086
+ }, cornerRadiusChanged = lastCornerRadius !== effectiveCornerRadius, dimensionsChanged = Math.abs(newSize.width - lastSize.width) > 1 || Math.abs(newSize.height - lastSize.height) > 1;
1087
+ var size;
1088
+ (forceUpdate || cornerRadiusChanged || dimensionsChanged) && validateGlassSize(size = newSize) && size.width <= CONSTANTS.MAX_SIZE && size.height <= CONSTANTS.MAX_SIZE && (lastSize = newSize,
1089
+ lastCornerRadius = effectiveCornerRadius, setGlassSize(newSize)), rafId = null;
1090
+ }));
1091
+ };
1092
+ let resizeTimeoutId = null;
1093
+ const debouncedResizeHandler = () => {
1094
+ resizeTimeoutId && clearTimeout(resizeTimeoutId), resizeTimeoutId = setTimeout((() => updateGlassSize(!1)), 16);
1095
+ }, initialTimeoutId = setTimeout((() => updateGlassSize(!0)), 0);
1096
+ let resizeObserver = null, resizeDebounceTimeout = null;
1097
+ // ResizeObserver has 98%+ browser support, no need for fallback
1098
+ if ("undefined" != typeof ResizeObserver && isValidElement(glassRef.current)) try {
1099
+ resizeObserver = new ResizeObserver((entries => {
1100
+ for (const entry of entries) if (entry.target === glassRef.current) {
1101
+ // Update cached rect when size changes
1102
+ glassRef.current && (cachedRectRef.current = glassRef.current.getBoundingClientRect()),
1103
+ // Debounce resize updates to match RAF timing (16ms)
1104
+ resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), resizeDebounceTimeout = setTimeout((() => updateGlassSize(!1)), 16);
1105
+ break;
1106
+ }
1107
+ })), resizeObserver.observe(glassRef.current);
1108
+ } catch (error) {
1109
+ console.warn("AtomixGlass: ResizeObserver not available, using window resize only", error);
1110
+ }
1111
+ return window.addEventListener("resize", debouncedResizeHandler, {
1112
+ passive: !0
1113
+ }), () => {
1114
+ clearTimeout(initialTimeoutId), null !== rafId && cancelAnimationFrame(rafId), resizeTimeoutId && clearTimeout(resizeTimeoutId),
1115
+ resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), window.removeEventListener("resize", debouncedResizeHandler),
1116
+ resizeObserver?.disconnect();
1117
+ };
1118
+ }), [ effectiveCornerRadius, glassRef ]);
1119
+ // OverLight config
1120
+ /**
1121
+ * Get effective overLight value based on configuration
1122
+ * - boolean: returns the boolean value directly
1123
+ * - 'auto': returns detectedOverLight (auto-detected from background)
1124
+ * - object: returns detectedOverLight (auto-detected, but config object provides customization)
1125
+ */
1126
+ const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
1127
+ const isOverLight = getEffectiveOverLight(), mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
1128
+ isOverLight: isOverLight,
1129
+ threshold: .7,
1130
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1131
+ contrast: Math.min(1.8, Math.max(1, 1.4 + .3 * mouseInfluence)),
1132
+ brightness: Math.min(1.2, Math.max(.7, .85 + .15 * mouseInfluence)),
1133
+ saturationBoost: Math.min(2, Math.max(1, 1.3 + .4 * mouseInfluence)),
1134
+ shadowIntensity: Math.min(1.5, Math.max(.5, .9 + .5 * mouseInfluence)),
1135
+ borderOpacity: Math.min(1, Math.max(.3, .7 + .3 * mouseInfluence))
1136
+ };
1137
+ if ("object" == typeof overLight && null !== overLight) {
1138
+ const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), finalConfig = {
1139
+ ...baseConfig,
1140
+ threshold: validatedThreshold,
1141
+ opacity: validatedOpacity * hoverIntensity * activeIntensity,
1142
+ contrast: validatedContrast + .3 * mouseInfluence,
1143
+ brightness: validatedBrightness + .15 * mouseInfluence,
1144
+ saturationBoost: validatedSaturationBoost + .4 * mouseInfluence
1145
+ };
1146
+ // Validate and apply object config values with proper clamping
1147
+ return process.env.NODE_ENV, finalConfig;
1148
+ }
1149
+ // Debug logging for non-object configs
1150
+ return process.env.NODE_ENV, baseConfig;
1151
+ }), [ overLight, getEffectiveOverLight, mouseOffset, isHovered, isActive, validateConfigValue, debugOverLight ]), handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1152
+ !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1153
+ }), [ onClick ]), handleMouseMove = useCallback((_e => {}), []);
1154
+ /**
1155
+ * Validate and clamp a numeric config value
1156
+ * @param value - The value to validate
1157
+ * @param min - Minimum allowed value
1158
+ * @param max - Maximum allowed value
1159
+ * @param defaultValue - Default value if validation fails
1160
+ * @returns Validated and clamped value
1161
+ */ return {
1162
+ // State
1163
+ isHovered: isHovered,
1164
+ isActive: isActive,
1165
+ glassSize: glassSize,
1166
+ dynamicCornerRadius: dynamicCornerRadius,
1167
+ effectiveCornerRadius: effectiveCornerRadius,
1168
+ effectiveReducedMotion: effectiveReducedMotion,
1169
+ effectiveHighContrast: effectiveHighContrast,
1170
+ effectiveDisableEffects: effectiveDisableEffects,
1171
+ detectedOverLight: detectedOverLight,
1172
+ globalMousePosition: globalMousePosition,
1173
+ mouseOffset: mouseOffset,
1174
+ // OverLight config
1175
+ overLightConfig: overLightConfig,
1176
+ // Transform calculations
1177
+ elasticTranslation: elasticTranslation,
1178
+ directionalScale: directionalScale,
1179
+ transformStyle: transformStyle,
1180
+ // Event handlers
1181
+ handleMouseEnter: handleMouseEnter,
1182
+ handleMouseLeave: handleMouseLeave,
1183
+ handleMouseDown: handleMouseDown,
1184
+ handleMouseUp: handleMouseUp,
1185
+ handleMouseMove: handleMouseMove,
1186
+ handleKeyDown: handleKeyDown
1187
+ };
1188
+ }
1189
+
1190
+ /**
1191
+ * AtomixGlass - A high-performance glass morphism component with liquid distortion effects
1192
+ *
1193
+ * Features:
1194
+ * - Hardware-accelerated glass effects with SVG filters
1195
+ * - Mouse-responsive liquid distortion
1196
+ * - Dynamic border-radius extraction from children CSS properties
1197
+ * - Automatic light/dark theme detection via overLight prop
1198
+ * - Accessibility and performance optimizations
1199
+ * - Multiple displacement modes (standard, polar, prominent, shader)
1200
+ * - Design token integration for consistent theming
1201
+ * - Focus ring support for keyboard navigation
1202
+ * - Responsive breakpoints for mobile optimization
1203
+ * - Enhanced ARIA attributes for screen readers
1204
+ *
1205
+ * Design System Compliance:
1206
+ * - Uses design tokens for opacity, spacing, and colors
1207
+ * - Follows BEM methodology for class naming
1208
+ * - Implements focus-ring mixin for accessibility
1209
+ * - Supports reduced motion and high contrast preferences
1210
+ *
1211
+ * @example
1212
+ * // Basic usage with dynamic border-radius extraction
1213
+ * <AtomixGlass>
1214
+ * <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
1215
+ * </AtomixGlass>
1216
+ *
1217
+ * @example
1218
+ * // Manual border-radius override
1219
+ * <AtomixGlass cornerRadius={20}>
1220
+ * <div>Content with 20px glass radius</div>
1221
+ * </AtomixGlass>
1222
+ *
1223
+ * @example
1224
+ * // Interactive glass with click handler
1225
+ * <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
1226
+ * <div>Clickable content</div>
1227
+ * </AtomixGlass>
1228
+ *
1229
+ * @example
1230
+ * // OverLight - Boolean mode (explicit control)
1231
+ * <AtomixGlass overLight={true}>
1232
+ * <div>Content on light background</div>
1233
+ * </AtomixGlass>
1234
+ *
1235
+ * @example
1236
+ * // OverLight - Auto-detection mode
1237
+ * <AtomixGlass overLight="auto">
1238
+ * <div>Content with auto-detected background</div>
1239
+ * </AtomixGlass>
1240
+ *
1241
+ * @example
1242
+ * // OverLight - Object config with custom settings
1243
+ * <AtomixGlass
1244
+ * overLight={{
1245
+ * threshold: 0.8,
1246
+ * opacity: 0.6,
1247
+ * contrast: 1.8,
1248
+ * brightness: 1.0,
1249
+ * saturationBoost: 1.5
1250
+ * }}
1251
+ * >
1252
+ * <div>Content with custom overLight config</div>
1253
+ * </AtomixGlass>
1254
+ *
1255
+ * @example
1256
+ * // Debug mode for overLight detection
1257
+ * <AtomixGlass overLight="auto" debugOverLight={true}>
1258
+ * <div>Content with debug logging enabled</div>
1259
+ * </AtomixGlass>
1260
+ */ function AtomixGlass({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, cornerRadius: cornerRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, disableEffects: disableEffects = !1, enableLiquidBlur: enableLiquidBlur = !1, enableBorderEffect: enableBorderEffect = !0, enableOverLightLayers: enableOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, enablePerformanceMonitoring: enablePerformanceMonitoring = !1, debugCornerRadius: debugCornerRadius = !1, debugOverLight: debugOverLight = !1}) {
1261
+ const glassRef = useRef(null), contentRef = useRef(null), opacityCacheRef = useRef(null), {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveCornerRadius: effectiveCornerRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveDisableEffects: effectiveDisableEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
1262
+ glassRef: glassRef,
1263
+ contentRef: contentRef,
1264
+ cornerRadius: cornerRadius,
1265
+ globalMousePosition: externalGlobalMousePosition,
1266
+ mouseOffset: externalMouseOffset,
1267
+ mouseContainer: mouseContainer,
1268
+ overLight: overLight,
1269
+ reducedMotion: reducedMotion,
1270
+ highContrast: highContrast,
1271
+ disableEffects: disableEffects,
1272
+ elasticity: elasticity,
1273
+ onClick: onClick,
1274
+ debugCornerRadius: debugCornerRadius,
1275
+ debugOverLight: debugOverLight,
1276
+ enablePerformanceMonitoring: enablePerformanceMonitoring,
1277
+ children: children
1278
+ }), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight;
1279
+ // Read CSS custom properties once on mount and cache them
1280
+ useEffect((() => {
1281
+ if ("undefined" != typeof window && glassRef.current && !opacityCacheRef.current) try {
1282
+ const computedStyle = window.getComputedStyle(glassRef.current), opacity50Value = computedStyle.getPropertyValue("--atomix-opacity-50").trim(), opacity40Value = computedStyle.getPropertyValue("--atomix-opacity-40").trim(), opacity80Value = computedStyle.getPropertyValue("--atomix-opacity-80").trim(), opacity0Value = computedStyle.getPropertyValue("--atomix-opacity-0").trim(), parseOpacity = (value, defaultValue) => {
1283
+ if (!value) return defaultValue;
1284
+ const parsed = parseFloat(value);
1285
+ return isNaN(parsed) ? defaultValue : parsed;
1286
+ };
1287
+ opacityCacheRef.current = {
1288
+ opacity50: parseOpacity(opacity50Value, .5),
1289
+ opacity40: parseOpacity(opacity40Value, .4),
1290
+ opacity80: parseOpacity(opacity80Value, .8),
1291
+ opacity0: parseOpacity(opacity0Value, 0)
1292
+ };
1293
+ } catch (error) {
1294
+ // Fallback to defaults if reading fails
1295
+ opacityCacheRef.current = {
1296
+ opacity50: .5,
1297
+ opacity40: .4,
1298
+ opacity80: .8,
1299
+ opacity0: 0
1300
+ };
1301
+ }
1302
+ }), []);
1303
+ // Calculate base style with transforms (only dynamic values)
1304
+ const baseStyle = useMemo((() => ({
1305
+ ...style,
1306
+ ...0 !== elasticity && !effectiveDisableEffects && {
1307
+ transform: transformStyle
1308
+ }
1309
+ })), [ style, transformStyle, effectiveDisableEffects, elasticity ]), componentClassName = useMemo((() => [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveDisableEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" ")), [ effectiveReducedMotion, effectiveHighContrast, effectiveDisableEffects, className ]), baseStylePosition = baseStyle.position, baseStyleTop = baseStyle.top, baseStyleLeft = baseStyle.left, positionStyles = useMemo((() => ({
1310
+ position: baseStylePosition || "absolute",
1311
+ top: baseStyleTop || 0,
1312
+ left: baseStyleLeft || 0
1313
+ })), [ baseStylePosition, baseStyleTop, baseStyleLeft ]), baseStyleWidth = baseStyle.width, baseStyleHeight = baseStyle.height, glassSizeWidth = glassSize.width, glassSizeHeight = glassSize.height, adjustedSize = useMemo((() => ({
1314
+ width: "fixed" !== baseStylePosition ? "100%" : baseStyleWidth || Math.max(glassSizeWidth, 0),
1315
+ height: "fixed" !== baseStylePosition ? "100%" : baseStyleHeight || Math.max(glassSizeHeight, 0)
1316
+ })), [ baseStylePosition, baseStyleWidth, baseStyleHeight, glassSizeWidth, glassSizeHeight ]), mouseOffsetX = mouseOffset.x, mouseOffsetY = mouseOffset.y, GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, gradientCalculations = useMemo((() => {
1317
+ const mx = mouseOffsetX, my = mouseOffsetY, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), borderOpacity1 = GRADIENT.BORDER_OPACITY.BASE_1 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity2 = GRADIENT.BORDER_OPACITY.BASE_2 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, borderOpacity3 = GRADIENT.BORDER_OPACITY.BASE_3 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity4 = GRADIENT.BORDER_OPACITY.BASE_4 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, hover1X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1, hover1Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1, hover2X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2, hover2Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2, hover3X = GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3, hover3Y = GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3, baseX = GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER, baseY = GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER;
1318
+ return {
1319
+ isOverLight: isOverLight,
1320
+ mx: mx,
1321
+ my: my,
1322
+ borderGradientAngle: borderGradientAngle,
1323
+ borderStop1: borderStop1,
1324
+ borderStop2: borderStop2,
1325
+ borderOpacity1: borderOpacity1,
1326
+ borderOpacity2: borderOpacity2,
1327
+ borderOpacity3: borderOpacity3,
1328
+ borderOpacity4: borderOpacity4,
1329
+ hover1X: hover1X,
1330
+ hover1Y: hover1Y,
1331
+ hover2X: hover2X,
1332
+ hover2Y: hover2Y,
1333
+ hover3X: hover3X,
1334
+ hover3Y: hover3Y,
1335
+ baseX: baseX,
1336
+ baseY: baseY
1337
+ };
1338
+ }), [ mouseOffsetX, mouseOffsetY, isOverLight ]), overLightOpacity = overLightConfig.opacity, opacityValues = useMemo((() => {
1339
+ // Use cached values if available, otherwise fallback to defaults
1340
+ const opacity50 = opacityCacheRef.current?.opacity50 ?? .5, opacity40 = opacityCacheRef.current?.opacity40 ?? .4, opacity80 = opacityCacheRef.current?.opacity80 ?? .8, opacity0 = opacityCacheRef.current?.opacity0 ?? 0;
1341
+ // Dynamic multiplier for overlay
1342
+ return {
1343
+ hover1: isHovered || isActive ? opacity50 : opacity0,
1344
+ hover2: isActive ? opacity50 : opacity0,
1345
+ hover3: isHovered ? opacity40 : isActive ? opacity80 : opacity0,
1346
+ base: isOverLight ? overLightOpacity || opacity40 : opacity0,
1347
+ over: isOverLight ? 1.1 * (overLightOpacity || opacity40) : opacity0
1348
+ };
1349
+ }), [ isHovered, isActive, isOverLight, overLightOpacity ]), gradientIsOverLight = gradientCalculations.isOverLight, gradientMx = gradientCalculations.mx, gradientMy = gradientCalculations.my, gradientBorderGradientAngle = gradientCalculations.borderGradientAngle, gradientBorderStop1 = gradientCalculations.borderStop1, gradientBorderStop2 = gradientCalculations.borderStop2, gradientBorderOpacity1 = gradientCalculations.borderOpacity1, gradientBorderOpacity2 = gradientCalculations.borderOpacity2, gradientBorderOpacity3 = gradientCalculations.borderOpacity3, gradientBorderOpacity4 = gradientCalculations.borderOpacity4, gradientHover1X = gradientCalculations.hover1X, gradientHover1Y = gradientCalculations.hover1Y, gradientHover2X = gradientCalculations.hover2X, gradientHover2Y = gradientCalculations.hover2Y, gradientHover3X = gradientCalculations.hover3X, gradientHover3Y = gradientCalculations.hover3Y, gradientBaseX = gradientCalculations.baseX, gradientBaseY = gradientCalculations.baseY, positionStylesPosition = positionStyles.position, positionStylesTop = positionStyles.top, positionStylesLeft = positionStyles.left, adjustedSizeWidth = adjustedSize.width, adjustedSizeHeight = adjustedSize.height, baseStyleTransform = baseStyle.transform, opacityValuesHover1 = opacityValues.hover1, opacityValuesHover2 = opacityValues.hover2, opacityValuesHover3 = opacityValues.hover3, opacityValuesBase = opacityValues.base, opacityValuesOver = opacityValues.over, glassVars = useMemo((() => {
1350
+ // RGB color values for rgba() functions
1351
+ // Note: CSS doesn't support rgba(var(--rgb), opacity) syntax, so we use direct values
1352
+ // These values align with design tokens: --atomix-white-rgb and --atomix-black-rgb
1353
+ // The actual RGB values are defined in SCSS and should match these fallbacks
1354
+ // TODO: Consider reading from CSS custom properties if browser support improves
1355
+ const whiteColor = "255, 255, 255";
1356
+ // Matches --atomix-white-rgb design token
1357
+ // Matches --atomix-black-rgb design token
1358
+ return {
1359
+ // Standard CSS custom properties for dynamic values
1360
+ "--atomix-glass-radius": `${effectiveCornerRadius}px`,
1361
+ "--atomix-glass-transform": baseStyleTransform || "none",
1362
+ "--atomix-glass-position": positionStylesPosition,
1363
+ "--atomix-glass-top": "fixed" !== positionStylesTop ? `${positionStylesTop}px` : "0",
1364
+ "--atomix-glass-left": "fixed" !== positionStylesLeft ? `${positionStylesLeft}px` : "0",
1365
+ "--atomix-glass-width": "fixed" !== baseStylePosition ? adjustedSizeWidth : `${adjustedSizeWidth}px`,
1366
+ "--atomix-glass-height": "fixed" !== baseStylePosition ? adjustedSizeHeight : `${adjustedSizeHeight}px`,
1367
+ // Border width: Use spacing token for consistency
1368
+ "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
1369
+ "--atomix-glass-blend-mode": gradientIsOverLight ? "multiply" : "overlay",
1370
+ // Dynamic gradients and backgrounds
1371
+ // Note: RGB values use design token-aligned constants (white: 255,255,255; black: 0,0,0)
1372
+ "--atomix-glass-border-gradient-1": `linear-gradient(${gradientBorderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${gradientBorderOpacity1}) ${gradientBorderStop1}%, rgba(${whiteColor}, ${gradientBorderOpacity2}) ${gradientBorderStop2}%, rgba(${whiteColor}, 0) 100%)`,
1373
+ "--atomix-glass-border-gradient-2": `linear-gradient(${gradientBorderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${gradientBorderOpacity3}) ${gradientBorderStop1}%, rgba(${whiteColor}, ${gradientBorderOpacity4}) ${gradientBorderStop2}%, rgba(${whiteColor}, 0) 100%)`,
1374
+ "--atomix-glass-hover-1-opacity": opacityValuesHover1,
1375
+ "--atomix-glass-hover-1-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover1X}% ${gradientHover1Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${gradientHover1X}% ${gradientHover1Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
1376
+ "--atomix-glass-hover-2-opacity": opacityValuesHover2,
1377
+ "--atomix-glass-hover-2-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover2X}% ${gradientHover2Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${gradientHover2X}% ${gradientHover2Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
1378
+ "--atomix-glass-hover-3-opacity": opacityValuesHover3,
1379
+ "--atomix-glass-hover-3-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover3X}% ${gradientHover3Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${gradientHover3X}% ${gradientHover3Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
1380
+ "--atomix-glass-base-opacity": opacityValuesBase,
1381
+ "--atomix-glass-base-gradient": gradientIsOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + gradientMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + gradientMy * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + Math.abs(gradientMx) * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
1382
+ "--atomix-glass-overlay-opacity": opacityValuesOver,
1383
+ "--atomix-glass-overlay-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientBaseX}% ${gradientBaseY}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + Math.abs(gradientMx) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + Math.abs(gradientMy) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
1384
+ };
1385
+ }), [
1386
+ // Position styles - only specific properties
1387
+ positionStylesPosition, positionStylesTop, positionStylesLeft,
1388
+ // Adjusted size - only specific properties
1389
+ adjustedSizeWidth, adjustedSizeHeight,
1390
+ // Base style - only transform property
1391
+ baseStyleTransform, baseStylePosition,
1392
+ // Other values
1393
+ effectiveCornerRadius, effectiveReducedMotion,
1394
+ // Gradient calculations - extracted properties
1395
+ gradientIsOverLight, gradientMx, gradientMy, gradientBorderGradientAngle, gradientBorderStop1, gradientBorderStop2, gradientBorderOpacity1, gradientBorderOpacity2, gradientBorderOpacity3, gradientBorderOpacity4, gradientHover1X, gradientHover1Y, gradientHover2X, gradientHover2Y, gradientHover3X, gradientHover3Y, gradientBaseX, gradientBaseY,
1396
+ // Opacity values - extracted properties
1397
+ opacityValuesHover1, opacityValuesHover2, opacityValuesHover3, opacityValuesBase, opacityValuesOver ]);
1398
+ // Build className with state modifiers
1399
+ return jsxs("div", {
1400
+ className: componentClassName,
1401
+ style: glassVars,
1402
+ role: role || (onClick ? "button" : void 0),
1403
+ tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
1404
+ "aria-label": ariaLabel,
1405
+ "aria-describedby": ariaDescribedBy,
1406
+ "aria-disabled": !(!onClick || !effectiveDisableEffects) || !onClick && void 0,
1407
+ "aria-pressed": !(!onClick || !isActive) || !onClick && void 0,
1408
+ onKeyDown: onClick ? handleKeyDown : void 0,
1409
+ children: [ jsx(AtomixGlassContainer, {
1410
+ ref: glassRef,
1411
+ contentRef: contentRef,
1412
+ className: className,
1413
+ style: baseStyle,
1414
+ cornerRadius: effectiveCornerRadius,
1415
+ displacementScale: effectiveDisableEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : overLightConfig.isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
1416
+ blurAmount: effectiveDisableEffects ? 0 : blurAmount,
1417
+ saturation: effectiveHighContrast ? ATOMIX_GLASS.CONSTANTS.SATURATION.HIGH_CONTRAST : overLightConfig.isOverLight ? saturation * overLightConfig.saturationBoost : saturation,
1418
+ aberrationIntensity: effectiveDisableEffects ? 0 : "shader" === mode ? aberrationIntensity * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_ABERRATION : aberrationIntensity,
1419
+ glassSize: glassSize,
1420
+ padding: padding,
1421
+ mouseOffset: effectiveDisableEffects ? {
1422
+ x: 0,
1423
+ y: 0
1424
+ } : mouseOffset,
1425
+ globalMousePosition: effectiveDisableEffects ? {
1426
+ x: 0,
1427
+ y: 0
1428
+ } : globalMousePosition,
1429
+ onMouseEnter: handleMouseEnter,
1430
+ onMouseLeave: handleMouseLeave,
1431
+ onMouseDown: handleMouseDown,
1432
+ onMouseUp: handleMouseUp,
1433
+ active: isActive,
1434
+ isHovered: isHovered,
1435
+ isActive: isActive,
1436
+ overLight: overLightConfig.isOverLight,
1437
+ onClick: onClick,
1438
+ mode: mode,
1439
+ transform: baseStyle.transform,
1440
+ effectiveDisableEffects: effectiveDisableEffects,
1441
+ effectiveReducedMotion: effectiveReducedMotion,
1442
+ shaderVariant: shaderVariant,
1443
+ elasticity: elasticity,
1444
+ enableLiquidBlur: enableLiquidBlur,
1445
+ children: children
1446
+ }), Boolean(onClick) && jsxs(Fragment, {
1447
+ children: [ jsx("div", {
1448
+ className: ATOMIX_GLASS.HOVER_1_CLASS
1449
+ }), jsx("div", {
1450
+ className: ATOMIX_GLASS.HOVER_2_CLASS
1451
+ }), jsx("div", {
1452
+ className: ATOMIX_GLASS.HOVER_3_CLASS
1453
+ }) ]
1454
+ }), jsx("div", {
1455
+ className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" "),
1456
+ style: {
1457
+ ...positionStyles,
1458
+ height: adjustedSize.height,
1459
+ width: adjustedSize.width,
1460
+ borderRadius: `${effectiveCornerRadius}px`,
1461
+ transform: baseStyle.transform
1462
+ }
1463
+ }), jsx("div", {
1464
+ className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" "),
1465
+ style: {
1466
+ ...positionStyles,
1467
+ height: adjustedSize.height,
1468
+ width: adjustedSize.width,
1469
+ borderRadius: `${effectiveCornerRadius}px`,
1470
+ transform: baseStyle.transform
1471
+ }
1472
+ }), shouldRenderOverLightLayers && jsxs(Fragment, {
1473
+ children: [ jsx("div", {
1474
+ className: ATOMIX_GLASS.BASE_LAYER_CLASS
1475
+ }), jsx("div", {
1476
+ className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
1477
+ }), jsx("div", {
1478
+ className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS,
1479
+ style: {
1480
+ opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
1481
+ background: `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
1482
+ }
1483
+ }) ]
1484
+ }), enableBorderEffect && jsxs(Fragment, {
1485
+ children: [ jsx("span", {
1486
+ className: ATOMIX_GLASS.BORDER_1_CLASS
1487
+ }), jsx("span", {
1488
+ className: ATOMIX_GLASS.BORDER_2_CLASS
1489
+ }) ]
1490
+ }) ]
1491
+ });
1492
+ }
1493
+
1494
+ /**
1495
+ * Checkbox - A component for checkbox inputs
1496
+ */ const Checkbox = memo((({label: label, checked: checked = !1, onChange: onChange, className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, value: value, invalid: invalid = !1, valid: valid = !1, indeterminate: indeterminate = !1, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, glass: glass}) => {
1497
+ const {generateCheckboxClass: generateCheckboxClass, checkboxRef: checkboxRef} = function(initialProps) {
1498
+ // Default checkbox properties
1499
+ const defaultProps = {
1500
+ disabled: !1,
1501
+ invalid: !1,
1502
+ valid: !1,
1503
+ indeterminate: !1,
1504
+ ...initialProps
1505
+ }, checkboxRef = useRef(null);
1506
+ // Ref for the checkbox input element
1507
+ // Handle indeterminate state
1508
+ return useEffect((() => {
1509
+ checkboxRef.current && (checkboxRef.current.indeterminate = Boolean(defaultProps.indeterminate));
1510
+ }), [ defaultProps.indeterminate ]), {
1511
+ defaultProps: defaultProps,
1512
+ generateCheckboxClass: props => {
1513
+ const {disabled: disabled = defaultProps.disabled, invalid: invalid = defaultProps.invalid, valid: valid = defaultProps.valid, indeterminate: indeterminate = defaultProps.indeterminate, className: className = ""} = props;
1514
+ let validationClass = "";
1515
+ return invalid ? validationClass = "is-error" : valid && (validationClass = "is-valid"),
1516
+ `c-checkbox ${validationClass} ${disabled ? "is-disabled" : ""} ${indeterminate ? "c-checkbox--mixed" : ""} ${className}`.trim();
1517
+ },
1518
+ checkboxRef: checkboxRef
1519
+ };
1520
+ }
1521
+ /**
1522
+ * Default theme colors for components
1523
+ */
1524
+ /**
1525
+ * Form-specific constants
1526
+ */ ({
1527
+ indeterminate: indeterminate,
1528
+ disabled: disabled,
1529
+ invalid: invalid,
1530
+ valid: valid
1531
+ }), checkboxClass = generateCheckboxClass({
1532
+ className: `${className} ${glass ? "c-checkbox--glass" : ""}`.trim(),
1533
+ disabled: disabled,
1534
+ invalid: invalid,
1535
+ valid: valid,
1536
+ indeterminate: indeterminate
1537
+ }), checkboxContent = jsxs("div", {
1538
+ className: checkboxClass,
1539
+ style: style,
1540
+ children: [ jsx("input", {
1541
+ ref: checkboxRef,
1542
+ type: "checkbox",
1543
+ className: "c-checkbox__input",
1544
+ checked: checked,
1545
+ onChange: onChange,
1546
+ disabled: disabled,
1547
+ required: required,
1548
+ id: id,
1549
+ name: name,
1550
+ value: value,
1551
+ "aria-label": label ? void 0 : ariaLabel,
1552
+ "aria-describedby": ariaDescribedBy,
1553
+ "aria-invalid": invalid
1554
+ }), label && jsx("label", {
1555
+ className: "c-checkbox__label",
1556
+ htmlFor: id,
1557
+ children: label
1558
+ }) ]
1559
+ });
1560
+ if (glass) {
1561
+ // Default glass settings for checkboxes
1562
+ const defaultGlassProps = {
1563
+ displacementScale: 40,
1564
+ blurAmount: 1,
1565
+ saturation: 160,
1566
+ aberrationIntensity: .3,
1567
+ cornerRadius: 6,
1568
+ mode: "shader"
1569
+ }, glassProps = !0 === glass ? defaultGlassProps : {
1570
+ ...defaultGlassProps,
1571
+ ...glass
1572
+ };
1573
+ return jsx(AtomixGlass, {
1574
+ ...glassProps,
1575
+ children: checkboxContent
1576
+ });
1577
+ }
1578
+ return checkboxContent;
1579
+ }));
1580
+
1581
+ Checkbox.displayName = "Checkbox";
1582
+
1583
+ /**
1584
+ * Form - A component for creating form layouts
1585
+ */
1586
+ const Form = ({children: children, onSubmit: onSubmit, onReset: onReset, className: className = "", style: style, disabled: disabled = !1, id: id, method: method = "post", encType: encType, noValidate: noValidate = !1, autoComplete: autoComplete = "on"}) => {
1587
+ const {generateFormClass: generateFormClass, handleSubmit: handleSubmit, handleReset: handleReset} =
1588
+ /**
1589
+ * Form state and functionality
1590
+ * @param initialProps - Initial form properties
1591
+ * @returns Form state and methods
1592
+ */
1593
+ function(initialProps) {
1594
+ // Default form properties
1595
+ const defaultProps = {
1596
+ disabled: !1,
1597
+ ...initialProps
1598
+ };
1599
+ /**
1600
+ * Generate form class based on properties
1601
+ * @param props - Form properties
1602
+ * @returns Class string
1603
+ */ return {
1604
+ defaultProps: defaultProps,
1605
+ generateFormClass: props => {
1606
+ const {disabled: disabled = defaultProps.disabled, className: className = ""} = props;
1607
+ return `${FORM_CLASSES_BASE} ${disabled ? FORM_CLASSES_DISABLED : ""} ${className}`.trim();
1608
+ },
1609
+ handleSubmit: handler => event => {
1610
+ event.preventDefault(), !defaultProps.disabled && handler && handler(event);
1611
+ },
1612
+ handleReset: handler => event => {
1613
+ !defaultProps.disabled && handler && handler(event);
1614
+ }
1615
+ };
1616
+ }({
1617
+ disabled: disabled
1618
+ }), formClass = generateFormClass({
1619
+ className: className,
1620
+ disabled: disabled
1621
+ });
1622
+ return jsx("form", {
1623
+ id: id,
1624
+ className: formClass,
1625
+ style: style,
1626
+ onSubmit: handleSubmit(onSubmit),
1627
+ onReset: handleReset(onReset),
1628
+ method: method,
1629
+ encType: encType,
1630
+ noValidate: noValidate,
1631
+ autoComplete: autoComplete,
1632
+ children: children
1633
+ });
1634
+ };
1635
+
1636
+ Form.displayName = "Form";
1637
+
1638
+ /**
1639
+ * FormGroup - A component for grouping form controls with labels and help text
1640
+ */
1641
+ const FormGroup = ({children: children, label: label, helperText: helperText, htmlFor: htmlFor, className: className = "", style: style, disabled: disabled = !1, required: required = !1, invalid: invalid = !1, valid: valid = !1, size: size = "md"}) => {
1642
+ const {generateFormGroupClass: generateFormGroupClass} =
1643
+ /**
1644
+ * Form Group state and functionality
1645
+ * @param initialProps - Initial form group properties
1646
+ * @returns Form Group state and methods
1647
+ */
1648
+ function(initialProps) {
1649
+ // Default form group properties
1650
+ const defaultProps = {
1651
+ size: "md",
1652
+ disabled: !1,
1653
+ invalid: !1,
1654
+ valid: !1,
1655
+ ...initialProps
1656
+ };
1657
+ /**
1658
+ * Generate form group class based on properties
1659
+ * @param props - Form group properties
1660
+ * @returns Class string
1661
+ */ return {
1662
+ defaultProps: defaultProps,
1663
+ generateFormGroupClass: props => {
1664
+ const {size: size = defaultProps.size, disabled: disabled = defaultProps.disabled, invalid: invalid = defaultProps.invalid, valid: valid = defaultProps.valid, className: className = ""} = props;
1665
+ return `${FORM_GROUP_CLASSES_BASE} ${"md" === size ? "" : "sm" === size ? FORM_GROUP_CLASSES_SMALL : FORM_GROUP_CLASSES_LARGE} ${invalid ? FORM_GROUP_CLASSES_INVALID : valid ? FORM_GROUP_CLASSES_VALID : ""} ${disabled ? FORM_GROUP_CLASSES_DISABLED : ""} ${className}`.trim();
1666
+ }
1667
+ };
1668
+ }({
1669
+ size: size,
1670
+ disabled: disabled,
1671
+ invalid: invalid,
1672
+ valid: valid
1673
+ }), formGroupClass = generateFormGroupClass({
1674
+ className: className,
1675
+ disabled: disabled,
1676
+ invalid: invalid,
1677
+ valid: valid,
1678
+ size: size
1679
+ });
1680
+ return jsxs("div", {
1681
+ className: formGroupClass,
1682
+ style: style,
1683
+ children: [ label && jsxs("label", {
1684
+ className: "c-form-group__label",
1685
+ htmlFor: htmlFor,
1686
+ children: [ label, required && jsx("span", {
1687
+ className: "c-form-group__required",
1688
+ children: "*"
1689
+ }) ]
1690
+ }), jsx("div", {
1691
+ className: "c-form-group__field",
1692
+ children: children
1693
+ }), helperText && jsx("div", {
1694
+ className: "c-form-group__helper",
1695
+ children: helperText
1696
+ }) ]
1697
+ });
1698
+ };
1699
+
1700
+ FormGroup.displayName = "FormGroup";
1701
+
1702
+ /**
1703
+ * Input - A component for text input fields
1704
+ */
1705
+ const Input = memo( forwardRef((({type: type = "text", value: value, onChange: onChange, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder, className: className = "", style: style, disabled: disabled = !1, required: required = !1, readOnly: readOnly = !1, id: id, name: name, autoComplete: autoComplete, autoFocus: autoFocus = !1, size: size = "md", variant: variant, invalid: invalid = !1, valid: valid = !1, maxLength: maxLength, minLength: minLength, pattern: pattern, min: min, max: max, step: step, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, glass: glass}, ref) => {
1706
+ const {generateInputClass: generateInputClass} =
1707
+ /**
1708
+ * Input state and functionality
1709
+ * @param initialProps - Initial input properties
1710
+ * @returns Input state and methods
1711
+ */
1712
+ function(initialProps) {
1713
+ // Default input properties
1714
+ const defaultProps = {
1715
+ size: "md",
1716
+ disabled: !1,
1717
+ invalid: !1,
1718
+ valid: !1,
1719
+ ...initialProps
1720
+ };
1721
+ /**
1722
+ * Generate input class based on properties
1723
+ * @param props - Input properties
1724
+ * @returns Class string
1725
+ */ return {
1726
+ defaultProps: defaultProps,
1727
+ generateInputClass: props => {
1728
+ const {size: size = defaultProps.size, variant: variant = defaultProps.variant, disabled: disabled = defaultProps.disabled, invalid: invalid = defaultProps.invalid, valid: valid = defaultProps.valid, className: className = "", type: type} = props;
1729
+ let validationClass = "";
1730
+ invalid ? validationClass = INPUT_CLASSES_INVALID : valid && (validationClass = INPUT_CLASSES_VALID);
1731
+ return `${INPUT_CLASSES_BASE} ${"md" === size ? "" : "sm" === size ? INPUT_CLASSES_SMALL : INPUT_CLASSES_LARGE} ${variant ? `c-input--${variant}` : ""} ${"textarea" === type ? "c-input--textarea" : ""} ${validationClass} ${disabled ? INPUT_CLASSES_DISABLED : ""} ${className}`.trim();
1732
+ },
1733
+ generateWrapperClass: props => {
1734
+ const {className: className = ""} = props, {prefixIcon: prefixIcon = !1, suffixIcon: suffixIcon = !1, clearable: clearable = !1, showCounter: showCounter = !1, showPasswordToggle: showPasswordToggle = !1, fullWidth: fullWidth = !1} = initialProps || {}, classes = [ INPUT_ELEMENTS_WRAPPER ];
1735
+ return prefixIcon && classes.push(INPUT_CLASSES_PREFIX_ICON), (suffixIcon || clearable || showPasswordToggle) && classes.push(INPUT_CLASSES_SUFFIX_ICON),
1736
+ clearable && classes.push(INPUT_CLASSES_CLEARABLE), showCounter && classes.push(INPUT_CLASSES_WITH_COUNTER),
1737
+ showPasswordToggle && classes.push(INPUT_CLASSES_PASSWORD_TOGGLE), fullWidth && classes.push(INPUT_CLASSES_FULL_WIDTH),
1738
+ className && classes.push(className), classes.filter(Boolean).join(" ");
1739
+ }
1740
+ };
1741
+ }({
1742
+ size: size,
1743
+ variant: variant,
1744
+ disabled: disabled,
1745
+ invalid: invalid,
1746
+ valid: valid
1747
+ }), inputClass = generateInputClass({
1748
+ className: `${className} ${glass ? "c-input--glass" : ""}`.trim(),
1749
+ size: size,
1750
+ variant: variant,
1751
+ disabled: disabled,
1752
+ invalid: invalid,
1753
+ valid: valid,
1754
+ type: type
1755
+ }), inputElement = jsx("input", {
1756
+ ref: ref,
1757
+ type: type,
1758
+ className: inputClass,
1759
+ value: value,
1760
+ onChange: onChange,
1761
+ onBlur: onBlur,
1762
+ onFocus: onFocus,
1763
+ placeholder: placeholder,
1764
+ disabled: disabled,
1765
+ required: required,
1766
+ readOnly: readOnly,
1767
+ id: id,
1768
+ name: name,
1769
+ autoComplete: autoComplete,
1770
+ autoFocus: autoFocus,
1771
+ maxLength: maxLength,
1772
+ minLength: minLength,
1773
+ pattern: pattern,
1774
+ min: min,
1775
+ max: max,
1776
+ step: step,
1777
+ "aria-label": ariaLabel,
1778
+ "aria-describedby": ariaDescribedBy,
1779
+ "aria-invalid": invalid,
1780
+ style: glass ? {
1781
+ ...style
1782
+ } : style
1783
+ });
1784
+ if (glass) {
1785
+ // Default glass settings for inputs
1786
+ const defaultGlassProps = {
1787
+ displacementScale: 60,
1788
+ blurAmount: 1,
1789
+ saturation: 180,
1790
+ aberrationIntensity: .2,
1791
+ cornerRadius: 12,
1792
+ mode: "shader"
1793
+ }, glassProps = !0 === glass ? defaultGlassProps : {
1794
+ ...defaultGlassProps,
1795
+ ...glass
1796
+ };
1797
+ return jsx(AtomixGlass, {
1798
+ ...glassProps,
1799
+ children: inputElement
1800
+ });
1801
+ }
1802
+ return inputElement;
1803
+ })));
1804
+
1805
+ Input.displayName = "Input";
1806
+
1807
+ /**
1808
+ * Radio - A component for radio button inputs
1809
+ */
1810
+ const Radio = memo((({label: label, checked: checked = !1, onChange: onChange, className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, value: value, invalid: invalid = !1, valid: valid = !1, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, glass: glass}) => {
1811
+ const {generateRadioClass: generateRadioClass} =
1812
+ /**
1813
+ * Radio state and functionality
1814
+ * @param initialProps - Initial radio properties
1815
+ * @returns Radio state and methods
1816
+ */
1817
+ function(initialProps) {
1818
+ // Default radio properties
1819
+ const defaultProps = {
1820
+ disabled: !1,
1821
+ invalid: !1,
1822
+ valid: !1,
1823
+ ...initialProps
1824
+ };
1825
+ /**
1826
+ * Generate radio class based on properties
1827
+ * @param props - Radio properties
1828
+ * @returns Class string
1829
+ */ return {
1830
+ defaultProps: defaultProps,
1831
+ generateRadioClass: props => {
1832
+ const {disabled: disabled = defaultProps.disabled, invalid: invalid = defaultProps.invalid, valid: valid = defaultProps.valid, className: className = ""} = props;
1833
+ let validationClass = "";
1834
+ invalid ? validationClass = RADIO_CLASSES_INVALID : valid && (validationClass = RADIO_CLASSES_VALID);
1835
+ return `${RADIO_CLASSES_BASE} ${validationClass} ${disabled ? RADIO_CLASSES_DISABLED : ""} ${className}`.trim();
1836
+ }
1837
+ };
1838
+ }({
1839
+ disabled: disabled,
1840
+ invalid: invalid,
1841
+ valid: valid
1842
+ }), radioClass = generateRadioClass({
1843
+ className: `${className} ${glass ? "c-radio--glass" : ""}`.trim(),
1844
+ disabled: disabled,
1845
+ invalid: invalid,
1846
+ valid: valid
1847
+ }), radioContent = jsxs("div", {
1848
+ className: radioClass,
1849
+ style: style,
1850
+ children: [ jsx("input", {
1851
+ type: "radio",
1852
+ className: "c-radio__input",
1853
+ checked: checked,
1854
+ onChange: onChange,
1855
+ disabled: disabled,
1856
+ required: required,
1857
+ id: id,
1858
+ name: name,
1859
+ value: value,
1860
+ "aria-label": label ? void 0 : ariaLabel,
1861
+ "aria-describedby": ariaDescribedBy,
1862
+ "aria-invalid": invalid
1863
+ }), label && jsx("label", {
1864
+ className: "c-radio__label",
1865
+ htmlFor: id,
1866
+ children: label
1867
+ }) ]
1868
+ });
1869
+ if (glass) {
1870
+ // Default glass settings for radio buttons
1871
+ const defaultGlassProps = {
1872
+ displacementScale: 40,
1873
+ blurAmount: 1,
1874
+ saturation: 160,
1875
+ aberrationIntensity: .3,
1876
+ cornerRadius: 6,
1877
+ mode: "shader"
1878
+ }, glassProps = !0 === glass ? defaultGlassProps : {
1879
+ ...defaultGlassProps,
1880
+ ...glass
1881
+ };
1882
+ return jsx(AtomixGlass, {
1883
+ ...glassProps,
1884
+ children: radioContent
1885
+ });
1886
+ }
1887
+ return radioContent;
1888
+ }));
1889
+
1890
+ Radio.displayName = "Radio";
1891
+
1892
+ /**
1893
+ * Select - A component for dropdown selection
1894
+ */
1895
+ const Select = memo((({options: options = [], value: value, onChange: onChange, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder = "Select an option", className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, size: size = "md", invalid: invalid = !1, valid: valid = !1, multiple: multiple = !1, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, glass: glass}) => {
1896
+ const {generateSelectClass: generateSelectClass} =
1897
+ /**
1898
+ * Select state and functionality
1899
+ * @param initialProps - Initial select properties
1900
+ * @returns Select state and methods
1901
+ */
1902
+ function(initialProps) {
1903
+ // Default select properties
1904
+ const defaultProps = {
1905
+ size: "md",
1906
+ disabled: !1,
1907
+ invalid: !1,
1908
+ valid: !1,
1909
+ ...initialProps
1910
+ };
1911
+ /**
1912
+ * Generate select class based on properties
1913
+ * @param props - Select properties
1914
+ * @returns Class string
1915
+ */ return {
1916
+ defaultProps: defaultProps,
1917
+ generateSelectClass: props => {
1918
+ const {size: size = defaultProps.size, disabled: disabled = defaultProps.disabled, invalid: invalid = defaultProps.invalid, valid: valid = defaultProps.valid, className: className = ""} = props;
1919
+ let validationClass = "";
1920
+ invalid ? validationClass = SELECT_CLASSES_INVALID : valid && (validationClass = SELECT_CLASSES_VALID);
1921
+ return `${SELECT_CLASSES_BASE} ${"md" === size ? "" : "sm" === size ? SELECT_CLASSES_SMALL : SELECT_CLASSES_LARGE} ${validationClass} ${disabled ? SELECT_CLASSES_DISABLED : ""} ${className}`.trim();
1922
+ }
1923
+ };
1924
+ }
1925
+ /**
1926
+ * Textarea state and functionality
1927
+ * @param initialProps - Initial textarea properties
1928
+ * @returns Textarea state and methods
1929
+ */ ({
1930
+ size: size,
1931
+ disabled: disabled,
1932
+ invalid: invalid,
1933
+ valid: valid
1934
+ }), selectClass = generateSelectClass({
1935
+ className: `${className} ${glass ? "c-select--glass" : ""}`.trim(),
1936
+ size: size,
1937
+ disabled: disabled,
1938
+ invalid: invalid,
1939
+ valid: valid
1940
+ }), [isOpen, setIsOpen] = useState(!1), [selectedLabel, setSelectedLabel] = useState(placeholder), dropdownRef = useRef(null), panelRef = useRef(null), bodyRef = useRef(null), nativeSelectRef = useRef(null);
1941
+ // Update selected label when value changes
1942
+ useEffect((() => {
1943
+ if (value) {
1944
+ const selectedOption = options.find((opt => opt.value === value));
1945
+ selectedOption && setSelectedLabel(selectedOption.label);
1946
+ } else setSelectedLabel(placeholder);
1947
+ }), [ value, options, placeholder ]),
1948
+ // Handle click outside to close dropdown
1949
+ useEffect((() => {
1950
+ const handleClickOutside = event => {
1951
+ dropdownRef.current && !dropdownRef.current.contains(event.target) && (setIsOpen(!1),
1952
+ bodyRef.current && (bodyRef.current.style.height = "0px"));
1953
+ };
1954
+ return document.addEventListener("mousedown", handleClickOutside), () => {
1955
+ document.removeEventListener("mousedown", handleClickOutside);
1956
+ };
1957
+ }), []);
1958
+ // Toggle dropdown
1959
+ const selectContent = jsxs("div", {
1960
+ className: `${selectClass} ${isOpen ? SELECT_CLASSES_IS_OPEN : ""}`,
1961
+ ref: dropdownRef,
1962
+ style: style,
1963
+ "aria-expanded": isOpen,
1964
+ children: [ jsxs("select", {
1965
+ ref: nativeSelectRef,
1966
+ value: value,
1967
+ onChange: onChange,
1968
+ onBlur: onBlur,
1969
+ onFocus: onFocus,
1970
+ disabled: disabled,
1971
+ required: required,
1972
+ id: id,
1973
+ name: name,
1974
+ multiple: multiple,
1975
+ "aria-label": ariaLabel,
1976
+ "aria-describedby": ariaDescribedBy,
1977
+ "aria-invalid": invalid,
1978
+ style: {
1979
+ display: "none"
1980
+ },
1981
+ children: [ placeholder && jsx("option", {
1982
+ value: "",
1983
+ disabled: !0,
1984
+ children: placeholder
1985
+ }), options.map((option => jsx("option", {
1986
+ value: option.value,
1987
+ disabled: option.disabled,
1988
+ children: option.label
1989
+ }, option.value))) ]
1990
+ }), jsx("div", {
1991
+ className: SELECT_CLASSES_SELECTED,
1992
+ onClick: () => {
1993
+ disabled || (!isOpen && bodyRef.current && panelRef.current ? bodyRef.current.style.height = `${panelRef.current.clientHeight}px` : bodyRef.current && (bodyRef.current.style.height = "0px"),
1994
+ setIsOpen(!isOpen));
1995
+ },
1996
+ "aria-disabled": disabled,
1997
+ children: selectedLabel
1998
+ }), jsx("i", {
1999
+ className: `${SELECT_CLASSES_ICON_CARET} ${SELECT_CLASSES_TOGGLE_ICON}`
2000
+ }), jsx("div", {
2001
+ className: SELECT_CLASSES_SELECT_BODY,
2002
+ ref: bodyRef,
2003
+ style: {
2004
+ height: 0
2005
+ },
2006
+ children: jsx("div", {
2007
+ className: SELECT_CLASSES_SELECT_PANEL,
2008
+ ref: panelRef,
2009
+ children: jsx("ul", {
2010
+ className: SELECT_CLASSES_SELECT_ITEMS,
2011
+ children: options.map(((option, index) => jsx("li", {
2012
+ className: SELECT_CLASSES_SELECT_ITEM,
2013
+ "data-value": option.value,
2014
+ onClick: () => !option.disabled && (option => {
2015
+ if (setSelectedLabel(option.label), setIsOpen(!1), bodyRef.current && (bodyRef.current.style.height = "0px"),
2016
+ nativeSelectRef.current && (nativeSelectRef.current.value = option.value), onChange) {
2017
+ // Create a synthetic event
2018
+ const event = {
2019
+ target: {
2020
+ name: name,
2021
+ value: option.value
2022
+ }
2023
+ };
2024
+ onChange(event);
2025
+ }
2026
+ })(option),
2027
+ children: jsxs("label", {
2028
+ htmlFor: `SelectItem${index}`,
2029
+ className: "c-checkbox",
2030
+ children: [ jsx("input", {
2031
+ type: "checkbox",
2032
+ id: `SelectItem${index}`,
2033
+ className: "c-checkbox__input c-select__item-input",
2034
+ checked: value === option.value,
2035
+ readOnly: !0,
2036
+ disabled: option.disabled
2037
+ }), jsx("div", {
2038
+ className: "c-select__item-label",
2039
+ children: option.label
2040
+ }) ]
2041
+ })
2042
+ }, option.value)))
2043
+ })
2044
+ })
2045
+ }) ]
2046
+ });
2047
+ // Handle item selection
2048
+ if (glass) {
2049
+ // Default glass settings for select components
2050
+ const defaultGlassProps = {
2051
+ displacementScale: 60,
2052
+ blurAmount: 1,
2053
+ saturation: 180,
2054
+ aberrationIntensity: .2,
2055
+ cornerRadius: 12,
2056
+ mode: "shader"
2057
+ }, glassProps = !0 === glass ? defaultGlassProps : {
2058
+ ...defaultGlassProps,
2059
+ ...glass
2060
+ };
2061
+ return jsx(AtomixGlass, {
2062
+ ...glassProps,
2063
+ children: selectContent
2064
+ });
2065
+ }
2066
+ return selectContent;
2067
+ }));
2068
+
2069
+ Select.displayName = "Select";
2070
+
2071
+ /**
2072
+ * Textarea - A component for multiline text input
2073
+ */
2074
+ const Textarea = memo( forwardRef((({value: value, onChange: onChange, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder, className: className = "", style: style, disabled: disabled = !1, required: required = !1, readOnly: readOnly = !1, id: id, name: name, rows: rows = 4, cols: cols, maxLength: maxLength, minLength: minLength, size: size = "md", variant: variant, invalid: invalid = !1, valid: valid = !1, autoFocus: autoFocus = !1, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, glass: glass}, ref) => {
2075
+ const {generateTextareaClass: generateTextareaClass} = function(initialProps) {
2076
+ // Default textarea properties
2077
+ const defaultProps = {
2078
+ size: "md",
2079
+ disabled: !1,
2080
+ invalid: !1,
2081
+ valid: !1,
2082
+ ...initialProps
2083
+ };
2084
+ /**
2085
+ * Generate textarea class based on properties
2086
+ * @param props - Textarea properties
2087
+ * @returns Class string
2088
+ */ return {
2089
+ defaultProps: defaultProps,
2090
+ generateTextareaClass: props => {
2091
+ const {size: size = defaultProps.size, variant: variant = defaultProps.variant, disabled: disabled = defaultProps.disabled, invalid: invalid = defaultProps.invalid, valid: valid = defaultProps.valid, className: className = ""} = props;
2092
+ let validationClass = "";
2093
+ invalid ? validationClass = TEXTAREA_CLASSES_INVALID : valid && (validationClass = TEXTAREA_CLASSES_VALID);
2094
+ return `${TEXTAREA_CLASSES_BASE} ${"md" === size ? "" : "sm" === size ? TEXTAREA_CLASSES_SMALL : TEXTAREA_CLASSES_LARGE} ${variant ? `c-input--${variant}` : ""} ${validationClass} ${disabled ? TEXTAREA_CLASSES_DISABLED : ""} ${className}`.trim();
2095
+ }
2096
+ };
2097
+ }({
2098
+ size: size,
2099
+ variant: variant,
2100
+ disabled: disabled,
2101
+ invalid: invalid,
2102
+ valid: valid
2103
+ }), textareaClass = generateTextareaClass({
2104
+ className: `${className} ${glass ? "c-input--glass" : ""}`.trim(),
2105
+ size: size,
2106
+ variant: variant,
2107
+ disabled: disabled,
2108
+ invalid: invalid,
2109
+ valid: valid
2110
+ }), textareaElement = jsx("textarea", {
2111
+ ref: ref,
2112
+ className: textareaClass,
2113
+ value: value,
2114
+ onChange: onChange,
2115
+ onBlur: onBlur,
2116
+ onFocus: onFocus,
2117
+ placeholder: placeholder,
2118
+ disabled: disabled,
2119
+ required: required,
2120
+ readOnly: readOnly,
2121
+ id: id,
2122
+ name: name,
2123
+ rows: rows,
2124
+ cols: cols,
2125
+ maxLength: maxLength,
2126
+ minLength: minLength,
2127
+ autoFocus: autoFocus,
2128
+ "aria-label": ariaLabel,
2129
+ "aria-describedby": ariaDescribedBy,
2130
+ "aria-invalid": invalid,
2131
+ style: glass ? {
2132
+ ...style
2133
+ } : style
2134
+ });
2135
+ if (glass) {
2136
+ // Default glass settings for textareas
2137
+ const defaultGlassProps = {
2138
+ displacementScale: 60,
2139
+ blurAmount: 1,
2140
+ saturation: 180,
2141
+ aberrationIntensity: 1,
2142
+ cornerRadius: 8,
2143
+ mode: "shader"
2144
+ }, glassProps = !0 === glass ? defaultGlassProps : {
2145
+ ...defaultGlassProps,
2146
+ ...glass
2147
+ };
2148
+ return jsx(AtomixGlass, {
2149
+ ...glassProps,
2150
+ children: textareaElement
2151
+ });
2152
+ }
2153
+ return textareaElement;
2154
+ })));
2155
+
2156
+ Textarea.displayName = "Textarea";
2157
+
2158
+ // Adapted from https://github.com/shuding/liquid-glass
2159
+ // Constants
2160
+ const smoothStep = (a, b, t) => {
2161
+ // Add input validation
2162
+ if ("number" != typeof a || "number" != typeof b || "number" != typeof t) return 0;
2163
+ const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
2164
+ return clamped * clamped * (3 - 2 * clamped);
2165
+ }, calculateLength = (x, y) => {
2166
+ // Add input validation and error handling
2167
+ if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
2168
+ // Prevent potential overflow
2169
+ const maxX = Math.max(Math.abs(x), Math.abs(y));
2170
+ if (0 === maxX) return 0;
2171
+ const scaledX = x / maxX, scaledY = y / maxX;
2172
+ return maxX * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
2173
+ }, roundedRectSDF = (x, y, width, height, radius) => {
2174
+ // Add input validation
2175
+ if ("number" != typeof x || "number" != typeof y || "number" != typeof width || "number" != typeof height || "number" != typeof radius) return 0;
2176
+ const qx = Math.abs(x) - width + radius, qy = Math.abs(y) - height + radius;
2177
+ return Math.min(Math.max(qx, qy), 0) + calculateLength(Math.max(qx, 0), Math.max(qy, 0)) - radius;
2178
+ }, createTexture = (x, y) => ({
2179
+ x: "number" != typeof x || isNaN(x) ? .5 : Math.max(0, Math.min(1, x)),
2180
+ y: "number" != typeof y || isNaN(y) ? .5 : Math.max(0, Math.min(1, y))
2181
+ }), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y), clampValue = (value, min, max) =>
2182
+ // Add input validation
2183
+ "number" != typeof value || "number" != typeof min || "number" != typeof max || isNaN(value) ? min : isNaN(min) ? 0 : isNaN(max) ? 1 : Math.max(min, Math.min(max, value)), easeInOutCubic = t => {
2184
+ // Add input validation
2185
+ if ("number" != typeof t || isNaN(t)) return 0;
2186
+ const clampedT = Math.max(0, Math.min(1, t));
2187
+ return clampedT < .5 ? 4 * clampedT * clampedT * clampedT : 1 - Math.pow(-2 * clampedT + 2, 3) / 2;
2188
+ }, easeOutQuart = t => {
2189
+ // Add input validation
2190
+ if ("number" != typeof t || isNaN(t)) return 0;
2191
+ const clampedT = Math.max(0, Math.min(1, t));
2192
+ return 1 - Math.pow(1 - clampedT, 4);
2193
+ }, noise2D = (x, y) => {
2194
+ // Add input validation
2195
+ if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
2196
+ const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = easeInOutCubic(xf), v = easeInOutCubic(yf), hash = (i, j) => {
2197
+ // Add input validation
2198
+ if ("number" != typeof i || "number" != typeof j) return 0;
2199
+ const n = i + 57 * j, hashed = 43758.5453 * Math.sin(12.9898 * n + 78.233);
2200
+ // Use a more stable hash function
2201
+ return hashed - Math.floor(hashed);
2202
+ }, a = hash(X, Y), b = hash(X + 1, Y), c = hash(X, Y + 1), x1 = a + u * (b - a);
2203
+ return x1 + v * (c + u * (hash(X + 1, Y + 1) - c) - x1);
2204
+ }, fbm = (x, y, octaves = 4) => {
2205
+ // Add input validation
2206
+ if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
2207
+ // Clamp octaves to prevent performance issues
2208
+ const clampedOctaves = Math.max(1, Math.min(8, Math.floor(octaves)));
2209
+ let value = 0, amplitude = .5, frequency = 1;
2210
+ for (let i = 0; i < clampedOctaves; i++) value += amplitude * noise2D(x * frequency, y * frequency),
2211
+ frequency *= 2, amplitude *= .5;
2212
+ return value;
2213
+ }, calculateParallaxOffset = (x, y, depth, mouseX = 0, mouseY = 0) => {
2214
+ // Add input validation
2215
+ if ("number" != typeof x || "number" != typeof y || "number" != typeof depth || "number" != typeof mouseX || "number" != typeof mouseY || isNaN(x) || isNaN(y) || isNaN(depth) || isNaN(mouseX) || isNaN(mouseY)) return {
2216
+ x: 0,
2217
+ y: 0
2218
+ };
2219
+ const parallaxStrength = Math.min(.02 * depth, .1);
2220
+ // Limit strength to prevent extreme values
2221
+ // Calculate offset based on view angle (simulated by mouse position)
2222
+ return {
2223
+ x: (x - mouseX) * parallaxStrength,
2224
+ y: (y - mouseY) * parallaxStrength
2225
+ };
2226
+ }, fragmentShaders = {
2227
+ liquidGlass: (uv, mousePosition) => {
2228
+ if (!validateVec2(uv)) return {
2229
+ x: .5,
2230
+ y: .5
2231
+ };
2232
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(2 * mouseDistance, 1)), organicFlow = fbm(12 * (ix + .5 * mouseX) + time, 12 * (iy + .5 * mouseY) + .7 * time, 3) - .5, distanceToEdge = roundedRectSDF(ix, iy, .4, .3, .35), baseDisplacement = smoothStep(.8, 0, distanceToEdge - .05), radialDist = ((x, y, strength) => {
2233
+ // Add input validation
2234
+ if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y) || isNaN(strength)) return {
2235
+ x: 0,
2236
+ y: 0
2237
+ };
2238
+ const distance = calculateLength(x, y), distortion = Math.pow(Math.min(distance, 10), 2) * strength;
2239
+ // Limit distance to prevent extreme values
2240
+ return {
2241
+ x: x * (1 + distortion),
2242
+ y: y * (1 + distortion)
2243
+ };
2244
+ })(ix, iy, .4 * .1), refractionX = 1.2 * (radialDist.x - ix) * baseDisplacement, refractionY = 1.2 * (radialDist.y - iy) * baseDisplacement, flowX = .018 * Math.sin(8 * (ix + 2 * mouseX) + 2 * time), flowY = .018 * Math.cos(8 * (iy + 2 * mouseY) + 1.5 * time), rippleEffect = (.015 * Math.sin(12 * (ix - mouseX) + 12 * (iy - mouseY) + 3 * time) + .012 * Math.cos(10 * (ix + mouseX) - 10 * (iy - mouseY) - 2 * time)) * mouseFalloff * mouseDistance, depthEffect = (Math.sin(15 * ix + time) * Math.cos(15 * iy - time) * .008 + Math.sin(20 * ix - .5 * time) * Math.cos(20 * iy + .5 * time) * .006) * baseDisplacement, liquidFlow = .85 * (flowX + flowY + .025 * organicFlow), totalDistortionX = refractionX + liquidFlow + rippleEffect + depthEffect, totalDistortionY = refractionY + .8 * liquidFlow + .9 * rippleEffect + depthEffect, chromaticOffset = ((x, y, intensity) => {
2245
+ // Add input validation
2246
+ if ("number" != typeof x || "number" != typeof y || "number" != typeof intensity || isNaN(x) || isNaN(y) || isNaN(intensity)) return {
2247
+ x: 0,
2248
+ y: 0
2249
+ };
2250
+ const distance = calculateLength(x, y);
2251
+ // Prevent division by zero and extreme values
2252
+ if (0 === distance) return {
2253
+ x: 0,
2254
+ y: 0
2255
+ };
2256
+ const angle = Math.atan2(y, x);
2257
+ return {
2258
+ x: Math.cos(angle) * distance * intensity,
2259
+ y: Math.sin(angle) * distance * intensity
2260
+ };
2261
+ })(ix, iy, .015 * baseDisplacement), scaled = smoothStep(0, 1, 1.15 * baseDisplacement), finalX = ix + totalDistortionX + .5 * chromaticOffset.x, finalY = iy + totalDistortionY + .5 * chromaticOffset.y;
2262
+ return createTexture(clampValue(finalX * scaled + .5, 0, 1), clampValue(finalY * scaled + .5, 0, 1));
2263
+ },
2264
+ // Premium Apple-style fluid glass with enhanced organic flow
2265
+ appleFluid: (uv, mousePosition) => {
2266
+ if (!validateVec2(uv)) return {
2267
+ x: .5,
2268
+ y: .5
2269
+ };
2270
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.5 * mouseDistance, 1)), organicX = fbm(10 * (ix + .3 * mouseX) + time, 10 * (iy + .3 * mouseY), 5) - .5, organicY = fbm(10 * (ix - .3 * mouseX), 10 * (iy - .3 * mouseY) + .8 * time, 5) - .5, distanceToEdge = roundedRectSDF(ix, iy, .42, .32, .38), mask = smoothStep(.85, -.1, distanceToEdge), fluidVelocityX = Math.sin(6 * ix + 2 * time) * Math.cos(4 * iy - time) * .025, fluidVelocityY = Math.cos(4 * ix - time) * Math.sin(6 * iy + 2 * time) * .025, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexStrength = mouseFalloff * mouseDistance * .08, vortexX = Math.cos(vortexAngle + time) * vortexStrength, totalY = iy + (.035 * organicY + fluidVelocityY + Math.sin(vortexAngle + time) * vortexStrength) * mask;
2271
+ return createTexture(clampValue(ix + (.035 * organicX + fluidVelocityX + vortexX) * mask + .5, 0, 1), clampValue(totalY + .5, 0, 1));
2272
+ },
2273
+ // High-end glass with advanced refraction and depth
2274
+ premiumGlass: (uv, mousePosition) => {
2275
+ if (!validateVec2(uv)) return {
2276
+ x: .5,
2277
+ y: .5
2278
+ };
2279
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), centerDistance = calculateLength(ix, iy), refractionStrength = .3 * Math.pow(Math.min(centerDistance, 1), 1.5), refractionAngle = Math.atan2(iy, ix);
2280
+ // Multi-layer depth effect
2281
+ let depthX = 0, depthY = 0;
2282
+ for (let layer = 0; layer < 3; layer++) {
2283
+ const layerScale = 5 * (layer + 1), layerTime = time * (1 + .3 * layer), layerStrength = .01 / (layer + 1);
2284
+ depthX += Math.sin(ix * layerScale + layerTime) * layerStrength, depthY += Math.cos(iy * layerScale - layerTime) * layerStrength;
2285
+ }
2286
+ // Glass refraction with mouse influence
2287
+ const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask = smoothStep(.9, -.05, distanceToEdge), finalY = iy + (refractionY + depthY + .015 * organicNoise) * edgeMask;
2288
+ return createTexture(clampValue(ix + (refractionX + depthX + .015 * organicNoise) * edgeMask + .5, 0, 1), clampValue(finalY + .5, 0, 1));
2289
+ },
2290
+ // Metallic liquid effect with shimmer
2291
+ liquidMetal: (uv, mousePosition) => {
2292
+ if (!validateVec2(uv)) return {
2293
+ x: .5,
2294
+ y: .5
2295
+ };
2296
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance = calculateLength(ix - mouseX, iy - mouseY), flowEffect = .02 * Math.sin(15 * flowDistance - 6 * time) * easeOutQuart(1 - Math.min(2 * flowDistance, 1)), distanceToEdge = roundedRectSDF(ix, iy, .41, .31, .37), mask = smoothStep(.88, -.08, distanceToEdge), totalX = ix + (wave1 + shimmer + Math.cos(flowAngle) * flowEffect) * mask, totalY = iy + (wave2 + .8 * shimmer + Math.sin(flowAngle) * flowEffect) * mask;
2297
+ return createTexture(clampValue(totalX + .5, 0, 1), clampValue(totalY + .5, 0, 1));
2298
+ },
2299
+ // basiBasi - Expert Premium Glass Shader
2300
+ // The most advanced shader with caustics, spectral dispersion, parallax depth, and volumetric effects
2301
+ basiBasi: (uv, mousePosition) => {
2302
+ if (!validateVec2(uv)) return {
2303
+ x: .5,
2304
+ y: .5
2305
+ };
2306
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.2 * mouseDistance, 1)), causticIntensity = ((x, y, time, intensity = 1) =>
2307
+ // Add input validation
2308
+ "number" != typeof x || "number" != typeof y || "number" != typeof time || "number" != typeof intensity || isNaN(x) || isNaN(y) || isNaN(time) || isNaN(intensity) ? .5 : .5 * (Math.sin(8 * x + 2 * time) * Math.cos(8 * y - 2 * time) * .5 + Math.sin(8 * (x + .5) * 1.3 - 2 * time * .8) * Math.cos(8 * (y - .3) * 1.3 + 2 * time * .8) * .3 + Math.sin(8 * (x - .3) * .7 + 2 * time * 1.2) * Math.cos(8 * (y + .4) * .7 - 2 * time * 1.2) * .2 + 1) * intensity)(ix, iy, time, .8), causticDistortion = .02 * (causticIntensity - .5), refractionAngle = Math.atan2(iy, ix), spectralDispersion = ((x, y, angle) => {
2309
+ // Add input validation
2310
+ if ("number" != typeof x || "number" != typeof y || "number" != typeof angle || isNaN(x) || isNaN(y) || isNaN(angle) || isNaN(.025)) return {
2311
+ r: {
2312
+ x: 0,
2313
+ y: 0
2314
+ },
2315
+ g: {
2316
+ x: 0,
2317
+ y: 0
2318
+ },
2319
+ b: {
2320
+ x: 0,
2321
+ y: 0
2322
+ }
2323
+ };
2324
+ const distance = calculateLength(x, y), dispersionStrength = Math.min(.025 * distance, 1), redOffset = .8 * dispersionStrength, greenOffset = 1 * dispersionStrength, blueOffset = 1.2 * dispersionStrength;
2325
+ return {
2326
+ r: {
2327
+ x: Math.cos(angle) * redOffset,
2328
+ y: Math.sin(angle) * redOffset
2329
+ },
2330
+ g: {
2331
+ x: Math.cos(angle) * greenOffset,
2332
+ y: Math.sin(angle) * greenOffset
2333
+ },
2334
+ b: {
2335
+ x: Math.cos(angle) * blueOffset,
2336
+ y: Math.sin(angle) * blueOffset
2337
+ }
2338
+ };
2339
+ })(ix, iy, refractionAngle), spectralX = (spectralDispersion.r.x + spectralDispersion.g.x + spectralDispersion.b.x) / 3, spectralY = (spectralDispersion.r.y + spectralDispersion.g.y + spectralDispersion.b.y) / 3;
2340
+ // === MULTI-LAYER PARALLAX DEPTH ===
2341
+ // Create depth perception with 7 layers
2342
+ let parallaxX = 0, parallaxY = 0;
2343
+ for (let layer = 0; layer < 7; layer++) {
2344
+ const parallaxOffset = calculateParallaxOffset(ix, iy, (layer + 1) / 7, mouseX, mouseY), layerNoise = fbm((ix + parallaxOffset.x) * (8 + 2 * layer) + time * (.5 + .1 * layer), (iy + parallaxOffset.y) * (8 + 2 * layer) - time * (.5 + .1 * layer), 3) - .5, layerWeight = 1 / (layer + 1);
2345
+ parallaxX += (parallaxOffset.x + .01 * layerNoise) * layerWeight, parallaxY += (parallaxOffset.y + .01 * layerNoise) * layerWeight;
2346
+ }
2347
+ // Normalize parallax effect
2348
+ parallaxX /= 7, parallaxY /= 7;
2349
+ // === VOLUMETRIC SCATTERING ===
2350
+ // Simulate light scattering through glass volume
2351
+ const volumetricDensity = ((x, y, depth, time) =>
2352
+ // Add input validation
2353
+ "number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(.5) || isNaN(time) ? .5 : fbm(5 * x + .5 * time, 5 * y - .5 * time, 3) * Math.exp(2 * -Math.max(0, .5)) * .5 + .5)(ix, iy, 0, time), scatteringX = Math.cos(refractionAngle) * volumetricDensity * .015, scatteringY = Math.sin(refractionAngle) * volumetricDensity * .015, turbulence = ((x, y, time, octaves = 5) => {
2354
+ // Add input validation
2355
+ if ("number" != typeof x || "number" != typeof y || "number" != typeof time || "number" != typeof octaves || isNaN(x) || isNaN(y) || isNaN(time) || isNaN(octaves)) return 0;
2356
+ // Clamp octaves to prevent performance issues
2357
+ const clampedOctaves = Math.max(1, Math.min(8, Math.floor(octaves)));
2358
+ let turbulence = 0, amplitude = 1, frequency = 1;
2359
+ for (let i = 0; i < clampedOctaves; i++) turbulence += Math.abs(noise2D(x * frequency + time, y * frequency - time)) * amplitude,
2360
+ frequency *= 2, amplitude *= .5;
2361
+ return turbulence;
2362
+ })(6 * ix, 6 * iy, time, 6), turbulenceX = .012 * Math.cos(turbulence * Math.PI * 2), turbulenceY = .012 * Math.sin(turbulence * Math.PI * 2), microSurface = ((x, y, time) =>
2363
+ // Add input validation
2364
+ "number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance = calculateLength(ix, iy), dynamicRefraction = .35 * Math.pow(Math.min(centerDistance, 1), 1.8) * (1 + mouseFalloff * mouseDistance * .8), refractionX = Math.cos(refractionAngle) * dynamicRefraction, refractionY = Math.sin(refractionAngle) * dynamicRefraction, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexDistance = calculateLength(ix - mouseX, iy - mouseY), vortexStrength = mouseFalloff * Math.sin(10 * vortexDistance - 3 * time) * .025, vortexX = Math.cos(vortexAngle + 2 * time) * vortexStrength, vortexY = Math.sin(vortexAngle + 2 * time) * vortexStrength, fluidX = Math.sin(10 * ix + 5 * mouseX + 2.5 * time) * Math.cos(8 * iy - 2 * time) * .018, fluidY = Math.cos(8 * ix - 2 * time) * Math.sin(10 * iy + 5 * mouseY + 2.5 * time) * .018, rippleEffect = (.012 * Math.sin(15 * Math.min(centerDistance, 10) - 4 * time) + .008 * Math.cos(20 * Math.min(centerDistance, 10) + 3 * time)) * mouseFalloff, rippleX = Math.cos(refractionAngle) * rippleEffect, rippleY = Math.sin(refractionAngle) * rippleEffect, distanceToEdge = roundedRectSDF(ix, iy, .44, .34, .39), edgeMask = smoothStep(.92, -.12, distanceToEdge), edgeSoftness = smoothStep(.85, .1, distanceToEdge), finalY = iy + (1.2 * refractionY + .8 * spectralY + 1.5 * parallaxY + .9 * scatteringY + 1 * turbulenceY + .6 * microDetailY + 1.3 * vortexY + 1.1 * fluidY + .7 * rippleY + .8 * causticDistortion) * edgeMask * edgeSoftness * .85;
2365
+ return createTexture(clampValue(ix + (1.2 * refractionX + .8 * spectralX + 1.5 * parallaxX + .9 * scatteringX + 1 * turbulenceX + .6 * microDetailX + 1.3 * vortexX + 1.1 * fluidX + .7 * rippleX + causticDistortion) * edgeMask * edgeSoftness * .85 + .5, 0, 1), clampValue(finalY + .5, 0, 1));
2366
+ }
2367
+ }, shaderUtils = Object.freeze( Object.defineProperty({
2368
+ __proto__: null,
2369
+ ShaderDisplacementGenerator: class {
2370
+ constructor(options) {
2371
+ if (this.options = options, this.canvasDPI = 1, !this.validateOptions(options)) throw new Error("Invalid shader options provided");
2372
+ this.canvas = document.createElement("canvas"),
2373
+ // Enhanced validation for canvas dimensions
2374
+ this.canvas.width = Math.max(1, Math.min(4096, Math.round(options.width * this.canvasDPI || 256))),
2375
+ this.canvas.height = Math.max(1, Math.min(4096, Math.round(options.height * this.canvasDPI || 256))),
2376
+ this.canvas.style.display = "none";
2377
+ const context = this.canvas.getContext("2d");
2378
+ if (!context) throw new Error("AtomixGlass: Could not get 2D canvas context");
2379
+ this.context = context;
2380
+ }
2381
+ validateOptions(options) {
2382
+ try {
2383
+ return options && "number" == typeof options.width && options.width > 0 && options.width <= 4096 && "number" == typeof options.height && options.height > 0 && options.height <= 4096 && "function" == typeof options.fragment;
2384
+ } catch (e) {
2385
+ // Graceful error handling
2386
+ return !1;
2387
+ }
2388
+ }
2389
+ updateShader(mousePosition) {
2390
+ try {
2391
+ const w = this.options.width * this.canvasDPI, h = this.options.height * this.canvasDPI;
2392
+ let maxScale = 0;
2393
+ const rawValues = [];
2394
+ // Calculate displacement values with enhanced smoothing
2395
+ for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
2396
+ const uv = {
2397
+ x: x / w,
2398
+ y: y / h
2399
+ }, pos = this.options.fragment(uv, mousePosition);
2400
+ let dx = pos.x * w - x, dy = pos.y * h - y;
2401
+ // Apply edge smoothing for Apple-like effect
2402
+ const edgeX = 2 * Math.min(x / w, (w - x) / w), edgeY = 2 * Math.min(y / h, (h - y) / h), edgeFactor = Math.min(edgeX, edgeY);
2403
+ dx *= smoothStep(0, .2, edgeFactor), dy *= smoothStep(0, .2, edgeFactor), maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)),
2404
+ rawValues.push(dx, dy);
2405
+ }
2406
+ // Improved normalization to prevent artifacts while maintaining intensity
2407
+ maxScale = Math.max(maxScale, 1);
2408
+ // Create ImageData and fill it
2409
+ const imageData = this.context.createImageData(w, h), data = imageData.data;
2410
+ // Convert to image data with smoother normalization
2411
+ let rawIndex = 0;
2412
+ for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
2413
+ const dx = rawValues[rawIndex++] || 0, dy = rawValues[rawIndex++] || 0, edgeDistance = Math.min(x, y, w - x - 1, h - y - 1), edgeFactor = Math.min(1, edgeDistance / 2), r = dx * edgeFactor / maxScale + .5, g = dy * edgeFactor / maxScale + .5, pixelIndex = 4 * (y * w + x);
2414
+ data[pixelIndex] = clampValue(255 * r, 0, 255), // Red channel (X displacement)
2415
+ data[pixelIndex + 1] = clampValue(255 * g, 0, 255), // Green channel (Y displacement)
2416
+ data[pixelIndex + 2] = clampValue(255 * g, 0, 255), // Blue channel (Y displacement for SVG filter compatibility)
2417
+ data[pixelIndex + 3] = 255;
2418
+ }
2419
+ return this.context.putImageData(imageData, 0, 0), this.canvas.toDataURL();
2420
+ } catch (error) {
2421
+ // Graceful fallback on error
2422
+ return console.warn("ShaderDisplacementGenerator: Error generating shader map, using fallback", error),
2423
+ "";
2424
+ // Return empty string as fallback
2425
+ }
2426
+ }
2427
+ destroy() {
2428
+ try {
2429
+ // Clear canvas data to free memory
2430
+ this.context && this.context.clearRect(0, 0, this.canvas.width, this.canvas.height),
2431
+ // Reduce memory footprint by setting dimensions to 0
2432
+ this.canvas.width = 0, this.canvas.height = 0,
2433
+ // Remove from DOM
2434
+ this.canvas.remove();
2435
+ } catch (e) {
2436
+ // Silently handle cleanup errors
2437
+ console.warn("ShaderDisplacementGenerator: Error during cleanup", e);
2438
+ }
2439
+ }
2440
+ getScale() {
2441
+ return this.canvasDPI;
2442
+ }
2443
+ },
2444
+ fragmentShaders: fragmentShaders
2445
+ }, Symbol.toStringTag, {
2446
+ value: "Module"
2447
+ }));
2448
+
2449
+ export { Checkbox, Form, FormGroup, Input, Radio, Select, Textarea };
2450
+ //# sourceMappingURL=forms.js.map