mtrl 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.typedocignore +11 -0
- package/DOCS.md +153 -0
- package/index.ts +18 -3
- package/package.json +7 -2
- package/src/components/badge/_styles.scss +174 -0
- package/src/components/badge/api.ts +292 -0
- package/src/components/badge/badge.ts +52 -0
- package/src/components/badge/config.ts +68 -0
- package/src/components/badge/constants.ts +30 -0
- package/src/components/badge/features.ts +185 -0
- package/src/components/badge/index.ts +4 -0
- package/src/components/badge/types.ts +105 -0
- package/src/components/button/types.ts +174 -29
- package/src/components/carousel/_styles.scss +645 -0
- package/src/components/carousel/api.ts +147 -0
- package/src/components/carousel/carousel.ts +178 -0
- package/src/components/carousel/config.ts +91 -0
- package/src/components/carousel/constants.ts +95 -0
- package/src/components/carousel/features/drag.ts +388 -0
- package/src/components/carousel/features/index.ts +8 -0
- package/src/components/carousel/features/slides.ts +682 -0
- package/src/components/carousel/index.ts +38 -0
- package/src/components/carousel/types.ts +327 -0
- package/src/components/dialog/_styles.scss +213 -0
- package/src/components/dialog/api.ts +283 -0
- package/src/components/dialog/config.ts +113 -0
- package/src/components/dialog/constants.ts +32 -0
- package/src/components/dialog/dialog.ts +56 -0
- package/src/components/dialog/features.ts +713 -0
- package/src/components/dialog/index.ts +15 -0
- package/src/components/dialog/types.ts +221 -0
- package/src/components/progress/_styles.scss +13 -1
- package/src/components/progress/api.ts +2 -2
- package/src/components/progress/progress.ts +2 -2
- package/src/components/progress/types.ts +3 -0
- package/src/components/radios/_styles.scss +232 -0
- package/src/components/radios/api.ts +100 -0
- package/src/components/radios/config.ts +60 -0
- package/src/components/radios/constants.ts +28 -0
- package/src/components/radios/index.ts +4 -0
- package/src/components/radios/radio.ts +269 -0
- package/src/components/radios/radios.ts +42 -0
- package/src/components/radios/types.ts +232 -0
- package/src/components/sheet/_styles.scss +236 -0
- package/src/components/sheet/api.ts +96 -0
- package/src/components/sheet/config.ts +66 -0
- package/src/components/sheet/constants.ts +20 -0
- package/src/components/sheet/features/content.ts +51 -0
- package/src/components/sheet/features/gestures.ts +177 -0
- package/src/components/sheet/features/index.ts +6 -0
- package/src/components/sheet/features/position.ts +42 -0
- package/src/components/sheet/features/state.ts +116 -0
- package/src/components/sheet/features/title.ts +86 -0
- package/src/components/sheet/index.ts +4 -0
- package/src/components/sheet/sheet.ts +57 -0
- package/src/components/sheet/types.ts +266 -0
- package/src/components/slider/_styles.scss +518 -0
- package/src/components/slider/api.ts +336 -0
- package/src/components/slider/config.ts +145 -0
- package/src/components/slider/constants.ts +28 -0
- package/src/components/slider/features/appearance.ts +140 -0
- package/src/components/slider/features/disabled.ts +43 -0
- package/src/components/slider/features/events.ts +164 -0
- package/src/components/slider/features/index.ts +5 -0
- package/src/components/slider/features/interactions.ts +256 -0
- package/src/components/slider/features/keyboard.ts +114 -0
- package/src/components/slider/features/slider.ts +336 -0
- package/src/components/slider/features/structure.ts +264 -0
- package/src/components/slider/features/ui.ts +518 -0
- package/src/components/slider/index.ts +9 -0
- package/src/components/slider/slider.ts +58 -0
- package/src/components/slider/types.ts +166 -0
- package/src/components/tabs/_styles.scss +224 -0
- package/src/components/tabs/api.ts +443 -0
- package/src/components/tabs/config.ts +80 -0
- package/src/components/tabs/constants.ts +12 -0
- package/src/components/tabs/index.ts +4 -0
- package/src/components/tabs/tabs.ts +52 -0
- package/src/components/tabs/types.ts +247 -0
- package/src/components/textfield/_styles.scss +97 -4
- package/src/components/tooltip/_styles.scss +241 -0
- package/src/components/tooltip/api.ts +411 -0
- package/src/components/tooltip/config.ts +78 -0
- package/src/components/tooltip/constants.ts +27 -0
- package/src/components/tooltip/index.ts +4 -0
- package/src/components/tooltip/tooltip.ts +60 -0
- package/src/components/tooltip/types.ts +178 -0
- package/src/index.ts +9 -1
- package/src/styles/abstract/_variables.scss +24 -12
- package/tsconfig.json +22 -0
- package/typedoc.json +28 -0
- package/typedoc.simple.json +14 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/components/carousel/api.ts
|
|
2
|
+
import { CarouselComponent, CarouselSlide } from './types';
|
|
3
|
+
|
|
4
|
+
interface ApiOptions {
|
|
5
|
+
slides: {
|
|
6
|
+
addSlide: (slide: CarouselSlide, index?: number) => any;
|
|
7
|
+
removeSlide: (index: number) => any;
|
|
8
|
+
updateSlide: (index: number, slide: CarouselSlide) => any;
|
|
9
|
+
getCount: () => number;
|
|
10
|
+
getElements: () => HTMLElement[];
|
|
11
|
+
};
|
|
12
|
+
lifecycle: {
|
|
13
|
+
destroy: () => void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ComponentWithElements {
|
|
18
|
+
element: HTMLElement;
|
|
19
|
+
getClass: (name: string) => string;
|
|
20
|
+
getCurrentSlide: () => number;
|
|
21
|
+
goTo: (index: number) => any;
|
|
22
|
+
next: () => any;
|
|
23
|
+
prev: () => any;
|
|
24
|
+
enableLoop: () => any;
|
|
25
|
+
disableLoop: () => any;
|
|
26
|
+
setBorderRadius?: (radius: number) => any;
|
|
27
|
+
setGap?: (gap: number) => any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Enhances a carousel component with API methods
|
|
32
|
+
* @param {ApiOptions} options - API configuration options
|
|
33
|
+
* @returns {Function} Higher-order function that adds API methods to component
|
|
34
|
+
* @internal This is an internal utility for the Carousel component
|
|
35
|
+
*/
|
|
36
|
+
export const withAPI = (options: ApiOptions) =>
|
|
37
|
+
(component: ComponentWithElements): CarouselComponent => {
|
|
38
|
+
// Create the API component
|
|
39
|
+
const apiComponent: CarouselComponent = {
|
|
40
|
+
element: component.element,
|
|
41
|
+
|
|
42
|
+
slides: {
|
|
43
|
+
addSlide: options.slides.addSlide,
|
|
44
|
+
removeSlide: options.slides.removeSlide,
|
|
45
|
+
updateSlide: options.slides.updateSlide,
|
|
46
|
+
getSlide: (index: number): CarouselSlide | null => {
|
|
47
|
+
if (component['slideData'] && index >= 0 && index < component['slideData'].length) {
|
|
48
|
+
return component['slideData'][index];
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
},
|
|
52
|
+
getCount: options.slides.getCount,
|
|
53
|
+
getElements: options.slides.getElements
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
lifecycle: {
|
|
57
|
+
destroy: options.lifecycle.destroy
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
getClass: component.getClass,
|
|
61
|
+
|
|
62
|
+
next() {
|
|
63
|
+
component.next();
|
|
64
|
+
return this;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
prev() {
|
|
68
|
+
component.prev();
|
|
69
|
+
return this;
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
goTo(index: number) {
|
|
73
|
+
component.goTo(index);
|
|
74
|
+
return this;
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
getCurrentSlide: component.getCurrentSlide,
|
|
78
|
+
|
|
79
|
+
addSlide(slide: CarouselSlide, index?: number) {
|
|
80
|
+
options.slides.addSlide(slide, index);
|
|
81
|
+
return this;
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
removeSlide(index: number) {
|
|
85
|
+
options.slides.removeSlide(index);
|
|
86
|
+
return this;
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
enableLoop() {
|
|
90
|
+
component.enableLoop();
|
|
91
|
+
return this;
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
disableLoop() {
|
|
95
|
+
component.disableLoop();
|
|
96
|
+
return this;
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
setBorderRadius(radius: number) {
|
|
100
|
+
if (component.setBorderRadius) {
|
|
101
|
+
component.setBorderRadius(radius);
|
|
102
|
+
}
|
|
103
|
+
return this;
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
setGap(gap: number) {
|
|
107
|
+
if (component.setGap) {
|
|
108
|
+
component.setGap(gap);
|
|
109
|
+
}
|
|
110
|
+
return this;
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
destroy() {
|
|
114
|
+
options.lifecycle.destroy();
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Add event handling and class methods from component
|
|
118
|
+
on(event: string, handler: Function) {
|
|
119
|
+
if (typeof (component as any).on === 'function') {
|
|
120
|
+
(component as any).on(event, handler);
|
|
121
|
+
} else if (component.element.addEventListener) {
|
|
122
|
+
component.element.addEventListener(event, handler as EventListener);
|
|
123
|
+
}
|
|
124
|
+
return this;
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
off(event: string, handler: Function) {
|
|
128
|
+
if (typeof (component as any).off === 'function') {
|
|
129
|
+
(component as any).off(event, handler);
|
|
130
|
+
} else if (component.element.removeEventListener) {
|
|
131
|
+
component.element.removeEventListener(event, handler as EventListener);
|
|
132
|
+
}
|
|
133
|
+
return this;
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
addClass(...classes: string[]) {
|
|
137
|
+
if (typeof (component as any).addClass === 'function') {
|
|
138
|
+
(component as any).addClass(...classes);
|
|
139
|
+
} else {
|
|
140
|
+
classes.forEach(cls => component.element.classList.add(cls));
|
|
141
|
+
}
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return apiComponent;
|
|
147
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// src/components/carousel/factory.ts
|
|
2
|
+
/**
|
|
3
|
+
* Carousel Factory - Creates different types of carousel layouts based on Material Design 3 guidelines
|
|
4
|
+
*
|
|
5
|
+
* This factory implements four carousel layout types:
|
|
6
|
+
* - Multi-browse: For browsing many visual items at once (photos, event feeds)
|
|
7
|
+
* - Uncontained: For highly customized or text-heavy carousels (traditional behavior)
|
|
8
|
+
* - Hero: For spotlighting very large visual items (featured content)
|
|
9
|
+
* - Full-screen: For immersive vertical-scrolling experiences
|
|
10
|
+
*
|
|
11
|
+
* @module CarouselFactory
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { pipe } from '../../core/compose';
|
|
15
|
+
import { createBase, withElement } from '../../core/compose/component';
|
|
16
|
+
import { withEvents, withLifecycle } from '../../core/compose/features';
|
|
17
|
+
import { withSlides, withDrag } from './features';
|
|
18
|
+
import { withAPI } from './api';
|
|
19
|
+
import {
|
|
20
|
+
CarouselConfig,
|
|
21
|
+
CarouselComponent,
|
|
22
|
+
CarouselLayout,
|
|
23
|
+
CarouselScrollBehavior
|
|
24
|
+
} from './types';
|
|
25
|
+
import { createBaseConfig, getElementConfig } from './config';
|
|
26
|
+
import { CAROUSEL_DEFAULTS } from './constants';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a new carousel with specified layout and scroll behavior
|
|
30
|
+
*
|
|
31
|
+
* @param {CarouselConfig} config - Carousel configuration
|
|
32
|
+
* @returns {CarouselComponent} The configured carousel component
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Create a multi-browse carousel with snap scrolling
|
|
37
|
+
* const carousel = createCarousel({
|
|
38
|
+
* layout: 'multi-browse',
|
|
39
|
+
* scrollBehavior: 'snap',
|
|
40
|
+
* slides: [
|
|
41
|
+
* { image: 'image1.jpg', title: 'Recent highlights', accent: '#3C4043' },
|
|
42
|
+
* { image: 'image2.jpg', title: 'La Familia', accent: '#7E5260' }
|
|
43
|
+
* ],
|
|
44
|
+
* showAllLink: true
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // Add the carousel to the DOM
|
|
48
|
+
* document.getElementById('container').appendChild(carousel.element);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export const createCarousel = (config: CarouselConfig = {}): CarouselComponent => {
|
|
52
|
+
// Ensure layout and scrollBehavior have defaults
|
|
53
|
+
config.layout = config.layout || 'multi-browse';
|
|
54
|
+
config.scrollBehavior = config.scrollBehavior || getDefaultScrollBehavior(config.layout);
|
|
55
|
+
|
|
56
|
+
const baseConfig = createBaseConfig(config);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Create a safer composition order to avoid circular dependencies
|
|
60
|
+
// First build the core functionality
|
|
61
|
+
const coreComponent = pipe(
|
|
62
|
+
createBase,
|
|
63
|
+
withEvents(),
|
|
64
|
+
withElement(getElementConfig(baseConfig))
|
|
65
|
+
)(baseConfig);
|
|
66
|
+
|
|
67
|
+
// Define the enhanced component early to avoid circular references
|
|
68
|
+
const enhancedComponent = { ...coreComponent };
|
|
69
|
+
|
|
70
|
+
// Apply layout-specific adjustments
|
|
71
|
+
applyLayoutConfig(enhancedComponent, config);
|
|
72
|
+
|
|
73
|
+
// Then add the features that depend on the core
|
|
74
|
+
const slidesComponent = withSlides(baseConfig)(enhancedComponent);
|
|
75
|
+
|
|
76
|
+
// Add drag navigation
|
|
77
|
+
const withDragComponent = withDrag(baseConfig)(slidesComponent);
|
|
78
|
+
const withLifecycleComponent = withLifecycle()(withDragComponent);
|
|
79
|
+
|
|
80
|
+
// Create a simplified API config
|
|
81
|
+
const apiConfig = {
|
|
82
|
+
slides: {
|
|
83
|
+
addSlide: withLifecycleComponent.slides.addSlide,
|
|
84
|
+
removeSlide: withLifecycleComponent.slides.removeSlide,
|
|
85
|
+
updateSlide: withLifecycleComponent.slides.updateSlide,
|
|
86
|
+
getCount: withLifecycleComponent.slides.getCount,
|
|
87
|
+
getElements: withLifecycleComponent.slides.getElements
|
|
88
|
+
},
|
|
89
|
+
lifecycle: {
|
|
90
|
+
destroy: withLifecycleComponent.lifecycle.destroy
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Add the API
|
|
95
|
+
const carousel = withAPI(apiConfig)(withLifecycleComponent);
|
|
96
|
+
|
|
97
|
+
// Add layout data attribute for CSS targeting
|
|
98
|
+
carousel.element.dataset.layout = config.layout;
|
|
99
|
+
carousel.element.dataset.scrollBehavior = config.scrollBehavior;
|
|
100
|
+
|
|
101
|
+
return carousel;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error('Carousel creation error:', error);
|
|
104
|
+
throw new Error(`Failed to create carousel: ${(error as Error).message}`);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get default scroll behavior based on layout type
|
|
110
|
+
*
|
|
111
|
+
* @param {CarouselLayout} layout - Carousel layout type
|
|
112
|
+
* @returns {CarouselScrollBehavior} Recommended scroll behavior
|
|
113
|
+
*/
|
|
114
|
+
function getDefaultScrollBehavior(layout: CarouselLayout): CarouselScrollBehavior {
|
|
115
|
+
switch (layout) {
|
|
116
|
+
case 'multi-browse':
|
|
117
|
+
case 'hero':
|
|
118
|
+
case 'full-screen':
|
|
119
|
+
return 'snap';
|
|
120
|
+
case 'uncontained':
|
|
121
|
+
return 'default';
|
|
122
|
+
default:
|
|
123
|
+
return 'default';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Apply layout-specific configurations to the component
|
|
129
|
+
*
|
|
130
|
+
* @param {any} component - The component to configure
|
|
131
|
+
* @param {CarouselConfig} config - Carousel configuration
|
|
132
|
+
*/
|
|
133
|
+
function applyLayoutConfig(component: any, config: CarouselConfig): void {
|
|
134
|
+
// Add layout-specific class
|
|
135
|
+
component.element.classList.add(`${component.getClass('carousel')}-layout--${config.layout}`);
|
|
136
|
+
|
|
137
|
+
// Apply additional layout-specific styling
|
|
138
|
+
switch (config.layout) {
|
|
139
|
+
case 'multi-browse':
|
|
140
|
+
// Configure for browsing many items with different sizes
|
|
141
|
+
component.element.dataset.enableParallax = 'true';
|
|
142
|
+
break;
|
|
143
|
+
|
|
144
|
+
case 'uncontained':
|
|
145
|
+
// Configure for same-sized items that flow past edge
|
|
146
|
+
component.element.style.overflow = 'visible';
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
case 'hero':
|
|
150
|
+
// Configure for spotlight content with preview of next item
|
|
151
|
+
component.element.dataset.largeItemFocus = 'true';
|
|
152
|
+
|
|
153
|
+
// Apply center alignment if specified
|
|
154
|
+
if (config.centered) {
|
|
155
|
+
component.element.dataset.centered = 'true';
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
|
|
159
|
+
case 'full-screen':
|
|
160
|
+
// Configure for immersive experience
|
|
161
|
+
component.element.style.width = '100%';
|
|
162
|
+
component.element.style.height = '100%';
|
|
163
|
+
component.element.style.maxWidth = '100vw';
|
|
164
|
+
component.element.style.maxHeight = '100vh';
|
|
165
|
+
component.element.dataset.verticalScroll = 'true';
|
|
166
|
+
|
|
167
|
+
// Force snap scrolling for full-screen layout
|
|
168
|
+
config.scrollBehavior = 'snap';
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Apply scroll behavior
|
|
173
|
+
if (config.scrollBehavior === 'snap') {
|
|
174
|
+
component.element.dataset.snapScroll = 'true';
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export default createCarousel;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// src/components/carousel/config.ts
|
|
2
|
+
import {
|
|
3
|
+
createComponentConfig,
|
|
4
|
+
createElementConfig,
|
|
5
|
+
BaseComponentConfig
|
|
6
|
+
} from '../../core/config/component-config';
|
|
7
|
+
import { CarouselConfig } from './types';
|
|
8
|
+
import { CAROUSEL_DEFAULTS, CAROUSEL_TRANSITIONS } from './constants';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Default configuration for the Carousel component
|
|
12
|
+
*/
|
|
13
|
+
export const defaultConfig: CarouselConfig = {
|
|
14
|
+
initialSlide: CAROUSEL_DEFAULTS.INITIAL_SLIDE,
|
|
15
|
+
loop: CAROUSEL_DEFAULTS.LOOP,
|
|
16
|
+
transition: CAROUSEL_TRANSITIONS.SLIDE as 'slide' | 'fade' | 'none',
|
|
17
|
+
transitionDuration: CAROUSEL_DEFAULTS.TRANSITION_DURATION,
|
|
18
|
+
borderRadius: CAROUSEL_DEFAULTS.BORDER_RADIUS,
|
|
19
|
+
gap: CAROUSEL_DEFAULTS.GAP,
|
|
20
|
+
prefix: 'carousel',
|
|
21
|
+
showAllLink: true // Show "Show all" button by default
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates the base configuration for Carousel component
|
|
26
|
+
* @param {CarouselConfig} config - User provided configuration
|
|
27
|
+
* @returns {CarouselConfig} Complete configuration with defaults applied
|
|
28
|
+
*/
|
|
29
|
+
export const createBaseConfig = (config: CarouselConfig = {}): CarouselConfig =>
|
|
30
|
+
createComponentConfig(defaultConfig, config, 'carousel') as CarouselConfig;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Generates element configuration for the Carousel component
|
|
34
|
+
* @param {CarouselConfig} config - Carousel configuration
|
|
35
|
+
* @returns {Object} Element configuration object for withElement
|
|
36
|
+
*/
|
|
37
|
+
export const getElementConfig = (config: CarouselConfig) => {
|
|
38
|
+
// Create the attributes object
|
|
39
|
+
const attrs: Record<string, any> = {
|
|
40
|
+
role: 'region',
|
|
41
|
+
'aria-roledescription': 'carousel',
|
|
42
|
+
'aria-live': 'polite'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Create data attributes for configuration
|
|
46
|
+
const dataAttrs = {
|
|
47
|
+
'data-transition': config.transition,
|
|
48
|
+
'data-loop': config.loop ? 'true' : 'false'
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return createElementConfig(config, {
|
|
52
|
+
tag: 'div',
|
|
53
|
+
attrs: { ...attrs, ...dataAttrs },
|
|
54
|
+
className: config.class,
|
|
55
|
+
forwardEvents: {
|
|
56
|
+
keydown: true,
|
|
57
|
+
focus: true,
|
|
58
|
+
blur: true
|
|
59
|
+
},
|
|
60
|
+
style: {
|
|
61
|
+
position: 'relative',
|
|
62
|
+
overflow: 'hidden',
|
|
63
|
+
borderRadius: `${config.borderRadius}px`,
|
|
64
|
+
width: '100%',
|
|
65
|
+
height: 'auto',
|
|
66
|
+
display: 'flex',
|
|
67
|
+
flexDirection: 'column'
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates API configuration for the Carousel component
|
|
74
|
+
* @param {Object} comp - Component with slides and lifecycle features
|
|
75
|
+
* @returns {Object} API configuration object
|
|
76
|
+
*/
|
|
77
|
+
export const getApiConfig = (comp) => ({
|
|
78
|
+
// Empty navigation API for compatibility
|
|
79
|
+
slides: {
|
|
80
|
+
addSlide: comp.slides.addSlide,
|
|
81
|
+
removeSlide: comp.slides.removeSlide,
|
|
82
|
+
updateSlide: comp.slides.updateSlide,
|
|
83
|
+
getCount: comp.slides.getCount,
|
|
84
|
+
getElements: comp.slides.getElements
|
|
85
|
+
},
|
|
86
|
+
lifecycle: {
|
|
87
|
+
destroy: comp.lifecycle.destroy
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export default defaultConfig;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// src/components/carousel/constants.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Carousel layout types as defined by Material Design 3
|
|
5
|
+
*/
|
|
6
|
+
export const CAROUSEL_LAYOUTS = {
|
|
7
|
+
/** Best for browsing many visual items at once (photos, event feeds) */
|
|
8
|
+
MULTI_BROWSE: 'multi-browse',
|
|
9
|
+
|
|
10
|
+
/** For highly customized or text-heavy carousels (traditional behavior) */
|
|
11
|
+
UNCONTAINED: 'uncontained',
|
|
12
|
+
|
|
13
|
+
/** For spotlighting very large visual items (featured content) */
|
|
14
|
+
HERO: 'hero',
|
|
15
|
+
|
|
16
|
+
/** For immersive vertical-scrolling experiences */
|
|
17
|
+
FULL_SCREEN: 'full-screen'
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Carousel scroll behaviors
|
|
22
|
+
*/
|
|
23
|
+
export const CAROUSEL_SCROLL_BEHAVIORS = {
|
|
24
|
+
/** Standard scrolling without snapping */
|
|
25
|
+
DEFAULT: 'default',
|
|
26
|
+
|
|
27
|
+
/** Items snap to carousel layout */
|
|
28
|
+
SNAP: 'snap'
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Carousel item sizes
|
|
33
|
+
*/
|
|
34
|
+
export const CAROUSEL_ITEM_SIZES = {
|
|
35
|
+
LARGE: 'large',
|
|
36
|
+
MEDIUM: 'medium',
|
|
37
|
+
SMALL: 'small'
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Transition effects for carousel slides
|
|
42
|
+
*/
|
|
43
|
+
export const CAROUSEL_TRANSITIONS = {
|
|
44
|
+
SLIDE: 'slide',
|
|
45
|
+
FADE: 'fade',
|
|
46
|
+
NONE: 'none'
|
|
47
|
+
} as const;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Event names for the carousel component
|
|
51
|
+
*/
|
|
52
|
+
export const CAROUSEL_EVENTS = {
|
|
53
|
+
SLIDE_CHANGE: 'slide-change',
|
|
54
|
+
SLIDE_CHANGED: 'slide-changed',
|
|
55
|
+
RESIZE: 'resize'
|
|
56
|
+
} as const;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Default values for carousel configuration
|
|
60
|
+
*/
|
|
61
|
+
export const CAROUSEL_DEFAULTS = {
|
|
62
|
+
INITIAL_SLIDE: 0,
|
|
63
|
+
LOOP: true,
|
|
64
|
+
TRANSITION: CAROUSEL_TRANSITIONS.SLIDE,
|
|
65
|
+
TRANSITION_DURATION: 300,
|
|
66
|
+
BORDER_RADIUS: 16,
|
|
67
|
+
GAP: 8,
|
|
68
|
+
LAYOUT: CAROUSEL_LAYOUTS.MULTI_BROWSE,
|
|
69
|
+
SCROLL_BEHAVIOR: CAROUSEL_SCROLL_BEHAVIORS.SNAP,
|
|
70
|
+
SMALL_ITEM_WIDTH: 48, // 40-56dp range as per MD3
|
|
71
|
+
|
|
72
|
+
// Item widths for different layouts in px
|
|
73
|
+
ITEM_WIDTHS: {
|
|
74
|
+
[CAROUSEL_LAYOUTS.MULTI_BROWSE]: {
|
|
75
|
+
LARGE: 240,
|
|
76
|
+
MEDIUM: 180,
|
|
77
|
+
SMALL: 48
|
|
78
|
+
},
|
|
79
|
+
[CAROUSEL_LAYOUTS.UNCONTAINED]: {
|
|
80
|
+
LARGE: 240,
|
|
81
|
+
MEDIUM: 240,
|
|
82
|
+
SMALL: 240 // All same size in uncontained
|
|
83
|
+
},
|
|
84
|
+
[CAROUSEL_LAYOUTS.HERO]: {
|
|
85
|
+
LARGE: 300,
|
|
86
|
+
MEDIUM: 240,
|
|
87
|
+
SMALL: 48
|
|
88
|
+
},
|
|
89
|
+
[CAROUSEL_LAYOUTS.FULL_SCREEN]: {
|
|
90
|
+
LARGE: '100%', // Full width
|
|
91
|
+
MEDIUM: '100%',
|
|
92
|
+
SMALL: '100%'
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} as const;
|