@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.
Files changed (173) hide show
  1. package/package.json +4 -1
  2. package/.eslintrc.mjs +0 -22
  3. package/.storybook/main.ts +0 -20
  4. package/.storybook/preview.ts +0 -1
  5. package/CHANGELOG.md +0 -1144
  6. package/postcss.config.mjs +0 -5
  7. package/src/index.css +0 -4
  8. package/src/index.ts +0 -1
  9. package/src/lib/components/AnchorPositioner.tsx +0 -185
  10. package/src/lib/components/Button.tsx +0 -208
  11. package/src/lib/components/Card.tsx +0 -47
  12. package/src/lib/components/Carousel.tsx +0 -437
  13. package/src/lib/components/CarouselItem.tsx +0 -61
  14. package/src/lib/components/Checkbox.tsx +0 -120
  15. package/src/lib/components/Chip.tsx +0 -341
  16. package/src/lib/components/Chips.tsx +0 -331
  17. package/src/lib/components/ContextMenu.tsx +0 -109
  18. package/src/lib/components/DatePicker.tsx +0 -432
  19. package/src/lib/components/Divider.tsx +0 -20
  20. package/src/lib/components/Fab.tsx +0 -127
  21. package/src/lib/components/FabMenu.tsx +0 -239
  22. package/src/lib/components/IconButton.tsx +0 -146
  23. package/src/lib/components/Menu.tsx +0 -88
  24. package/src/lib/components/MenuGroup.tsx +0 -34
  25. package/src/lib/components/MenuHeadline.tsx +0 -9
  26. package/src/lib/components/MenuItem.tsx +0 -215
  27. package/src/lib/components/NavigationRail.tsx +0 -186
  28. package/src/lib/components/NavigationRailItem.tsx +0 -227
  29. package/src/lib/components/ProgressIndicator.tsx +0 -214
  30. package/src/lib/components/SideSheet.tsx +0 -135
  31. package/src/lib/components/Slider.tsx +0 -374
  32. package/src/lib/components/Snackbar.tsx +0 -77
  33. package/src/lib/components/Switch.tsx +0 -107
  34. package/src/lib/components/Tab.tsx +0 -123
  35. package/src/lib/components/TabGroup.tsx +0 -66
  36. package/src/lib/components/TabGroupContext.tsx +0 -16
  37. package/src/lib/components/TabPanel.tsx +0 -27
  38. package/src/lib/components/TabPanels.tsx +0 -76
  39. package/src/lib/components/Tabs.tsx +0 -105
  40. package/src/lib/components/TextField.tsx +0 -586
  41. package/src/lib/components/Tooltip.tsx +0 -217
  42. package/src/lib/components/index.ts +0 -34
  43. package/src/lib/config/config.interface.ts +0 -9
  44. package/src/lib/config/define-config.ts +0 -16
  45. package/src/lib/config/index.ts +0 -2
  46. package/src/lib/effects/AnimateOnScroll.ts +0 -391
  47. package/src/lib/effects/State.tsx +0 -90
  48. package/src/lib/effects/SyncedFixedWrapper.tsx +0 -62
  49. package/src/lib/effects/ThemeProvider.tsx +0 -174
  50. package/src/lib/effects/block-scroll.effect.tsx +0 -313
  51. package/src/lib/effects/custom-scroll/custom-scroll.effect.tsx +0 -407
  52. package/src/lib/effects/custom-scroll/custom-scroll.interface.ts +0 -29
  53. package/src/lib/effects/custom-scroll/custom-scroll.style.ts +0 -32
  54. package/src/lib/effects/custom-scroll/index.ts +0 -3
  55. package/src/lib/effects/index.ts +0 -7
  56. package/src/lib/effects/ripple/RippleEffect.tsx +0 -116
  57. package/src/lib/effects/ripple/index.tsx +0 -1
  58. package/src/lib/effects/scrollDriven.ts +0 -239
  59. package/src/lib/effects/smooth-scroll.effect.tsx +0 -112
  60. package/src/lib/effects/theme.worker.ts +0 -97
  61. package/src/lib/hooks/index.ts +0 -10
  62. package/src/lib/hooks/useTooltipTrigger.ts +0 -270
  63. package/src/lib/icon/icon.tsx +0 -125
  64. package/src/lib/icon/index.ts +0 -1
  65. package/src/lib/index.ts +0 -8
  66. package/src/lib/interfaces/button.interface.ts +0 -65
  67. package/src/lib/interfaces/card.interface.ts +0 -11
  68. package/src/lib/interfaces/carousel-item.interface.ts +0 -12
  69. package/src/lib/interfaces/carousel.interface.ts +0 -41
  70. package/src/lib/interfaces/checkbox.interface.ts +0 -39
  71. package/src/lib/interfaces/chip.interface.ts +0 -97
  72. package/src/lib/interfaces/chips.interface.ts +0 -37
  73. package/src/lib/interfaces/date-picker.interface.ts +0 -79
  74. package/src/lib/interfaces/divider.interface.ts +0 -7
  75. package/src/lib/interfaces/fab-menu.interface.ts +0 -12
  76. package/src/lib/interfaces/fab.interface.ts +0 -27
  77. package/src/lib/interfaces/icon-button.interface.ts +0 -38
  78. package/src/lib/interfaces/index.ts +0 -26
  79. package/src/lib/interfaces/menu-group.interface.ts +0 -13
  80. package/src/lib/interfaces/menu-item.interface.ts +0 -29
  81. package/src/lib/interfaces/menu.interface.ts +0 -19
  82. package/src/lib/interfaces/navigation-rail-item.interface.ts +0 -39
  83. package/src/lib/interfaces/navigation-rail.interface.ts +0 -39
  84. package/src/lib/interfaces/progress-indicator.interface.ts +0 -41
  85. package/src/lib/interfaces/side-sheet.interface.tsx +0 -28
  86. package/src/lib/interfaces/slider.interface.ts +0 -27
  87. package/src/lib/interfaces/snackbar.interface.ts +0 -13
  88. package/src/lib/interfaces/switch.interface.ts +0 -14
  89. package/src/lib/interfaces/tab-group.interface.ts +0 -13
  90. package/src/lib/interfaces/tab-panels.interface.ts +0 -21
  91. package/src/lib/interfaces/tab.interface.ts +0 -31
  92. package/src/lib/interfaces/tabs.interface.ts +0 -22
  93. package/src/lib/interfaces/text-field.interface.ts +0 -61
  94. package/src/lib/interfaces/tooltip.interface.ts +0 -61
  95. package/src/lib/styles/button.style.ts +0 -136
  96. package/src/lib/styles/card.style.ts +0 -29
  97. package/src/lib/styles/carousel-item.style.ts +0 -24
  98. package/src/lib/styles/carousel.style.ts +0 -22
  99. package/src/lib/styles/checkbox.style.ts +0 -64
  100. package/src/lib/styles/chip.style.ts +0 -62
  101. package/src/lib/styles/chips.style.ts +0 -20
  102. package/src/lib/styles/date-picker.style.ts +0 -43
  103. package/src/lib/styles/divider.style.ts +0 -31
  104. package/src/lib/styles/fab-menu.style.ts +0 -29
  105. package/src/lib/styles/fab.style.ts +0 -49
  106. package/src/lib/styles/icon-button.style.ts +0 -168
  107. package/src/lib/styles/index.ts +0 -25
  108. package/src/lib/styles/menu-group.style.ts +0 -34
  109. package/src/lib/styles/menu-headline.style.ts +0 -20
  110. package/src/lib/styles/menu-item.style.ts +0 -45
  111. package/src/lib/styles/menu.style.ts +0 -32
  112. package/src/lib/styles/navigation-rail-item.style.ts +0 -56
  113. package/src/lib/styles/navigation-rail.style.ts +0 -36
  114. package/src/lib/styles/progress-indicator.style.ts +0 -72
  115. package/src/lib/styles/side-sheet.style.ts +0 -45
  116. package/src/lib/styles/slider.style.ts +0 -41
  117. package/src/lib/styles/snackbar.style.ts +0 -26
  118. package/src/lib/styles/switch.style.ts +0 -67
  119. package/src/lib/styles/tab-panels.style.ts +0 -35
  120. package/src/lib/styles/tab.style.ts +0 -78
  121. package/src/lib/styles/tabs.style.ts +0 -22
  122. package/src/lib/styles/text-field.style.ts +0 -115
  123. package/src/lib/styles/tooltip.style.ts +0 -48
  124. package/src/lib/utils/component-helper.ts +0 -134
  125. package/src/lib/utils/component.ts +0 -34
  126. package/src/lib/utils/index.ts +0 -7
  127. package/src/lib/utils/string.ts +0 -9
  128. package/src/lib/utils/styles/classnames.ts +0 -49
  129. package/src/lib/utils/styles/get-classname.ts +0 -96
  130. package/src/lib/utils/styles/index.ts +0 -4
  131. package/src/lib/utils/styles/use-classnames.ts +0 -25
  132. package/src/stories/action/button.stories.tsx +0 -86
  133. package/src/stories/action/fab.stories.tsx +0 -54
  134. package/src/stories/action/icon-button.stories.tsx +0 -134
  135. package/src/stories/assets/accessibility.png +0 -0
  136. package/src/stories/assets/accessibility.svg +0 -5
  137. package/src/stories/assets/addon-library.png +0 -0
  138. package/src/stories/assets/assets.png +0 -0
  139. package/src/stories/assets/context.png +0 -0
  140. package/src/stories/assets/discord.svg +0 -15
  141. package/src/stories/assets/docs.png +0 -0
  142. package/src/stories/assets/figma-plugin.png +0 -0
  143. package/src/stories/assets/github.svg +0 -3
  144. package/src/stories/assets/share.png +0 -0
  145. package/src/stories/assets/styling.png +0 -0
  146. package/src/stories/assets/testing.png +0 -0
  147. package/src/stories/assets/theming.png +0 -0
  148. package/src/stories/assets/tutorials.svg +0 -12
  149. package/src/stories/assets/youtube.svg +0 -4
  150. package/src/stories/communication/ProgressIndicator.stories.tsx +0 -57
  151. package/src/stories/communication/SnackBar.stories.tsx +0 -32
  152. package/src/stories/communication/tool-tip.stories.tsx +0 -133
  153. package/src/stories/containment/card.stories.tsx +0 -42
  154. package/src/stories/containment/carousel.stories.tsx +0 -65
  155. package/src/stories/containment/divider.stories.tsx +0 -35
  156. package/src/stories/containment/slide-sheet.stories.tsx +0 -45
  157. package/src/stories/effect/smooth-scroll.stories.tsx +0 -54
  158. package/src/stories/navigation/navigation-rail/navigation-rail-item.stories.tsx +0 -65
  159. package/src/stories/navigation/navigation-rail/navigation-rail.stories.tsx +0 -122
  160. package/src/stories/navigation/tabs/tab.stories.tsx +0 -57
  161. package/src/stories/navigation/tabs/tabs.stories.tsx +0 -102
  162. package/src/stories/selection/slider.stories.tsx +0 -85
  163. package/src/stories/selection/switch.stories.tsx +0 -46
  164. package/src/stories/text-inputs/text-field.stories.tsx +0 -135
  165. package/src/tests/Button.spec.tsx +0 -67
  166. package/src/tests/useClassNames.spec.tsx +0 -82
  167. package/src/udixio.css +0 -120
  168. package/theme.config.ts +0 -7
  169. package/tsconfig.json +0 -16
  170. package/tsconfig.lib.json +0 -51
  171. package/tsconfig.spec.json +0 -37
  172. package/tsconfig.storybook.json +0 -38
  173. package/vite.config.ts +0 -96
@@ -1,374 +0,0 @@
1
- import { AnimatePresence, motion } from 'motion/react';
2
- import { SliderInterface } from '../interfaces';
3
- import { useSliderStyle } from '../styles';
4
- import { classNames, ReactProps } from '../utils';
5
- import { useEffect, useRef, useState } from 'react';
6
-
7
- /**
8
- * Sliders let users make selections from a range of values
9
- * @status beta
10
- * @category Input
11
- * @devx
12
- * - `value` is treated as the initial value; component is uncontrolled after mount.
13
- * - `onChange` receives the numeric value (not the DOM event).
14
- * @a11y
15
- * - Provides slider role/aria values, but no label prop.
16
- */
17
- export const Slider = ({
18
- className,
19
- valueFormatter,
20
- step = 10,
21
- name,
22
- value: defaultValue = 0,
23
- min = 0,
24
- max = 100,
25
- marks = [
26
- {
27
- value: 0,
28
- label: '0',
29
- },
30
- {
31
- value: 100,
32
- label: '100',
33
- },
34
- ],
35
- ref,
36
- onChange,
37
- ...restProps
38
- }: ReactProps<SliderInterface>) => {
39
- const getpercentFromValue = (value: number) => {
40
- const min = getMin();
41
- const max = getMax();
42
-
43
- if (value === Infinity) {
44
- return 100;
45
- } else if (value === -Infinity) {
46
- return 0;
47
- }
48
- return ((value - min) / (max - min)) * 100;
49
- };
50
-
51
- const getMax = (isInfinity = false) => {
52
- if (isInfinity) {
53
- return max;
54
- }
55
- return max == Infinity ? marks[marks?.length - 1].value : max;
56
- };
57
- const getMin = (isInfinity = false) => {
58
- if (isInfinity) {
59
- return min;
60
- }
61
- return min == -Infinity ? marks[0].value : min;
62
- };
63
-
64
- const getValueFrompercent = (percent: number) => {
65
- const min = getMin(false);
66
- const max = getMax(false);
67
- return ((max - min) * percent) / 100 + min;
68
- };
69
-
70
- const [isChanging, setIsChanging] = useState(false);
71
- const defaultRef = useRef<HTMLDivElement>(null);
72
- const resolvedRef: React.RefObject<any> | React.ForwardedRef<any> =
73
- ref || defaultRef;
74
-
75
- const [value, setValue] = useState(defaultValue);
76
- const [percent, setpercent] = useState(getpercentFromValue(defaultValue));
77
- const [mouseDown, setMouseDown] = useState(false);
78
-
79
- useEffect(() => {
80
- setValue(defaultValue);
81
- setpercent(getpercentFromValue(defaultValue));
82
- }, [defaultValue]);
83
-
84
- const handleMouseDown = (e: any) => {
85
- setMouseDown(true);
86
- setIsChanging(true);
87
- handleChange(e);
88
- };
89
-
90
- const handleMouseUp = () => {
91
- setMouseDown(false);
92
- setIsChanging(false);
93
- };
94
- useEffect(() => {
95
- if (mouseDown) {
96
- // Add mouse events
97
- window.addEventListener('mouseup', handleMouseUp);
98
- window.addEventListener('mousemove', handleChange);
99
- // Add touch events
100
- window.addEventListener('touchend', handleMouseUp);
101
- window.addEventListener('touchmove', handleChange);
102
- } else {
103
- // Remove mouse events
104
- window.removeEventListener('mouseup', handleMouseUp);
105
- window.removeEventListener('mousemove', handleChange);
106
- // Remove touch events
107
- window.removeEventListener('touchend', handleMouseUp);
108
- window.removeEventListener('touchmove', handleChange);
109
- }
110
-
111
- return () => {
112
- // Cleanup - remove both mouse, touch and drag events
113
- window.removeEventListener('mouseup', handleMouseUp);
114
- window.removeEventListener('mousemove', handleChange);
115
- window.removeEventListener('touchend', handleMouseUp);
116
- window.removeEventListener('touchmove', handleChange);
117
- };
118
- }, [mouseDown]);
119
-
120
- const styles = useSliderStyle({
121
- className,
122
- isChanging,
123
- marks,
124
- max,
125
- min,
126
- name,
127
- step,
128
- value,
129
- valueFormatter,
130
- onChange,
131
- });
132
- const handleChange = (event: any) => {
133
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
134
- // @ts-expect-error
135
- const current = resolvedRef?.current;
136
- if (current) {
137
- const refPosition = current.getBoundingClientRect().left;
138
-
139
- const clientX =
140
- event.type === 'touchmove' || event.type === 'touchstart'
141
- ? event.touches[0].clientX
142
- : event.clientX;
143
-
144
- const percent = ((clientX - refPosition) / current.offsetWidth) * 100;
145
-
146
- updateSliderValues({ percent });
147
- }
148
- };
149
- const updateSliderValues = ({
150
- percent,
151
- value,
152
- }: {
153
- percent?: number;
154
- value?: number;
155
- }) => {
156
- if (percent) {
157
- if (percent >= 100) {
158
- setValue(getMax(true));
159
- setpercent(100);
160
- return;
161
- }
162
- if (percent <= 0) {
163
- setValue(getMin(true));
164
- setpercent(0);
165
- return;
166
- }
167
-
168
- value = getValueFrompercent(percent);
169
- if (value == getMin()) {
170
- value = getMin(true);
171
- }
172
- if (value == getMax()) {
173
- value = getMax(true);
174
- }
175
- } else if (value != undefined) {
176
- if (value >= getMax()) {
177
- setValue(getMax(true));
178
- setpercent(100);
179
- return;
180
- }
181
- if (value <= getMin()) {
182
- setValue(getMin(true));
183
- setpercent(0);
184
- return;
185
- }
186
- percent = getpercentFromValue(value);
187
- } else {
188
- return;
189
- }
190
- if (step != null) {
191
- value = Math.round((value - getMin()) / step) * step + getMin();
192
- } else if (marks) {
193
- value = marks.reduce((prev, curr, currentIndex) => {
194
- let currDiff =
195
- curr.value === Infinity
196
- ? getMax()
197
- : curr.value === -Infinity
198
- ? getMin()
199
- : curr.value;
200
- let prevDiff =
201
- prev.value === Infinity
202
- ? getMax()
203
- : prev.value === -Infinity
204
- ? getMin()
205
- : prev.value;
206
- currDiff = Math.abs(currDiff - value!);
207
- prevDiff = Math.abs(prevDiff - value!);
208
-
209
- return currDiff < prevDiff ? curr : prev;
210
- }).value;
211
- }
212
-
213
- if (value >= getMax()) {
214
- value = getMax(true);
215
- }
216
- if (value <= getMin()) {
217
- value = getMin(true);
218
- }
219
-
220
- percent = getpercentFromValue(value);
221
-
222
- setValue(value);
223
- setpercent(percent);
224
- if (onChange) {
225
- onChange(value);
226
- }
227
- };
228
- const [sliderWidth, setSliderWidth] = useState(0);
229
- useEffect(() => {
230
- const updateSliderWidth = () => {
231
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
232
- // @ts-expect-error
233
- if (resolvedRef.current) {
234
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
235
- // @ts-expect-error
236
- setSliderWidth(resolvedRef.current.offsetWidth);
237
- }
238
- };
239
-
240
- updateSliderWidth(); // Initial setup
241
- window.addEventListener('resize', updateSliderWidth);
242
-
243
- // Clean up
244
- return () => {
245
- window.removeEventListener('resize', updateSliderWidth);
246
- };
247
- }, []);
248
-
249
- const handleKeyDown = (e: React.KeyboardEvent) => {
250
- // Check which key is pressed
251
- switch (e.key) {
252
- case 'ArrowRight':
253
- if (step) {
254
- updateSliderValues({ value: value + step });
255
- } else if (marks) {
256
- // Find the next mark (greater than the current value)
257
- const nextMark = marks.find((mark) => mark.value > value);
258
- if (nextMark) {
259
- // If one exists, update the value to the mark's value
260
- updateSliderValues({ value: nextMark.value });
261
- }
262
- }
263
- break;
264
-
265
- case 'ArrowLeft':
266
- if (step) {
267
- updateSliderValues({ value: value - step });
268
- } else if (marks) {
269
- // Find the previous mark (less than the current value)
270
- const previousMark = marks
271
- .slice(0)
272
- .reverse()
273
- .find((mark, index, array) => {
274
- if (value === Infinity) {
275
- // If value is Infinity, take the second-to-last mark
276
- return index === 1;
277
- }
278
- return mark.value < value;
279
- });
280
-
281
- if (previousMark) {
282
- // If one exists, update the value to the mark's value
283
- updateSliderValues({ value: previousMark.value });
284
- }
285
- }
286
- break;
287
- default:
288
- return;
289
- }
290
- };
291
- return (
292
- <div
293
- tabIndex={0} // Make the slider focusable
294
- onKeyDown={handleKeyDown} // Attach the keydown event
295
- role="slider" // Inform assistive technologies about the type of the component
296
- aria-valuemin={getMin(true)} // Inform about the minimum value
297
- aria-valuemax={getMax(true)} // Inform about the maximum value
298
- aria-valuenow={value} // Inform about the current value
299
- aria-valuetext={value.toString()} // Textual representation of the value
300
- className={styles.slider}
301
- onMouseDown={handleMouseDown}
302
- onClick={handleChange}
303
- ref={resolvedRef}
304
- onTouchStart={handleMouseDown}
305
- onDragStart={(e) => e.preventDefault()}
306
- {...restProps}
307
- >
308
- <input type="hidden" name={name} value={value} />
309
- <div className={styles.activeTrack} style={{ flex: percent / 100 }}></div>
310
- <div className={styles.handle}>
311
- <AnimatePresence>
312
- {isChanging && (
313
- <motion.div
314
- className={styles.valueIndicator}
315
- initial="hidden"
316
- animate="visible"
317
- exit="hidden"
318
- style={{
319
- translate: '-50%',
320
- transformOrigin: 'center bottom',
321
- textWrap: 'nowrap',
322
- }}
323
- variants={{
324
- visible: { opacity: 1, scale: 1 },
325
- hidden: { opacity: 1, scale: 0 },
326
- }}
327
- transition={{ duration: 0.1 }}
328
- >
329
- {valueFormatter ? valueFormatter(value) : value}
330
- </motion.div>
331
- )}
332
- </AnimatePresence>
333
- </div>
334
- <div
335
- className={styles.inactiveTrack}
336
- style={{ flex: 1 - percent / 100 }}
337
- ></div>
338
- <div
339
- className={
340
- 'w-[calc(100%-12px)] h-full absolute -translate-x-1/2 transform left-1/2'
341
- }
342
- >
343
- {marks &&
344
- marks.map((mark, index) => {
345
- let isUnderActiveTrack = null;
346
-
347
- const handleAndGapPercent =
348
- ((isChanging ? 9 : 10) / sliderWidth) * 100;
349
- const markPercent = getpercentFromValue(mark.value);
350
-
351
- if (markPercent <= percent - handleAndGapPercent) {
352
- isUnderActiveTrack = true;
353
- } else if (markPercent >= percent + handleAndGapPercent) {
354
- isUnderActiveTrack = false;
355
- }
356
- return (
357
- <div
358
- key={index}
359
- className={classNames(styles.dot, {
360
- 'bg-primary-container':
361
- isUnderActiveTrack != null && isUnderActiveTrack,
362
- 'bg-primary':
363
- isUnderActiveTrack != null && !isUnderActiveTrack,
364
- })}
365
- style={{
366
- left: `${getpercentFromValue(mark.value)}%`,
367
- }}
368
- ></div>
369
- );
370
- })}
371
- </div>
372
- </div>
373
- );
374
- };
@@ -1,77 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
- import { AnimatePresence, motion } from 'motion/react';
3
- import { faXmark } from '@fortawesome/free-solid-svg-icons';
4
- import { SnackbarInterface } from '../interfaces/snackbar.interface';
5
- import { useSnackbarStyle } from '../styles/snackbar.style';
6
-
7
- import { MotionProps } from '../utils/component';
8
- import { IconButton } from './IconButton';
9
-
10
- /**
11
- * Snackbars show short updates about app processes at the bottom of the screen
12
- * @status beta
13
- * @category Communication
14
- * @devx
15
- * - Uncontrolled visibility; use `duration` to auto-dismiss.
16
- * @a11y
17
- * - No `role="status"`/`alert` announcements.
18
- * @limitations
19
- * - No queue/stacking and no controlled open prop.
20
- */
21
- export const Snackbar = ({
22
- message,
23
- className,
24
- duration,
25
- closeIcon = faXmark,
26
- onClose,
27
- ...restProps
28
- }: MotionProps<SnackbarInterface>) => {
29
- const [isVisible, setIsVisible] = useState(true);
30
-
31
- const styles = useSnackbarStyle({
32
- className,
33
- closeIcon,
34
- duration,
35
- isVisible,
36
- onClose,
37
- message,
38
- });
39
-
40
- useEffect(() => {
41
- if (duration) {
42
- setTimeout(() => {
43
- handleClose();
44
- }, duration);
45
- }
46
- }, [duration]);
47
-
48
- const handleClose = () => {
49
- setIsVisible(false);
50
- onClose?.();
51
- };
52
-
53
- return (
54
- <AnimatePresence>
55
- {isVisible && (
56
- <motion.div
57
- initial={{ height: 0 }}
58
- animate={{ height: 'auto' }}
59
- exit={{ height: 0 }}
60
- transition={{ duration: 0.1 }}
61
- className={styles.snackbar}
62
- {...restProps}
63
- >
64
- <div className={styles.container}>
65
- <p className={styles.supportingText}>{message}</p>
66
- <IconButton
67
- onClick={() => handleClose()}
68
- className={styles.icon}
69
- icon={closeIcon}
70
- label={'close the snackbar'}
71
- ></IconButton>
72
- </div>
73
- </motion.div>
74
- )}
75
- </AnimatePresence>
76
- );
77
- };
@@ -1,107 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
-
3
- import { Icon } from '../icon';
4
- import { motion } from 'motion/react';
5
- import { SwitchInterface } from '../interfaces/switch.interface';
6
- import { useSwitchStyle } from '../styles/switch.style';
7
- import { MotionProps } from '../utils/component';
8
-
9
- /**
10
- * Switches toggle the selection of an item on or off
11
- * @status beta
12
- * @category Input
13
- * @devx
14
- * - `selected` is used as initial state only; prop changes won’t sync.
15
- * @a11y
16
- * - Uses `role="switch"` but no label prop is exposed here.
17
- */
18
- export const Switch = ({
19
- selected = false,
20
- className,
21
- activeIcon,
22
- disabled = false,
23
- inactiveIcon,
24
- onChange,
25
- onClick,
26
- onKeyDown,
27
- ref,
28
- ...restProps
29
- }: MotionProps<SwitchInterface>) => {
30
- const [isSelected, setIsSelected] = useState(selected);
31
-
32
- useEffect(() => {
33
- setIsSelected(selected);
34
- }, [selected]);
35
-
36
- const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
37
- if (disabled) return;
38
- toggleSwitchState();
39
- if (onClick) {
40
- onClick(event);
41
- }
42
- };
43
-
44
- const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
45
- if (disabled) return;
46
- if (event.key === ' ' || event.key === 'Enter') {
47
- event.preventDefault();
48
- toggleSwitchState();
49
- }
50
- if (onKeyDown) {
51
- onKeyDown(event);
52
- }
53
- };
54
-
55
- const toggleSwitchState = () => {
56
- setIsSelected(!isSelected);
57
- onChange?.(!isSelected);
58
- };
59
- const styles = useSwitchStyle({
60
- className,
61
- isSelected,
62
- activeIcon,
63
- inactiveIcon,
64
- disabled,
65
- selected: isSelected,
66
- onChange,
67
- });
68
-
69
- const defaultRef = useRef<HTMLDivElement>(null);
70
- const resolvedRef: React.RefObject<any> | React.ForwardedRef<any> =
71
- ref || defaultRef;
72
-
73
- return (
74
- <motion.div
75
- role="switch"
76
- aria-checked={isSelected}
77
- tabIndex={disabled ? -1 : 0}
78
- onKeyDown={handleKeyDown}
79
- onClick={handleClick}
80
- ref={resolvedRef}
81
- className={styles.switch}
82
- {...restProps}
83
- >
84
- <input type="hidden" value={isSelected ? '1' : '0'} />
85
- <motion.div
86
- layout
87
- style={{ translate: isSelected ? '50%' : '-50%' }}
88
- transition={{
89
- type: 'spring',
90
- stiffness: 700,
91
- damping: 30,
92
- }}
93
- className={styles.handleContainer}
94
- >
95
- <div className={styles.handle}>
96
- {(isSelected ? activeIcon : inactiveIcon) && (
97
- <Icon
98
- className={styles.icon}
99
- icon={isSelected ? activeIcon! : inactiveIcon!}
100
- ></Icon>
101
- )}
102
- </div>
103
- <div className={styles.handleStateLayer} />
104
- </motion.div>
105
- </motion.div>
106
- );
107
- };
@@ -1,123 +0,0 @@
1
- import { motion } from 'motion/react';
2
- import React, { useEffect, useRef, useState } from 'react';
3
-
4
- import { Icon } from '../icon';
5
- import { useTabStyle } from '../styles/tab.style';
6
- import { TabInterface } from '../interfaces/tab.interface';
7
- import { ReactProps } from '../utils/component';
8
- import { State } from '../effects';
9
-
10
- /**
11
- * @status beta
12
- * @parent Tabs
13
- * @devx
14
- * - `label` can come from string children; selection is index-based.
15
- * - Use `TabGroup` to sync selection with panels/animations.
16
- * @a11y
17
- * - No keyboard navigation or `aria-controls` wiring.
18
- */
19
- export const Tab = ({
20
- className,
21
- onClick,
22
- label: labelProp,
23
- variant = 'primary',
24
- href,
25
- icon,
26
- selectedTab,
27
- setSelectedTab,
28
- tabsId,
29
- index,
30
- onTabSelected,
31
- scrollable = false,
32
- selected = false,
33
- children,
34
- ref,
35
- ...restProps
36
- }: ReactProps<TabInterface>) => {
37
- const defaultRef = useRef(null);
38
- const resolvedRef = ref || defaultRef;
39
-
40
- // children (string) peut être utilisé comme alternative à label prop
41
- const label = labelProp ?? (typeof children === 'string' ? children : undefined);
42
-
43
- const [isSelected, setIsSelected] = useState<boolean>(selected);
44
-
45
- useEffect(() => {
46
- if (selected && selectedTab == null) {
47
- setIsSelected(true);
48
- } else {
49
- setIsSelected(selectedTab == index && index != null);
50
- }
51
- }, [selectedTab]);
52
-
53
- useEffect(() => {
54
- if (selectedTab == index && onTabSelected) {
55
- onTabSelected({
56
- ref: resolvedRef as any,
57
- index: index || 0,
58
- label,
59
- icon,
60
- });
61
- }
62
- }, [selectedTab]);
63
-
64
- const ElementType = href ? 'a' : 'button';
65
-
66
- const handleClick = (e: React.MouseEvent<any>) => {
67
- if (setSelectedTab) {
68
- setSelectedTab(index ?? null);
69
- }
70
- if (onClick) {
71
- onClick(e);
72
- }
73
- };
74
-
75
- const styles = useTabStyle({
76
- className,
77
- onTabSelected,
78
- scrollable,
79
- selectedTab,
80
- index,
81
- tabsId,
82
- selected: isSelected,
83
- variant,
84
- icon,
85
- label,
86
- isSelected,
87
- setSelectedTab,
88
- href: href as any,
89
- });
90
-
91
- return (
92
- <ElementType
93
- {...restProps}
94
- role="tab"
95
- aria-selected={isSelected}
96
- ref={resolvedRef}
97
- href={href}
98
- className={styles.tab}
99
- onClick={handleClick}
100
- {...(restProps as any)}
101
- >
102
- <State
103
- style={{ transition: 0.3 + 's' }}
104
- className={styles.stateLayer}
105
- colorName={
106
- variant === 'primary' && isSelected ? 'primary' : 'on-surface'
107
- }
108
- stateClassName={'state-ripple-group-[tab]'}
109
- />
110
- <span className={styles.content}>
111
- {icon && <Icon icon={icon} className={styles.icon} />}
112
- <span className={styles.label}>{label}</span>
113
- {isSelected && (
114
- <motion.span
115
- layoutId={`underline-${tabsId}`}
116
- className={styles.underline}
117
- transition={{ duration: 0.3 }}
118
- />
119
- )}
120
- </span>
121
- </ElementType>
122
- );
123
- };