mtrl 0.2.6 → 0.2.7
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/index.ts +18 -0
- package/package.json +1 -1
- package/src/components/badge/_styles.scss +117 -109
- package/src/components/badge/api.ts +57 -59
- package/src/components/badge/badge.ts +16 -2
- package/src/components/badge/config.ts +65 -11
- package/src/components/badge/constants.ts +22 -12
- package/src/components/badge/features.ts +44 -40
- package/src/components/badge/types.ts +42 -30
- package/src/components/bottom-app-bar/_styles.scss +103 -0
- package/src/components/bottom-app-bar/bottom-app-bar.ts +196 -0
- package/src/components/bottom-app-bar/config.ts +73 -0
- package/src/components/bottom-app-bar/index.ts +11 -0
- package/src/components/bottom-app-bar/types.ts +108 -0
- package/src/components/button/_styles.scss +0 -10
- package/src/components/button/api.ts +5 -0
- package/src/components/button/config.ts +5 -0
- package/src/components/button/types.ts +6 -0
- package/src/components/card/card.ts +13 -25
- package/src/components/card/config.ts +67 -22
- package/src/components/card/features.ts +3 -0
- package/src/components/card/types.ts +28 -0
- package/src/components/checkbox/_styles.scss +0 -2
- package/src/components/datepicker/_styles.scss +358 -0
- package/src/components/datepicker/api.ts +272 -0
- package/src/components/datepicker/config.ts +144 -0
- package/src/components/datepicker/constants.ts +98 -0
- package/src/components/datepicker/datepicker.ts +346 -0
- package/src/components/datepicker/index.ts +9 -0
- package/src/components/datepicker/render.ts +452 -0
- package/src/components/datepicker/types.ts +268 -0
- package/src/components/datepicker/utils.ts +290 -0
- package/src/components/dialog/_styles.scss +174 -128
- package/src/components/dialog/api.ts +48 -13
- package/src/components/dialog/config.ts +9 -5
- package/src/components/dialog/dialog.ts +6 -3
- package/src/components/dialog/features.ts +290 -130
- package/src/components/dialog/types.ts +7 -4
- package/src/components/divider/_styles.scss +57 -0
- package/src/components/divider/config.ts +81 -0
- package/src/components/divider/divider.ts +37 -0
- package/src/components/divider/features.ts +207 -0
- package/src/components/divider/index.ts +5 -0
- package/src/components/divider/types.ts +55 -0
- package/src/components/extended-fab/_styles.scss +267 -0
- package/src/components/extended-fab/api.ts +141 -0
- package/src/components/extended-fab/config.ts +108 -0
- package/src/components/extended-fab/constants.ts +36 -0
- package/src/components/extended-fab/extended-fab.ts +125 -0
- package/src/components/extended-fab/index.ts +4 -0
- package/src/components/extended-fab/types.ts +287 -0
- package/src/components/fab/_styles.scss +225 -0
- package/src/components/fab/api.ts +97 -0
- package/src/components/fab/config.ts +94 -0
- package/src/components/fab/constants.ts +41 -0
- package/src/components/fab/fab.ts +67 -0
- package/src/components/fab/index.ts +4 -0
- package/src/components/fab/types.ts +234 -0
- package/src/components/navigation/_styles.scss +1 -0
- package/src/components/navigation/api.ts +78 -50
- package/src/components/navigation/features/items.ts +280 -0
- package/src/components/navigation/nav-item.ts +72 -23
- package/src/components/navigation/navigation.ts +54 -2
- package/src/components/navigation/types.ts +210 -188
- package/src/components/search/_styles.scss +306 -0
- package/src/components/search/api.ts +203 -0
- package/src/components/search/config.ts +87 -0
- package/src/components/search/constants.ts +21 -0
- package/src/components/search/features/index.ts +4 -0
- package/src/components/search/features/search.ts +718 -0
- package/src/components/search/features/states.ts +165 -0
- package/src/components/search/features/structure.ts +198 -0
- package/src/components/search/index.ts +10 -0
- package/src/components/search/search.ts +52 -0
- package/src/components/search/types.ts +163 -0
- package/src/components/segmented-button/_styles.scss +117 -0
- package/src/components/segmented-button/config.ts +67 -0
- package/src/components/segmented-button/constants.ts +42 -0
- package/src/components/segmented-button/index.ts +4 -0
- package/src/components/segmented-button/segment.ts +155 -0
- package/src/components/segmented-button/segmented-button.ts +250 -0
- package/src/components/segmented-button/types.ts +219 -0
- package/src/components/slider/_styles.scss +83 -24
- package/src/components/slider/accessibility.md +5 -5
- package/src/components/slider/api.ts +41 -120
- package/src/components/slider/config.ts +51 -47
- package/src/components/slider/features/handlers.ts +495 -0
- package/src/components/slider/features/index.ts +1 -2
- package/src/components/slider/features/slider.ts +66 -84
- package/src/components/slider/features/states.ts +195 -0
- package/src/components/slider/features/structure.ts +136 -206
- package/src/components/slider/features/ui.ts +145 -206
- package/src/components/slider/index.ts +2 -11
- package/src/components/slider/slider.ts +9 -12
- package/src/components/slider/types.ts +39 -24
- package/src/components/switch/_styles.scss +0 -2
- package/src/components/tabs/_styles.scss +94 -32
- package/src/components/tabs/features.ts +4 -2
- package/src/components/tabs/indicator.ts +73 -13
- package/src/components/tabs/types.ts +10 -2
- package/src/components/timepicker/README.md +277 -0
- package/src/components/timepicker/_styles.scss +451 -0
- package/src/components/timepicker/api.ts +632 -0
- package/src/components/timepicker/clockdial.ts +482 -0
- package/src/components/timepicker/config.ts +130 -0
- package/src/components/timepicker/constants.ts +138 -0
- package/src/components/timepicker/index.ts +8 -0
- package/src/components/timepicker/render.ts +613 -0
- package/src/components/timepicker/timepicker.ts +117 -0
- package/src/components/timepicker/types.ts +336 -0
- package/src/components/timepicker/utils.ts +241 -0
- package/src/components/top-app-bar/_styles.scss +225 -0
- package/src/components/top-app-bar/config.ts +83 -0
- package/src/components/top-app-bar/index.ts +11 -0
- package/src/components/top-app-bar/top-app-bar.ts +316 -0
- package/src/components/top-app-bar/types.ts +140 -0
- package/src/core/build/_ripple.scss +6 -6
- package/src/core/build/ripple.ts +72 -95
- package/src/core/compose/features/icon.ts +3 -1
- package/src/core/compose/features/ripple.ts +4 -1
- package/src/core/compose/features/textlabel.ts +26 -2
- package/src/core/dom/create.ts +5 -0
- package/src/index.ts +9 -0
- package/src/styles/abstract/_theme.scss +9 -1
- package/src/styles/themes/_autumn.scss +21 -0
- package/src/styles/themes/_base-theme.scss +61 -0
- package/src/styles/themes/_baseline.scss +58 -0
- package/src/styles/themes/_bluekhaki.scss +125 -0
- package/src/styles/themes/_brownbeige.scss +125 -0
- package/src/styles/themes/_browngreen.scss +125 -0
- package/src/styles/themes/_forest.scss +6 -0
- package/src/styles/themes/_greenbeige.scss +125 -0
- package/src/styles/themes/_material.scss +125 -0
- package/src/styles/themes/_ocean.scss +6 -0
- package/src/styles/themes/_sageivory.scss +125 -0
- package/src/styles/themes/_spring.scss +6 -0
- package/src/styles/themes/_summer.scss +5 -0
- package/src/styles/themes/_sunset.scss +5 -0
- package/src/styles/themes/_tealcaramel.scss +125 -0
- package/src/styles/themes/_winter.scss +6 -0
- package/src/components/navigation/features/items.js +0 -192
- package/src/components/slider/features/appearance.ts +0 -94
- package/src/components/slider/features/disabled.ts +0 -68
- package/src/components/slider/features/events.ts +0 -164
- package/src/components/slider/features/interactions.ts +0 -396
- package/src/components/slider/features/keyboard.ts +0 -233
- package/src/core/collection/adapters/mongodb.js +0 -232
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// src/components/top-app-bar/types.ts
|
|
2
|
+
/**
|
|
3
|
+
* @module components/top-app-bar
|
|
4
|
+
* @description Type definitions for Top App Bar component
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ElementComponent } from '../../core/compose';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Top App Bar types
|
|
11
|
+
* @category Components
|
|
12
|
+
*/
|
|
13
|
+
export type TopAppBarType = 'small' | 'medium' | 'large' | 'center';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Configuration options for Top App Bar component
|
|
17
|
+
* @category Components
|
|
18
|
+
*/
|
|
19
|
+
export interface TopAppBarConfig {
|
|
20
|
+
/**
|
|
21
|
+
* Element to use for the container
|
|
22
|
+
* @default 'header'
|
|
23
|
+
*/
|
|
24
|
+
tag?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Type of top app bar to display
|
|
28
|
+
* @default 'small'
|
|
29
|
+
*/
|
|
30
|
+
type?: TopAppBarType;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Title text to display in the app bar
|
|
34
|
+
*/
|
|
35
|
+
title?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Whether to enable scrolling behavior
|
|
39
|
+
* @default true
|
|
40
|
+
*/
|
|
41
|
+
scrollable?: boolean;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Whether to compress medium/large variants to small on scroll
|
|
45
|
+
* @default true
|
|
46
|
+
*/
|
|
47
|
+
compressible?: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Scroll threshold in pixels to trigger the scrolled state
|
|
51
|
+
* @default 4
|
|
52
|
+
*/
|
|
53
|
+
scrollThreshold?: number;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Additional CSS classes to apply
|
|
57
|
+
*/
|
|
58
|
+
class?: string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Optional callback when scrolling changes the bar appearance
|
|
62
|
+
*/
|
|
63
|
+
onScroll?: (scrolled: boolean) => void;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Component prefix for class names
|
|
67
|
+
* @default 'mtrl'
|
|
68
|
+
*/
|
|
69
|
+
prefix?: string;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Component name for class generation
|
|
73
|
+
*/
|
|
74
|
+
componentName?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Top App Bar component interface
|
|
79
|
+
* @category Components
|
|
80
|
+
*/
|
|
81
|
+
export interface TopAppBar extends ElementComponent {
|
|
82
|
+
/**
|
|
83
|
+
* Sets the title of the top app bar
|
|
84
|
+
* @param {string} title - Title text
|
|
85
|
+
* @returns {TopAppBar} TopAppBar instance for chaining
|
|
86
|
+
*/
|
|
87
|
+
setTitle: (title: string) => TopAppBar;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Gets the current title
|
|
91
|
+
* @returns {string} Current title text
|
|
92
|
+
*/
|
|
93
|
+
getTitle: () => string;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Adds a leading navigation icon or element
|
|
97
|
+
* @param {HTMLElement} element - Element to add to the leading section
|
|
98
|
+
* @returns {TopAppBar} TopAppBar instance for chaining
|
|
99
|
+
*/
|
|
100
|
+
addLeadingElement: (element: HTMLElement) => TopAppBar;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Adds a trailing action icon or element
|
|
104
|
+
* @param {HTMLElement} element - Element to add to the trailing section
|
|
105
|
+
* @returns {TopAppBar} TopAppBar instance for chaining
|
|
106
|
+
*/
|
|
107
|
+
addTrailingElement: (element: HTMLElement) => TopAppBar;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Changes the top app bar type
|
|
111
|
+
* @param {TopAppBarType} type - New app bar type
|
|
112
|
+
* @returns {TopAppBar} TopAppBar instance for chaining
|
|
113
|
+
*/
|
|
114
|
+
setType: (type: TopAppBarType) => TopAppBar;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Manually sets the scrolled state
|
|
118
|
+
* @param {boolean} scrolled - Whether to show the scrolled state
|
|
119
|
+
* @returns {TopAppBar} TopAppBar instance for chaining
|
|
120
|
+
*/
|
|
121
|
+
setScrollState: (scrolled: boolean) => TopAppBar;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Gets the headline element
|
|
125
|
+
* @returns {HTMLElement} Headline element
|
|
126
|
+
*/
|
|
127
|
+
getHeadlineElement: () => HTMLElement;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Gets the leading container element
|
|
131
|
+
* @returns {HTMLElement} Leading container element
|
|
132
|
+
*/
|
|
133
|
+
getLeadingContainer: () => HTMLElement;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Gets the trailing container element
|
|
137
|
+
* @returns {HTMLElement} Trailing container element
|
|
138
|
+
*/
|
|
139
|
+
getTrailingContainer: () => HTMLElement;
|
|
140
|
+
}
|
|
@@ -19,20 +19,20 @@ $component: '#{base.$prefix}-ripple';
|
|
|
19
19
|
pointer-events: none;
|
|
20
20
|
z-index: 0;
|
|
21
21
|
|
|
22
|
-
// Ripple element
|
|
23
22
|
&-wave {
|
|
24
23
|
position: absolute;
|
|
25
24
|
border-radius: 50%;
|
|
25
|
+
|
|
26
|
+
// Make the ripple more visible with these changes:
|
|
26
27
|
background-color: currentColor;
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
opacity: 0; // Start with 0 opacity
|
|
29
|
+
transform: scale(0); // Start slightly larger for better visibility
|
|
29
30
|
pointer-events: none;
|
|
30
31
|
will-change: transform, opacity;
|
|
31
32
|
|
|
32
33
|
// Animation
|
|
33
|
-
transition
|
|
34
|
-
|
|
35
|
-
transition-timing-function: v.motion('easing-standard');
|
|
34
|
+
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),
|
|
35
|
+
opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
36
36
|
|
|
37
37
|
// Active ripple
|
|
38
38
|
&.active {
|
package/src/core/build/ripple.ts
CHANGED
|
@@ -1,73 +1,13 @@
|
|
|
1
1
|
// src/core/build/ripple.ts
|
|
2
|
-
|
|
3
2
|
import { RIPPLE_CONFIG, RIPPLE_TIMING } from './constants';
|
|
3
|
+
import { PREFIX } from '../config';
|
|
4
|
+
|
|
5
|
+
// ... existing interfaces ...
|
|
4
6
|
|
|
5
|
-
/**
|
|
6
|
-
* Ripple animation configuration
|
|
7
|
-
*/
|
|
8
|
-
export interface RippleConfig {
|
|
9
|
-
/**
|
|
10
|
-
* Animation duration in milliseconds
|
|
11
|
-
*/
|
|
12
|
-
duration?: number;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Animation timing function
|
|
16
|
-
*/
|
|
17
|
-
timing?: string;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Opacity start and end values
|
|
21
|
-
*/
|
|
22
|
-
opacity?: [string, string];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* End coordinates for ripple animation
|
|
27
|
-
*/
|
|
28
|
-
interface EndCoordinates {
|
|
29
|
-
size: string;
|
|
30
|
-
top: string;
|
|
31
|
-
left: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Document event listener
|
|
36
|
-
*/
|
|
37
|
-
interface DocumentListener {
|
|
38
|
-
event: string;
|
|
39
|
-
handler: EventListener;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Ripple controller interface
|
|
44
|
-
*/
|
|
45
|
-
export interface RippleController {
|
|
46
|
-
/**
|
|
47
|
-
* Attaches ripple effect to an element
|
|
48
|
-
* @param element - Target element
|
|
49
|
-
*/
|
|
50
|
-
mount: (element: HTMLElement) => void;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Removes ripple effect from an element
|
|
54
|
-
* @param element - Target element
|
|
55
|
-
*/
|
|
56
|
-
unmount: (element: HTMLElement) => void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Creates a ripple effect instance
|
|
61
|
-
*
|
|
62
|
-
* @param config - Ripple configuration
|
|
63
|
-
* @returns Ripple controller instance
|
|
64
|
-
*/
|
|
65
7
|
export const createRipple = (config: RippleConfig = {}): RippleController => {
|
|
66
|
-
// Make sure we fully merge the config options
|
|
67
8
|
const options = {
|
|
68
9
|
...RIPPLE_CONFIG,
|
|
69
10
|
...config,
|
|
70
|
-
// Handle nested objects like opacity array
|
|
71
11
|
opacity: config.opacity || RIPPLE_CONFIG.opacity
|
|
72
12
|
};
|
|
73
13
|
|
|
@@ -84,18 +24,18 @@ export const createRipple = (config: RippleConfig = {}): RippleController => {
|
|
|
84
24
|
};
|
|
85
25
|
};
|
|
86
26
|
|
|
27
|
+
// Track active ripples for proper cleanup
|
|
28
|
+
const activeRipples = new WeakMap<HTMLElement, Set<HTMLElement>>();
|
|
29
|
+
|
|
87
30
|
const createRippleElement = (): HTMLDivElement => {
|
|
88
31
|
const ripple = document.createElement('div');
|
|
89
|
-
ripple.className =
|
|
90
|
-
//
|
|
91
|
-
ripple.style.transition = `all ${options.duration}ms ${options.timing}`;
|
|
32
|
+
ripple.className = `${PREFIX}-ripple-wave`;
|
|
33
|
+
// No inline transition style - let CSS handle it
|
|
92
34
|
return ripple;
|
|
93
35
|
};
|
|
94
36
|
|
|
95
|
-
// Store document event listeners for cleanup
|
|
96
37
|
let documentListeners: DocumentListener[] = [];
|
|
97
38
|
|
|
98
|
-
// Safe document event handling
|
|
99
39
|
const addDocumentListener = (event: string, handler: EventListener): void => {
|
|
100
40
|
if (typeof document.addEventListener === 'function') {
|
|
101
41
|
document.addEventListener(event, handler);
|
|
@@ -113,45 +53,56 @@ export const createRipple = (config: RippleConfig = {}): RippleController => {
|
|
|
113
53
|
};
|
|
114
54
|
|
|
115
55
|
const animate = (event: MouseEvent, container: HTMLElement): void => {
|
|
116
|
-
if (!container) return;
|
|
56
|
+
if (!container || !container.__rippleContainer) return;
|
|
117
57
|
|
|
58
|
+
const rippleContainer = container.__rippleContainer;
|
|
118
59
|
const bounds = container.getBoundingClientRect();
|
|
119
60
|
const ripple = createRippleElement();
|
|
120
61
|
|
|
121
|
-
//
|
|
62
|
+
// Calculate ripple size - should be larger than the container
|
|
63
|
+
// Use the maximum dimension of the container multiplied by 2
|
|
64
|
+
const size = Math.max(bounds.width, bounds.height) * 2;
|
|
65
|
+
|
|
66
|
+
// Calculate position to center the ripple on the click point
|
|
67
|
+
const x = event.clientX - bounds.left - (size / 2);
|
|
68
|
+
const y = event.clientY - bounds.top - (size / 2);
|
|
69
|
+
|
|
70
|
+
// Set explicit size and position
|
|
122
71
|
Object.assign(ripple.style, {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
72
|
+
width: `${size}px`,
|
|
73
|
+
height: `${size}px`,
|
|
74
|
+
left: `${x}px`,
|
|
75
|
+
top: `${y}px`
|
|
127
76
|
});
|
|
128
77
|
|
|
129
|
-
container
|
|
78
|
+
// Append to container
|
|
79
|
+
rippleContainer.appendChild(ripple);
|
|
130
80
|
|
|
131
81
|
// Force reflow
|
|
132
|
-
// eslint-disable-next-line no-unused-expressions
|
|
133
82
|
ripple.offsetHeight;
|
|
134
83
|
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
...end,
|
|
139
|
-
transform: 'scale(1)',
|
|
140
|
-
opacity: options.opacity[1]
|
|
84
|
+
// Add active class to trigger animation
|
|
85
|
+
requestAnimationFrame(() => {
|
|
86
|
+
ripple.classList.add('active');
|
|
141
87
|
});
|
|
142
88
|
|
|
143
89
|
const cleanup = () => {
|
|
144
|
-
|
|
90
|
+
// Remove document listeners
|
|
91
|
+
removeDocumentListener('mouseup', cleanup);
|
|
92
|
+
removeDocumentListener('mouseleave', cleanup);
|
|
145
93
|
|
|
146
|
-
//
|
|
94
|
+
// Remove active class and add fade-out class
|
|
95
|
+
ripple.classList.remove('active');
|
|
96
|
+
ripple.classList.add('fade-out');
|
|
97
|
+
|
|
98
|
+
// Remove after animation
|
|
147
99
|
setTimeout(() => {
|
|
148
100
|
if (ripple.parentNode) {
|
|
149
101
|
ripple.parentNode.removeChild(ripple);
|
|
150
102
|
}
|
|
103
|
+
// Remove from tracking
|
|
104
|
+
activeRipples.get(container)?.delete(ripple);
|
|
151
105
|
}, options.duration);
|
|
152
|
-
|
|
153
|
-
removeDocumentListener('mouseup', cleanup);
|
|
154
|
-
removeDocumentListener('mouseleave', cleanup);
|
|
155
106
|
};
|
|
156
107
|
|
|
157
108
|
addDocumentListener('mouseup', cleanup);
|
|
@@ -167,8 +118,21 @@ export const createRipple = (config: RippleConfig = {}): RippleController => {
|
|
|
167
118
|
if (currentPosition === 'static') {
|
|
168
119
|
element.style.position = 'relative';
|
|
169
120
|
}
|
|
170
|
-
|
|
121
|
+
|
|
122
|
+
// Create ripple container if it doesn't exist
|
|
123
|
+
let rippleContainer = element.querySelector(`.${PREFIX}-ripple`);
|
|
124
|
+
if (!rippleContainer) {
|
|
125
|
+
rippleContainer = document.createElement('div');
|
|
126
|
+
rippleContainer.className = `${PREFIX}-ripple`;
|
|
127
|
+
element.appendChild(rippleContainer);
|
|
128
|
+
}
|
|
171
129
|
|
|
130
|
+
// Store reference to container
|
|
131
|
+
element.__rippleContainer = rippleContainer as HTMLElement;
|
|
132
|
+
|
|
133
|
+
// Initialize ripple tracking
|
|
134
|
+
activeRipples.set(element, new Set());
|
|
135
|
+
|
|
172
136
|
// Store the mousedown handler to be able to remove it later
|
|
173
137
|
const mousedownHandler = (e: MouseEvent) => animate(e, element);
|
|
174
138
|
|
|
@@ -198,19 +162,32 @@ export const createRipple = (config: RippleConfig = {}): RippleController => {
|
|
|
198
162
|
element.__rippleHandlers = [];
|
|
199
163
|
}
|
|
200
164
|
|
|
201
|
-
// Remove all
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
165
|
+
// Remove all active ripples immediately
|
|
166
|
+
if (activeRipples.has(element)) {
|
|
167
|
+
const ripples = activeRipples.get(element);
|
|
168
|
+
if (ripples) {
|
|
169
|
+
ripples.forEach(ripple => {
|
|
170
|
+
if (ripple.parentNode) {
|
|
171
|
+
ripple.parentNode.removeChild(ripple);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
activeRipples.delete(element);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Remove ripple container
|
|
179
|
+
if (element.__rippleContainer && element.__rippleContainer.parentNode) {
|
|
180
|
+
element.__rippleContainer.parentNode.removeChild(element.__rippleContainer);
|
|
181
|
+
delete element.__rippleContainer;
|
|
182
|
+
}
|
|
207
183
|
}
|
|
208
184
|
};
|
|
209
185
|
};
|
|
210
186
|
|
|
211
|
-
// Extend the HTMLElement interface
|
|
187
|
+
// Extend the HTMLElement interface
|
|
212
188
|
declare global {
|
|
213
189
|
interface HTMLElement {
|
|
214
190
|
__rippleHandlers?: Array<(e: MouseEvent) => void>;
|
|
191
|
+
__rippleContainer?: HTMLElement;
|
|
215
192
|
}
|
|
216
193
|
}
|
|
@@ -58,7 +58,9 @@ export const withIcon = <T extends IconConfig>(config: T) =>
|
|
|
58
58
|
icon.setIcon(config.icon);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
if (component.componentName === 'button') {
|
|
62
|
+
updateCircularStyle(component, config);
|
|
63
|
+
}
|
|
62
64
|
|
|
63
65
|
return {
|
|
64
66
|
...component,
|
|
@@ -31,6 +31,9 @@ export const withRipple = <T extends RippleFeatureConfig>(config: T) =>
|
|
|
31
31
|
if (!config.ripple) return component as C & RippleComponent;
|
|
32
32
|
|
|
33
33
|
const rippleInstance = createRipple(config.rippleConfig);
|
|
34
|
+
|
|
35
|
+
// Immediately mount ripple to ensure it's available right away
|
|
36
|
+
rippleInstance.mount(component.element);
|
|
34
37
|
|
|
35
38
|
// If component has lifecycle methods, integrate ripple with them
|
|
36
39
|
if (component.lifecycle) {
|
|
@@ -39,7 +42,7 @@ export const withRipple = <T extends RippleFeatureConfig>(config: T) =>
|
|
|
39
42
|
|
|
40
43
|
component.lifecycle.mount = () => {
|
|
41
44
|
originalMount.call(component.lifecycle);
|
|
42
|
-
|
|
45
|
+
// We don't need to mount again here since we already did it above
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
component.lifecycle.destroy = () => {
|
|
@@ -11,6 +11,11 @@ export interface TextLabelConfig {
|
|
|
11
11
|
*/
|
|
12
12
|
label?: string;
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Label position ('start' or 'end')
|
|
16
|
+
*/
|
|
17
|
+
labelPosition?: 'start' | 'end';
|
|
18
|
+
|
|
14
19
|
/**
|
|
15
20
|
* CSS class prefix
|
|
16
21
|
*/
|
|
@@ -69,8 +74,27 @@ export const withTextLabel = <T extends TextLabelConfig>(config: T = {} as T) =>
|
|
|
69
74
|
labelElement.className = `${config.prefix}-${config.componentName}-label`;
|
|
70
75
|
labelElement.textContent = config.label;
|
|
71
76
|
|
|
72
|
-
//
|
|
73
|
-
|
|
77
|
+
// Position the label based on labelPosition (default to 'start')
|
|
78
|
+
const position = config.labelPosition || 'start';
|
|
79
|
+
|
|
80
|
+
if (position === 'start') {
|
|
81
|
+
// Insert label as the first child
|
|
82
|
+
if (component.element.firstChild) {
|
|
83
|
+
component.element.insertBefore(labelElement, component.element.firstChild);
|
|
84
|
+
} else {
|
|
85
|
+
component.element.appendChild(labelElement);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
// Insert label at the end (default behavior)
|
|
89
|
+
component.element.appendChild(labelElement);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log('componentName', component.componentName)
|
|
93
|
+
console.log('position', position)
|
|
94
|
+
|
|
95
|
+
if (position && component.componentName !== 'slider') {
|
|
96
|
+
component.element.classList.add(`${config.prefix}-${config.componentName}--label-${position}`);
|
|
97
|
+
}
|
|
74
98
|
|
|
75
99
|
const label: LabelManager = {
|
|
76
100
|
setText(text: string) {
|
package/src/core/dom/create.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,21 +2,30 @@
|
|
|
2
2
|
export { createElement } from './core/dom/create'
|
|
3
3
|
export { default as createLayout } from './core/layout'
|
|
4
4
|
export { default as createButton } from './components/button'
|
|
5
|
+
export { default as createFab } from './components/fab'
|
|
6
|
+
export { default as createExtendedFab } from './components/extended-fab'
|
|
7
|
+
export { default as createSegmentedButton } from './components/segmented-button'
|
|
8
|
+
export { default as createBottomAppBar } from './components/bottom-app-bar'
|
|
5
9
|
export { default as createBadge } from './components/badge'
|
|
6
10
|
export { default as createCard } from './components/card'
|
|
7
11
|
export { default as createCarousel } from './components/carousel'
|
|
8
12
|
export { default as createCheckbox } from './components/checkbox'
|
|
9
13
|
export { default as createChip } from './components/chip'
|
|
14
|
+
export { default as createDatePicker } from './components/datepicker'
|
|
10
15
|
export { default as createDialog } from './components/dialog'
|
|
16
|
+
export { default as createDivider } from './components/divider'
|
|
11
17
|
export { default as createMenu } from './components/menu'
|
|
12
18
|
export { default as createNavigation } from './components/navigation'
|
|
13
19
|
export { default as createProgress } from './components/progress'
|
|
14
20
|
export { default as createRadios } from './components/radios'
|
|
21
|
+
export { default as createSearch } from './components/search'
|
|
15
22
|
export { default as createSheet } from './components/sheet'
|
|
16
23
|
export { default as createSlider } from './components/slider'
|
|
17
24
|
export { default as createSnackbar } from './components/snackbar'
|
|
18
25
|
export { default as createSwitch } from './components/switch'
|
|
19
26
|
export { default as createTabs } from './components/tabs'
|
|
20
27
|
export { default as createTextfield } from './components/textfield'
|
|
28
|
+
export { default as createTimePicker } from './components/timepicker'
|
|
29
|
+
export { default as createTopAppBar } from './components/top-app-bar'
|
|
21
30
|
export { default as createTooltip } from './components/tooltip'
|
|
22
31
|
export { default as createList } from './components/list'
|
|
@@ -48,8 +48,16 @@ $mtrl-sys-shape: (
|
|
|
48
48
|
@return var(--#{$prefix}-sys-color-#{$key}-rgb);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Creates a color with alpha transparency using RGB values
|
|
53
|
+
* This version uses string.unquote to preserve the rgba function correctly
|
|
54
|
+
* @param {String} $key - Color token name
|
|
55
|
+
* @param {Number} $opacity - Opacity value (0-1)
|
|
56
|
+
* @return {String} rgba CSS function with variable
|
|
57
|
+
*/
|
|
51
58
|
@function alpha($key, $opacity) {
|
|
52
|
-
|
|
59
|
+
// #{'...'} prevents SASS from interpreting rgba as a SASS function
|
|
60
|
+
@return #{'rgba(var(--#{$prefix}-sys-color-#{$key}-rgb), #{$opacity})'};
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
@function state($key) {
|
|
@@ -40,6 +40,24 @@
|
|
|
40
40
|
--#{$prefix}-sys-color-outline: #85736C;
|
|
41
41
|
--#{$prefix}-sys-color-outline-variant: #D7C1BA;
|
|
42
42
|
|
|
43
|
+
// Success colors
|
|
44
|
+
--#{$prefix}-sys-color-success: #85CFA9;
|
|
45
|
+
--#{$prefix}-sys-color-success-rgb: 133, 207, 169;
|
|
46
|
+
--#{$prefix}-sys-color-on-success: #00392D;
|
|
47
|
+
--#{$prefix}-sys-color-on-success-rgb: 0, 57, 45;
|
|
48
|
+
|
|
49
|
+
// Warning colors
|
|
50
|
+
--#{$prefix}-sys-color-warning: #FFB95C;
|
|
51
|
+
--#{$prefix}-sys-color-warning-rgb: 255, 185, 92;
|
|
52
|
+
--#{$prefix}-sys-color-on-warning: #3F2200;
|
|
53
|
+
--#{$prefix}-sys-color-on-warning-rgb: 63, 34, 0;
|
|
54
|
+
|
|
55
|
+
// Info colors
|
|
56
|
+
--#{$prefix}-sys-color-info: #99CBFF;
|
|
57
|
+
--#{$prefix}-sys-color-info-rgb: 153, 203, 255;
|
|
58
|
+
--#{$prefix}-sys-color-on-info: #003060;
|
|
59
|
+
--#{$prefix}-sys-color-on-info-rgb: 0, 48, 96;
|
|
60
|
+
|
|
43
61
|
&[data-theme-mode="dark"] {
|
|
44
62
|
// Key colors
|
|
45
63
|
--#{$prefix}-sys-color-primary: #DDB995; // Softer brown
|
|
@@ -62,6 +80,9 @@
|
|
|
62
80
|
--#{$prefix}-sys-color-quaternary-container: #644900;
|
|
63
81
|
--#{$prefix}-sys-color-on-quaternary-container: #FFDF8A;
|
|
64
82
|
|
|
83
|
+
// Include status colors for dark theme
|
|
84
|
+
@include status-colors-dark();
|
|
85
|
+
|
|
65
86
|
// Neutral colors
|
|
66
87
|
--#{$prefix}-sys-color-surface: #201A17;
|
|
67
88
|
--#{$prefix}-sys-color-surface-dim: #17120F;
|
|
@@ -8,6 +8,67 @@
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
// Common status colors that should be available in all themes
|
|
12
|
+
@mixin status-colors-light() {
|
|
13
|
+
// Error colors
|
|
14
|
+
--#{$prefix}-sys-color-error: #B3261E;
|
|
15
|
+
--#{$prefix}-sys-color-error-rgb: 179, 38, 30;
|
|
16
|
+
--#{$prefix}-sys-color-on-error: #FFFFFF;
|
|
17
|
+
--#{$prefix}-sys-color-on-error-rgb: 255, 255, 255;
|
|
18
|
+
--#{$prefix}-sys-color-error-container: #F9DEDC;
|
|
19
|
+
--#{$prefix}-sys-color-error-container-rgb: 249, 222, 220;
|
|
20
|
+
--#{$prefix}-sys-color-on-error-container: #410E0B;
|
|
21
|
+
--#{$prefix}-sys-color-on-error-container-rgb: 65, 14, 11;
|
|
22
|
+
|
|
23
|
+
// Success colors
|
|
24
|
+
--#{$prefix}-sys-color-success: #007B5A;
|
|
25
|
+
--#{$prefix}-sys-color-success-rgb: 0, 123, 90;
|
|
26
|
+
--#{$prefix}-sys-color-on-success: #FFFFFF;
|
|
27
|
+
--#{$prefix}-sys-color-on-success-rgb: 255, 255, 255;
|
|
28
|
+
|
|
29
|
+
// Warning colors
|
|
30
|
+
--#{$prefix}-sys-color-warning: #DD6D06;
|
|
31
|
+
--#{$prefix}-sys-color-warning-rgb: 221, 109, 6;
|
|
32
|
+
--#{$prefix}-sys-color-on-warning: #FFFFFF;
|
|
33
|
+
--#{$prefix}-sys-color-on-warning-rgb: 255, 255, 255;
|
|
34
|
+
|
|
35
|
+
// Info colors
|
|
36
|
+
--#{$prefix}-sys-color-info: #0061A4;
|
|
37
|
+
--#{$prefix}-sys-color-info-rgb: 0, 97, 164;
|
|
38
|
+
--#{$prefix}-sys-color-on-info: #FFFFFF;
|
|
39
|
+
--#{$prefix}-sys-color-on-info-rgb: 255, 255, 255;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@mixin status-colors-dark() {
|
|
43
|
+
// Error colors
|
|
44
|
+
--#{$prefix}-sys-color-error: #F2B8B5;
|
|
45
|
+
--#{$prefix}-sys-color-error-rgb: 242, 184, 181;
|
|
46
|
+
--#{$prefix}-sys-color-on-error: #601410;
|
|
47
|
+
--#{$prefix}-sys-color-on-error-rgb: 96, 20, 16;
|
|
48
|
+
--#{$prefix}-sys-color-error-container: #8C1D18;
|
|
49
|
+
--#{$prefix}-sys-color-error-container-rgb: 140, 29, 24;
|
|
50
|
+
--#{$prefix}-sys-color-on-error-container: #F9DEDC;
|
|
51
|
+
--#{$prefix}-sys-color-on-error-container-rgb: 249, 222, 220;
|
|
52
|
+
|
|
53
|
+
// Success colors
|
|
54
|
+
--#{$prefix}-sys-color-success: #85CFA9;
|
|
55
|
+
--#{$prefix}-sys-color-success-rgb: 133, 207, 169;
|
|
56
|
+
--#{$prefix}-sys-color-on-success: #00392D;
|
|
57
|
+
--#{$prefix}-sys-color-on-success-rgb: 0, 57, 45;
|
|
58
|
+
|
|
59
|
+
// Warning colors
|
|
60
|
+
--#{$prefix}-sys-color-warning: #FFB95C;
|
|
61
|
+
--#{$prefix}-sys-color-warning-rgb: 255, 185, 92;
|
|
62
|
+
--#{$prefix}-sys-color-on-warning: #3F2200;
|
|
63
|
+
--#{$prefix}-sys-color-on-warning-rgb: 63, 34, 0;
|
|
64
|
+
|
|
65
|
+
// Info colors
|
|
66
|
+
--#{$prefix}-sys-color-info: #99CBFF;
|
|
67
|
+
--#{$prefix}-sys-color-info-rgb: 153, 203, 255;
|
|
68
|
+
--#{$prefix}-sys-color-on-info: #003060;
|
|
69
|
+
--#{$prefix}-sys-color-on-info-rgb: 0, 48, 96;
|
|
70
|
+
}
|
|
71
|
+
|
|
11
72
|
%theme-base {
|
|
12
73
|
// Common properties for all themes
|
|
13
74
|
--#{$prefix}-sys-typescale-label-large-font-family-name: "Roboto";
|