@shohojdhara/atomix 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +510 -106
- package/dist/atomix.css +30 -24
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +6 -6
- package/dist/atomix.min.css.map +1 -1
- package/dist/atomix.umd.js +1 -1
- package/dist/atomix.umd.js.map +1 -1
- package/dist/atomix.umd.min.js +1 -1
- package/dist/charts.d.ts +11 -2
- package/dist/charts.js +294 -139
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +14 -39
- package/dist/core.js +297 -145
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +11 -1
- package/dist/forms.js +385 -185
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +9 -0
- package/dist/heavy.js +297 -143
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +156 -164
- package/dist/index.esm.js +391 -203
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +391 -203
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +14 -6
- package/dist/theme.js +2 -9
- package/dist/theme.js.map +1 -1
- package/package.json +26 -26
- package/src/components/AtomixGlass/AtomixGlass.tsx +1 -1
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +8 -1
- package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +390 -0
- package/src/components/AtomixGlass/glass-utils.ts +29 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +32 -1
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Button/Button.tsx +6 -5
- package/src/components/Card/Card.tsx +2 -2
- package/src/components/Dropdown/Dropdown.tsx +1 -0
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Form/Select.test.tsx +75 -0
- package/src/components/Form/Select.tsx +348 -252
- package/src/components/Form/SelectOption.tsx +16 -10
- package/src/components/index.ts +1 -1
- package/src/layouts/CssGrid/index.ts +1 -0
- package/src/lib/composables/shared-mouse-tracker.ts +62 -6
- package/src/lib/composables/useAtomixGlass.ts +241 -139
- package/src/lib/composables/useAtomixGlassStyles.ts +201 -149
- package/src/lib/constants/components.ts +54 -35
- package/src/lib/theme/config/configLoader.ts +1 -1
- package/src/lib/theme/test/testTheme.ts +2 -2
- package/src/lib/theme/utils/themeUtils.ts +98 -110
- package/src/lib/types/components.ts +29 -65
- package/src/styles/01-settings/_settings.spacing.scss +6 -1
- package/src/styles/03-generic/_generic.reset.scss +1 -1
- package/src/styles/06-components/_components.atomix-glass.scss +20 -29
- package/src/styles/06-components/_components.data-table.scss +5 -4
- package/src/styles/06-components/_components.dynamic-background.scss +9 -8
- package/src/styles/06-components/_components.footer.scss +8 -7
- package/src/styles/06-components/_components.hero.scss +2 -2
- package/src/styles/06-components/_components.messages.scss +16 -16
- package/src/styles/06-components/_components.navbar.scss +2 -0
- package/src/styles/06-components/_components.select.scss +15 -2
- package/src/styles/06-components/_components.upload.scss +3 -3
- package/CHANGELOG.md +0 -165
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +0 -215
package/dist/index.js
CHANGED
|
@@ -1750,12 +1750,23 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
|
|
|
1750
1750
|
},
|
|
1751
1751
|
DEFAULTS: {
|
|
1752
1752
|
DISPLACEMENT_SCALE: 70,
|
|
1753
|
-
BLUR_AMOUNT
|
|
1754
|
-
|
|
1755
|
-
|
|
1753
|
+
get BLUR_AMOUNT() {
|
|
1754
|
+
return .15 * this.DISPLACEMENT_SCALE;
|
|
1755
|
+
// Dynamically computed based on displacement
|
|
1756
|
+
},
|
|
1757
|
+
get SATURATION() {
|
|
1758
|
+
return 100 + .5 * this.DISPLACEMENT_SCALE;
|
|
1759
|
+
// Saturate relative to intensity
|
|
1760
|
+
},
|
|
1761
|
+
get ABERRATION_INTENSITY() {
|
|
1762
|
+
return .03 * this.DISPLACEMENT_SCALE;
|
|
1763
|
+
// Scale aberration with displacement
|
|
1764
|
+
},
|
|
1756
1765
|
ELASTICITY: .15,
|
|
1757
|
-
CORNER_RADIUS
|
|
1758
|
-
|
|
1766
|
+
get CORNER_RADIUS() {
|
|
1767
|
+
return 16;
|
|
1768
|
+
// Use 16 to match SCSS design system (was 20)
|
|
1769
|
+
},
|
|
1759
1770
|
PADDING: "0",
|
|
1760
1771
|
MODE: "standard",
|
|
1761
1772
|
OVER_LIGHT: !1,
|
|
@@ -1777,6 +1788,15 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
|
|
|
1777
1788
|
MIN_BLUR: .1,
|
|
1778
1789
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
1779
1790
|
EDGE_FADE_PIXELS: 2,
|
|
1791
|
+
// Elasticity physics constants
|
|
1792
|
+
ELASTICITY_TRANSLATION_FACTOR: .1,
|
|
1793
|
+
ELASTICITY_DISTANCE_THRESHOLD: 200,
|
|
1794
|
+
ELASTICITY_COMPRESSION_FACTOR: .3,
|
|
1795
|
+
ELASTICITY_STIFFNESS: .1,
|
|
1796
|
+
ELASTICITY_DAMPING: .76,
|
|
1797
|
+
ELASTICITY_VELOCITY_FACTOR: .65,
|
|
1798
|
+
ELASTICITY_STRETCH_RATIO: .45,
|
|
1799
|
+
ELASTICITY_MAGNIFICATION_BASE: 1.02,
|
|
1780
1800
|
// Note: This default must match the SCSS variable --atomix-radius-md
|
|
1781
1801
|
// @see src/styles/01-settings/_settings.global.scss
|
|
1782
1802
|
DEFAULT_CORNER_RADIUS: 16,
|
|
@@ -1793,84 +1813,126 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
|
|
|
1793
1813
|
// Base angle for border gradients (degrees)
|
|
1794
1814
|
ANGLE_MULTIPLIER: 1.2,
|
|
1795
1815
|
// Multiplier for mouse influence on angle
|
|
1816
|
+
VELOCITY_ANGLE_MULTIPLIER: 2.5,
|
|
1817
|
+
// How much velocity affects gradient rotation
|
|
1818
|
+
CHROMATIC_OFFSET: 1.5,
|
|
1819
|
+
// Degree offset for chromatic rim layers
|
|
1796
1820
|
BORDER_STOP_1: {
|
|
1797
1821
|
MIN: 10,
|
|
1798
1822
|
// Minimum percentage for border stop 1
|
|
1799
1823
|
BASE: 33,
|
|
1800
1824
|
// Base percentage for border stop 1
|
|
1801
|
-
MULTIPLIER
|
|
1825
|
+
get MULTIPLIER() {
|
|
1826
|
+
return .009 * this.BASE;
|
|
1827
|
+
}
|
|
1802
1828
|
},
|
|
1803
1829
|
BORDER_STOP_2: {
|
|
1804
1830
|
MAX: 90,
|
|
1805
1831
|
// Maximum percentage for border stop 2
|
|
1806
1832
|
BASE: 66,
|
|
1807
1833
|
// Base percentage for border stop 2
|
|
1808
|
-
MULTIPLIER
|
|
1834
|
+
get MULTIPLIER() {
|
|
1835
|
+
return .006 * this.BASE;
|
|
1836
|
+
}
|
|
1809
1837
|
},
|
|
1810
1838
|
BORDER_OPACITY: {
|
|
1811
1839
|
BASE_1: .12,
|
|
1812
1840
|
// Base opacity for border gradient 1
|
|
1813
|
-
BASE_2
|
|
1841
|
+
get BASE_2() {
|
|
1842
|
+
return 3.33 * this.BASE_1;
|
|
1843
|
+
},
|
|
1814
1844
|
// Base opacity for border gradient 2
|
|
1815
|
-
BASE_3
|
|
1845
|
+
get BASE_3() {
|
|
1846
|
+
return 2.66 * this.BASE_1;
|
|
1847
|
+
},
|
|
1816
1848
|
// Base opacity for border gradient 3
|
|
1817
|
-
BASE_4
|
|
1849
|
+
get BASE_4() {
|
|
1850
|
+
return 5 * this.BASE_1;
|
|
1851
|
+
},
|
|
1818
1852
|
// Base opacity for border gradient 4
|
|
1819
|
-
MULTIPLIER_LOW
|
|
1853
|
+
get MULTIPLIER_LOW() {
|
|
1854
|
+
return .066 * this.BASE_1;
|
|
1855
|
+
},
|
|
1820
1856
|
// Low multiplier for mouse influence on opacity
|
|
1821
|
-
MULTIPLIER_HIGH
|
|
1857
|
+
get MULTIPLIER_HIGH() {
|
|
1858
|
+
return .1 * this.BASE_1;
|
|
1859
|
+
}
|
|
1822
1860
|
},
|
|
1823
1861
|
CENTER_POSITION: 50,
|
|
1824
1862
|
// Center position percentage (50%)
|
|
1825
1863
|
HOVER_POSITION: {
|
|
1826
1864
|
DIVISOR_1: 2,
|
|
1827
1865
|
// Divisor for hover 1 position calculation
|
|
1828
|
-
DIVISOR_2
|
|
1866
|
+
get DIVISOR_2() {
|
|
1867
|
+
return .75 * this.DIVISOR_1;
|
|
1868
|
+
},
|
|
1829
1869
|
// Divisor for hover 2 position calculation
|
|
1830
|
-
MULTIPLIER_3
|
|
1870
|
+
get MULTIPLIER_3() {
|
|
1871
|
+
return .5 * this.DIVISOR_1;
|
|
1872
|
+
}
|
|
1831
1873
|
},
|
|
1832
|
-
BASE_LAYER_MULTIPLIER
|
|
1874
|
+
get BASE_LAYER_MULTIPLIER() {
|
|
1875
|
+
return .5;
|
|
1876
|
+
}
|
|
1833
1877
|
},
|
|
1834
1878
|
// Gradient opacity values for hover effects
|
|
1835
1879
|
GRADIENT_OPACITY: {
|
|
1836
1880
|
HOVER_1: {
|
|
1837
1881
|
BLACK_START: .3,
|
|
1838
1882
|
// Start opacity for black hover 1
|
|
1839
|
-
BLACK_MID
|
|
1883
|
+
get BLACK_MID() {
|
|
1884
|
+
return this.BLACK_START / 3;
|
|
1885
|
+
},
|
|
1840
1886
|
// Mid opacity for black hover 1
|
|
1841
1887
|
BLACK_STOP: 30,
|
|
1842
1888
|
// Stop percentage for black hover 1
|
|
1843
|
-
BLACK_END
|
|
1889
|
+
get BLACK_END() {
|
|
1890
|
+
return 2 * this.BLACK_STOP;
|
|
1891
|
+
},
|
|
1844
1892
|
// End percentage for black hover 1
|
|
1845
1893
|
WHITE_START: .5,
|
|
1846
1894
|
// Start opacity for white hover 1
|
|
1847
|
-
WHITE_STOP
|
|
1895
|
+
get WHITE_STOP() {
|
|
1896
|
+
return this.BLACK_END - 10;
|
|
1897
|
+
}
|
|
1848
1898
|
},
|
|
1849
1899
|
HOVER_2: {
|
|
1850
1900
|
BLACK_START: .4,
|
|
1851
1901
|
// Start opacity for black hover 2
|
|
1852
|
-
BLACK_MID
|
|
1902
|
+
get BLACK_MID() {
|
|
1903
|
+
return .375 * this.BLACK_START;
|
|
1904
|
+
},
|
|
1853
1905
|
// Mid opacity for black hover 2
|
|
1854
1906
|
BLACK_STOP: 40,
|
|
1855
1907
|
// Stop percentage for black hover 2
|
|
1856
|
-
BLACK_END
|
|
1908
|
+
get BLACK_END() {
|
|
1909
|
+
return 2 * this.BLACK_STOP;
|
|
1910
|
+
},
|
|
1857
1911
|
// End percentage for black hover 2
|
|
1858
1912
|
WHITE_START: 1,
|
|
1859
1913
|
// Start opacity for white hover 2
|
|
1860
|
-
WHITE_STOP
|
|
1914
|
+
get WHITE_STOP() {
|
|
1915
|
+
return this.BLACK_END;
|
|
1916
|
+
}
|
|
1861
1917
|
},
|
|
1862
1918
|
HOVER_3: {
|
|
1863
1919
|
BLACK_START: .5,
|
|
1864
1920
|
// Start opacity for black hover 3
|
|
1865
|
-
BLACK_MID
|
|
1921
|
+
get BLACK_MID() {
|
|
1922
|
+
return .4 * this.BLACK_START;
|
|
1923
|
+
},
|
|
1866
1924
|
// Mid opacity for black hover 3
|
|
1867
1925
|
BLACK_STOP: 50,
|
|
1868
1926
|
// Stop percentage for black hover 3
|
|
1869
|
-
BLACK_END
|
|
1927
|
+
get BLACK_END() {
|
|
1928
|
+
return 2 * this.BLACK_STOP;
|
|
1929
|
+
},
|
|
1870
1930
|
// End percentage for black hover 3
|
|
1871
1931
|
WHITE_START: 1,
|
|
1872
1932
|
// Start opacity for white hover 3
|
|
1873
|
-
WHITE_STOP
|
|
1933
|
+
get WHITE_STOP() {
|
|
1934
|
+
return this.BLACK_END;
|
|
1935
|
+
}
|
|
1874
1936
|
}
|
|
1875
1937
|
},
|
|
1876
1938
|
// Base and overlay gradient constants
|
|
@@ -1879,34 +1941,54 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
|
|
|
1879
1941
|
// Gradient angle in degrees
|
|
1880
1942
|
BLACK_START_BASE: .15,
|
|
1881
1943
|
// Base start opacity for black
|
|
1882
|
-
BLACK_START_MULTIPLIER
|
|
1944
|
+
get BLACK_START_MULTIPLIER() {
|
|
1945
|
+
return .02 * this.BLACK_START_BASE;
|
|
1946
|
+
},
|
|
1883
1947
|
// Multiplier for mouse X influence on start
|
|
1884
1948
|
BLACK_MID_BASE: .1,
|
|
1885
1949
|
// Base mid opacity for black
|
|
1886
|
-
BLACK_MID_MULTIPLIER
|
|
1950
|
+
get BLACK_MID_MULTIPLIER() {
|
|
1951
|
+
return .02 * this.BLACK_MID_BASE;
|
|
1952
|
+
},
|
|
1887
1953
|
// Multiplier for mouse Y influence on mid
|
|
1888
1954
|
BLACK_MID_STOP: 50,
|
|
1889
1955
|
// Mid stop percentage
|
|
1890
|
-
BLACK_END_BASE
|
|
1956
|
+
get BLACK_END_BASE() {
|
|
1957
|
+
return 1.2 * this.BLACK_START_BASE;
|
|
1958
|
+
},
|
|
1891
1959
|
// Base end opacity for black
|
|
1892
|
-
BLACK_END_MULTIPLIER
|
|
1960
|
+
get BLACK_END_MULTIPLIER() {
|
|
1961
|
+
return .022 * this.BLACK_END_BASE;
|
|
1962
|
+
},
|
|
1893
1963
|
// Multiplier for mouse X influence on end
|
|
1894
|
-
WHITE_OPACITY
|
|
1964
|
+
get WHITE_OPACITY() {
|
|
1965
|
+
return .666 * this.BLACK_START_BASE;
|
|
1966
|
+
}
|
|
1895
1967
|
},
|
|
1896
1968
|
OVERLAY_GRADIENT: {
|
|
1897
1969
|
BLACK_START_BASE: .12,
|
|
1898
1970
|
// Base start opacity for black overlay
|
|
1899
|
-
BLACK_START_MULTIPLIER
|
|
1971
|
+
get BLACK_START_MULTIPLIER() {
|
|
1972
|
+
return .025 * this.BLACK_START_BASE;
|
|
1973
|
+
},
|
|
1900
1974
|
// Multiplier for mouse X influence on start
|
|
1901
|
-
BLACK_MID
|
|
1975
|
+
get BLACK_MID() {
|
|
1976
|
+
return .5 * this.BLACK_START_BASE;
|
|
1977
|
+
},
|
|
1902
1978
|
// Mid opacity for black overlay
|
|
1903
1979
|
BLACK_MID_STOP: 40,
|
|
1904
1980
|
// Mid stop percentage
|
|
1905
|
-
BLACK_END_BASE
|
|
1981
|
+
get BLACK_END_BASE() {
|
|
1982
|
+
return 1.25 * this.BLACK_START_BASE;
|
|
1983
|
+
},
|
|
1906
1984
|
// Base end opacity for black overlay
|
|
1907
|
-
BLACK_END_MULTIPLIER
|
|
1985
|
+
get BLACK_END_MULTIPLIER() {
|
|
1986
|
+
return .02 * this.BLACK_END_BASE;
|
|
1987
|
+
},
|
|
1908
1988
|
// Multiplier for mouse Y influence on end
|
|
1909
|
-
WHITE_OPACITY
|
|
1989
|
+
get WHITE_OPACITY() {
|
|
1990
|
+
return .416 * this.BLACK_START_BASE;
|
|
1991
|
+
}
|
|
1910
1992
|
},
|
|
1911
1993
|
// Overlay highlight constants
|
|
1912
1994
|
OVERLAY_HIGHLIGHT: {
|
|
@@ -1916,9 +1998,13 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
|
|
|
1916
1998
|
// Y position percentage
|
|
1917
1999
|
WHITE_OPACITY: .4,
|
|
1918
2000
|
// White opacity in gradient
|
|
1919
|
-
STOP
|
|
2001
|
+
get STOP() {
|
|
2002
|
+
return 150 * this.WHITE_OPACITY;
|
|
2003
|
+
},
|
|
1920
2004
|
// Stop percentage
|
|
1921
|
-
OPACITY_MULTIPLIER
|
|
2005
|
+
get OPACITY_MULTIPLIER() {
|
|
2006
|
+
return 1.75 * this.WHITE_OPACITY;
|
|
2007
|
+
}
|
|
1922
2008
|
},
|
|
1923
2009
|
// Displacement and aberration multipliers
|
|
1924
2010
|
MULTIPLIERS: {
|
|
@@ -2028,11 +2114,7 @@ function useAccordion(initialProps) {
|
|
|
2028
2114
|
};
|
|
2029
2115
|
}
|
|
2030
2116
|
|
|
2031
|
-
const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS,
|
|
2032
|
-
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
2033
|
-
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
2034
|
-
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
2035
|
-
}, calculateElementCenter = rect => rect ? {
|
|
2117
|
+
const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
|
|
2036
2118
|
x: rect.left + rect.width / 2,
|
|
2037
2119
|
y: rect.top + rect.height / 2
|
|
2038
2120
|
} : {
|
|
@@ -2104,7 +2186,16 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2104
2186
|
// Silently handle errors
|
|
2105
2187
|
}
|
|
2106
2188
|
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
2107
|
-
},
|
|
2189
|
+
}, smoothstep = t => {
|
|
2190
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
2191
|
+
return clamped * clamped * (3 - 2 * clamped);
|
|
2192
|
+
}, lerp$1 = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
|
|
2193
|
+
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
2194
|
+
return {
|
|
2195
|
+
value: current + newVelocity,
|
|
2196
|
+
velocity: newVelocity
|
|
2197
|
+
};
|
|
2198
|
+
}, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
2108
2199
|
switch (mode) {
|
|
2109
2200
|
case "standard":
|
|
2110
2201
|
return displacementMap;
|
|
@@ -2497,6 +2588,9 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2497
2588
|
}), jsxRuntime.jsx("div", {
|
|
2498
2589
|
ref: contentRef,
|
|
2499
2590
|
className: ATOMIX_GLASS.CONTENT_CLASS,
|
|
2591
|
+
style: {
|
|
2592
|
+
transform: "var(--atomix-glass-child-parallax, none)"
|
|
2593
|
+
},
|
|
2500
2594
|
children: children
|
|
2501
2595
|
}) ]
|
|
2502
2596
|
})
|
|
@@ -2531,9 +2625,21 @@ class {
|
|
|
2531
2625
|
y: this.lastEvent.clientY
|
|
2532
2626
|
},
|
|
2533
2627
|
// Notify all subscribers
|
|
2534
|
-
this.listeners.forEach((
|
|
2628
|
+
this.listeners.forEach((listener => {
|
|
2535
2629
|
try {
|
|
2536
|
-
|
|
2630
|
+
// If the listener has an element, calculate distance-based attenuation
|
|
2631
|
+
if (listener.element) {
|
|
2632
|
+
const elementRect = listener.element.getBoundingClientRect(), elementCenter = {
|
|
2633
|
+
x: elementRect.left + elementRect.width / 2,
|
|
2634
|
+
y: elementRect.top + elementRect.height / 2
|
|
2635
|
+
}, distance = this.calculateDistance(this.position, elementCenter), maxDistance = listener.maxDistance || 300, attenuation = Math.max(0, 1 - distance / maxDistance), attenuatedRelativePosition = {
|
|
2636
|
+
x: (this.position.x - elementCenter.x) / elementRect.width * 100 * attenuation,
|
|
2637
|
+
y: (this.position.y - elementCenter.y) / elementRect.height * 100 * attenuation
|
|
2638
|
+
};
|
|
2639
|
+
listener.callback(attenuatedRelativePosition);
|
|
2640
|
+
} else
|
|
2641
|
+
// Send original position for listeners without distance-based attenuation
|
|
2642
|
+
listener.callback(this.position);
|
|
2537
2643
|
} catch (error) {
|
|
2538
2644
|
console.error("GlobalMouseTracker: Error in subscriber callback", error);
|
|
2539
2645
|
}
|
|
@@ -2544,10 +2650,17 @@ class {
|
|
|
2544
2650
|
/**
|
|
2545
2651
|
* Subscribe to mouse position updates
|
|
2546
2652
|
* @param callback Function to call when mouse position changes
|
|
2653
|
+
* @param element Optional element for distance-based attenuation
|
|
2654
|
+
* @param maxDistance Optional maximum distance for full effect
|
|
2547
2655
|
* @returns Unsubscribe function
|
|
2548
|
-
*/ subscribe(callback) {
|
|
2656
|
+
*/ subscribe(callback, element, maxDistance) {
|
|
2657
|
+
const listener = {
|
|
2658
|
+
callback: callback,
|
|
2659
|
+
element: element,
|
|
2660
|
+
maxDistance: maxDistance
|
|
2661
|
+
};
|
|
2549
2662
|
// Return unsubscribe function
|
|
2550
|
-
return this.listeners.add(
|
|
2663
|
+
return this.listeners.add(listener),
|
|
2551
2664
|
// Start tracking if this is the first subscriber
|
|
2552
2665
|
1 === this.listeners.size && this.startTracking(),
|
|
2553
2666
|
// Immediately notify with current position
|
|
@@ -2558,9 +2671,13 @@ class {
|
|
|
2558
2671
|
/**
|
|
2559
2672
|
* Unsubscribe from mouse position updates
|
|
2560
2673
|
*/ unsubscribe(callback) {
|
|
2561
|
-
|
|
2674
|
+
// Find and remove the listener with the given callback
|
|
2675
|
+
for (const listener of this.listeners) if (listener.callback === callback) {
|
|
2676
|
+
this.listeners.delete(listener);
|
|
2677
|
+
break;
|
|
2678
|
+
}
|
|
2562
2679
|
// Stop tracking if no more subscribers
|
|
2563
|
-
|
|
2680
|
+
0 === this.listeners.size && this.stopTracking();
|
|
2564
2681
|
}
|
|
2565
2682
|
/**
|
|
2566
2683
|
* Start tracking mouse movement
|
|
@@ -2579,6 +2696,12 @@ class {
|
|
|
2579
2696
|
null !== this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = null), this.lastEvent = null);
|
|
2580
2697
|
}
|
|
2581
2698
|
/**
|
|
2699
|
+
* Calculate distance between two points
|
|
2700
|
+
*/ calculateDistance(point1, point2) {
|
|
2701
|
+
const dx = point1.x - point2.x, dy = point1.y - point2.y;
|
|
2702
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
2703
|
+
}
|
|
2704
|
+
/**
|
|
2582
2705
|
* Get current mouse position (synchronous)
|
|
2583
2706
|
*/ getPosition() {
|
|
2584
2707
|
return {
|
|
@@ -2592,51 +2715,26 @@ class {
|
|
|
2592
2715
|
}
|
|
2593
2716
|
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
2594
2717
|
if (!wrapperElement && !containerElement) return;
|
|
2595
|
-
|
|
2718
|
+
if (!validateGlassSize(params.glassSize)) return;
|
|
2719
|
+
const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, isFixedOrSticky: isFixedOrSticky = !1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
|
|
2596
2720
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
2597
2721
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
2598
2722
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
2599
2723
|
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
2600
2724
|
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
|
|
2601
2725
|
saturationBoost: baseOverLightConfig.saturationBoost
|
|
2602
|
-
}
|
|
2603
|
-
|
|
2604
|
-
|
|
2726
|
+
}, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, stretchMagnitude = ((pos1, pos2) => {
|
|
2727
|
+
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
2728
|
+
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
2729
|
+
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
2730
|
+
})({
|
|
2605
2731
|
x: 0,
|
|
2606
2732
|
y: 0
|
|
2607
|
-
};
|
|
2608
|
-
// Calculate
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
|
|
2613
|
-
const 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({
|
|
2614
|
-
x: edgeDistanceX,
|
|
2615
|
-
y: edgeDistanceY
|
|
2616
|
-
}, {
|
|
2617
|
-
x: 0,
|
|
2618
|
-
y: 0
|
|
2619
|
-
}), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
|
|
2620
|
-
const clamped = Math.max(0, Math.min(1, t));
|
|
2621
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
2622
|
-
})(rawT);
|
|
2623
|
-
// Directional scale
|
|
2624
|
-
if (elasticTranslation = {
|
|
2625
|
-
x: deltaX * elasticity * .1 * fadeInFactor,
|
|
2626
|
-
y: deltaY * elasticity * .1 * fadeInFactor
|
|
2627
|
-
}, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
|
|
2628
|
-
const centerDistance = calculateDistance(globalMousePosition, center);
|
|
2629
|
-
if (centerDistance > 0) {
|
|
2630
|
-
const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15, softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), .2), softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), .2);
|
|
2631
|
-
computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
|
|
2632
|
-
}
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
}
|
|
2636
|
-
const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : computedDirectionalScale}`;
|
|
2637
|
-
// Update Wrapper Styles (glassVars)
|
|
2638
|
-
if (wrapperElement) {
|
|
2639
|
-
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, 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), borderOpacities = [ GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
2733
|
+
}, elasticTranslation), tensionFactor = smoothstep(stretchMagnitude / 80), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
|
|
2734
|
+
// Calculate mouse influence
|
|
2735
|
+
// Update Wrapper Styles (glassVars)
|
|
2736
|
+
if (wrapperElement) {
|
|
2737
|
+
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, velocityRotation = (mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5), borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, 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), tensionGlow = 1 + .5 * tensionFactor, borderOpacities = [ (GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
2640
2738
|
hover1: {
|
|
2641
2739
|
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
|
|
2642
2740
|
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
|
|
@@ -2659,10 +2757,16 @@ class {
|
|
|
2659
2757
|
base: isOverLight ? overLightConfig.opacity : 0,
|
|
2660
2758
|
over: isOverLight ? 1.1 * overLightConfig.opacity : 0
|
|
2661
2759
|
}, style = wrapperElement.style;
|
|
2662
|
-
style.setProperty("--atomix-glass-transform", transformStyle || "none")
|
|
2663
|
-
//
|
|
2664
|
-
|
|
2665
|
-
style.setProperty("--atomix-glass-
|
|
2760
|
+
style.setProperty("--atomix-glass-transform", transformStyle || "none");
|
|
2761
|
+
// Parallax for content (liquid refraction feel)
|
|
2762
|
+
const parallaxFactor = .38 + .12 * tensionFactor;
|
|
2763
|
+
style.setProperty("--atomix-glass-child-parallax", `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`),
|
|
2764
|
+
style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString()),
|
|
2765
|
+
// ── Chromatic Rim Lighting ──────────────────────────────────────
|
|
2766
|
+
// Layer 1: Core White/Blue highlight
|
|
2767
|
+
style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${angleB}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
|
|
2768
|
+
// Layer 2: Subtle Red/Warm highlight (offset angle)
|
|
2769
|
+
style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${angleR}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
|
|
2666
2770
|
// Hover gradients
|
|
2667
2771
|
style.setProperty("--atomix-glass-hover-1-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`),
|
|
2668
2772
|
style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`),
|
|
@@ -2690,7 +2794,7 @@ class {
|
|
|
2690
2794
|
flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
|
|
2691
2795
|
};
|
|
2692
2796
|
if (withLiquidBlur && rect) {
|
|
2693
|
-
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur =
|
|
2797
|
+
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur = softClamp(blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR, maxBlur), edgeBlur = softClamp(baseBlur * (.8 + mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR * .4), maxBlur), centerBlur = softClamp(baseBlur * (.3 + mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR * .3), maxBlur), flowBlur = softClamp(baseBlur * FLOW_BLUR_MULTIPLIER, maxBlur);
|
|
2694
2798
|
liquidBlur = {
|
|
2695
2799
|
baseBlur: clampBlur(baseBlur),
|
|
2696
2800
|
edgeBlur: clampBlur(edgeBlur),
|
|
@@ -2699,9 +2803,10 @@ class {
|
|
|
2699
2803
|
};
|
|
2700
2804
|
}
|
|
2701
2805
|
// Backdrop filter
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2806
|
+
const dynamicSaturation = saturation + 40 * tensionFactor + 15 * (liquidBlur.baseBlur || 0);
|
|
2807
|
+
let backdropFilterString = "";
|
|
2808
|
+
const area = rect ? rect.width * rect.height : 0;
|
|
2809
|
+
backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})`;
|
|
2705
2810
|
// Container variables
|
|
2706
2811
|
const style = containerElement.style;
|
|
2707
2812
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
@@ -2863,7 +2968,8 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
2863
2968
|
* Composable hook for AtomixGlass component logic
|
|
2864
2969
|
* Manages all state, calculations, and event handlers
|
|
2865
2970
|
*/
|
|
2866
|
-
function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, elasticity: elasticity = .
|
|
2971
|
+
function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, padding: padding, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1, withTimeAnimation:
|
|
2972
|
+
// Default priority
|
|
2867
2973
|
// Phase 1: Animation System Props
|
|
2868
2974
|
withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: animationSpeed = ATOMIX_GLASS.DEFAULTS.ANIMATION_SPEED, withMultiLayerDistortion: withMultiLayerDistortion = ATOMIX_GLASS.DEFAULTS.WITH_MULTI_LAYER_DISTORTION, distortionOctaves: distortionOctaves = ATOMIX_GLASS.DEFAULTS.DISTORTION_OCTAVES, distortionLacunarity: distortionLacunarity = ATOMIX_GLASS.DEFAULTS.DISTORTION_LACUNARITY, distortionGain: distortionGain = ATOMIX_GLASS.DEFAULTS.DISTORTION_GAIN, distortionQuality: distortionQuality = ATOMIX_GLASS.DEFAULTS.DISTORTION_QUALITY}) {
|
|
2869
2975
|
// State
|
|
@@ -2879,7 +2985,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2879
2985
|
}), targetGlobalMousePositionRef = React.useRef({
|
|
2880
2986
|
x: 0,
|
|
2881
2987
|
y: 0
|
|
2882
|
-
}), lerpRafRef = React.useRef(null), lerpActiveRef = React.useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = React.useState(CONSTANTS.DEFAULT_CORNER_RADIUS),
|
|
2988
|
+
}), lerpRafRef = React.useRef(null), lerpActiveRef = React.useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = React.useState(CONSTANTS.DEFAULT_CORNER_RADIUS), elasticTranslationRef = React.useRef({
|
|
2989
|
+
x: 0,
|
|
2990
|
+
y: 0
|
|
2991
|
+
}), elasticVelocityRef = React.useRef({
|
|
2992
|
+
x: 0,
|
|
2993
|
+
y: 0
|
|
2994
|
+
}), directionalScaleRef = React.useRef({
|
|
2995
|
+
x: 1,
|
|
2996
|
+
y: 1
|
|
2997
|
+
}), scaleVelocityRef = React.useRef({
|
|
2998
|
+
x: 0,
|
|
2999
|
+
y: 0
|
|
3000
|
+
});
|
|
3001
|
+
React.useRef(0);
|
|
3002
|
+
const mouseVelocityRef = React.useRef({
|
|
3003
|
+
x: 0,
|
|
3004
|
+
y: 0
|
|
3005
|
+
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = React.useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = React.useState(!1), [detectedOverLight, setDetectedOverLight] = React.useState(!1), animationFrameIdRef = React.useRef(null), animationStartTimeRef = React.useRef(0), elapsedTimeRef = React.useRef(0), shaderTimeRef = React.useRef(0), fbmConfig = React.useMemo((() => {
|
|
2883
3006
|
// If quality preset is provided, use it as base
|
|
2884
3007
|
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
2885
3008
|
// Override with custom values if provided
|
|
@@ -3164,57 +3287,85 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3164
3287
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
3165
3288
|
}
|
|
3166
3289
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
3167
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = React.useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.
|
|
3290
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = React.useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.99)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = React.useRef(null), stopLerpLoop = React.useCallback((() => {
|
|
3168
3291
|
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
3169
3292
|
lerpRafRef.current = null);
|
|
3170
3293
|
}), []), startLerpLoop = React.useCallback((() => {
|
|
3171
3294
|
if (lerpActiveRef.current) return;
|
|
3172
|
-
lerpActiveRef.current = !0;
|
|
3173
|
-
|
|
3295
|
+
lerpActiveRef.current = !0, CONSTANTS.LERP_FACTOR;
|
|
3296
|
+
// 0.08 – lower = more viscous
|
|
3297
|
+
const tick = () => {
|
|
3174
3298
|
if (!lerpActiveRef.current) return;
|
|
3175
3299
|
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
3176
|
-
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current,
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
},
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
// Final update and stop
|
|
3184
|
-
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3185
|
-
mouseOffset: internalMouseOffsetRef.current,
|
|
3186
|
-
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3187
|
-
glassSize: glassSize,
|
|
3188
|
-
isHovered: isHovered,
|
|
3189
|
-
isActive: isActive,
|
|
3190
|
-
isOverLight: overLightConfig.isOverLight,
|
|
3191
|
-
baseOverLightConfig: overLightConfig,
|
|
3192
|
-
effectiveBorderRadius: effectiveBorderRadius,
|
|
3193
|
-
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3194
|
-
effectiveReducedMotion: effectiveReducedMotion,
|
|
3195
|
-
elasticity: elasticity,
|
|
3196
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
3197
|
-
onClick: onClick,
|
|
3198
|
-
withLiquidBlur: withLiquidBlur,
|
|
3199
|
-
blurAmount: blurAmount,
|
|
3200
|
-
saturation: saturation,
|
|
3201
|
-
padding: padding,
|
|
3202
|
-
isFixedOrSticky: isFixedOrSticky
|
|
3203
|
-
}), void stopLerpLoop();
|
|
3204
|
-
// Smooth step
|
|
3205
|
-
internalMouseOffsetRef.current = {
|
|
3206
|
-
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
3207
|
-
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
3300
|
+
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, springX = calculateSpring(cur.x, tgt.x, mouseVelocityRef.current.x, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING), springY = calculateSpring(cur.y, tgt.y, mouseVelocityRef.current.y, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING);
|
|
3301
|
+
internalMouseOffsetRef.current = {
|
|
3302
|
+
x: springX.value,
|
|
3303
|
+
y: springY.value
|
|
3304
|
+
}, mouseVelocityRef.current = {
|
|
3305
|
+
x: springX.velocity,
|
|
3306
|
+
y: springY.velocity
|
|
3208
3307
|
};
|
|
3209
3308
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
3210
3309
|
internalGlobalMousePositionRef.current = {
|
|
3211
|
-
x: lerp$1(curG.x, tgtG.x,
|
|
3212
|
-
y: lerp$1(curG.y, tgtG.y,
|
|
3310
|
+
x: lerp$1(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
3311
|
+
y: lerp$1(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
3312
|
+
};
|
|
3313
|
+
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
3314
|
+
let targetElasticTranslation = {
|
|
3315
|
+
x: 0,
|
|
3316
|
+
y: 0
|
|
3317
|
+
}, targetScale = {
|
|
3318
|
+
x: 1,
|
|
3319
|
+
y: 1
|
|
3320
|
+
};
|
|
3321
|
+
if (!effectiveWithoutEffects && glassRef.current) {
|
|
3322
|
+
const rect = cachedRectRef.current || glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), globalPos = internalGlobalMousePositionRef.current;
|
|
3323
|
+
if (globalPos.x && globalPos.y) {
|
|
3324
|
+
const deltaX = globalPos.x - center.x, deltaY = globalPos.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - rect.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - rect.height / 2), edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY), activationZone = CONSTANTS.ACTIVATION_ZONE, rawT = edgeDistance > activationZone ? 0 : 1 - edgeDistance / activationZone, fadeInFactor = smoothstep(rawT);
|
|
3325
|
+
// Scale stretch logic (liquid surface tension)
|
|
3326
|
+
if (targetElasticTranslation = {
|
|
3327
|
+
x: deltaX * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor,
|
|
3328
|
+
y: deltaY * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor
|
|
3329
|
+
}, edgeDistance <= activationZone) {
|
|
3330
|
+
const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
3331
|
+
if (centerDistance > 0) {
|
|
3332
|
+
const nx = deltaX / centerDistance, ny = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 350, 1) * elasticity * rawT, mag = 1 + .06 * stretchIntensity;
|
|
3333
|
+
targetScale = {
|
|
3334
|
+
x: mag + Math.abs(nx) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO,
|
|
3335
|
+
y: mag + Math.abs(ny) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO
|
|
3336
|
+
},
|
|
3337
|
+
// Maintain liquid volume by compressing the perpendicular axis
|
|
3338
|
+
targetScale.x -= Math.abs(ny) * stretchIntensity * .15, targetScale.y -= Math.abs(nx) * stretchIntensity * .15;
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
// Integrate Elastic Translation Spring
|
|
3344
|
+
const springTX = calculateSpring(elasticTranslationRef.current.x, targetElasticTranslation.x, elasticVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springTY = calculateSpring(elasticTranslationRef.current.y, targetElasticTranslation.y, elasticVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
|
|
3345
|
+
elasticTranslationRef.current = {
|
|
3346
|
+
x: springTX.value,
|
|
3347
|
+
y: springTY.value
|
|
3348
|
+
}, elasticVelocityRef.current = {
|
|
3349
|
+
x: springTX.velocity,
|
|
3350
|
+
y: springTY.velocity
|
|
3351
|
+
};
|
|
3352
|
+
// Integrate Scale Spring
|
|
3353
|
+
const springSX = calculateSpring(directionalScaleRef.current.x, targetScale.x, scaleVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springSY = calculateSpring(directionalScaleRef.current.y, targetScale.y, scaleVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
|
|
3354
|
+
directionalScaleRef.current = {
|
|
3355
|
+
x: springSX.value,
|
|
3356
|
+
y: springSY.value
|
|
3357
|
+
}, scaleVelocityRef.current = {
|
|
3358
|
+
x: springSX.velocity,
|
|
3359
|
+
y: springSY.velocity
|
|
3213
3360
|
},
|
|
3214
3361
|
// Imperative style update
|
|
3215
3362
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3216
3363
|
mouseOffset: internalMouseOffsetRef.current,
|
|
3217
3364
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3365
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
3366
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
3367
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
3368
|
+
directionalScale: directionalScaleRef.current,
|
|
3218
3369
|
glassSize: glassSize,
|
|
3219
3370
|
isHovered: isHovered,
|
|
3220
3371
|
isActive: isActive,
|
|
@@ -3224,17 +3375,16 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3224
3375
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3225
3376
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
3226
3377
|
elasticity: elasticity,
|
|
3227
|
-
|
|
3378
|
+
scaleBase: isActive && Boolean(onClick) ? .99 : 1,
|
|
3228
3379
|
onClick: onClick,
|
|
3229
3380
|
withLiquidBlur: withLiquidBlur,
|
|
3230
3381
|
blurAmount: blurAmount,
|
|
3231
3382
|
saturation: saturation,
|
|
3232
3383
|
padding: padding,
|
|
3233
3384
|
isFixedOrSticky: isFixedOrSticky
|
|
3234
|
-
}), lerpRafRef.current = requestAnimationFrame(tick);
|
|
3385
|
+
}), Math.abs(mouseVelocityRef.current.x) < .001 && Math.abs(mouseVelocityRef.current.y) < .001 && Math.abs(elasticVelocityRef.current.x) < .001 && Math.abs(elasticVelocityRef.current.y) < .001 && Math.abs(scaleVelocityRef.current.x) < .001 && Math.abs(scaleVelocityRef.current.y) < .001 && Math.abs(internalMouseOffsetRef.current.x - targetMouseOffsetRef.current.x) < .001 && Math.abs(internalMouseOffsetRef.current.y - targetMouseOffsetRef.current.y) < .001 ? stopLerpLoop() : lerpRafRef.current = requestAnimationFrame(tick);
|
|
3235
3386
|
};
|
|
3236
|
-
|
|
3237
|
-
lerpRafRef.current = requestAnimationFrame(tick);
|
|
3387
|
+
lerpRafRef.current = requestAnimationFrame(tick);
|
|
3238
3388
|
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = React.useCallback((globalPos => {
|
|
3239
3389
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3240
3390
|
if (effectiveWithoutEffects) return;
|
|
@@ -3260,7 +3410,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3260
3410
|
React.useEffect((() => {
|
|
3261
3411
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3262
3412
|
if (effectiveWithoutEffects) return;
|
|
3263
|
-
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
3413
|
+
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition, glassRef.current || void 0, 300);
|
|
3414
|
+
// 300px max distance for full effect
|
|
3264
3415
|
// Initial start
|
|
3265
3416
|
startLerpLoop();
|
|
3266
3417
|
const container = mouseContainer?.current || glassRef.current;
|
|
@@ -3280,6 +3431,11 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3280
3431
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3281
3432
|
mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
|
|
3282
3433
|
globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
|
|
3434
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
3435
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
3436
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
3437
|
+
directionalScale: directionalScaleRef.current,
|
|
3438
|
+
scaleBase: isActive && Boolean(onClick) ? .96 : 1,
|
|
3283
3439
|
glassSize: glassSize,
|
|
3284
3440
|
isHovered: isHovered,
|
|
3285
3441
|
isActive: isActive,
|
|
@@ -3289,7 +3445,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3289
3445
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3290
3446
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
3291
3447
|
elasticity: elasticity,
|
|
3292
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
3293
3448
|
onClick: onClick,
|
|
3294
3449
|
withLiquidBlur: withLiquidBlur,
|
|
3295
3450
|
blurAmount: blurAmount,
|
|
@@ -4255,7 +4410,7 @@ function getDevicePreset(presetName) {
|
|
|
4255
4410
|
"aria-label": ariaLabel,
|
|
4256
4411
|
"aria-describedby": ariaDescribedBy,
|
|
4257
4412
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
4258
|
-
"aria-pressed": void 0,
|
|
4413
|
+
"aria-pressed": onClick ? isActive : void 0,
|
|
4259
4414
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
4260
4415
|
children: [ jsxRuntime.jsx(AtomixGlassContainer, {
|
|
4261
4416
|
ref: glassRef,
|
|
@@ -5426,10 +5581,10 @@ function renderSlot(slot, props, fallback) {
|
|
|
5426
5581
|
children: renderSlot(slots?.spinner, {
|
|
5427
5582
|
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
|
|
5428
5583
|
size: spinnerSize,
|
|
5429
|
-
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "
|
|
5584
|
+
variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
|
|
5430
5585
|
}, jsxRuntime.jsx(Spinner, {
|
|
5431
5586
|
size: spinnerSize,
|
|
5432
|
-
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "
|
|
5587
|
+
variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
|
|
5433
5588
|
}))
|
|
5434
5589
|
}), iconElement && !loading && jsxRuntime.jsx("span", {
|
|
5435
5590
|
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
|
|
@@ -5518,8 +5673,7 @@ function renderSlot(slot, props, fallback) {
|
|
|
5518
5673
|
const defaultGlassProps = {
|
|
5519
5674
|
displacementScale: 20,
|
|
5520
5675
|
blurAmount: 0,
|
|
5521
|
-
saturation: 200
|
|
5522
|
-
elasticity: 0
|
|
5676
|
+
saturation: 200
|
|
5523
5677
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
5524
5678
|
...defaultGlassProps,
|
|
5525
5679
|
...glass
|
|
@@ -5950,7 +6104,6 @@ className: className = "", style: style, ...rest}, ref) => {
|
|
|
5950
6104
|
const glassProps = !0 === glass ? {} : glass;
|
|
5951
6105
|
return jsxRuntime.jsx(AtomixGlass, {
|
|
5952
6106
|
...glassProps,
|
|
5953
|
-
elasticity: 0,
|
|
5954
6107
|
children: anchorElement
|
|
5955
6108
|
});
|
|
5956
6109
|
}
|
|
@@ -5966,7 +6119,6 @@ className: className = "", style: style, ...rest}, ref) => {
|
|
|
5966
6119
|
const glassProps = !0 === glass ? {} : glass;
|
|
5967
6120
|
return jsxRuntime.jsx(AtomixGlass, {
|
|
5968
6121
|
...glassProps,
|
|
5969
|
-
elasticity: 0,
|
|
5970
6122
|
children: divElement
|
|
5971
6123
|
});
|
|
5972
6124
|
}
|
|
@@ -12209,9 +12361,7 @@ const EdgePanelComponentBase = ({title: title, children: children, position: pos
|
|
|
12209
12361
|
// The original code returned null if !isOpenState && isOpen === false.
|
|
12210
12362
|
// Let's keep that logic.
|
|
12211
12363
|
if (!isOpenState && !1 === isOpen) return null;
|
|
12212
|
-
const defaultGlassProps = {
|
|
12213
|
-
elasticity: 0
|
|
12214
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
12364
|
+
const defaultGlassProps = {}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
12215
12365
|
...defaultGlassProps,
|
|
12216
12366
|
...glass
|
|
12217
12367
|
}, panelContent = React__default.default.Children.toArray(children).some((child => {
|
|
@@ -13587,26 +13737,25 @@ var composablesImport = Object.freeze({
|
|
|
13587
13737
|
useTodo: useTodo
|
|
13588
13738
|
});
|
|
13589
13739
|
|
|
13590
|
-
const SelectContext = React.createContext(null), SelectOption = React.memo((({value: value, children: children, disabled: disabled = !1, className: className = "", style: style}) => {
|
|
13591
|
-
const context = React.useContext(SelectContext),
|
|
13592
|
-
|
|
13593
|
-
// For simplicity, we use children as label for registration if it's a string.
|
|
13594
|
-
if (React.useEffect((() => {
|
|
13740
|
+
const SelectContext = React.createContext(null), SelectOption = React.memo((({value: value, label: label, children: children, disabled: disabled = !1, className: className = "", style: style}) => {
|
|
13741
|
+
const context = React.useContext(SelectContext), displayLabel = label || ("string" == typeof children ? children : value);
|
|
13742
|
+
if (React.useEffect((() => {
|
|
13595
13743
|
if (context) return context.registerOption({
|
|
13596
13744
|
value: value,
|
|
13597
|
-
label:
|
|
13745
|
+
label: displayLabel,
|
|
13598
13746
|
disabled: disabled
|
|
13599
13747
|
}), () => {
|
|
13600
13748
|
context.unregisterOption(value);
|
|
13601
13749
|
};
|
|
13602
|
-
}), [ context, value,
|
|
13750
|
+
}), [ context, value, displayLabel, disabled ]), !context) return console.warn("SelectOption must be used within a Select component"),
|
|
13603
13751
|
null;
|
|
13604
|
-
const {selectedValue: selectedValue, onSelect: onSelect} = context, isSelected = Array.isArray(selectedValue) ? _includesInstanceProperty(selectedValue).call(selectedValue, value) : selectedValue === value;
|
|
13752
|
+
const {selectedValue: selectedValue, onSelect: onSelect, focusedValue: focusedValue, id: id} = context, isSelected = Array.isArray(selectedValue) ? _includesInstanceProperty(selectedValue).call(selectedValue, value) : selectedValue === value, isFocused = focusedValue === value;
|
|
13605
13753
|
return jsxRuntime.jsx("li", {
|
|
13606
|
-
|
|
13754
|
+
id: id ? `${id}-opt-${value}` : void 0,
|
|
13755
|
+
className: `${SELECT.CLASSES.SELECT_ITEM} ${isFocused ? "is-focused" : ""} ${isSelected ? "is-selected" : ""} ${className}`.trim(),
|
|
13607
13756
|
"data-value": value,
|
|
13608
13757
|
onClick: e => {
|
|
13609
|
-
e.preventDefault(), e.stopPropagation(), disabled || onSelect(value,
|
|
13758
|
+
e.preventDefault(), e.stopPropagation(), disabled || onSelect(value, displayLabel);
|
|
13610
13759
|
},
|
|
13611
13760
|
style: style,
|
|
13612
13761
|
role: "option",
|
|
@@ -13626,7 +13775,7 @@ const SelectContext = React.createContext(null), SelectOption = React.memo((({
|
|
|
13626
13775
|
tabIndex: -1
|
|
13627
13776
|
}), jsxRuntime.jsx("div", {
|
|
13628
13777
|
className: "c-select__item-label",
|
|
13629
|
-
children: children
|
|
13778
|
+
children: children || displayLabel
|
|
13630
13779
|
}) ]
|
|
13631
13780
|
})
|
|
13632
13781
|
});
|
|
@@ -13649,18 +13798,18 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13649
13798
|
disabled: disabled,
|
|
13650
13799
|
invalid: invalid,
|
|
13651
13800
|
valid: valid
|
|
13652
|
-
}), [isOpen, setIsOpen] = React.useState(!1), [
|
|
13801
|
+
}), [isOpen, setIsOpen] = React.useState(!1), [focusedIndex, setFocusedIndex] = React.useState(-1), dropdownRef = React.useRef(null), panelRef = React.useRef(null), bodyRef = React.useRef(null), nativeSelectRef = React.useRef(null), [registeredOptions, setRegisteredOptions] = React.useState([]), registerOption = React.useCallback((option => {
|
|
13653
13802
|
setRegisteredOptions((prev => prev.some((o => o.value === option.value)) ? prev : [ ...prev, option ]));
|
|
13654
13803
|
}), []), unregisterOption = React.useCallback((value => {
|
|
13655
13804
|
setRegisteredOptions((prev => prev.filter((o => o.value !== value))));
|
|
13656
|
-
}), []), hasOptionsProp = options && options.length > 0, activeOptions = hasOptionsProp ? options : registeredOptions
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
if (value) {
|
|
13805
|
+
}), []), hasOptionsProp = options && options.length > 0, activeOptions = hasOptionsProp ? options : registeredOptions, selectedLabel = React.useMemo((() => {
|
|
13806
|
+
if (multiple && Array.isArray(value)) return 0 === value.length ? placeholder : activeOptions.filter((opt => _includesInstanceProperty(value).call(value, opt.value))).map((opt => opt.label)).join(", ");
|
|
13807
|
+
if (value && "string" == typeof value) {
|
|
13660
13808
|
const selectedOption = activeOptions.find((opt => opt.value === value));
|
|
13661
|
-
selectedOption
|
|
13662
|
-
}
|
|
13663
|
-
|
|
13809
|
+
return selectedOption ? selectedOption.label : placeholder;
|
|
13810
|
+
}
|
|
13811
|
+
return placeholder;
|
|
13812
|
+
}), [ value, activeOptions, placeholder, multiple ]);
|
|
13664
13813
|
// Handle click outside to close dropdown
|
|
13665
13814
|
React.useEffect((() => {
|
|
13666
13815
|
const handleClickOutside = event => {
|
|
@@ -13673,31 +13822,54 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13673
13822
|
}), []);
|
|
13674
13823
|
// Toggle dropdown
|
|
13675
13824
|
const handleToggle = () => {
|
|
13676
|
-
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
|
|
13687
|
-
|
|
13688
|
-
|
|
13825
|
+
if (!disabled) {
|
|
13826
|
+
const nextOpen = !isOpen;
|
|
13827
|
+
if (nextOpen && bodyRef.current && panelRef.current)
|
|
13828
|
+
// Set focused index to current selection or first item
|
|
13829
|
+
if (bodyRef.current.style.height = `${panelRef.current.clientHeight}px`, value && !multiple && "string" == typeof value) {
|
|
13830
|
+
const index = activeOptions.findIndex((opt => opt.value === value));
|
|
13831
|
+
setFocusedIndex(index >= 0 ? index : 0);
|
|
13832
|
+
} else if (multiple && Array.isArray(value) && value.length > 0) {
|
|
13833
|
+
const index = activeOptions.findIndex((opt => _includesInstanceProperty(value).call(value, opt.value)));
|
|
13834
|
+
setFocusedIndex(index >= 0 ? index : 0);
|
|
13835
|
+
} else setFocusedIndex(0); else bodyRef.current && (bodyRef.current.style.height = "0px",
|
|
13836
|
+
setFocusedIndex(-1));
|
|
13837
|
+
setIsOpen(nextOpen);
|
|
13689
13838
|
}
|
|
13690
|
-
}
|
|
13839
|
+
}, handleItemClick = React.useCallback((option => {
|
|
13840
|
+
let newValue;
|
|
13841
|
+
if (multiple) {
|
|
13842
|
+
const currentValues = Array.isArray(value) ? value : value ? [ value ] : [];
|
|
13843
|
+
newValue = _includesInstanceProperty(currentValues).call(currentValues, option.value) ? currentValues.filter((v => v !== option.value)) : [ ...currentValues, option.value ];
|
|
13844
|
+
} else newValue = option.value, setIsOpen(!1), bodyRef.current && (bodyRef.current.style.height = "0px");
|
|
13845
|
+
onChange && (
|
|
13846
|
+
// Sync native select before firing onChange
|
|
13847
|
+
nativeSelectRef.current && (multiple && Array.isArray(newValue) ? Array.from(nativeSelectRef.current.options).forEach((opt => {
|
|
13848
|
+
opt.selected = _includesInstanceProperty(newValue).call(newValue, opt.value);
|
|
13849
|
+
})) : "string" == typeof newValue && (nativeSelectRef.current.value = newValue)),
|
|
13850
|
+
onChange({
|
|
13851
|
+
target: {
|
|
13852
|
+
name: name,
|
|
13853
|
+
value: newValue
|
|
13854
|
+
}
|
|
13855
|
+
}));
|
|
13856
|
+
}), [ onChange, name, multiple, value ]), onSelect = React.useCallback(((val, label) => {
|
|
13691
13857
|
handleItemClick({
|
|
13692
13858
|
value: val,
|
|
13693
13859
|
label: label
|
|
13694
13860
|
});
|
|
13695
|
-
}), [ handleItemClick ]),
|
|
13861
|
+
}), [ handleItemClick ]), focusedValue = React.useMemo((() => {
|
|
13862
|
+
if (focusedIndex >= 0 && focusedIndex < activeOptions.length) return activeOptions[focusedIndex]?.value;
|
|
13863
|
+
}), [ focusedIndex, activeOptions ]), focusedOptionId = React.useMemo((() => {
|
|
13864
|
+
if (isOpen && focusedValue) return `${id || "select"}-opt-${focusedValue}`;
|
|
13865
|
+
}), [ isOpen, focusedValue, id ]), contextValue = React__default.default.useMemo((() => ({
|
|
13696
13866
|
registerOption: registerOption,
|
|
13697
13867
|
unregisterOption: unregisterOption,
|
|
13698
13868
|
selectedValue: value,
|
|
13699
|
-
onSelect: onSelect
|
|
13700
|
-
|
|
13869
|
+
onSelect: onSelect,
|
|
13870
|
+
focusedValue: focusedValue,
|
|
13871
|
+
id: id || "select"
|
|
13872
|
+
})), [ registerOption, unregisterOption, value, onSelect, focusedValue, id ]), selectContent = jsxRuntime.jsx(SelectContext.Provider, {
|
|
13701
13873
|
value: contextValue,
|
|
13702
13874
|
children: jsxRuntime.jsxs("div", {
|
|
13703
13875
|
className: `${selectClass} ${isOpen ? SELECT.CLASSES.IS_OPEN : ""}`,
|
|
@@ -13745,7 +13917,12 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13745
13917
|
if (!disabled) switch (event.key) {
|
|
13746
13918
|
case "Enter":
|
|
13747
13919
|
case " ":
|
|
13748
|
-
event.preventDefault(),
|
|
13920
|
+
if (event.preventDefault(), isOpen) {
|
|
13921
|
+
if (focusedIndex >= 0 && focusedIndex < activeOptions.length) {
|
|
13922
|
+
const option = activeOptions[focusedIndex];
|
|
13923
|
+
option && !option.disabled && handleItemClick(option);
|
|
13924
|
+
}
|
|
13925
|
+
} else handleToggle();
|
|
13749
13926
|
break;
|
|
13750
13927
|
|
|
13751
13928
|
case "Escape":
|
|
@@ -13753,8 +13930,23 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13753
13930
|
break;
|
|
13754
13931
|
|
|
13755
13932
|
case "ArrowDown":
|
|
13933
|
+
event.preventDefault(), isOpen ? setFocusedIndex((prev => prev < activeOptions.length - 1 ? prev + 1 : prev)) : handleToggle();
|
|
13934
|
+
break;
|
|
13935
|
+
|
|
13756
13936
|
case "ArrowUp":
|
|
13757
|
-
|
|
13937
|
+
event.preventDefault(), isOpen ? setFocusedIndex((prev => prev > 0 ? prev - 1 : 0)) : handleToggle();
|
|
13938
|
+
break;
|
|
13939
|
+
|
|
13940
|
+
case "Home":
|
|
13941
|
+
isOpen && (event.preventDefault(), setFocusedIndex(0));
|
|
13942
|
+
break;
|
|
13943
|
+
|
|
13944
|
+
case "End":
|
|
13945
|
+
isOpen && (event.preventDefault(), setFocusedIndex(activeOptions.length - 1));
|
|
13946
|
+
break;
|
|
13947
|
+
|
|
13948
|
+
case "Tab":
|
|
13949
|
+
isOpen && (setIsOpen(!1), bodyRef.current && (bodyRef.current.style.height = "0px"));
|
|
13758
13950
|
}
|
|
13759
13951
|
},
|
|
13760
13952
|
"aria-disabled": disabled,
|
|
@@ -13763,7 +13955,11 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13763
13955
|
"aria-haspopup": "listbox",
|
|
13764
13956
|
"aria-expanded": isOpen,
|
|
13765
13957
|
"aria-controls": id ? `${id}-listbox` : void 0,
|
|
13766
|
-
|
|
13958
|
+
"aria-activedescendant": focusedOptionId,
|
|
13959
|
+
children: jsxRuntime.jsx("div", {
|
|
13960
|
+
className: "c-select__selected-text",
|
|
13961
|
+
children: selectedLabel
|
|
13962
|
+
})
|
|
13767
13963
|
}), jsxRuntime.jsx("i", {
|
|
13768
13964
|
className: `${SELECT.CLASSES.ICON_CARET} ${SELECT.CLASSES.TOGGLE_ICON}`
|
|
13769
13965
|
}), jsxRuntime.jsx("div", {
|
|
@@ -13781,11 +13977,13 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13781
13977
|
id: id ? `${id}-listbox` : void 0,
|
|
13782
13978
|
"aria-labelledby": id,
|
|
13783
13979
|
children: hasOptionsProp ? options.map(((option, index) => jsxRuntime.jsx("li", {
|
|
13784
|
-
|
|
13980
|
+
id: `${id || "select"}-opt-${option.value}`,
|
|
13981
|
+
className: `${SELECT.CLASSES.SELECT_ITEM} ${focusedIndex === index ? "is-focused" : ""} ${multiple && Array.isArray(value) && _includesInstanceProperty(value).call(value, option.value) || value === option.value ? "is-selected" : ""}`,
|
|
13785
13982
|
"data-value": option.value,
|
|
13786
13983
|
onClick: () => !option.disabled && handleItemClick(option),
|
|
13984
|
+
onMouseEnter: () => setFocusedIndex(index),
|
|
13787
13985
|
role: "option",
|
|
13788
|
-
"aria-selected": value === option.value,
|
|
13986
|
+
"aria-selected": multiple && Array.isArray(value) && _includesInstanceProperty(value).call(value, option.value) || value === option.value,
|
|
13789
13987
|
"aria-disabled": option.disabled,
|
|
13790
13988
|
children: jsxRuntime.jsxs("label", {
|
|
13791
13989
|
htmlFor: `SelectItem${index}`,
|
|
@@ -13794,7 +13992,7 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13794
13992
|
type: "checkbox",
|
|
13795
13993
|
id: `SelectItem${index}`,
|
|
13796
13994
|
className: "c-checkbox__input c-select__item-input",
|
|
13797
|
-
checked: value === option.value,
|
|
13995
|
+
checked: multiple && Array.isArray(value) && _includesInstanceProperty(value).call(value, option.value) || value === option.value,
|
|
13798
13996
|
readOnly: !0,
|
|
13799
13997
|
disabled: option.disabled
|
|
13800
13998
|
}), jsxRuntime.jsx("div", {
|
|
@@ -13813,10 +14011,7 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
|
|
|
13813
14011
|
// Default glass settings for select components
|
|
13814
14012
|
const defaultGlassProps = {
|
|
13815
14013
|
displacementScale: 60,
|
|
13816
|
-
blurAmount:
|
|
13817
|
-
saturation: 180,
|
|
13818
|
-
aberrationIntensity: .2,
|
|
13819
|
-
borderRadius: 12,
|
|
14014
|
+
blurAmount: 10,
|
|
13820
14015
|
mode: "shader"
|
|
13821
14016
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
13822
14017
|
...defaultGlassProps,
|
|
@@ -22040,7 +22235,7 @@ class ThemeLogger {
|
|
|
22040
22235
|
document.body && document.body.setAttribute(dataAttribute, themeName),
|
|
22041
22236
|
// Also set on documentElement for broader compatibility
|
|
22042
22237
|
document.documentElement.setAttribute(dataAttribute, themeName));
|
|
22043
|
-
}, isValidThemeName = themeName => !(!themeName || "string" != typeof themeName) && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(themeName), createLocalStorageAdapter = () => ({
|
|
22238
|
+
}, getSystemTheme = () => isServer() ? "light" : window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light", isValidThemeName = themeName => !(!themeName || "string" != typeof themeName) && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(themeName), createLocalStorageAdapter = () => ({
|
|
22044
22239
|
getItem: key => {
|
|
22045
22240
|
if (isServer()) return null;
|
|
22046
22241
|
try {
|
|
@@ -22081,6 +22276,7 @@ class ThemeLogger {
|
|
|
22081
22276
|
applyThemeAttributes: applyThemeAttributes,
|
|
22082
22277
|
buildThemePath: buildThemePath,
|
|
22083
22278
|
createLocalStorageAdapter: createLocalStorageAdapter,
|
|
22279
|
+
getSystemTheme: getSystemTheme,
|
|
22084
22280
|
isBrowser: isBrowser,
|
|
22085
22281
|
isServer: isServer,
|
|
22086
22282
|
isValidThemeName: isValidThemeName,
|
|
@@ -22185,14 +22381,6 @@ class ThemeLogger {
|
|
|
22185
22381
|
return "undefined" == typeof window ? "light" : localStorage.getItem(storageKey) || "light";
|
|
22186
22382
|
}
|
|
22187
22383
|
|
|
22188
|
-
/**
|
|
22189
|
-
* Get system theme preference
|
|
22190
|
-
*
|
|
22191
|
-
* @returns 'dark' if system prefers dark mode, 'light' otherwise
|
|
22192
|
-
*/ function getSystemTheme() {
|
|
22193
|
-
return "undefined" == typeof window ? "light" : window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
22194
|
-
}
|
|
22195
|
-
|
|
22196
22384
|
/**
|
|
22197
22385
|
* Initialize theme based on saved preference or system preference
|
|
22198
22386
|
*
|