@udixio/ui-react 2.10.13 → 2.10.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -1
- package/.eslintrc.mjs +0 -22
- package/.storybook/main.ts +0 -20
- package/.storybook/preview.ts +0 -1
- package/CHANGELOG.md +0 -1144
- package/postcss.config.mjs +0 -5
- package/src/index.css +0 -4
- package/src/index.ts +0 -1
- package/src/lib/components/AnchorPositioner.tsx +0 -185
- package/src/lib/components/Button.tsx +0 -208
- package/src/lib/components/Card.tsx +0 -47
- package/src/lib/components/Carousel.tsx +0 -437
- package/src/lib/components/CarouselItem.tsx +0 -61
- package/src/lib/components/Checkbox.tsx +0 -120
- package/src/lib/components/Chip.tsx +0 -341
- package/src/lib/components/Chips.tsx +0 -331
- package/src/lib/components/ContextMenu.tsx +0 -109
- package/src/lib/components/DatePicker.tsx +0 -432
- package/src/lib/components/Divider.tsx +0 -20
- package/src/lib/components/Fab.tsx +0 -127
- package/src/lib/components/FabMenu.tsx +0 -239
- package/src/lib/components/IconButton.tsx +0 -146
- package/src/lib/components/Menu.tsx +0 -88
- package/src/lib/components/MenuGroup.tsx +0 -34
- package/src/lib/components/MenuHeadline.tsx +0 -9
- package/src/lib/components/MenuItem.tsx +0 -215
- package/src/lib/components/NavigationRail.tsx +0 -186
- package/src/lib/components/NavigationRailItem.tsx +0 -227
- package/src/lib/components/ProgressIndicator.tsx +0 -214
- package/src/lib/components/SideSheet.tsx +0 -135
- package/src/lib/components/Slider.tsx +0 -374
- package/src/lib/components/Snackbar.tsx +0 -77
- package/src/lib/components/Switch.tsx +0 -107
- package/src/lib/components/Tab.tsx +0 -123
- package/src/lib/components/TabGroup.tsx +0 -66
- package/src/lib/components/TabGroupContext.tsx +0 -16
- package/src/lib/components/TabPanel.tsx +0 -27
- package/src/lib/components/TabPanels.tsx +0 -76
- package/src/lib/components/Tabs.tsx +0 -105
- package/src/lib/components/TextField.tsx +0 -586
- package/src/lib/components/Tooltip.tsx +0 -217
- package/src/lib/components/index.ts +0 -34
- package/src/lib/config/config.interface.ts +0 -9
- package/src/lib/config/define-config.ts +0 -16
- package/src/lib/config/index.ts +0 -2
- package/src/lib/effects/AnimateOnScroll.ts +0 -391
- package/src/lib/effects/State.tsx +0 -90
- package/src/lib/effects/SyncedFixedWrapper.tsx +0 -62
- package/src/lib/effects/ThemeProvider.tsx +0 -174
- package/src/lib/effects/block-scroll.effect.tsx +0 -313
- package/src/lib/effects/custom-scroll/custom-scroll.effect.tsx +0 -407
- package/src/lib/effects/custom-scroll/custom-scroll.interface.ts +0 -29
- package/src/lib/effects/custom-scroll/custom-scroll.style.ts +0 -32
- package/src/lib/effects/custom-scroll/index.ts +0 -3
- package/src/lib/effects/index.ts +0 -7
- package/src/lib/effects/ripple/RippleEffect.tsx +0 -116
- package/src/lib/effects/ripple/index.tsx +0 -1
- package/src/lib/effects/scrollDriven.ts +0 -239
- package/src/lib/effects/smooth-scroll.effect.tsx +0 -112
- package/src/lib/effects/theme.worker.ts +0 -97
- package/src/lib/hooks/index.ts +0 -10
- package/src/lib/hooks/useTooltipTrigger.ts +0 -270
- package/src/lib/icon/icon.tsx +0 -125
- package/src/lib/icon/index.ts +0 -1
- package/src/lib/index.ts +0 -8
- package/src/lib/interfaces/button.interface.ts +0 -65
- package/src/lib/interfaces/card.interface.ts +0 -11
- package/src/lib/interfaces/carousel-item.interface.ts +0 -12
- package/src/lib/interfaces/carousel.interface.ts +0 -41
- package/src/lib/interfaces/checkbox.interface.ts +0 -39
- package/src/lib/interfaces/chip.interface.ts +0 -97
- package/src/lib/interfaces/chips.interface.ts +0 -37
- package/src/lib/interfaces/date-picker.interface.ts +0 -79
- package/src/lib/interfaces/divider.interface.ts +0 -7
- package/src/lib/interfaces/fab-menu.interface.ts +0 -12
- package/src/lib/interfaces/fab.interface.ts +0 -27
- package/src/lib/interfaces/icon-button.interface.ts +0 -38
- package/src/lib/interfaces/index.ts +0 -26
- package/src/lib/interfaces/menu-group.interface.ts +0 -13
- package/src/lib/interfaces/menu-item.interface.ts +0 -29
- package/src/lib/interfaces/menu.interface.ts +0 -19
- package/src/lib/interfaces/navigation-rail-item.interface.ts +0 -39
- package/src/lib/interfaces/navigation-rail.interface.ts +0 -39
- package/src/lib/interfaces/progress-indicator.interface.ts +0 -41
- package/src/lib/interfaces/side-sheet.interface.tsx +0 -28
- package/src/lib/interfaces/slider.interface.ts +0 -27
- package/src/lib/interfaces/snackbar.interface.ts +0 -13
- package/src/lib/interfaces/switch.interface.ts +0 -14
- package/src/lib/interfaces/tab-group.interface.ts +0 -13
- package/src/lib/interfaces/tab-panels.interface.ts +0 -21
- package/src/lib/interfaces/tab.interface.ts +0 -31
- package/src/lib/interfaces/tabs.interface.ts +0 -22
- package/src/lib/interfaces/text-field.interface.ts +0 -61
- package/src/lib/interfaces/tooltip.interface.ts +0 -61
- package/src/lib/styles/button.style.ts +0 -136
- package/src/lib/styles/card.style.ts +0 -29
- package/src/lib/styles/carousel-item.style.ts +0 -24
- package/src/lib/styles/carousel.style.ts +0 -22
- package/src/lib/styles/checkbox.style.ts +0 -64
- package/src/lib/styles/chip.style.ts +0 -62
- package/src/lib/styles/chips.style.ts +0 -20
- package/src/lib/styles/date-picker.style.ts +0 -43
- package/src/lib/styles/divider.style.ts +0 -31
- package/src/lib/styles/fab-menu.style.ts +0 -29
- package/src/lib/styles/fab.style.ts +0 -49
- package/src/lib/styles/icon-button.style.ts +0 -168
- package/src/lib/styles/index.ts +0 -25
- package/src/lib/styles/menu-group.style.ts +0 -34
- package/src/lib/styles/menu-headline.style.ts +0 -20
- package/src/lib/styles/menu-item.style.ts +0 -45
- package/src/lib/styles/menu.style.ts +0 -32
- package/src/lib/styles/navigation-rail-item.style.ts +0 -56
- package/src/lib/styles/navigation-rail.style.ts +0 -36
- package/src/lib/styles/progress-indicator.style.ts +0 -72
- package/src/lib/styles/side-sheet.style.ts +0 -45
- package/src/lib/styles/slider.style.ts +0 -41
- package/src/lib/styles/snackbar.style.ts +0 -26
- package/src/lib/styles/switch.style.ts +0 -67
- package/src/lib/styles/tab-panels.style.ts +0 -35
- package/src/lib/styles/tab.style.ts +0 -78
- package/src/lib/styles/tabs.style.ts +0 -22
- package/src/lib/styles/text-field.style.ts +0 -115
- package/src/lib/styles/tooltip.style.ts +0 -48
- package/src/lib/utils/component-helper.ts +0 -134
- package/src/lib/utils/component.ts +0 -34
- package/src/lib/utils/index.ts +0 -7
- package/src/lib/utils/string.ts +0 -9
- package/src/lib/utils/styles/classnames.ts +0 -49
- package/src/lib/utils/styles/get-classname.ts +0 -96
- package/src/lib/utils/styles/index.ts +0 -4
- package/src/lib/utils/styles/use-classnames.ts +0 -25
- package/src/stories/action/button.stories.tsx +0 -86
- package/src/stories/action/fab.stories.tsx +0 -54
- package/src/stories/action/icon-button.stories.tsx +0 -134
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +0 -5
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +0 -15
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +0 -3
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +0 -12
- package/src/stories/assets/youtube.svg +0 -4
- package/src/stories/communication/ProgressIndicator.stories.tsx +0 -57
- package/src/stories/communication/SnackBar.stories.tsx +0 -32
- package/src/stories/communication/tool-tip.stories.tsx +0 -133
- package/src/stories/containment/card.stories.tsx +0 -42
- package/src/stories/containment/carousel.stories.tsx +0 -65
- package/src/stories/containment/divider.stories.tsx +0 -35
- package/src/stories/containment/slide-sheet.stories.tsx +0 -45
- package/src/stories/effect/smooth-scroll.stories.tsx +0 -54
- package/src/stories/navigation/navigation-rail/navigation-rail-item.stories.tsx +0 -65
- package/src/stories/navigation/navigation-rail/navigation-rail.stories.tsx +0 -122
- package/src/stories/navigation/tabs/tab.stories.tsx +0 -57
- package/src/stories/navigation/tabs/tabs.stories.tsx +0 -102
- package/src/stories/selection/slider.stories.tsx +0 -85
- package/src/stories/selection/switch.stories.tsx +0 -46
- package/src/stories/text-inputs/text-field.stories.tsx +0 -135
- package/src/tests/Button.spec.tsx +0 -67
- package/src/tests/useClassNames.spec.tsx +0 -82
- package/src/udixio.css +0 -120
- package/theme.config.ts +0 -7
- package/tsconfig.json +0 -16
- package/tsconfig.lib.json +0 -51
- package/tsconfig.spec.json +0 -37
- package/tsconfig.storybook.json +0 -38
- package/vite.config.ts +0 -96
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
2
|
-
|
|
3
|
-
export type InitAnimationOptions = {
|
|
4
|
-
once?: boolean;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
let initialized = false;
|
|
8
|
-
let teardown: (() => void) | null = null;
|
|
9
|
-
|
|
10
|
-
function supportsScrollTimeline(): boolean {
|
|
11
|
-
if (typeof window === 'undefined') return false;
|
|
12
|
-
try {
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
if (window.CSS && typeof window.CSS.supports === 'function') {
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
return (
|
|
17
|
-
CSS.supports('animation-timeline: view()') ||
|
|
18
|
-
CSS.supports('animation-timeline: scroll()') ||
|
|
19
|
-
CSS.supports('view-timeline-name: --a')
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
} catch {}
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function prefersReducedMotion(): boolean {
|
|
27
|
-
if (typeof window === 'undefined' || !('matchMedia' in window)) return false;
|
|
28
|
-
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Helpers to read CSS custom properties used by the Tailwind plugin
|
|
32
|
-
function readVar(el: Element, name: string): string | null {
|
|
33
|
-
const v = getComputedStyle(el).getPropertyValue(name).trim();
|
|
34
|
-
return v || null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function parsePercentFromRangeToken(token?: string | null): number | null {
|
|
38
|
-
if (!token) return null;
|
|
39
|
-
// Expect patterns like "entry 20%", "cover 80%", "center 60%" etc.
|
|
40
|
-
const parts = token.split(/\s+/);
|
|
41
|
-
const last = parts[parts.length - 1];
|
|
42
|
-
if (!last) return null;
|
|
43
|
-
if (last.endsWith('%')) {
|
|
44
|
-
const n = parseFloat(last);
|
|
45
|
-
if (!isNaN(n)) return Math.max(0, Math.min(100, n)) / 100;
|
|
46
|
-
}
|
|
47
|
-
// px not supported for now (would require element size); fallback null
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function getRange(el: Element): { start: number; end: number } {
|
|
52
|
-
const startToken = readVar(el, '--udx-range-start');
|
|
53
|
-
const endToken = readVar(el, '--udx-range-end');
|
|
54
|
-
const start = parsePercentFromRangeToken(startToken) ?? 0.2; // default entry 20%
|
|
55
|
-
const end = parsePercentFromRangeToken(endToken) ?? 0.5; // default cover 50%
|
|
56
|
-
// Ensure sane ordering
|
|
57
|
-
const s = Math.max(0, Math.min(1, start));
|
|
58
|
-
const e = Math.max(s + 0.001, Math.min(1, end));
|
|
59
|
-
return { start: s, end: e };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function num(val: string | null | undefined, unit?: 'px' | 'deg'): number | null {
|
|
63
|
-
if (!val) return null;
|
|
64
|
-
const v = val.trim();
|
|
65
|
-
if (unit && v.endsWith(unit)) {
|
|
66
|
-
const n = parseFloat(v);
|
|
67
|
-
return isNaN(n) ? null : n;
|
|
68
|
-
}
|
|
69
|
-
// Try plain number
|
|
70
|
-
const n = parseFloat(v);
|
|
71
|
-
return isNaN(n) ? null : n;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function lerp(a: number, b: number, t: number) {
|
|
75
|
-
return a + (b - a) * t;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function applyProgress(el: HTMLElement, from: CSSProperties, to: CSSProperties, p: number) {
|
|
79
|
-
// Opacity
|
|
80
|
-
const o0 = from.opacity != null ? Number(from.opacity) : 1;
|
|
81
|
-
const o1 = to.opacity != null ? Number(to.opacity) : 1;
|
|
82
|
-
const op = lerp(o0, o1, p);
|
|
83
|
-
el.style.opacity = String(op);
|
|
84
|
-
|
|
85
|
-
// Transform: translateX/Y (px only), scale, rotate (deg)
|
|
86
|
-
const fx = num((from as any)['--tw-enter-translate-x'] as any) ??
|
|
87
|
-
num((from as any)['--tw-exit-translate-x'] as any) ?? 0;
|
|
88
|
-
const fy = num((from as any)['--tw-enter-translate-y'] as any) ??
|
|
89
|
-
num((from as any)['--tw-exit-translate-y'] as any) ?? 0;
|
|
90
|
-
const tx = num((to as any)['--tw-enter-translate-x'] as any) ??
|
|
91
|
-
num((to as any)['--tw-exit-translate-x'] as any) ?? 0;
|
|
92
|
-
const ty = num((to as any)['--tw-enter-translate-y'] as any) ??
|
|
93
|
-
num((to as any)['--tw-exit-translate-y'] as any) ?? 0;
|
|
94
|
-
|
|
95
|
-
const fs = num((from as any)['--tw-enter-scale'] as any) ??
|
|
96
|
-
num((from as any)['--tw-exit-scale'] as any) ?? 1;
|
|
97
|
-
const ts = num((to as any)['--tw-enter-scale'] as any) ??
|
|
98
|
-
num((to as any)['--tw-exit-scale'] as any) ?? 1;
|
|
99
|
-
|
|
100
|
-
const fr = num((from as any)['--tw-enter-rotate'] as any) ??
|
|
101
|
-
num((from as any)['--tw-exit-rotate'] as any) ?? 0;
|
|
102
|
-
const tr = num((to as any)['--tw-enter-rotate'] as any) ??
|
|
103
|
-
num((to as any)['--tw-exit-rotate'] as any) ?? 0;
|
|
104
|
-
|
|
105
|
-
const x = lerp(fx, tx, p);
|
|
106
|
-
const y = lerp(fy, ty, p);
|
|
107
|
-
const s = lerp(fs, ts, p);
|
|
108
|
-
const r = lerp(fr, tr, p);
|
|
109
|
-
|
|
110
|
-
const transforms: string[] = [];
|
|
111
|
-
if (x !== 0 || y !== 0) transforms.push(`translate3d(${x}px, ${y}px, 0)`);
|
|
112
|
-
if (s !== 1) transforms.push(`scale(${s})`);
|
|
113
|
-
if (r !== 0) transforms.push(`rotate(${r}deg)`);
|
|
114
|
-
el.style.transform = transforms.length ? transforms.join(' ') : 'none';
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function buildFromTo(el: Element): { from: CSSProperties; to: CSSProperties } | null {
|
|
118
|
-
const cls = el.classList;
|
|
119
|
-
const isIn = cls.contains('animate-in');
|
|
120
|
-
const isOut = cls.contains('animate-out');
|
|
121
|
-
if (!isIn && !isOut) return null;
|
|
122
|
-
|
|
123
|
-
const cs = getComputedStyle(el as Element);
|
|
124
|
-
const enter = {
|
|
125
|
-
opacity: num(cs.getPropertyValue('--tw-enter-opacity')) ?? undefined,
|
|
126
|
-
'--tw-enter-translate-x': cs.getPropertyValue('--tw-enter-translate-x') || undefined,
|
|
127
|
-
'--tw-enter-translate-y': cs.getPropertyValue('--tw-enter-translate-y') || undefined,
|
|
128
|
-
'--tw-enter-scale': cs.getPropertyValue('--tw-enter-scale') || undefined,
|
|
129
|
-
'--tw-enter-rotate': cs.getPropertyValue('--tw-enter-rotate') || undefined,
|
|
130
|
-
} as CSSProperties & Record<string, any>;
|
|
131
|
-
const exit = {
|
|
132
|
-
opacity: num(cs.getPropertyValue('--tw-exit-opacity')) ?? undefined,
|
|
133
|
-
'--tw-exit-translate-x': cs.getPropertyValue('--tw-exit-translate-x') || undefined,
|
|
134
|
-
'--tw-exit-translate-y': cs.getPropertyValue('--tw-exit-translate-y') || undefined,
|
|
135
|
-
'--tw-exit-scale': cs.getPropertyValue('--tw-exit-scale') || undefined,
|
|
136
|
-
'--tw-exit-rotate': cs.getPropertyValue('--tw-exit-rotate') || undefined,
|
|
137
|
-
} as CSSProperties & Record<string, any>;
|
|
138
|
-
|
|
139
|
-
if (isIn) {
|
|
140
|
-
// from enter vars to neutral
|
|
141
|
-
return {
|
|
142
|
-
from: enter,
|
|
143
|
-
to: { opacity: 1, '--tw-enter-translate-x': '0', '--tw-enter-translate-y': '0', '--tw-enter-scale': '1', '--tw-enter-rotate': '0' } as any,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
if (isOut) {
|
|
147
|
-
// from neutral to exit vars
|
|
148
|
-
return {
|
|
149
|
-
from: { opacity: 1, '--tw-exit-translate-x': '0', '--tw-exit-translate-y': '0', '--tw-exit-scale': '1', '--tw-exit-rotate': '0' } as any,
|
|
150
|
-
to: exit,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function findTargets(): HTMLElement[] {
|
|
157
|
-
const selector = [
|
|
158
|
-
'.udx-view',
|
|
159
|
-
'.udx-view-x',
|
|
160
|
-
'.udx-view-y',
|
|
161
|
-
'.udx-view-inline',
|
|
162
|
-
'.udx-view-block',
|
|
163
|
-
'[data-udx-view]'
|
|
164
|
-
]
|
|
165
|
-
.map((s) => `${s}.animate-in, ${s}.animate-out`)
|
|
166
|
-
.join(', ');
|
|
167
|
-
return Array.from(document.querySelectorAll<HTMLElement>(selector));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export function initScrollViewFallback(options: InitAnimationOptions = {}) {
|
|
171
|
-
if (initialized) return teardown || (() => {});
|
|
172
|
-
if (typeof window === 'undefined') return () => {};
|
|
173
|
-
if (supportsScrollTimeline() || prefersReducedMotion()) {
|
|
174
|
-
initialized = true; // No-op in supporting browsers or reduced motion
|
|
175
|
-
return () => {};
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
initialized = true;
|
|
179
|
-
const once = options.once ?? true;
|
|
180
|
-
const seen = new WeakSet<Element>();
|
|
181
|
-
let rafId: number | null = null;
|
|
182
|
-
|
|
183
|
-
const measure = () => {
|
|
184
|
-
const targets = findTargets();
|
|
185
|
-
const vh = window.innerHeight || 0;
|
|
186
|
-
for (const el of targets) {
|
|
187
|
-
const rect = el.getBoundingClientRect();
|
|
188
|
-
const visible = Math.min(rect.bottom, vh) - Math.max(rect.top, 0);
|
|
189
|
-
const visibleClamped = Math.max(0, Math.min(visible, rect.height));
|
|
190
|
-
const ratio = rect.height > 0 ? visibleClamped / rect.height : 0;
|
|
191
|
-
|
|
192
|
-
const { start, end } = getRange(el);
|
|
193
|
-
let p = (ratio - start) / (end - start);
|
|
194
|
-
p = Math.max(0, Math.min(1, p));
|
|
195
|
-
|
|
196
|
-
if (once && seen.has(el) && p < 1) p = 1;
|
|
197
|
-
|
|
198
|
-
const fe = buildFromTo(el);
|
|
199
|
-
if (!fe) continue;
|
|
200
|
-
const { from, to } = fe;
|
|
201
|
-
applyProgress(el, from, to, p);
|
|
202
|
-
|
|
203
|
-
if (p >= 1 && once) seen.add(el);
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const onScroll = () => {
|
|
208
|
-
if (rafId != null) return;
|
|
209
|
-
rafId = window.requestAnimationFrame(() => {
|
|
210
|
-
rafId = null;
|
|
211
|
-
measure();
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
// Initial run and listeners
|
|
216
|
-
measure();
|
|
217
|
-
window.addEventListener('scroll', onScroll, { passive: true });
|
|
218
|
-
window.addEventListener('resize', onScroll);
|
|
219
|
-
|
|
220
|
-
const mo = new MutationObserver(() => {
|
|
221
|
-
onScroll();
|
|
222
|
-
});
|
|
223
|
-
mo.observe(document.documentElement, {
|
|
224
|
-
childList: true,
|
|
225
|
-
subtree: true,
|
|
226
|
-
attributes: true,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
teardown = () => {
|
|
230
|
-
window.removeEventListener('scroll', onScroll);
|
|
231
|
-
window.removeEventListener('resize', onScroll);
|
|
232
|
-
if (rafId != null) cancelAnimationFrame(rafId);
|
|
233
|
-
mo.disconnect();
|
|
234
|
-
initialized = false;
|
|
235
|
-
teardown = null;
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
return teardown;
|
|
239
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { ReactNode, useEffect, useRef } from 'react';
|
|
2
|
-
import Lenis from 'lenis';
|
|
3
|
-
|
|
4
|
-
export type SmoothScrollProps = {
|
|
5
|
-
/**
|
|
6
|
-
* Duration of the scroll animation in seconds or as a CSS string (e.g., '1s', '500ms').
|
|
7
|
-
* Default: 1.2
|
|
8
|
-
*/
|
|
9
|
-
transition?: number | string;
|
|
10
|
-
/**
|
|
11
|
-
* Easing function for the scroll animation.
|
|
12
|
-
* Default: easeOutQuint
|
|
13
|
-
*/
|
|
14
|
-
easing?: (t: number) => number;
|
|
15
|
-
/**
|
|
16
|
-
* Scroll orientation.
|
|
17
|
-
* Default: 'vertical'
|
|
18
|
-
*/
|
|
19
|
-
orientation?: 'vertical' | 'horizontal';
|
|
20
|
-
/**
|
|
21
|
-
* Enable smooth scrolling on touch devices.
|
|
22
|
-
* Default: false (native touch scrolling is usually preferred)
|
|
23
|
-
*/
|
|
24
|
-
smoothTouch?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Multiplier for touch scroll sensitivity.
|
|
27
|
-
* Default: 2
|
|
28
|
-
*/
|
|
29
|
-
touchMultiplier?: number;
|
|
30
|
-
/**
|
|
31
|
-
* Children elements (optional, component works at document level)
|
|
32
|
-
*/
|
|
33
|
-
children?: ReactNode;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* SmoothScroll component using Lenis for smooth scrolling.
|
|
38
|
-
* This component enables smooth scrolling at the document level.
|
|
39
|
-
*
|
|
40
|
-
* @warning **Use with caution.** Overriding native scroll behavior can cause:
|
|
41
|
-
* - **Accessibility issues**: Screen readers, keyboard navigation, and assistive technologies
|
|
42
|
-
* may not work correctly with custom scroll implementations.
|
|
43
|
-
* - **Anchor links broken**: `scrollIntoView()`, hash navigation (`#section`), and
|
|
44
|
-
* `window.scrollTo()` may behave unexpectedly or be ignored.
|
|
45
|
-
* - **Third-party library conflicts**: Libraries relying on native scroll events
|
|
46
|
-
* (infinite scroll, lazy loading, scroll-triggered animations) may malfunction.
|
|
47
|
-
* - **Browser features disabled**: Find-in-page (Ctrl+F), autoscroll, and native
|
|
48
|
-
* momentum scrolling on trackpads may not work as expected.
|
|
49
|
-
* - **Performance overhead**: The RAF loop runs continuously, which may impact
|
|
50
|
-
* battery life and performance on low-end devices.
|
|
51
|
-
* - **Mobile issues**: Touch gestures, pull-to-refresh, and overscroll behaviors
|
|
52
|
-
* can conflict with smooth scroll implementations.
|
|
53
|
-
*/
|
|
54
|
-
export const SmoothScroll = ({
|
|
55
|
-
transition = 1.2,
|
|
56
|
-
easing,
|
|
57
|
-
orientation = 'vertical',
|
|
58
|
-
smoothTouch = false,
|
|
59
|
-
touchMultiplier = 2,
|
|
60
|
-
children,
|
|
61
|
-
}: SmoothScrollProps) => {
|
|
62
|
-
const lenisRef = useRef<Lenis | null>(null);
|
|
63
|
-
const rafRef = useRef<number | null>(null);
|
|
64
|
-
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
// Parse duration from string if needed (e.g., '1s' -> 1, '500ms' -> 0.5)
|
|
67
|
-
let duration: number;
|
|
68
|
-
if (typeof transition === 'string') {
|
|
69
|
-
if (transition.endsWith('ms')) {
|
|
70
|
-
duration = parseFloat(transition) / 1000;
|
|
71
|
-
} else if (transition.endsWith('s')) {
|
|
72
|
-
duration = parseFloat(transition);
|
|
73
|
-
} else {
|
|
74
|
-
duration = parseFloat(transition) || 1.2;
|
|
75
|
-
}
|
|
76
|
-
} else {
|
|
77
|
-
duration = transition;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Default easing: easeOutQuint
|
|
81
|
-
const defaultEasing = (t: number) => 1 - Math.pow(1 - t, 5);
|
|
82
|
-
|
|
83
|
-
// Initialize Lenis
|
|
84
|
-
lenisRef.current = new Lenis({
|
|
85
|
-
duration,
|
|
86
|
-
easing: easing ?? defaultEasing,
|
|
87
|
-
orientation,
|
|
88
|
-
smoothWheel: true,
|
|
89
|
-
touchMultiplier,
|
|
90
|
-
syncTouch: smoothTouch,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// Animation frame loop
|
|
94
|
-
const raf = (time: number) => {
|
|
95
|
-
lenisRef.current?.raf(time);
|
|
96
|
-
rafRef.current = requestAnimationFrame(raf);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
rafRef.current = requestAnimationFrame(raf);
|
|
100
|
-
|
|
101
|
-
// Cleanup
|
|
102
|
-
return () => {
|
|
103
|
-
if (rafRef.current !== null) {
|
|
104
|
-
cancelAnimationFrame(rafRef.current);
|
|
105
|
-
}
|
|
106
|
-
lenisRef.current?.destroy();
|
|
107
|
-
lenisRef.current = null;
|
|
108
|
-
};
|
|
109
|
-
}, [transition, easing, orientation, smoothTouch, touchMultiplier]);
|
|
110
|
-
|
|
111
|
-
return children ? <>{children}</> : null;
|
|
112
|
-
};
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loader,
|
|
3
|
-
getVariantByName,
|
|
4
|
-
Hct,
|
|
5
|
-
FontPlugin,
|
|
6
|
-
} from '@udixio/theme';
|
|
7
|
-
import type { API, FontPluginOptions, ThemeContextSnapshot } from '@udixio/theme';
|
|
8
|
-
import { TailwindPlugin } from '@udixio/tailwind';
|
|
9
|
-
import type { TailwindPluginOptions } from '@udixio/tailwind';
|
|
10
|
-
|
|
11
|
-
export interface WorkerInboundMessage {
|
|
12
|
-
id: number;
|
|
13
|
-
snapshot: ThemeContextSnapshot;
|
|
14
|
-
tailwindOptions: TailwindPluginOptions;
|
|
15
|
-
fontOptions: FontPluginOptions;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface WorkerOutboundMessage {
|
|
19
|
-
id: number;
|
|
20
|
-
css: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
let workerApi: API | null = null;
|
|
24
|
-
let latestMessage: WorkerInboundMessage | null = null;
|
|
25
|
-
let processing = false;
|
|
26
|
-
|
|
27
|
-
async function processLatest() {
|
|
28
|
-
if (processing || !latestMessage) return;
|
|
29
|
-
processing = true;
|
|
30
|
-
|
|
31
|
-
const msg = latestMessage;
|
|
32
|
-
latestMessage = null;
|
|
33
|
-
|
|
34
|
-
const { snapshot, tailwindOptions, fontOptions } = msg;
|
|
35
|
-
|
|
36
|
-
const palettesCallbacks = Object.fromEntries(
|
|
37
|
-
Object.entries(snapshot.palettes).map(([key, { hue, chroma }]) => [
|
|
38
|
-
key,
|
|
39
|
-
() => ({ hue, chroma }),
|
|
40
|
-
]),
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
if (!workerApi) {
|
|
45
|
-
// Initialisation unique — coût amorti sur tous les messages suivants
|
|
46
|
-
workerApi = await loader(
|
|
47
|
-
{
|
|
48
|
-
sourceColor: Hct.from(
|
|
49
|
-
snapshot.sourceColor.hue,
|
|
50
|
-
snapshot.sourceColor.chroma,
|
|
51
|
-
snapshot.sourceColor.tone,
|
|
52
|
-
),
|
|
53
|
-
isDark: snapshot.isDark,
|
|
54
|
-
contrastLevel: snapshot.contrastLevel,
|
|
55
|
-
variant: getVariantByName(snapshot.variantName),
|
|
56
|
-
plugins: [new FontPlugin(fontOptions), new TailwindPlugin(tailwindOptions)],
|
|
57
|
-
},
|
|
58
|
-
false,
|
|
59
|
-
);
|
|
60
|
-
workerApi.palettes.sync(palettesCallbacks);
|
|
61
|
-
} else {
|
|
62
|
-
// Mise à jour légère — pas de re-bootstrap
|
|
63
|
-
workerApi.context.update({
|
|
64
|
-
isDark: snapshot.isDark,
|
|
65
|
-
contrastLevel: snapshot.contrastLevel,
|
|
66
|
-
sourceColor: Hct.from(
|
|
67
|
-
snapshot.sourceColor.hue,
|
|
68
|
-
snapshot.sourceColor.chroma,
|
|
69
|
-
snapshot.sourceColor.tone,
|
|
70
|
-
),
|
|
71
|
-
variant: getVariantByName(snapshot.variantName),
|
|
72
|
-
});
|
|
73
|
-
workerApi.palettes.sync(palettesCallbacks);
|
|
74
|
-
|
|
75
|
-
// Mise à jour des options plugins si elles ont changé
|
|
76
|
-
workerApi.plugins.getPlugin(TailwindPlugin).options = tailwindOptions;
|
|
77
|
-
workerApi.plugins.getPlugin(FontPlugin).options = fontOptions;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
await workerApi.load();
|
|
81
|
-
|
|
82
|
-
const css = workerApi.plugins.getPlugin(TailwindPlugin).getInstance().outputCss;
|
|
83
|
-
self.postMessage({ id: msg.id, css } satisfies WorkerOutboundMessage);
|
|
84
|
-
} catch (e) {
|
|
85
|
-
console.error('[Worker] error during processLatest:', e);
|
|
86
|
-
workerApi = null; // reset state for clean retry
|
|
87
|
-
} finally {
|
|
88
|
-
processing = false;
|
|
89
|
-
// Traite le prochain message s'il est arrivé pendant le traitement
|
|
90
|
-
processLatest();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
self.onmessage = (event: MessageEvent<WorkerInboundMessage>) => {
|
|
95
|
-
latestMessage = event.data;
|
|
96
|
-
processLatest();
|
|
97
|
-
};
|
package/src/lib/hooks/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { useTooltipTrigger } from './useTooltipTrigger';
|
|
2
|
-
export type {
|
|
3
|
-
UseTooltipTriggerOptions,
|
|
4
|
-
UseTooltipTriggerReturn,
|
|
5
|
-
} from './useTooltipTrigger';
|
|
6
|
-
|
|
7
|
-
export type {
|
|
8
|
-
UseTooltipPositionOptions,
|
|
9
|
-
UseTooltipPositionReturn,
|
|
10
|
-
} from './useTooltipPosition';
|