@shohojdhara/atomix 0.2.1 → 0.2.2
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 +1 -28
- package/dist/atomix.css +1810 -314
- package/dist/atomix.min.css +5 -5
- package/dist/index.d.ts +359 -3
- package/dist/index.esm.js +831 -124
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +834 -123
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/boomdevs.css +1808 -372
- package/dist/themes/boomdevs.min.css +60 -8
- package/dist/themes/esrar.css +1810 -314
- package/dist/themes/esrar.min.css +6 -6
- package/dist/themes/mashroom.css +1807 -308
- package/dist/themes/mashroom.min.css +8 -8
- package/dist/themes/shaj-default.css +1772 -273
- package/dist/themes/shaj-default.min.css +6 -6
- package/dist/themes/yabai.css +1804 -308
- package/dist/themes/yabai.min.css +8 -8
- package/package.json +1 -1
- package/src/components/Footer/Footer.stories.tsx +388 -0
- package/src/components/Footer/Footer.tsx +197 -0
- package/src/components/Footer/FooterLink.tsx +72 -0
- package/src/components/Footer/FooterSection.tsx +87 -0
- package/src/components/Footer/FooterSocialLink.tsx +117 -0
- package/src/components/Footer/README.md +261 -0
- package/src/components/Footer/index.ts +13 -0
- package/src/components/SectionIntro/SectionIntro.tsx +9 -11
- package/src/components/Slider/Slider.stories.tsx +634 -50
- package/src/components/Slider/Slider.tsx +5 -3
- package/src/components/index.ts +13 -0
- package/src/layouts/Grid/Grid.stories.tsx +226 -159
- package/src/lib/composables/useFooter.ts +85 -0
- package/src/lib/composables/useSlider.ts +191 -4
- package/src/lib/constants/components.ts +85 -0
- package/src/lib/types/components.ts +270 -0
- package/src/styles/01-settings/_index.scss +1 -0
- package/src/styles/01-settings/_settings.accordion.scss +20 -19
- package/src/styles/01-settings/_settings.animations.scss +5 -5
- package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
- package/src/styles/01-settings/_settings.avatar.scss +17 -18
- package/src/styles/01-settings/_settings.background.scss +9 -0
- package/src/styles/01-settings/_settings.badge.scss +1 -1
- package/src/styles/01-settings/_settings.breadcrumb.scss +8 -2
- package/src/styles/01-settings/_settings.card.scss +2 -2
- package/src/styles/01-settings/_settings.chart.scss +7 -7
- package/src/styles/01-settings/_settings.checkbox-group.scss +5 -2
- package/src/styles/01-settings/_settings.checkbox.scss +10 -4
- package/src/styles/01-settings/_settings.countdown.scss +6 -4
- package/src/styles/01-settings/_settings.dropdown.scss +9 -7
- package/src/styles/01-settings/_settings.edge-panel.scss +3 -2
- package/src/styles/01-settings/_settings.footer.scss +125 -0
- package/src/styles/01-settings/_settings.form-group.scss +3 -1
- package/src/styles/01-settings/_settings.form.scss +4 -2
- package/src/styles/01-settings/_settings.hero.scss +9 -7
- package/src/styles/01-settings/_settings.input.scss +9 -7
- package/src/styles/01-settings/_settings.list-group.scss +4 -2
- package/src/styles/01-settings/_settings.list.scss +4 -2
- package/src/styles/01-settings/_settings.menu.scss +10 -8
- package/src/styles/01-settings/_settings.messages.scss +19 -17
- package/src/styles/01-settings/_settings.modal.scss +6 -4
- package/src/styles/01-settings/_settings.nav.scss +6 -4
- package/src/styles/01-settings/_settings.navbar.scss +8 -5
- package/src/styles/01-settings/_settings.pagination.scss +5 -3
- package/src/styles/01-settings/_settings.popover.scss +6 -4
- package/src/styles/01-settings/_settings.rating.scss +5 -3
- package/src/styles/01-settings/_settings.river.scss +8 -6
- package/src/styles/01-settings/_settings.sectionintro.scss +8 -6
- package/src/styles/01-settings/_settings.select.scss +7 -5
- package/src/styles/01-settings/_settings.side-menu.scss +15 -13
- package/src/styles/01-settings/_settings.spacing.scss +4 -0
- package/src/styles/01-settings/_settings.steps.scss +7 -5
- package/src/styles/01-settings/_settings.tabs.scss +7 -5
- package/src/styles/01-settings/_settings.testimonials.scss +6 -4
- package/src/styles/01-settings/_settings.toggle.scss +3 -1
- package/src/styles/01-settings/_settings.tooltip.scss +5 -3
- package/src/styles/01-settings/_settings.upload.scss +22 -20
- package/src/styles/02-tools/_tools.background.scss +85 -0
- package/src/styles/02-tools/_tools.rem.scss +18 -5
- package/src/styles/02-tools/_tools.utility-api.scss +32 -26
- package/src/styles/03-generic/_generic.root.scss +14 -2
- package/src/styles/04-elements/_elements.body.scss +24 -0
- package/src/styles/06-components/_components.accordion.scss +8 -4
- package/src/styles/06-components/_components.avatar-group.scss +2 -1
- package/src/styles/06-components/_components.avatar.scss +2 -1
- package/src/styles/06-components/_components.badge.scss +2 -1
- package/src/styles/06-components/_components.breadcrumb.scss +2 -1
- package/src/styles/06-components/_components.button.scss +4 -3
- package/src/styles/06-components/_components.callout.scss +3 -2
- package/src/styles/06-components/_components.card.scss +4 -2
- package/src/styles/06-components/_components.chart.scss +2 -1
- package/src/styles/06-components/_components.checkbox.scss +2 -1
- package/src/styles/06-components/_components.color-mode-toggle.scss +3 -2
- package/src/styles/06-components/_components.countdown.scss +2 -1
- package/src/styles/06-components/_components.data-table.scss +7 -6
- package/src/styles/06-components/_components.datepicker.scss +2 -1
- package/src/styles/06-components/_components.dropdown.scss +4 -3
- package/src/styles/06-components/_components.edge-panel.scss +4 -3
- package/src/styles/06-components/_components.footer.scss +825 -0
- package/src/styles/06-components/_components.form-group.scss +1 -0
- package/src/styles/06-components/_components.hero.scss +3 -2
- package/src/styles/06-components/_components.image-gallery.scss +1 -0
- package/src/styles/06-components/_components.input.scss +2 -1
- package/src/styles/06-components/_components.list-group.scss +3 -2
- package/src/styles/06-components/_components.list.scss +2 -1
- package/src/styles/06-components/_components.menu.scss +5 -4
- package/src/styles/06-components/_components.messages.scss +8 -7
- package/src/styles/06-components/_components.modal.scss +3 -2
- package/src/styles/06-components/_components.nav.scss +6 -5
- package/src/styles/06-components/_components.navbar.scss +4 -3
- package/src/styles/06-components/_components.pagination.scss +2 -1
- package/src/styles/06-components/_components.photoviewer.scss +4 -3
- package/src/styles/06-components/_components.popover.scss +3 -2
- package/src/styles/06-components/_components.product-review.scss +3 -2
- package/src/styles/06-components/_components.progress.scss +3 -2
- package/src/styles/06-components/_components.river.scss +3 -2
- package/src/styles/06-components/_components.sectionintro.scss +2 -1
- package/src/styles/06-components/_components.select.scss +5 -4
- package/src/styles/06-components/_components.side-menu.scss +8 -7
- package/src/styles/06-components/_components.skeleton.scss +3 -2
- package/src/styles/06-components/_components.slider.scss +7 -6
- package/src/styles/06-components/_components.spinner.scss +1 -0
- package/src/styles/06-components/_components.steps.scss +3 -2
- package/src/styles/06-components/_components.tabs.scss +4 -3
- package/src/styles/06-components/_components.testimonials.scss +2 -1
- package/src/styles/06-components/_components.todo.scss +3 -2
- package/src/styles/06-components/_components.toggle.scss +5 -4
- package/src/styles/06-components/_components.tooltip.scss +3 -2
- package/src/styles/06-components/_components.upload.scss +4 -3
- package/src/styles/06-components/_components.video-player.scss +4 -3
- package/src/styles/06-components/_index.scss +1 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { FooterLayout, ThemeColor, Size, SocialLink } from '../types/components';
|
|
2
|
+
import { FOOTER } from '../constants/components';
|
|
3
|
+
|
|
4
|
+
export interface UseFooterOptions {
|
|
5
|
+
layout?: FooterLayout;
|
|
6
|
+
variant?: ThemeColor;
|
|
7
|
+
size?: Size;
|
|
8
|
+
sticky?: boolean;
|
|
9
|
+
showNewsletter?: boolean;
|
|
10
|
+
showBackToTop?: boolean;
|
|
11
|
+
socialLinks?: SocialLink[];
|
|
12
|
+
onNewsletterSubmit?: (email: string) => void | Promise<void>;
|
|
13
|
+
onBackToTop?: () => void;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export function useFooter(options: UseFooterOptions = {}) {
|
|
20
|
+
const {
|
|
21
|
+
layout = FOOTER.DEFAULTS.LAYOUT,
|
|
22
|
+
variant = FOOTER.DEFAULTS.VARIANT,
|
|
23
|
+
size = FOOTER.DEFAULTS.SIZE,
|
|
24
|
+
sticky = FOOTER.DEFAULTS.STICKY,
|
|
25
|
+
showNewsletter = FOOTER.DEFAULTS.SHOW_NEWSLETTER,
|
|
26
|
+
showBackToTop = FOOTER.DEFAULTS.SHOW_BACK_TO_TOP,
|
|
27
|
+
socialLinks = [],
|
|
28
|
+
onNewsletterSubmit,
|
|
29
|
+
onBackToTop,
|
|
30
|
+
className = '',
|
|
31
|
+
} = options;
|
|
32
|
+
|
|
33
|
+
// Generate footer classes
|
|
34
|
+
const footerClass = (() => {
|
|
35
|
+
const classes = [
|
|
36
|
+
FOOTER.CLASSES.BASE,
|
|
37
|
+
FOOTER.CLASSES[layout.toUpperCase() as keyof typeof FOOTER.CLASSES] || FOOTER.CLASSES.COLUMNS,
|
|
38
|
+
`c-footer--${variant}`,
|
|
39
|
+
FOOTER.CLASSES[size.toUpperCase() as keyof typeof FOOTER.CLASSES] || FOOTER.CLASSES.MD,
|
|
40
|
+
sticky && FOOTER.CLASSES.STICKY,
|
|
41
|
+
className,
|
|
42
|
+
];
|
|
43
|
+
return classes.filter(Boolean).join(' ');
|
|
44
|
+
})();
|
|
45
|
+
|
|
46
|
+
const containerClass = FOOTER.CLASSES.CONTAINER;
|
|
47
|
+
const brandClass = FOOTER.CLASSES.BRAND;
|
|
48
|
+
const sectionsClass = (() => {
|
|
49
|
+
const classes = [
|
|
50
|
+
FOOTER.CLASSES.SECTIONS,
|
|
51
|
+
layout === 'columns' && 'c-footer__sections--columns',
|
|
52
|
+
layout === 'centered' && 'c-footer__sections--centered',
|
|
53
|
+
layout === 'stacked' && 'c-footer__sections--stacked',
|
|
54
|
+
];
|
|
55
|
+
return classes.filter(Boolean).join(' ');
|
|
56
|
+
})();
|
|
57
|
+
const bottomClass = FOOTER.CLASSES.BOTTOM;
|
|
58
|
+
|
|
59
|
+
// Handle newsletter submission
|
|
60
|
+
const handleNewsletterSubmit = (email: string) => {
|
|
61
|
+
if (onNewsletterSubmit) {
|
|
62
|
+
onNewsletterSubmit(email);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Handle back to top
|
|
67
|
+
const handleBackToTop = () => {
|
|
68
|
+
if (onBackToTop) {
|
|
69
|
+
onBackToTop();
|
|
70
|
+
} else {
|
|
71
|
+
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
footerClass,
|
|
77
|
+
containerClass,
|
|
78
|
+
brandClass,
|
|
79
|
+
sectionsClass,
|
|
80
|
+
bottomClass,
|
|
81
|
+
handleNewsletterSubmit,
|
|
82
|
+
handleBackToTop,
|
|
83
|
+
socialLinks,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -35,12 +35,15 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
35
35
|
speed = 300,
|
|
36
36
|
allowTouchMove = true,
|
|
37
37
|
threshold = 50,
|
|
38
|
+
autoplay,
|
|
38
39
|
onSlideChange,
|
|
39
40
|
} = options;
|
|
40
41
|
|
|
41
42
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
42
43
|
const wrapperRef = useRef<HTMLDivElement | null>(null);
|
|
43
44
|
const repositioningRef = useRef(false);
|
|
45
|
+
const autoplayRef = useRef<NodeJS.Timeout | null>(null);
|
|
46
|
+
const [autoplayRunning, setAutoplayRunning] = useState(false);
|
|
44
47
|
|
|
45
48
|
const [realIndex, setRealIndex] = useState(initialSlide);
|
|
46
49
|
const [internalIndex, setInternalIndex] = useState(0);
|
|
@@ -73,6 +76,160 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
73
76
|
return -(internalIndex * slideWidth) + dragOffset;
|
|
74
77
|
}, [slideWidth, internalIndex, dragOffset]);
|
|
75
78
|
|
|
79
|
+
// Autoplay effect
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (!autoplay) {
|
|
82
|
+
if (autoplayRef.current) {
|
|
83
|
+
clearInterval(autoplayRef.current);
|
|
84
|
+
autoplayRef.current = null;
|
|
85
|
+
}
|
|
86
|
+
setAutoplayRunning(false);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const autoplayParams = typeof autoplay === 'boolean' ? { delay: 3000 } : autoplay;
|
|
91
|
+
const { delay = 3000, pauseOnMouseEnter = false, disableOnInteraction = false, reverseDirection = false } = autoplayParams;
|
|
92
|
+
|
|
93
|
+
// Clear any existing interval
|
|
94
|
+
if (autoplayRef.current) {
|
|
95
|
+
clearInterval(autoplayRef.current);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Create new interval
|
|
99
|
+
autoplayRef.current = setInterval(() => {
|
|
100
|
+
// We need to use a functional update to get the latest values
|
|
101
|
+
setRealIndex(prevRealIndex => {
|
|
102
|
+
if (isTransitioning) return prevRealIndex;
|
|
103
|
+
|
|
104
|
+
// Stop autoplay on interaction if disableOnInteraction is true
|
|
105
|
+
if (disableOnInteraction && autoplayRef.current) {
|
|
106
|
+
clearInterval(autoplayRef.current);
|
|
107
|
+
autoplayRef.current = null;
|
|
108
|
+
setAutoplayRunning(false);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let nextIndex;
|
|
112
|
+
if (loop) {
|
|
113
|
+
nextIndex = (prevRealIndex + 1) % slides.length;
|
|
114
|
+
} else {
|
|
115
|
+
nextIndex = Math.min(prevRealIndex + 1, slides.length - slidesToShow);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Trigger the slide change
|
|
119
|
+
if (reverseDirection) {
|
|
120
|
+
// For reverse direction, we would go to previous slide
|
|
121
|
+
const prevIndex = loop ? (prevRealIndex === 0 ? slides.length - 1 : prevRealIndex - 1) : Math.max(prevRealIndex - 1, 0);
|
|
122
|
+
setInternalIndex(loop ? slides.length + prevIndex : prevIndex);
|
|
123
|
+
setIsTransitioning(true);
|
|
124
|
+
setDragOffset(0);
|
|
125
|
+
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
setIsTransitioning(false);
|
|
128
|
+
onSlideChange?.(prevIndex);
|
|
129
|
+
}, speed);
|
|
130
|
+
|
|
131
|
+
return prevIndex;
|
|
132
|
+
} else {
|
|
133
|
+
// Normal direction
|
|
134
|
+
setInternalIndex(loop ? slides.length + nextIndex : nextIndex);
|
|
135
|
+
setIsTransitioning(true);
|
|
136
|
+
setDragOffset(0);
|
|
137
|
+
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
setIsTransitioning(false);
|
|
140
|
+
onSlideChange?.(nextIndex);
|
|
141
|
+
|
|
142
|
+
// Reposition after transition ends for looped sliders
|
|
143
|
+
if (loop && nextIndex >= slides.length * 2) {
|
|
144
|
+
repositioningRef.current = true;
|
|
145
|
+
setInternalIndex(slides.length + nextIndex);
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
repositioningRef.current = false;
|
|
148
|
+
}, 0);
|
|
149
|
+
}
|
|
150
|
+
}, speed);
|
|
151
|
+
|
|
152
|
+
return nextIndex;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}, delay);
|
|
156
|
+
|
|
157
|
+
setAutoplayRunning(true);
|
|
158
|
+
|
|
159
|
+
// Handle pause on mouse enter/leave if enabled
|
|
160
|
+
let containerElement: HTMLDivElement | null = null;
|
|
161
|
+
const handleMouseEnter = () => {
|
|
162
|
+
if (autoplayRef.current) {
|
|
163
|
+
clearInterval(autoplayRef.current);
|
|
164
|
+
autoplayRef.current = null;
|
|
165
|
+
setAutoplayRunning(false);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const handleMouseLeave = () => {
|
|
170
|
+
// Restart autoplay
|
|
171
|
+
if (autoplayRef.current) {
|
|
172
|
+
clearInterval(autoplayRef.current);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
autoplayRef.current = setInterval(() => {
|
|
176
|
+
setRealIndex(prevRealIndex => {
|
|
177
|
+
if (isTransitioning) return prevRealIndex;
|
|
178
|
+
|
|
179
|
+
let nextIndex;
|
|
180
|
+
if (loop) {
|
|
181
|
+
nextIndex = (prevRealIndex + 1) % slides.length;
|
|
182
|
+
} else {
|
|
183
|
+
nextIndex = Math.min(prevRealIndex + 1, slides.length - slidesToShow);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
setInternalIndex(loop ? slides.length + nextIndex : nextIndex);
|
|
187
|
+
setIsTransitioning(true);
|
|
188
|
+
setDragOffset(0);
|
|
189
|
+
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
setIsTransitioning(false);
|
|
192
|
+
onSlideChange?.(nextIndex);
|
|
193
|
+
|
|
194
|
+
if (loop) {
|
|
195
|
+
// Reposition after transition ends
|
|
196
|
+
if (nextIndex >= slides.length * 2) {
|
|
197
|
+
repositioningRef.current = true;
|
|
198
|
+
setInternalIndex(slides.length + nextIndex);
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
repositioningRef.current = false;
|
|
201
|
+
}, 0);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}, speed);
|
|
205
|
+
|
|
206
|
+
return nextIndex;
|
|
207
|
+
});
|
|
208
|
+
}, delay);
|
|
209
|
+
|
|
210
|
+
setAutoplayRunning(true);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
if (pauseOnMouseEnter && containerRef.current) {
|
|
214
|
+
containerElement = containerRef.current;
|
|
215
|
+
containerElement.addEventListener('mouseenter', handleMouseEnter);
|
|
216
|
+
containerElement.addEventListener('mouseleave', handleMouseLeave);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Cleanup
|
|
220
|
+
return () => {
|
|
221
|
+
if (autoplayRef.current) {
|
|
222
|
+
clearInterval(autoplayRef.current);
|
|
223
|
+
autoplayRef.current = null;
|
|
224
|
+
}
|
|
225
|
+
if (containerElement) {
|
|
226
|
+
containerElement.removeEventListener('mouseenter', handleMouseEnter);
|
|
227
|
+
containerElement.removeEventListener('mouseleave', handleMouseLeave);
|
|
228
|
+
}
|
|
229
|
+
setAutoplayRunning(false);
|
|
230
|
+
};
|
|
231
|
+
}, [autoplay, slides.length, loop, slidesToShow, isTransitioning, speed, onSlideChange, repositioningRef]);
|
|
232
|
+
|
|
76
233
|
// Initialize
|
|
77
234
|
useEffect(() => {
|
|
78
235
|
if (loop) {
|
|
@@ -100,6 +257,13 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
100
257
|
const slideNext = useCallback(() => {
|
|
101
258
|
if (isTransitioning) return;
|
|
102
259
|
|
|
260
|
+
// Stop autoplay on interaction if disableOnInteraction is true
|
|
261
|
+
if (autoplay && typeof autoplay === 'object' && autoplay.disableOnInteraction && autoplayRef.current) {
|
|
262
|
+
clearInterval(autoplayRef.current);
|
|
263
|
+
autoplayRef.current = null;
|
|
264
|
+
setAutoplayRunning(false);
|
|
265
|
+
}
|
|
266
|
+
|
|
103
267
|
if (loop) {
|
|
104
268
|
const nextRealIndex = (realIndex + 1) % slides.length;
|
|
105
269
|
const nextInternalIndex = internalIndex + 1;
|
|
@@ -145,11 +309,19 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
145
309
|
onSlideChange,
|
|
146
310
|
allSlides.length,
|
|
147
311
|
loopedSlides,
|
|
312
|
+
autoplay
|
|
148
313
|
]);
|
|
149
314
|
|
|
150
315
|
const slidePrev = useCallback(() => {
|
|
151
316
|
if (isTransitioning) return;
|
|
152
317
|
|
|
318
|
+
// Stop autoplay on interaction if disableOnInteraction is true
|
|
319
|
+
if (autoplay && typeof autoplay === 'object' && autoplay.disableOnInteraction && autoplayRef.current) {
|
|
320
|
+
clearInterval(autoplayRef.current);
|
|
321
|
+
autoplayRef.current = null;
|
|
322
|
+
setAutoplayRunning(false);
|
|
323
|
+
}
|
|
324
|
+
|
|
153
325
|
if (loop) {
|
|
154
326
|
const prevRealIndex = realIndex === 0 ? slides.length - 1 : realIndex - 1;
|
|
155
327
|
const prevInternalIndex = internalIndex - 1;
|
|
@@ -194,12 +366,20 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
194
366
|
onSlideChange,
|
|
195
367
|
allSlides.length,
|
|
196
368
|
loopedSlides,
|
|
369
|
+
autoplay
|
|
197
370
|
]);
|
|
198
371
|
|
|
199
372
|
const goToSlide = useCallback(
|
|
200
373
|
(index: number) => {
|
|
201
374
|
if (isTransitioning || index === realIndex) return;
|
|
202
375
|
|
|
376
|
+
// Stop autoplay on interaction if disableOnInteraction is true
|
|
377
|
+
if (autoplay && typeof autoplay === 'object' && autoplay.disableOnInteraction && autoplayRef.current) {
|
|
378
|
+
clearInterval(autoplayRef.current);
|
|
379
|
+
autoplayRef.current = null;
|
|
380
|
+
setAutoplayRunning(false);
|
|
381
|
+
}
|
|
382
|
+
|
|
203
383
|
setIsTransitioning(true);
|
|
204
384
|
setDragOffset(0);
|
|
205
385
|
|
|
@@ -211,13 +391,20 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
211
391
|
onSlideChange?.(index);
|
|
212
392
|
}, speed);
|
|
213
393
|
},
|
|
214
|
-
[realIndex, isTransitioning, speed, onSlideChange, loop, loopedSlides]
|
|
394
|
+
[realIndex, isTransitioning, speed, onSlideChange, loop, loopedSlides, autoplay]
|
|
215
395
|
);
|
|
216
396
|
|
|
217
397
|
const handleTouchStart = useCallback(
|
|
218
398
|
(e: React.TouchEvent | React.MouseEvent) => {
|
|
219
399
|
if (!allowTouchMove) return;
|
|
220
400
|
|
|
401
|
+
// Stop autoplay on interaction if disableOnInteraction is true
|
|
402
|
+
if (autoplay && typeof autoplay === 'object' && autoplay.disableOnInteraction && autoplayRef.current) {
|
|
403
|
+
clearInterval(autoplayRef.current);
|
|
404
|
+
autoplayRef.current = null;
|
|
405
|
+
setAutoplayRunning(false);
|
|
406
|
+
}
|
|
407
|
+
|
|
221
408
|
const client =
|
|
222
409
|
direction === 'horizontal'
|
|
223
410
|
? 'touches' in e
|
|
@@ -230,7 +417,7 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
230
417
|
setTouching(true);
|
|
231
418
|
setDragOffset(0);
|
|
232
419
|
},
|
|
233
|
-
[allowTouchMove, direction]
|
|
420
|
+
[allowTouchMove, direction, autoplay]
|
|
234
421
|
);
|
|
235
422
|
|
|
236
423
|
const handleTouchMove = useCallback(
|
|
@@ -293,7 +480,7 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
293
480
|
isBeginning: !loop && realIndex === 0,
|
|
294
481
|
isEnd: !loop && realIndex >= slides.length - slidesToShow,
|
|
295
482
|
progress: slides.length > 0 ? realIndex / (slides.length - 1) : 0,
|
|
296
|
-
autoplayRunning
|
|
483
|
+
autoplayRunning,
|
|
297
484
|
transitioning: isTransitioning,
|
|
298
485
|
touching,
|
|
299
486
|
translate: translateValue,
|
|
@@ -336,4 +523,4 @@ export function useSlider(options: UseSliderOptions): UseSliderReturn {
|
|
|
336
523
|
loopedSlides,
|
|
337
524
|
repositioningRef,
|
|
338
525
|
};
|
|
339
|
-
}
|
|
526
|
+
}
|
|
@@ -1431,3 +1431,88 @@ export const BLOCK = {
|
|
|
1431
1431
|
DEFAULT: 'md' as const,
|
|
1432
1432
|
},
|
|
1433
1433
|
};
|
|
1434
|
+
|
|
1435
|
+
/**
|
|
1436
|
+
* Footer-specific constants
|
|
1437
|
+
*/
|
|
1438
|
+
export const FOOTER = {
|
|
1439
|
+
SELECTORS: {
|
|
1440
|
+
FOOTER: '.c-footer',
|
|
1441
|
+
CONTAINER: '.c-footer__container',
|
|
1442
|
+
SECTIONS: '.c-footer__sections',
|
|
1443
|
+
BRAND: '.c-footer__brand',
|
|
1444
|
+
BRAND_LOGO: '.c-footer__brand-logo',
|
|
1445
|
+
BRAND_NAME: '.c-footer__brand-name',
|
|
1446
|
+
BRAND_DESCRIPTION: '.c-footer__brand-description',
|
|
1447
|
+
SECTION: '.c-footer__section',
|
|
1448
|
+
SECTION_HEADER: '.c-footer__section-header',
|
|
1449
|
+
SECTION_TITLE: '.c-footer__section-title',
|
|
1450
|
+
SECTION_CONTENT: '.c-footer__section-content',
|
|
1451
|
+
SECTION_TOGGLE: '.c-footer__section-toggle',
|
|
1452
|
+
LINK: '.c-footer__link',
|
|
1453
|
+
SOCIAL: '.c-footer__social',
|
|
1454
|
+
SOCIAL_LINK: '.c-footer__social-link',
|
|
1455
|
+
NEWSLETTER: '.c-footer__newsletter',
|
|
1456
|
+
NEWSLETTER_FORM: '.c-footer__newsletter-form',
|
|
1457
|
+
NEWSLETTER_INPUT: '.c-footer__newsletter-input',
|
|
1458
|
+
NEWSLETTER_BUTTON: '.c-footer__newsletter-button',
|
|
1459
|
+
BOTTOM: '.c-footer__bottom',
|
|
1460
|
+
COPYRIGHT: '.c-footer__copyright',
|
|
1461
|
+
BACK_TO_TOP: '.c-footer__back-to-top',
|
|
1462
|
+
DIVIDER: '.c-footer__divider',
|
|
1463
|
+
},
|
|
1464
|
+
CLASSES: {
|
|
1465
|
+
BASE: 'c-footer',
|
|
1466
|
+
CONTAINER: 'c-footer__container',
|
|
1467
|
+
SECTIONS: 'c-footer__sections',
|
|
1468
|
+
BRAND: 'c-footer__brand',
|
|
1469
|
+
BRAND_LOGO: 'c-footer__brand-logo',
|
|
1470
|
+
BRAND_NAME: 'c-footer__brand-name',
|
|
1471
|
+
BRAND_DESCRIPTION: 'c-footer__brand-description',
|
|
1472
|
+
SECTION: 'c-footer__section',
|
|
1473
|
+
SECTION_HEADER: 'c-footer__section-header',
|
|
1474
|
+
SECTION_TITLE: 'c-footer__section-title',
|
|
1475
|
+
SECTION_CONTENT: 'c-footer__section-content',
|
|
1476
|
+
SECTION_TOGGLE: 'c-footer__section-toggle',
|
|
1477
|
+
SECTION_COLLAPSIBLE: 'c-footer__section--collapsible',
|
|
1478
|
+
SECTION_COLLAPSED: 'c-footer__section--collapsed',
|
|
1479
|
+
LINK: 'c-footer__link',
|
|
1480
|
+
LINK_ACTIVE: 'c-footer__link--active',
|
|
1481
|
+
LINK_DISABLED: 'c-footer__link--disabled',
|
|
1482
|
+
SOCIAL: 'c-footer__social',
|
|
1483
|
+
SOCIAL_LINK: 'c-footer__social-link',
|
|
1484
|
+
NEWSLETTER: 'c-footer__newsletter',
|
|
1485
|
+
NEWSLETTER_FORM: 'c-footer__newsletter-form',
|
|
1486
|
+
NEWSLETTER_INPUT: 'c-footer__newsletter-input',
|
|
1487
|
+
NEWSLETTER_BUTTON: 'c-footer__newsletter-button',
|
|
1488
|
+
BOTTOM: 'c-footer__bottom',
|
|
1489
|
+
COPYRIGHT: 'c-footer__copyright',
|
|
1490
|
+
BACK_TO_TOP: 'c-footer__back-to-top',
|
|
1491
|
+
DIVIDER: 'c-footer__divider',
|
|
1492
|
+
// Layout variants
|
|
1493
|
+
COLUMNS: 'c-footer--columns',
|
|
1494
|
+
CENTERED: 'c-footer--centered',
|
|
1495
|
+
MINIMAL: 'c-footer--minimal',
|
|
1496
|
+
STACKED: 'c-footer--stacked',
|
|
1497
|
+
// Size variants
|
|
1498
|
+
SM: 'c-footer--sm',
|
|
1499
|
+
MD: 'c-footer--md',
|
|
1500
|
+
LG: 'c-footer--lg',
|
|
1501
|
+
// State modifiers
|
|
1502
|
+
STICKY: 'c-footer--sticky',
|
|
1503
|
+
},
|
|
1504
|
+
DEFAULTS: {
|
|
1505
|
+
LAYOUT: 'columns',
|
|
1506
|
+
VARIANT: 'primary',
|
|
1507
|
+
SIZE: 'md',
|
|
1508
|
+
SHOW_NEWSLETTER: false,
|
|
1509
|
+
SHOW_BACK_TO_TOP: false,
|
|
1510
|
+
SHOW_DIVIDER: true,
|
|
1511
|
+
STICKY: false,
|
|
1512
|
+
NEWSLETTER_TITLE: 'Stay Updated',
|
|
1513
|
+
NEWSLETTER_DESCRIPTION: 'Subscribe to our newsletter for the latest updates.',
|
|
1514
|
+
NEWSLETTER_PLACEHOLDER: 'Enter your email',
|
|
1515
|
+
NEWSLETTER_BUTTON_TEXT: 'Subscribe',
|
|
1516
|
+
BACK_TO_TOP_TEXT: 'Back to Top',
|
|
1517
|
+
},
|
|
1518
|
+
};
|