@udixio/ui-react 2.10.12 → 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 (179) hide show
  1. package/dist/index.cjs +3 -3
  2. package/dist/index.js +2696 -2710
  3. package/dist/lib/effects/ThemeProvider.d.ts.map +1 -1
  4. package/dist/theme.worker.js +6633 -0
  5. package/package.json +4 -1
  6. package/.eslintrc.mjs +0 -22
  7. package/.storybook/main.ts +0 -20
  8. package/.storybook/preview.ts +0 -1
  9. package/CHANGELOG.md +0 -1130
  10. package/dist/scrollDriven-AP2yWhzi.js +0 -121
  11. package/postcss.config.mjs +0 -5
  12. package/src/index.css +0 -4
  13. package/src/index.ts +0 -1
  14. package/src/lib/components/AnchorPositioner.tsx +0 -185
  15. package/src/lib/components/Button.tsx +0 -208
  16. package/src/lib/components/Card.tsx +0 -47
  17. package/src/lib/components/Carousel.tsx +0 -437
  18. package/src/lib/components/CarouselItem.tsx +0 -61
  19. package/src/lib/components/Checkbox.tsx +0 -120
  20. package/src/lib/components/Chip.tsx +0 -341
  21. package/src/lib/components/Chips.tsx +0 -331
  22. package/src/lib/components/ContextMenu.tsx +0 -109
  23. package/src/lib/components/DatePicker.tsx +0 -432
  24. package/src/lib/components/Divider.tsx +0 -20
  25. package/src/lib/components/Fab.tsx +0 -127
  26. package/src/lib/components/FabMenu.tsx +0 -239
  27. package/src/lib/components/IconButton.tsx +0 -146
  28. package/src/lib/components/Menu.tsx +0 -88
  29. package/src/lib/components/MenuGroup.tsx +0 -34
  30. package/src/lib/components/MenuHeadline.tsx +0 -9
  31. package/src/lib/components/MenuItem.tsx +0 -215
  32. package/src/lib/components/NavigationRail.tsx +0 -186
  33. package/src/lib/components/NavigationRailItem.tsx +0 -227
  34. package/src/lib/components/ProgressIndicator.tsx +0 -214
  35. package/src/lib/components/SideSheet.tsx +0 -135
  36. package/src/lib/components/Slider.tsx +0 -374
  37. package/src/lib/components/Snackbar.tsx +0 -77
  38. package/src/lib/components/Switch.tsx +0 -107
  39. package/src/lib/components/Tab.tsx +0 -123
  40. package/src/lib/components/TabGroup.tsx +0 -66
  41. package/src/lib/components/TabGroupContext.tsx +0 -16
  42. package/src/lib/components/TabPanel.tsx +0 -27
  43. package/src/lib/components/TabPanels.tsx +0 -76
  44. package/src/lib/components/Tabs.tsx +0 -105
  45. package/src/lib/components/TextField.tsx +0 -586
  46. package/src/lib/components/Tooltip.tsx +0 -217
  47. package/src/lib/components/index.ts +0 -34
  48. package/src/lib/config/config.interface.ts +0 -9
  49. package/src/lib/config/define-config.ts +0 -16
  50. package/src/lib/config/index.ts +0 -2
  51. package/src/lib/effects/AnimateOnScroll.ts +0 -391
  52. package/src/lib/effects/State.tsx +0 -90
  53. package/src/lib/effects/SyncedFixedWrapper.tsx +0 -62
  54. package/src/lib/effects/ThemeProvider.tsx +0 -172
  55. package/src/lib/effects/block-scroll.effect.tsx +0 -313
  56. package/src/lib/effects/custom-scroll/custom-scroll.effect.tsx +0 -407
  57. package/src/lib/effects/custom-scroll/custom-scroll.interface.ts +0 -29
  58. package/src/lib/effects/custom-scroll/custom-scroll.style.ts +0 -32
  59. package/src/lib/effects/custom-scroll/index.ts +0 -3
  60. package/src/lib/effects/index.ts +0 -7
  61. package/src/lib/effects/ripple/RippleEffect.tsx +0 -116
  62. package/src/lib/effects/ripple/index.tsx +0 -1
  63. package/src/lib/effects/scrollDriven.ts +0 -239
  64. package/src/lib/effects/smooth-scroll.effect.tsx +0 -112
  65. package/src/lib/effects/theme.worker.ts +0 -97
  66. package/src/lib/hooks/index.ts +0 -10
  67. package/src/lib/hooks/useTooltipTrigger.ts +0 -270
  68. package/src/lib/icon/icon.tsx +0 -125
  69. package/src/lib/icon/index.ts +0 -1
  70. package/src/lib/index.ts +0 -8
  71. package/src/lib/interfaces/button.interface.ts +0 -65
  72. package/src/lib/interfaces/card.interface.ts +0 -11
  73. package/src/lib/interfaces/carousel-item.interface.ts +0 -12
  74. package/src/lib/interfaces/carousel.interface.ts +0 -41
  75. package/src/lib/interfaces/checkbox.interface.ts +0 -39
  76. package/src/lib/interfaces/chip.interface.ts +0 -97
  77. package/src/lib/interfaces/chips.interface.ts +0 -37
  78. package/src/lib/interfaces/date-picker.interface.ts +0 -79
  79. package/src/lib/interfaces/divider.interface.ts +0 -7
  80. package/src/lib/interfaces/fab-menu.interface.ts +0 -12
  81. package/src/lib/interfaces/fab.interface.ts +0 -27
  82. package/src/lib/interfaces/icon-button.interface.ts +0 -38
  83. package/src/lib/interfaces/index.ts +0 -26
  84. package/src/lib/interfaces/menu-group.interface.ts +0 -13
  85. package/src/lib/interfaces/menu-item.interface.ts +0 -29
  86. package/src/lib/interfaces/menu.interface.ts +0 -19
  87. package/src/lib/interfaces/navigation-rail-item.interface.ts +0 -39
  88. package/src/lib/interfaces/navigation-rail.interface.ts +0 -39
  89. package/src/lib/interfaces/progress-indicator.interface.ts +0 -41
  90. package/src/lib/interfaces/side-sheet.interface.tsx +0 -28
  91. package/src/lib/interfaces/slider.interface.ts +0 -27
  92. package/src/lib/interfaces/snackbar.interface.ts +0 -13
  93. package/src/lib/interfaces/switch.interface.ts +0 -14
  94. package/src/lib/interfaces/tab-group.interface.ts +0 -13
  95. package/src/lib/interfaces/tab-panels.interface.ts +0 -21
  96. package/src/lib/interfaces/tab.interface.ts +0 -31
  97. package/src/lib/interfaces/tabs.interface.ts +0 -22
  98. package/src/lib/interfaces/text-field.interface.ts +0 -61
  99. package/src/lib/interfaces/tooltip.interface.ts +0 -61
  100. package/src/lib/styles/button.style.ts +0 -136
  101. package/src/lib/styles/card.style.ts +0 -29
  102. package/src/lib/styles/carousel-item.style.ts +0 -24
  103. package/src/lib/styles/carousel.style.ts +0 -22
  104. package/src/lib/styles/checkbox.style.ts +0 -64
  105. package/src/lib/styles/chip.style.ts +0 -62
  106. package/src/lib/styles/chips.style.ts +0 -20
  107. package/src/lib/styles/date-picker.style.ts +0 -43
  108. package/src/lib/styles/divider.style.ts +0 -31
  109. package/src/lib/styles/fab-menu.style.ts +0 -29
  110. package/src/lib/styles/fab.style.ts +0 -49
  111. package/src/lib/styles/icon-button.style.ts +0 -168
  112. package/src/lib/styles/index.ts +0 -25
  113. package/src/lib/styles/menu-group.style.ts +0 -34
  114. package/src/lib/styles/menu-headline.style.ts +0 -20
  115. package/src/lib/styles/menu-item.style.ts +0 -45
  116. package/src/lib/styles/menu.style.ts +0 -32
  117. package/src/lib/styles/navigation-rail-item.style.ts +0 -56
  118. package/src/lib/styles/navigation-rail.style.ts +0 -36
  119. package/src/lib/styles/progress-indicator.style.ts +0 -72
  120. package/src/lib/styles/side-sheet.style.ts +0 -45
  121. package/src/lib/styles/slider.style.ts +0 -41
  122. package/src/lib/styles/snackbar.style.ts +0 -26
  123. package/src/lib/styles/switch.style.ts +0 -67
  124. package/src/lib/styles/tab-panels.style.ts +0 -35
  125. package/src/lib/styles/tab.style.ts +0 -78
  126. package/src/lib/styles/tabs.style.ts +0 -22
  127. package/src/lib/styles/text-field.style.ts +0 -115
  128. package/src/lib/styles/tooltip.style.ts +0 -48
  129. package/src/lib/utils/component-helper.ts +0 -134
  130. package/src/lib/utils/component.ts +0 -34
  131. package/src/lib/utils/index.ts +0 -7
  132. package/src/lib/utils/string.ts +0 -9
  133. package/src/lib/utils/styles/classnames.ts +0 -49
  134. package/src/lib/utils/styles/get-classname.ts +0 -96
  135. package/src/lib/utils/styles/index.ts +0 -4
  136. package/src/lib/utils/styles/use-classnames.ts +0 -25
  137. package/src/stories/action/button.stories.tsx +0 -86
  138. package/src/stories/action/fab.stories.tsx +0 -54
  139. package/src/stories/action/icon-button.stories.tsx +0 -134
  140. package/src/stories/assets/accessibility.png +0 -0
  141. package/src/stories/assets/accessibility.svg +0 -5
  142. package/src/stories/assets/addon-library.png +0 -0
  143. package/src/stories/assets/assets.png +0 -0
  144. package/src/stories/assets/context.png +0 -0
  145. package/src/stories/assets/discord.svg +0 -15
  146. package/src/stories/assets/docs.png +0 -0
  147. package/src/stories/assets/figma-plugin.png +0 -0
  148. package/src/stories/assets/github.svg +0 -3
  149. package/src/stories/assets/share.png +0 -0
  150. package/src/stories/assets/styling.png +0 -0
  151. package/src/stories/assets/testing.png +0 -0
  152. package/src/stories/assets/theming.png +0 -0
  153. package/src/stories/assets/tutorials.svg +0 -12
  154. package/src/stories/assets/youtube.svg +0 -4
  155. package/src/stories/communication/ProgressIndicator.stories.tsx +0 -57
  156. package/src/stories/communication/SnackBar.stories.tsx +0 -32
  157. package/src/stories/communication/tool-tip.stories.tsx +0 -133
  158. package/src/stories/containment/card.stories.tsx +0 -42
  159. package/src/stories/containment/carousel.stories.tsx +0 -65
  160. package/src/stories/containment/divider.stories.tsx +0 -35
  161. package/src/stories/containment/slide-sheet.stories.tsx +0 -45
  162. package/src/stories/effect/smooth-scroll.stories.tsx +0 -54
  163. package/src/stories/navigation/navigation-rail/navigation-rail-item.stories.tsx +0 -65
  164. package/src/stories/navigation/navigation-rail/navigation-rail.stories.tsx +0 -122
  165. package/src/stories/navigation/tabs/tab.stories.tsx +0 -57
  166. package/src/stories/navigation/tabs/tabs.stories.tsx +0 -102
  167. package/src/stories/selection/slider.stories.tsx +0 -85
  168. package/src/stories/selection/switch.stories.tsx +0 -46
  169. package/src/stories/text-inputs/text-field.stories.tsx +0 -135
  170. package/src/tests/Button.spec.tsx +0 -67
  171. package/src/tests/useClassNames.spec.tsx +0 -82
  172. package/src/udixio.css +0 -120
  173. package/theme.config.ts +0 -7
  174. package/tsconfig.json +0 -16
  175. package/tsconfig.lib.json +0 -51
  176. package/tsconfig.spec.json +0 -37
  177. package/tsconfig.storybook.json +0 -38
  178. package/vite.config.ts +0 -82
  179. /package/dist/{scrollDriven-DWAu7CR0.cjs → scrollDriven.js} +0 -0
@@ -1,109 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import { AnchorPositioner } from './AnchorPositioner';
3
- import { Menu } from './Menu';
4
- // import { MenuProps } from '../interfaces/menu.interface'; // MenuProps is not exported from interface file usually, check file content
5
- import { MenuInterface } from '../interfaces';
6
- import { ReactProps } from '../utils';
7
-
8
- // MenuInterface has props: MenuProps.
9
- // But MenuProps might not be exported directly from the package index, so accessing it via MenuInterface['props'] is safer if we can't import it.
10
- // Actually checking Step 1271, MenuProps IS exported.
11
-
12
- export type ContextMenuProps = {
13
- props: { trigger: React.ReactNode } & MenuInterface['props'];
14
- type: 'div';
15
- states: {
16
- hasGroups: boolean;
17
- };
18
- elements: [''];
19
- };
20
-
21
- export const ContextMenu = ({
22
- trigger,
23
- children,
24
- ...menuProps
25
- }: ReactProps<ContextMenuProps>) => {
26
- const [contextMenu, setContextMenu] = useState<{
27
- mouseX: number;
28
- mouseY: number;
29
- } | null>(null);
30
- const anchorRef = useRef<HTMLDivElement>(null);
31
-
32
- const handleContextMenu = (event: React.MouseEvent) => {
33
- event.preventDefault();
34
- setContextMenu({
35
- mouseX: event.clientX,
36
- mouseY: event.clientY,
37
- });
38
- };
39
-
40
- const handleClose = () => {
41
- setContextMenu(null);
42
- };
43
-
44
- const handleSelect = () => {
45
- handleClose();
46
- };
47
-
48
- useEffect(() => {
49
- if (!contextMenu) return;
50
- const handleOutsideInteraction = () => setContextMenu(null);
51
- window.addEventListener('click', handleOutsideInteraction);
52
- window.addEventListener('scroll', handleOutsideInteraction, true);
53
-
54
- return () => {
55
- window.removeEventListener('click', handleOutsideInteraction);
56
- window.removeEventListener('scroll', handleOutsideInteraction, true);
57
- };
58
- }, [contextMenu]);
59
-
60
- // Clone trigger if valid element to attach onContextMenu, otherwise wrap
61
- const triggerElement = React.isValidElement(trigger) ? (
62
- React.cloneElement(
63
- trigger as React.ReactElement,
64
- {
65
- onContextMenu: (e: React.MouseEvent) => {
66
- handleContextMenu(e);
67
- // Call original handler if exists
68
- (trigger as React.ReactElement).props.onContextMenu?.(e);
69
- },
70
- } as any,
71
- )
72
- ) : (
73
- <div onContextMenu={handleContextMenu} className="inline-block">
74
- {trigger}
75
- </div>
76
- );
77
-
78
- return (
79
- <>
80
- {triggerElement}
81
-
82
- {/* Invisible anchor element positioned at cursor */}
83
- <div
84
- ref={anchorRef}
85
- style={{
86
- position: 'fixed',
87
- top: contextMenu?.mouseY ?? 0,
88
- left: contextMenu?.mouseX ?? 0,
89
- width: 1,
90
- height: 1,
91
- pointerEvents: 'none',
92
- visibility: 'hidden',
93
- }}
94
- />
95
-
96
- {contextMenu && (
97
- <AnchorPositioner
98
- anchorRef={anchorRef}
99
- position="bottom right"
100
- onClick={(e) => e.stopPropagation()}
101
- >
102
- <Menu onClick={handleSelect} {...menuProps}>
103
- {children}
104
- </Menu>
105
- </AnchorPositioner>
106
- )}
107
- </>
108
- );
109
- };
@@ -1,432 +0,0 @@
1
- import { useEffect, useMemo, useRef, useState } from 'react';
2
- import { useDatePickerStyle } from '../styles/date-picker.style';
3
- import { classNames, ReactProps } from '../utils';
4
- import {
5
- DatePickerInterface,
6
- DateRange,
7
- } from '../interfaces/date-picker.interface';
8
- import {
9
- faChevronDown,
10
- faChevronLeft,
11
- faChevronRight,
12
- } from '@fortawesome/free-solid-svg-icons';
13
- import { Button } from './Button';
14
- import { IconButton } from './IconButton';
15
- import { AnimatePresence, motion } from 'motion/react';
16
- import { Icon } from '../icon';
17
-
18
- /**
19
- * DatePickers let users select a date, or a range of dates.
20
- * @status beta
21
- * @category Selection
22
- */
23
- export const DatePicker = ({
24
- value: valueProp,
25
- defaultValue,
26
- onChange,
27
- minDate,
28
- maxDate,
29
- shouldDisableDate,
30
- locale = 'default',
31
- weekStartDay = 0,
32
- className,
33
- style,
34
- mode = 'single',
35
- ...restProps
36
- }: ReactProps<DatePickerInterface>) => {
37
- // State for the currently displayed month (always set to the 1st of the month)
38
- const [viewDate, setViewDate] = useState(() => {
39
- // Try to find a valid start date from value to focus
40
- const extractDate = (v: any): Date | null => {
41
- if (v instanceof Date) return v;
42
- if (Array.isArray(v) && v[0]) return v[0];
43
- return null;
44
- };
45
- const start =
46
- extractDate(valueProp) || extractDate(defaultValue) || new Date();
47
- return new Date(start.getFullYear(), start.getMonth(), 1);
48
- });
49
-
50
- const [direction, setDirection] = useState(0);
51
- const [viewMode, setViewMode] = useState<'day' | 'year'>('day');
52
-
53
- // State for selected date
54
- const isControlled = valueProp !== undefined;
55
- const [internalValue, setInternalValue] = useState<Date | DateRange | null>(
56
- defaultValue || null,
57
- );
58
- const selectedValue = isControlled ? valueProp || null : internalValue;
59
-
60
- // Calendar generation logic
61
- const daysInMonth = (year: number, month: number) =>
62
- new Date(year, month + 1, 0).getDate();
63
-
64
- const calendarDays = useMemo(() => {
65
- const year = viewDate.getFullYear();
66
- const month = viewDate.getMonth();
67
- const daysCount = daysInMonth(year, month);
68
- const startDay = new Date(year, month, 1).getDay(); // 0=Sun (Fixed JS getDay)
69
-
70
- // Adjust start index based on weekStartDay
71
- // shift: logic to map standard JS Day (0=Sun) to our week start
72
- // If weekStart=1 (Mon): Sun(0) -> 6, Mon(1) -> 0, Tue(2) -> 1
73
- const startIndex = (startDay - weekStartDay + 7) % 7;
74
-
75
- const days: Array<{ date: Date; isCurrentMonth: boolean }> = [];
76
-
77
- // Prev month
78
- const prevMonthDaysCount = daysInMonth(year, month - 1);
79
- for (let i = startIndex - 1; i >= 0; i--) {
80
- days.push({
81
- date: new Date(year, month - 1, prevMonthDaysCount - i),
82
- isCurrentMonth: false,
83
- });
84
- }
85
-
86
- // Current month
87
- for (let i = 1; i <= daysCount; i++) {
88
- days.push({ date: new Date(year, month, i), isCurrentMonth: true });
89
- }
90
-
91
- // Next month padding - Ensure always 42 days (6 rows) for fixed height animation
92
- const currentLen = days.length;
93
- const remaining = 42 - currentLen;
94
- for (let i = 1; i <= remaining; i++) {
95
- days.push({
96
- date: new Date(year, month + 1, i),
97
- isCurrentMonth: false,
98
- });
99
- }
100
-
101
- return days;
102
- }, [viewDate, weekStartDay]);
103
-
104
- const years = useMemo(() => {
105
- const currentYear = new Date().getFullYear();
106
- const start = currentYear - 100;
107
- const end = currentYear + 100;
108
- const list = [];
109
- for (let i = start; i <= end; i++) {
110
- list.push(i);
111
- }
112
- return list;
113
- }, []);
114
-
115
- const yearsContainerRef = useRef<HTMLDivElement>(null);
116
-
117
- // Scroll to selected year when opening year view
118
- useEffect(() => {
119
- if (viewMode === 'year' && yearsContainerRef.current) {
120
- const selectedYearBtn = yearsContainerRef.current.querySelector(
121
- '[data-selected="true"]',
122
- );
123
- if (selectedYearBtn) {
124
- selectedYearBtn.scrollIntoView({ block: 'center' });
125
- }
126
- }
127
- }, [viewMode]);
128
-
129
- // Formatters
130
- const monthFormatter = useMemo(
131
- () => new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }),
132
- [locale],
133
- );
134
- const weekDayFormatter = useMemo(
135
- () => new Intl.DateTimeFormat(locale, { weekday: 'narrow' }),
136
- [locale],
137
- );
138
-
139
- const weekDays = useMemo(() => {
140
- const baseDate = new Date(2023, 0, 1 + weekStartDay); // Jan 1 2023 was Sun. Jan (1+1)=2 is Mon.
141
- return Array.from({ length: 7 }).map((_, i) => {
142
- const d = new Date(baseDate);
143
- d.setDate(baseDate.getDate() + i);
144
- return weekDayFormatter.format(d).charAt(0).toUpperCase();
145
- });
146
- }, [weekDayFormatter, weekStartDay]);
147
-
148
- // Handlers
149
- const handlePrevMonth = () => {
150
- setDirection(-1);
151
- setViewDate((d) => new Date(d.getFullYear(), d.getMonth() - 1, 1));
152
- };
153
- const handleNextMonth = () => {
154
- setDirection(1);
155
- setViewDate((d) => new Date(d.getFullYear(), d.getMonth() + 1, 1));
156
- };
157
-
158
- const handleYearSelect = (year: number) => {
159
- setViewDate((d) => new Date(year, d.getMonth(), 1));
160
- setViewMode('day');
161
- };
162
-
163
- const isSameDay = (d1: Date | null | undefined, d2: Date) => {
164
- if (!d1) return false;
165
- return (
166
- d1.getDate() === d2.getDate() &&
167
- d1.getMonth() === d2.getMonth() &&
168
- d1.getFullYear() === d2.getFullYear()
169
- );
170
- };
171
-
172
- const isToday = (date: Date) => isSameDay(new Date(), date);
173
-
174
- const handleDateClick = (date: Date) => {
175
- let newValue: Date | DateRange | null = date;
176
-
177
- if (mode === 'single') {
178
- newValue = date;
179
- // Single mode always sets date
180
- } else {
181
- // Range mode
182
- const current = selectedValue as DateRange | null;
183
- const [start, end] = Array.isArray(current) ? current : [null, null];
184
-
185
- if (!start || (start && end)) {
186
- // Start new range (if was simple date or full range)
187
- newValue = [date, null];
188
- } else {
189
- // Complete range
190
- if (date < start) {
191
- newValue = [date, start];
192
- } else {
193
- newValue = [start, date];
194
- }
195
- }
196
- }
197
-
198
- if (!isControlled) {
199
- setInternalValue(newValue);
200
- }
201
- if (onChange) {
202
- onChange(newValue);
203
- }
204
- };
205
-
206
- const checkSelection = (date: Date) => {
207
- if (mode === 'single') {
208
- return {
209
- isSelected: isSameDay(selectedValue as Date, date),
210
- isStart: false,
211
- isEnd: false,
212
- isInRange: false,
213
- };
214
- }
215
- const safeRange = Array.isArray(selectedValue)
216
- ? selectedValue
217
- : [selectedValue, null];
218
- const [start, end] = safeRange as DateRange;
219
- const isStart = isSameDay(start, date);
220
- const isEnd = isSameDay(end, date);
221
-
222
- // Check range
223
- let isInRange = false;
224
- if (start && end) {
225
- // Simple range check (ignore time components for safety)
226
- // Normalize to midnight for strict day comparison
227
- const s = new Date(
228
- start.getFullYear(),
229
- start.getMonth(),
230
- start.getDate(),
231
- ).getTime();
232
- const e = new Date(
233
- end.getFullYear(),
234
- end.getMonth(),
235
- end.getDate(),
236
- ).getTime();
237
- const d = new Date(
238
- date.getFullYear(),
239
- date.getMonth(),
240
- date.getDate(),
241
- ).getTime();
242
- isInRange = d > s && d < e;
243
- }
244
-
245
- return { isSelected: isStart || isEnd, isStart, isEnd, isInRange };
246
- };
247
-
248
- const styles = useDatePickerStyle({
249
- hasSelected: !!selectedValue,
250
- });
251
-
252
- const variants = {
253
- enter: (direction: number) => ({
254
- x: direction > 0 ? '100%' : '-100%',
255
- opacity: 0,
256
- }),
257
- center: {
258
- x: 0,
259
- opacity: 1,
260
- },
261
- exit: (direction: number) => ({
262
- x: direction < 0 ? '100%' : '-100%',
263
- opacity: 0,
264
- }),
265
- };
266
-
267
- return (
268
- <div
269
- className={classNames(styles.datePicker, className)}
270
- style={style}
271
- {...(restProps as any)}
272
- >
273
- {/* Header */}
274
- <div className={styles.header}>
275
- <Button
276
- variant="text"
277
- disableTextMargins
278
- size="small"
279
- onClick={() => setViewMode((m) => (m === 'day' ? 'year' : 'day'))}
280
- className="text-label-large font-bold capitalize text-on-surface hover:bg-surface-container-highest"
281
- >
282
- <span className="mr-2">
283
- {viewMode === 'day'
284
- ? monthFormatter.format(viewDate)
285
- : viewDate.getFullYear()}
286
- </span>
287
- <Icon
288
- icon={faChevronDown}
289
- className={classNames(
290
- 'w-3 h-3 transition-transform duration-200 inline',
291
- viewMode === 'year' && 'rotate-180',
292
- )}
293
- />
294
- </Button>
295
-
296
- {viewMode === 'day' && (
297
- <div className="flex items-center">
298
- <IconButton
299
- size={'xSmall'}
300
- allowShapeTransformation={false}
301
- onClick={handlePrevMonth}
302
- icon={faChevronLeft}
303
- label="Previous month"
304
- title={null}
305
- />
306
- <IconButton
307
- size={'xSmall'}
308
- allowShapeTransformation={false}
309
- onClick={handleNextMonth}
310
- icon={faChevronRight}
311
- label="Next month"
312
- title={null}
313
- />
314
- </div>
315
- )}
316
- </div>
317
-
318
- {viewMode === 'year' ? (
319
- <div
320
- className="h-[280px] overflow-y-auto grid grid-cols-3 gap-2 p-2 scrollbar-hide"
321
- ref={yearsContainerRef}
322
- >
323
- {years.map((year) => (
324
- <Button
325
- size={'small'}
326
- key={year}
327
- variant={year === viewDate.getFullYear() ? 'filled' : 'text'}
328
- onClick={() => handleYearSelect(year)}
329
- data-selected={year === viewDate.getFullYear()}
330
- className={classNames('w-full', {
331
- 'text-on-surface': year !== viewDate.getFullYear(),
332
- })}
333
- label={year.toString()}
334
- >
335
- {year}
336
- </Button>
337
- ))}
338
- </div>
339
- ) : (
340
- <>
341
- {/* Week Days */}
342
- <div className={styles.weekDays}>
343
- {weekDays.map((day, i) => (
344
- <div key={i} className={styles.weekDay}>
345
- {day}
346
- </div>
347
- ))}
348
- </div>
349
-
350
- {/* Days Grid */}
351
- <div className="overflow-hidden relative min-h-[240px]">
352
- <AnimatePresence
353
- mode="popLayout"
354
- initial={false}
355
- custom={direction}
356
- >
357
- <motion.div
358
- key={viewDate.toISOString()}
359
- custom={direction}
360
- variants={variants}
361
- initial="enter"
362
- animate="center"
363
- exit="exit"
364
- transition={{ type: 'spring', bounce: 0, duration: 0.3 }}
365
- className={styles.daysGrid}
366
- >
367
- {calendarDays.map((item, index) => {
368
- if (!item.isCurrentMonth) {
369
- return <div key={index} className={styles.dayCell} />;
370
- }
371
-
372
- const { isSelected, isStart, isEnd, isInRange } =
373
- checkSelection(item.date);
374
- const isTodayDate = isToday(item.date);
375
- const isDisabled =
376
- (minDate && item.date < minDate) ||
377
- (maxDate && item.date > maxDate) ||
378
- shouldDisableDate?.(item.date);
379
-
380
- return (
381
- <div
382
- key={index}
383
- className={classNames(
384
- styles.dayCell,
385
- // Range background styles applied to the cell wrapper
386
- isInRange && 'bg-primary/20',
387
- isStart &&
388
- (selectedValue as DateRange)?.[1] &&
389
- 'bg-gradient-to-r from-transparent to-primary/20',
390
- isEnd &&
391
- (selectedValue as DateRange)?.[0] &&
392
- 'bg-gradient-to-l from-transparent to-primary/20',
393
- )}
394
- >
395
- <Button
396
- className={() => ({
397
- button: classNames('aspect-square h-[40px] p-0', {
398
- 'text-on-surface': !isSelected && !isTodayDate,
399
- 'opacity-50': isDisabled,
400
- }),
401
- stateLayer: classNames({
402
- '!bg-transparent': isDisabled,
403
- }),
404
- })}
405
- size="small"
406
- allowShapeTransformation={false}
407
- variant={
408
- classNames({
409
- filled: isSelected,
410
- outlined: isTodayDate,
411
- text: !isSelected && !isTodayDate,
412
- }) as any
413
- }
414
- label={item.date.getDate().toString()}
415
- onClick={() => handleDateClick(item.date)}
416
- disabled={isDisabled}
417
- >
418
- {item.date.getDate().toString()}
419
- </Button>
420
- </div>
421
- );
422
- })}
423
- </motion.div>
424
- </AnimatePresence>
425
- </div>
426
- </>
427
- )}
428
- </div>
429
- );
430
- };
431
-
432
- // Helper for generic check - removed unused
@@ -1,20 +0,0 @@
1
- import { useDividerStyle } from '../styles';
2
- import { DividerInterface } from '../interfaces';
3
- import { ReactProps } from '../utils';
4
-
5
- /**
6
- * Dividers are thin lines that group content in lists or other containers
7
- * @status beta
8
- * @category Layout
9
- * @devx
10
- * - Renders a semantic `<hr>`; use `orientation` for vertical dividers.
11
- */
12
- export const Divider = ({
13
- orientation = 'horizontal',
14
- className,
15
- ...restProps
16
- }: ReactProps<DividerInterface>) => {
17
- const styles = useDividerStyle({ orientation, className });
18
-
19
- return <hr className={styles.divider} {...restProps} />;
20
- };
@@ -1,127 +0,0 @@
1
- import React, { useRef } from 'react';
2
- import { Icon } from '../icon';
3
- import { AnimatePresence, motion } from 'motion/react';
4
- import { FabInterface } from '../interfaces/fab.interface';
5
- import { useFabStyle } from '../styles/fab.style';
6
- import { classNames } from '../utils';
7
- import { ReactProps } from '../utils/component';
8
- import { Tooltip } from './Tooltip';
9
- import { State } from '../effects';
10
-
11
- /**
12
- * Floating action buttons (FABs) help people take primary actions
13
- * @status beta
14
- * @category Action
15
- * @devx
16
- * - Requires `label` or children; icon-only still needs a label for a11y.
17
- * @limitations
18
- * - No built-in positioning; placement is handled by the layout.
19
- */
20
- export const Fab = ({
21
- className,
22
- label,
23
- variant = 'primary',
24
- size = 'medium',
25
- href,
26
- type,
27
- icon,
28
- extended = false,
29
- ref,
30
- transition,
31
- children,
32
- ...restProps
33
- }: ReactProps<FabInterface>) => {
34
- if (children) label = children;
35
- if (!label) {
36
- throw new Error(
37
- 'FAB component requires either a label prop or children content',
38
- );
39
- }
40
- const ElementType = href ? 'a' : 'button';
41
-
42
- const styles = useFabStyle({
43
- href,
44
- icon,
45
- extended,
46
- label,
47
- size,
48
- variant,
49
- className,
50
- transition,
51
- children: label,
52
- });
53
-
54
- transition = { duration: 0.3, ...transition };
55
-
56
- const defaultRef = useRef(null);
57
- const resolvedRef = ref || defaultRef;
58
-
59
- const labelVariants = {
60
- visible: {
61
- width: 'auto',
62
- marginLeft: 12,
63
- opacity: 1,
64
- transition: {
65
- ...transition,
66
- opacity: {
67
- duration: transition.duration! / 2,
68
- delay: transition.duration! - transition.duration! / 2,
69
- },
70
- },
71
- },
72
- hidden: {
73
- width: 0,
74
- marginLeft: 0,
75
- opacity: 0,
76
- transition: {
77
- ...transition,
78
- marginLeft: {
79
- duration: transition.duration! / 2,
80
- delay: transition.duration! - transition.duration! / 2,
81
- },
82
- },
83
- },
84
- };
85
- return (
86
- <ElementType
87
- {...(restProps as any)}
88
- ref={resolvedRef}
89
- href={href}
90
- aria-label={extended ? undefined : label}
91
- className={styles.fab}
92
- >
93
- <Tooltip
94
- trigger={extended ? null : undefined}
95
- text={label}
96
- targetRef={resolvedRef}
97
- />
98
- <State
99
- style={{ transition: transition.duration + 's' }}
100
- className={styles.stateLayer}
101
- colorName={classNames({
102
- 'on-primary': variant == 'primary',
103
- 'on-secondary': variant == 'secondary',
104
- 'on-tertiary': variant == 'tertiary',
105
- 'on-primary-container': variant == 'primaryContainer',
106
- 'on-secondary-container': variant == 'secondaryContainer',
107
- 'on-tertiary-container': variant == 'tertiaryContainer',
108
- })}
109
- stateClassName={'state-ripple-group-[fab]'}
110
- />
111
- <Icon icon={icon} className={styles.icon} />
112
- <AnimatePresence>
113
- {extended && (
114
- <motion.span
115
- variants={labelVariants}
116
- initial="hidden"
117
- animate="visible"
118
- exit="hidden"
119
- className={styles.label}
120
- >
121
- {label}
122
- </motion.span>
123
- )}
124
- </AnimatePresence>
125
- </ElementType>
126
- );
127
- };