mtrl 0.2.6 → 0.2.8
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/demo/build.ts +349 -0
- package/demo/index.html +110 -0
- package/demo/main.js +448 -0
- package/demo/styles.css +239 -0
- package/index.ts +18 -0
- package/package.json +14 -3
- package/server.ts +86 -0
- package/src/components/badge/api.ts +70 -63
- package/src/components/badge/badge.ts +16 -2
- package/src/components/badge/config.ts +66 -13
- package/src/components/badge/features.ts +51 -42
- package/src/components/badge/index.ts +27 -2
- package/src/components/badge/types.ts +62 -30
- package/src/components/bottom-app-bar/bottom-app-bar.ts +154 -0
- package/src/components/bottom-app-bar/config.ts +29 -0
- package/src/components/bottom-app-bar/index.ts +17 -0
- package/src/components/bottom-app-bar/types.ts +114 -0
- package/src/components/button/api.ts +5 -0
- package/src/components/button/button.ts +0 -1
- package/src/components/button/config.ts +6 -2
- package/src/components/button/index.ts +10 -2
- package/src/components/button/types.ts +20 -2
- package/src/components/card/card.ts +13 -25
- package/src/components/card/config.ts +83 -30
- package/src/components/card/content.ts +8 -10
- package/src/components/card/features.ts +4 -3
- package/src/components/card/index.ts +29 -2
- package/src/components/card/types.ts +33 -22
- package/src/components/checkbox/config.ts +3 -4
- package/src/components/checkbox/index.ts +1 -2
- package/src/components/checkbox/types.ts +12 -3
- package/src/components/chip/api.ts +170 -221
- package/src/components/chip/chip.ts +34 -302
- package/src/components/chip/config.ts +1 -2
- package/src/components/chip/index.ts +10 -2
- package/src/components/chip/types.ts +224 -35
- package/src/components/datepicker/api.ts +265 -0
- package/src/components/datepicker/config.ts +141 -0
- package/src/components/datepicker/datepicker.ts +341 -0
- package/src/components/datepicker/index.ts +12 -0
- package/src/components/datepicker/render.ts +450 -0
- package/src/components/datepicker/types.ts +397 -0
- package/src/components/datepicker/utils.ts +289 -0
- package/src/components/dialog/api.ts +55 -21
- package/src/components/dialog/config.ts +12 -9
- package/src/components/dialog/dialog.ts +6 -3
- package/src/components/dialog/features.ts +345 -151
- package/src/components/dialog/index.ts +38 -8
- package/src/components/dialog/types.ts +40 -14
- 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 +9 -0
- package/src/components/divider/types.ts +55 -0
- package/src/components/extended-fab/api.ts +141 -0
- package/src/components/extended-fab/config.ts +112 -0
- package/src/components/extended-fab/extended-fab.ts +125 -0
- package/src/components/extended-fab/index.ts +9 -0
- package/src/components/extended-fab/types.ts +304 -0
- package/src/components/fab/api.ts +97 -0
- package/src/components/fab/config.ts +93 -0
- package/src/components/fab/fab.ts +67 -0
- package/src/components/fab/index.ts +9 -0
- package/src/components/fab/types.ts +251 -0
- package/src/components/list/config.ts +4 -5
- package/src/components/list/features.ts +6 -7
- package/src/components/list/index.ts +7 -9
- package/src/components/list/list-item.ts +12 -13
- package/src/components/list/types.ts +50 -5
- package/src/components/list/utils.ts +30 -3
- package/src/components/menu/features/items-manager.ts +9 -9
- package/src/components/menu/features/positioning.ts +7 -7
- package/src/components/menu/features/visibility.ts +7 -7
- package/src/components/menu/index.ts +7 -9
- package/src/components/menu/menu-item.ts +6 -6
- package/src/components/menu/menu.ts +22 -0
- package/src/components/menu/types.ts +29 -10
- package/src/components/menu/utils.ts +67 -0
- package/src/components/navigation/api.ts +78 -50
- package/src/components/navigation/config.ts +22 -10
- package/src/components/navigation/features/items.ts +284 -0
- package/src/components/navigation/index.ts +0 -6
- package/src/components/navigation/nav-item.ts +70 -33
- package/src/components/navigation/navigation.ts +53 -3
- package/src/components/navigation/types.ts +117 -70
- package/src/components/progress/api.ts +2 -3
- package/src/components/progress/config.ts +2 -3
- package/src/components/progress/index.ts +0 -1
- package/src/components/progress/progress.ts +1 -2
- package/src/components/progress/types.ts +186 -33
- package/src/components/radios/config.ts +1 -1
- package/src/components/radios/index.ts +0 -1
- package/src/components/radios/types.ts +0 -7
- package/src/components/search/api.ts +203 -0
- package/src/components/search/config.ts +86 -0
- package/src/components/search/features/index.ts +4 -0
- package/src/components/search/features/search.ts +717 -0
- package/src/components/search/features/states.ts +169 -0
- package/src/components/search/features/structure.ts +197 -0
- package/src/components/search/index.ts +7 -0
- package/src/components/search/search.ts +52 -0
- package/src/components/search/types.ts +175 -0
- package/src/components/segmented-button/config.ts +80 -0
- package/src/components/segmented-button/index.ts +4 -0
- package/src/components/segmented-button/segment.ts +154 -0
- package/src/components/segmented-button/segmented-button.ts +249 -0
- package/src/components/segmented-button/types.ts +254 -0
- 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 +67 -26
- package/src/components/snackbar/config.ts +2 -3
- package/src/components/snackbar/constants.ts +0 -32
- package/src/components/snackbar/index.ts +0 -1
- package/src/components/snackbar/position.ts +9 -1
- package/src/components/snackbar/types.ts +122 -46
- package/src/components/switch/config.ts +2 -3
- package/src/components/switch/index.ts +0 -1
- package/src/components/switch/types.ts +3 -2
- package/src/components/tabs/config.ts +3 -4
- package/src/components/tabs/features.ts +4 -2
- package/src/components/tabs/index.ts +0 -15
- package/src/components/tabs/indicator.ts +73 -13
- package/src/components/tabs/tab-api.ts +12 -4
- package/src/components/tabs/tab.ts +18 -6
- package/src/components/tabs/types.ts +23 -5
- package/src/components/textfield/config.ts +2 -3
- package/src/components/textfield/index.ts +0 -1
- package/src/components/textfield/types.ts +17 -3
- package/src/components/timepicker/README.md +277 -0
- package/src/components/timepicker/api.ts +632 -0
- package/src/components/timepicker/clockdial.ts +482 -0
- package/src/components/timepicker/config.ts +228 -0
- package/src/components/timepicker/index.ts +3 -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/tooltip/api.ts +1 -1
- package/src/components/tooltip/config.ts +27 -6
- package/src/components/tooltip/index.ts +0 -1
- package/src/components/tooltip/types.ts +13 -3
- 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 +23 -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/components/_badge.scss +182 -0
- package/src/styles/components/_bottom-app-bar.scss +103 -0
- package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -10
- package/src/{components/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -2
- package/src/styles/components/_datepicker.scss +358 -0
- package/src/styles/components/_dialog.scss +259 -0
- package/src/styles/components/_divider.scss +57 -0
- package/src/styles/components/_extended-fab.scss +267 -0
- package/src/styles/components/_fab.scss +225 -0
- package/src/{components/navigation/_styles.scss → styles/components/_navigation.scss} +1 -0
- package/src/styles/components/_search.scss +306 -0
- package/src/styles/components/_segmented-button.scss +117 -0
- package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +83 -24
- package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -2
- package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +95 -33
- package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +70 -67
- package/src/styles/components/_timepicker.scss +451 -0
- package/src/styles/components/_top-app-bar.scss +225 -0
- package/src/styles/main.scss +98 -49
- 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/badge/_styles.scss +0 -174
- package/src/components/badge/constants.ts +0 -30
- package/src/components/button/constants.ts +0 -11
- package/src/components/card/constants.ts +0 -84
- package/src/components/dialog/_styles.scss +0 -213
- package/src/components/dialog/constants.ts +0 -32
- package/src/components/menu/constants.ts +0 -154
- package/src/components/navigation/constants.ts +0 -200
- package/src/components/navigation/features/items.js +0 -192
- package/src/components/progress/constants.ts +0 -29
- 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/components/switch/constants.ts +0 -80
- package/src/components/tabs/constants.ts +0 -89
- package/src/core/collection/adapters/mongodb.js +0 -232
- /package/src/{components/card/_styles.scss → styles/components/_card.scss} +0 -0
- /package/src/{components/carousel/_styles.scss → styles/components/_carousel.scss} +0 -0
- /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
- /package/src/{components/list/_styles.scss → styles/components/_list.scss} +0 -0
- /package/src/{components/menu/_styles.scss → styles/components/_menu.scss} +0 -0
- /package/src/{components/progress/_styles.scss → styles/components/_progress.scss} +0 -0
- /package/src/{components/radios/_styles.scss → styles/components/_radios.scss} +0 -0
- /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
- /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
- /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
- /package/src/styles/utilities/{_color.scss → _colors.scss} +0 -0
|
@@ -1,29 +1,61 @@
|
|
|
1
|
-
// src/components/dialog/features.ts
|
|
1
|
+
// src/components/dialog/features.ts (partial updated code)
|
|
2
|
+
|
|
2
3
|
import { getOverlayConfig } from './config';
|
|
3
|
-
import {
|
|
4
|
-
import { DialogConfig, DialogButton, DialogEvent } from './types';
|
|
4
|
+
import { DialogConfig, DialogButton } from './types';
|
|
5
5
|
import createButton from '../button';
|
|
6
|
-
import {
|
|
6
|
+
import { createDivider } from '../divider'; // Import the divider component
|
|
7
|
+
import { addClass, removeClass, hasClass } from '../../core/dom/classes';
|
|
8
|
+
|
|
9
|
+
// Common constants for internal use
|
|
10
|
+
const SIZE_MEDIUM = 'medium';
|
|
11
|
+
const ANIMATION_SCALE = 'scale';
|
|
12
|
+
const FOOTER_ALIGNMENT_RIGHT = 'right';
|
|
13
|
+
const EVENT_BEFORE_OPEN = 'beforeopen';
|
|
14
|
+
const EVENT_OPEN = 'open';
|
|
15
|
+
const EVENT_AFTER_OPEN = 'afteropen';
|
|
16
|
+
const EVENT_BEFORE_CLOSE = 'beforeclose';
|
|
17
|
+
const EVENT_CLOSE = 'close';
|
|
18
|
+
const EVENT_AFTER_CLOSE = 'afterclose';
|
|
19
|
+
|
|
20
|
+
// Common button variants for internal use
|
|
21
|
+
const BUTTON_VARIANT_TEXT = 'text';
|
|
22
|
+
const BUTTON_VARIANT_FILLED = 'filled';
|
|
23
|
+
|
|
24
|
+
// Arrays for class management
|
|
25
|
+
const ALL_SIZES = ['small', 'medium', 'large', 'fullwidth', 'fullscreen'];
|
|
26
|
+
const ALL_ANIMATIONS = ['scale', 'slide-up', 'slide-down', 'fade'];
|
|
27
|
+
const ALL_FOOTER_ALIGNMENTS = ['right', 'left', 'center', 'space-between'];
|
|
28
|
+
|
|
29
|
+
const DIALOG_EVENTS = {
|
|
30
|
+
OPEN: 'open',
|
|
31
|
+
CLOSE: 'close',
|
|
32
|
+
BEFORE_OPEN: 'beforeopen',
|
|
33
|
+
BEFORE_CLOSE: 'beforeclose',
|
|
34
|
+
AFTER_OPEN: 'afteropen',
|
|
35
|
+
AFTER_CLOSE: 'afterclose'
|
|
36
|
+
};
|
|
7
37
|
|
|
8
38
|
/**
|
|
9
|
-
* Creates the dialog DOM structure
|
|
39
|
+
* Creates the dialog DOM structure with proper divider handling
|
|
10
40
|
* @param config Dialog configuration
|
|
11
41
|
* @returns Component enhancer with DOM structure
|
|
12
42
|
*/
|
|
13
43
|
export const withStructure = (config: DialogConfig) => component => {
|
|
14
44
|
// Create the overlay element
|
|
15
45
|
const overlayConfig = getOverlayConfig(config);
|
|
16
|
-
const overlay = document.createElement(overlayConfig.tag);
|
|
46
|
+
const overlay = document.createElement(overlayConfig.tag || 'div');
|
|
17
47
|
|
|
18
48
|
// Add overlay classes
|
|
19
49
|
overlay.classList.add(component.getClass('dialog-overlay'));
|
|
20
50
|
|
|
21
|
-
// Set overlay attributes
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
51
|
+
// Set overlay attributes safely
|
|
52
|
+
if (overlayConfig.attrs && typeof overlayConfig.attrs === 'object') {
|
|
53
|
+
Object.entries(overlayConfig.attrs).forEach(([key, value]) => {
|
|
54
|
+
if (key && typeof key === 'string' && value !== undefined) {
|
|
55
|
+
overlay.setAttribute(key, String(value));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
27
59
|
|
|
28
60
|
// Set custom z-index if provided
|
|
29
61
|
if (config.zIndex) {
|
|
@@ -63,9 +95,18 @@ export const withStructure = (config: DialogConfig) => component => {
|
|
|
63
95
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
64
96
|
</svg>
|
|
65
97
|
`;
|
|
66
|
-
|
|
67
|
-
|
|
98
|
+
|
|
99
|
+
// Close button click handler with event-based communication
|
|
100
|
+
closeButton.addEventListener('click', (e) => {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
e.stopPropagation();
|
|
103
|
+
|
|
104
|
+
// Use the dialog:close custom event which will be listened for in withVisibility
|
|
105
|
+
if (component && component.emit) {
|
|
106
|
+
component.emit('dialog:close', { source: 'closeButton' });
|
|
107
|
+
}
|
|
68
108
|
});
|
|
109
|
+
|
|
69
110
|
header.appendChild(closeButton);
|
|
70
111
|
}
|
|
71
112
|
|
|
@@ -88,9 +129,9 @@ export const withStructure = (config: DialogConfig) => component => {
|
|
|
88
129
|
footer.classList.add(component.getClass('dialog-footer'));
|
|
89
130
|
|
|
90
131
|
// Apply footer alignment
|
|
91
|
-
const alignment = config.footerAlignment ||
|
|
92
|
-
if (alignment !==
|
|
93
|
-
footer
|
|
132
|
+
const alignment = config.footerAlignment || 'right';
|
|
133
|
+
if (alignment !== 'right') {
|
|
134
|
+
addClass(footer, `${component.getClass('dialog-footer')}--${alignment}`);
|
|
94
135
|
}
|
|
95
136
|
|
|
96
137
|
// Add buttons if provided
|
|
@@ -101,36 +142,70 @@ export const withStructure = (config: DialogConfig) => component => {
|
|
|
101
142
|
return footer;
|
|
102
143
|
};
|
|
103
144
|
|
|
145
|
+
const createDividerElement = () => {
|
|
146
|
+
const divider = createDivider({
|
|
147
|
+
variant: 'full-width',
|
|
148
|
+
class: component.getClass('dialog-divider')
|
|
149
|
+
});
|
|
150
|
+
return divider;
|
|
151
|
+
};
|
|
152
|
+
|
|
104
153
|
// Create the dialog structure
|
|
105
154
|
const header = createHeader();
|
|
106
155
|
const content = createContent();
|
|
107
156
|
const footer = Array.isArray(config.buttons) && config.buttons.length > 0 ? createFooter() : null;
|
|
108
157
|
|
|
109
|
-
// Add
|
|
110
|
-
component.element.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
158
|
+
// Add dialog classes to the main component element
|
|
159
|
+
addClass(component.element, component.getClass('dialog'));
|
|
160
|
+
|
|
161
|
+
// Apply size class
|
|
162
|
+
const size = config.size || 'medium';
|
|
163
|
+
if (size !== 'medium') {
|
|
164
|
+
addClass(component.element, `${component.getClass('dialog')}--${size}`);
|
|
114
165
|
}
|
|
115
166
|
|
|
116
|
-
//
|
|
117
|
-
|
|
167
|
+
// Apply animation class
|
|
168
|
+
const animation = config.animation || 'scale';
|
|
169
|
+
if (animation !== 'scale') {
|
|
170
|
+
addClass(component.element, `${component.getClass('dialog')}--${animation}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Add header to dialog
|
|
174
|
+
component.element.appendChild(header);
|
|
118
175
|
|
|
119
|
-
//
|
|
120
|
-
|
|
176
|
+
// Create divider elements if configured
|
|
177
|
+
let headerDivider = null;
|
|
178
|
+
let footerDivider = null;
|
|
121
179
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
180
|
+
if (config.divider) {
|
|
181
|
+
// Add header divider (between header and content)
|
|
182
|
+
headerDivider = createDividerElement();
|
|
183
|
+
headerDivider.element.classList.add(component.getClass('dialog-header-divider'));
|
|
184
|
+
component.element.appendChild(headerDivider.element);
|
|
185
|
+
|
|
186
|
+
// If footer exists, add footer divider (between content and footer)
|
|
187
|
+
if (footer) {
|
|
188
|
+
footerDivider = createDividerElement();
|
|
189
|
+
footerDivider.element.classList.add(component.getClass('dialog-footer-divider'));
|
|
190
|
+
}
|
|
126
191
|
}
|
|
127
192
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
193
|
+
// Add content to dialog
|
|
194
|
+
component.element.appendChild(content);
|
|
195
|
+
|
|
196
|
+
// Add footer divider before footer if it exists
|
|
197
|
+
if (footerDivider) {
|
|
198
|
+
component.element.appendChild(footerDivider.element);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Add footer to dialog if exists
|
|
202
|
+
if (footer) {
|
|
203
|
+
component.element.appendChild(footer);
|
|
132
204
|
}
|
|
133
205
|
|
|
206
|
+
// Add the dialog element to the overlay
|
|
207
|
+
overlay.appendChild(component.element);
|
|
208
|
+
|
|
134
209
|
// Add overlay to container or document.body
|
|
135
210
|
const container = config.container || document.body;
|
|
136
211
|
container.appendChild(overlay);
|
|
@@ -143,11 +218,88 @@ export const withStructure = (config: DialogConfig) => component => {
|
|
|
143
218
|
header,
|
|
144
219
|
content,
|
|
145
220
|
footer,
|
|
221
|
+
headerDivider,
|
|
222
|
+
footerDivider,
|
|
146
223
|
container
|
|
147
224
|
}
|
|
148
225
|
};
|
|
149
226
|
};
|
|
150
227
|
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Add methods to manage dividers
|
|
231
|
+
* @returns Component enhancer with divider management features
|
|
232
|
+
*/
|
|
233
|
+
export const withDivider = () => component => {
|
|
234
|
+
return {
|
|
235
|
+
...component,
|
|
236
|
+
divider: {
|
|
237
|
+
/**
|
|
238
|
+
* Shows or hides the dividers
|
|
239
|
+
* @param show Whether to show the dividers
|
|
240
|
+
* @returns Component instance for chaining
|
|
241
|
+
*/
|
|
242
|
+
toggleDivider(show) {
|
|
243
|
+
// Handle header divider
|
|
244
|
+
if (show && !component.structure.headerDivider) {
|
|
245
|
+
// Create and add header divider
|
|
246
|
+
const headerDivider = createDivider({
|
|
247
|
+
variant: 'full-width',
|
|
248
|
+
class: `${component.getClass('dialog-divider')} ${component.getClass('dialog-header-divider')}`
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Insert after header, before content
|
|
252
|
+
component.element.insertBefore(
|
|
253
|
+
headerDivider.element,
|
|
254
|
+
component.structure.content
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
component.structure.headerDivider = headerDivider;
|
|
258
|
+
|
|
259
|
+
// If footer exists, add footer divider
|
|
260
|
+
if (component.structure.footer && !component.structure.footerDivider) {
|
|
261
|
+
const footerDivider = createDivider({
|
|
262
|
+
variant: 'full-width',
|
|
263
|
+
class: `${component.getClass('dialog-divider')} ${component.getClass('dialog-footer-divider')}`
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Insert before footer
|
|
267
|
+
component.element.insertBefore(
|
|
268
|
+
footerDivider.element,
|
|
269
|
+
component.structure.footer
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
component.structure.footerDivider = footerDivider;
|
|
273
|
+
}
|
|
274
|
+
} else if (!show) {
|
|
275
|
+
// Remove header divider if it exists
|
|
276
|
+
if (component.structure.headerDivider) {
|
|
277
|
+
component.structure.headerDivider.element.remove();
|
|
278
|
+
component.structure.headerDivider = null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Remove footer divider if it exists
|
|
282
|
+
if (component.structure.footerDivider) {
|
|
283
|
+
component.structure.footerDivider.element.remove();
|
|
284
|
+
component.structure.footerDivider = null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return component;
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Checks if the dialog has dividers
|
|
293
|
+
* @returns Whether the dialog has dividers
|
|
294
|
+
*/
|
|
295
|
+
hasDivider() {
|
|
296
|
+
return component.structure.headerDivider !== null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
|
|
151
303
|
/**
|
|
152
304
|
* Adds button to dialog footer
|
|
153
305
|
* @param footer Footer element
|
|
@@ -157,7 +309,7 @@ export const withStructure = (config: DialogConfig) => component => {
|
|
|
157
309
|
const addButton = (footer: HTMLElement, buttonConfig: DialogButton, component: any) => {
|
|
158
310
|
const {
|
|
159
311
|
text,
|
|
160
|
-
variant = BUTTON_VARIANTS.TEXT
|
|
312
|
+
variant = 'text', // Using string literal directly instead of BUTTON_VARIANTS.TEXT
|
|
161
313
|
onClick,
|
|
162
314
|
closeDialog = true,
|
|
163
315
|
autofocus = false,
|
|
@@ -170,26 +322,32 @@ const addButton = (footer: HTMLElement, buttonConfig: DialogButton, component: a
|
|
|
170
322
|
...attrs
|
|
171
323
|
});
|
|
172
324
|
|
|
173
|
-
//
|
|
325
|
+
// Button click handler with event-based communication
|
|
174
326
|
button.on('click', event => {
|
|
327
|
+
console.log('button click');
|
|
175
328
|
let shouldClose = closeDialog;
|
|
176
329
|
|
|
177
330
|
// Call onClick handler if provided
|
|
178
331
|
if (typeof onClick === 'function') {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
332
|
+
try {
|
|
333
|
+
const result = onClick(event, component);
|
|
334
|
+
if (result === false) {
|
|
335
|
+
shouldClose = false;
|
|
336
|
+
}
|
|
337
|
+
} catch (err) {
|
|
338
|
+
console.error('Error in onClick handler:', err);
|
|
183
339
|
}
|
|
184
340
|
}
|
|
185
341
|
|
|
186
|
-
// Close dialog if needed
|
|
342
|
+
// Close dialog if needed - using event-based communication
|
|
187
343
|
if (shouldClose) {
|
|
188
|
-
component
|
|
344
|
+
if (component && component.emit) {
|
|
345
|
+
component.emit('dialog:close', { source: 'button', text });
|
|
346
|
+
}
|
|
189
347
|
}
|
|
190
348
|
});
|
|
191
349
|
|
|
192
|
-
// Set autofocus
|
|
350
|
+
// Set autofocus if needed
|
|
193
351
|
if (autofocus) {
|
|
194
352
|
button.element.setAttribute('autofocus', 'true');
|
|
195
353
|
}
|
|
@@ -300,125 +458,154 @@ export const withVisibility = () => component => {
|
|
|
300
458
|
function handleOverlayClick(e: MouseEvent) {
|
|
301
459
|
// Only close if the click was directly on the overlay
|
|
302
460
|
if (e.target === component.overlay) {
|
|
303
|
-
|
|
304
|
-
dialog: component,
|
|
305
|
-
originalEvent: e
|
|
306
|
-
});
|
|
461
|
+
visibility.close();
|
|
307
462
|
}
|
|
308
463
|
}
|
|
309
464
|
|
|
310
465
|
function handleEscKey(e: KeyboardEvent) {
|
|
311
|
-
if (e.key === 'Escape' &&
|
|
312
|
-
|
|
313
|
-
dialog: component,
|
|
314
|
-
originalEvent: e
|
|
315
|
-
});
|
|
466
|
+
if (e.key === 'Escape' && visibility.isOpen()) {
|
|
467
|
+
visibility.close();
|
|
316
468
|
}
|
|
317
469
|
}
|
|
318
470
|
|
|
319
471
|
// Setup initial state
|
|
320
472
|
if (isOpen) {
|
|
321
|
-
component.overlay
|
|
322
|
-
component.element
|
|
473
|
+
addClass(component.overlay, `${component.getClass('dialog-overlay')}--visible`);
|
|
474
|
+
addClass(component.element, `${component.getClass('dialog')}--visible`);
|
|
323
475
|
|
|
324
476
|
// Setup focus trap and events
|
|
325
477
|
trapFocus();
|
|
326
478
|
setupEvents();
|
|
327
479
|
}
|
|
328
480
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
open
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
481
|
+
// Create visibility object with clean methods
|
|
482
|
+
const visibility = {
|
|
483
|
+
open() {
|
|
484
|
+
// Don't do anything if already open
|
|
485
|
+
if (this.isOpen()) return;
|
|
486
|
+
|
|
487
|
+
// Store the currently focused element
|
|
488
|
+
previouslyFocusedElement = document.activeElement as HTMLElement;
|
|
489
|
+
|
|
490
|
+
// Trigger before open event
|
|
491
|
+
const beforeOpenEvent = {
|
|
492
|
+
dialog: component,
|
|
493
|
+
defaultPrevented: false,
|
|
494
|
+
preventDefault: () => { beforeOpenEvent.defaultPrevented = true; }
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
if (typeof component.emit === 'function') {
|
|
498
|
+
component.emit(DIALOG_EVENTS.BEFORE_OPEN, beforeOpenEvent);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// If event was prevented, don't open
|
|
502
|
+
if (beforeOpenEvent.defaultPrevented) return;
|
|
503
|
+
|
|
504
|
+
// Add to DOM if needed
|
|
505
|
+
if (component.overlay && !component.overlay.parentNode) {
|
|
506
|
+
const container = component.structure.container || document.body;
|
|
507
|
+
container.appendChild(component.overlay);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Show the overlay
|
|
511
|
+
addClass(component.overlay, `${component.getClass('dialog-overlay')}--visible`);
|
|
512
|
+
|
|
513
|
+
// Show the dialog
|
|
514
|
+
setTimeout(() => {
|
|
515
|
+
addClass(component.element, `${component.getClass('dialog')}--visible`);
|
|
345
516
|
|
|
346
|
-
//
|
|
347
|
-
|
|
517
|
+
// Setup focus trap and events
|
|
518
|
+
trapFocus();
|
|
519
|
+
setupEvents();
|
|
348
520
|
|
|
349
|
-
//
|
|
350
|
-
|
|
351
|
-
component.
|
|
352
|
-
|
|
353
|
-
// Setup focus trap and events
|
|
354
|
-
trapFocus();
|
|
355
|
-
setupEvents();
|
|
521
|
+
// Trigger open event
|
|
522
|
+
if (typeof component.emit === 'function') {
|
|
523
|
+
component.emit(DIALOG_EVENTS.OPEN, { dialog: component });
|
|
356
524
|
|
|
357
|
-
// Trigger after open event after animation completes
|
|
358
525
|
setTimeout(() => {
|
|
359
|
-
component.
|
|
526
|
+
component.emit(DIALOG_EVENTS.AFTER_OPEN, { dialog: component });
|
|
360
527
|
}, animationDuration);
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
528
|
+
}
|
|
529
|
+
}, 10);
|
|
530
|
+
},
|
|
531
|
+
|
|
532
|
+
close() {
|
|
533
|
+
console.log('Dialog close method called');
|
|
366
534
|
|
|
367
|
-
close
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
component.events.trigger(DIALOG_EVENTS.BEFORE_CLOSE, beforeCloseEvent);
|
|
374
|
-
|
|
375
|
-
// If event was prevented, don't close
|
|
376
|
-
if (beforeCloseEvent.defaultPrevented) return;
|
|
377
|
-
|
|
378
|
-
// Hide the dialog
|
|
379
|
-
component.element.classList.remove(`${component.getClass('dialog')}--visible`);
|
|
380
|
-
|
|
381
|
-
// Release focus trap and cleanup events
|
|
382
|
-
releaseFocus();
|
|
383
|
-
cleanupEvents();
|
|
384
|
-
|
|
385
|
-
// Trigger close event
|
|
386
|
-
component.events.trigger(DIALOG_EVENTS.CLOSE, { dialog: component });
|
|
387
|
-
|
|
388
|
-
// Hide the overlay after animation completes
|
|
389
|
-
setTimeout(() => {
|
|
390
|
-
component.overlay.classList.remove(`${component.getClass('dialog-overlay')}--visible`);
|
|
391
|
-
|
|
392
|
-
// Trigger after close event
|
|
393
|
-
component.events.trigger(DIALOG_EVENTS.AFTER_CLOSE, { dialog: component });
|
|
394
|
-
}, animationDuration);
|
|
395
|
-
},
|
|
535
|
+
// Trigger before close event
|
|
536
|
+
const beforeCloseEvent = {
|
|
537
|
+
dialog: component,
|
|
538
|
+
defaultPrevented: false,
|
|
539
|
+
preventDefault: () => { beforeCloseEvent.defaultPrevented = true; }
|
|
540
|
+
};
|
|
396
541
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
},
|
|
542
|
+
if (typeof component.emit === 'function') {
|
|
543
|
+
component.emit(DIALOG_EVENTS.BEFORE_CLOSE, beforeCloseEvent);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// If event was prevented, don't close
|
|
547
|
+
if (beforeCloseEvent.defaultPrevented) {
|
|
548
|
+
console.log('Dialog close prevented by event handler');
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Get class names
|
|
553
|
+
const dialogVisibleClass = `${component.getClass('dialog')}--visible`;
|
|
554
|
+
const overlayVisibleClass = `${component.getClass('dialog-overlay')}--visible`;
|
|
411
555
|
|
|
412
|
-
|
|
413
|
-
|
|
556
|
+
// Remove dialog visible class
|
|
557
|
+
removeClass(component.element, dialogVisibleClass);
|
|
558
|
+
|
|
559
|
+
// Remove overlay visible class
|
|
560
|
+
removeClass(component.overlay, overlayVisibleClass);
|
|
561
|
+
|
|
562
|
+
// Release focus and cleanup events
|
|
563
|
+
releaseFocus();
|
|
564
|
+
cleanupEvents();
|
|
565
|
+
|
|
566
|
+
// Trigger close events
|
|
567
|
+
if (typeof component.emit === 'function') {
|
|
568
|
+
component.emit(DIALOG_EVENTS.CLOSE, { dialog: component });
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Remove from DOM after animation completes
|
|
572
|
+
setTimeout(() => {
|
|
573
|
+
if (component.overlay && component.overlay.parentNode) {
|
|
574
|
+
component.overlay.parentNode.removeChild(component.overlay);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (typeof component.emit === 'function') {
|
|
578
|
+
component.emit(DIALOG_EVENTS.AFTER_CLOSE, { dialog: component });
|
|
579
|
+
}
|
|
580
|
+
}, animationDuration);
|
|
581
|
+
},
|
|
582
|
+
|
|
583
|
+
toggle(open?: boolean) {
|
|
584
|
+
if (open === undefined) {
|
|
585
|
+
this.isOpen() ? this.close() : this.open();
|
|
586
|
+
} else if (open) {
|
|
587
|
+
this.open();
|
|
588
|
+
} else {
|
|
589
|
+
this.close();
|
|
414
590
|
}
|
|
415
591
|
},
|
|
416
592
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
releaseFocus
|
|
593
|
+
isOpen() {
|
|
594
|
+
return component.element.classList.contains(`${component.getClass('dialog')}--visible`);
|
|
420
595
|
}
|
|
421
596
|
};
|
|
597
|
+
|
|
598
|
+
// Set up event listener for the dialog:close event
|
|
599
|
+
if (component && component.on) {
|
|
600
|
+
component.on('dialog:close', () => {
|
|
601
|
+
visibility.close();
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
return {
|
|
606
|
+
...component,
|
|
607
|
+
visibility
|
|
608
|
+
};
|
|
422
609
|
};
|
|
423
610
|
|
|
424
611
|
/**
|
|
@@ -558,9 +745,9 @@ export const withButtons = () => component => {
|
|
|
558
745
|
footer.classList.add(component.getClass('dialog-footer'));
|
|
559
746
|
|
|
560
747
|
// Apply footer alignment
|
|
561
|
-
const alignment = component.config.footerAlignment ||
|
|
562
|
-
if (alignment !==
|
|
563
|
-
footer
|
|
748
|
+
const alignment = component.config.footerAlignment || 'right';
|
|
749
|
+
if (alignment !== 'right') {
|
|
750
|
+
addClass(footer, `${component.getClass('dialog-footer')}--${alignment}`);
|
|
564
751
|
}
|
|
565
752
|
|
|
566
753
|
component.element.appendChild(footer);
|
|
@@ -614,19 +801,22 @@ export const withButtons = () => component => {
|
|
|
614
801
|
* Sets footer alignment
|
|
615
802
|
* @param alignment Footer alignment
|
|
616
803
|
*/
|
|
617
|
-
setFooterAlignment(alignment:
|
|
804
|
+
setFooterAlignment(alignment: string) {
|
|
618
805
|
if (!component.structure.footer) return;
|
|
619
806
|
|
|
807
|
+
// Define all possible alignments
|
|
808
|
+
const ALL_ALIGNMENTS = ['right', 'left', 'center', 'space-between'];
|
|
809
|
+
|
|
620
810
|
// Remove existing alignment classes
|
|
621
|
-
|
|
622
|
-
if (align !==
|
|
623
|
-
component.structure.footer
|
|
811
|
+
ALL_ALIGNMENTS.forEach(align => {
|
|
812
|
+
if (align !== 'right') {
|
|
813
|
+
removeClass(component.structure.footer, `${component.getClass('dialog-footer')}--${align}`);
|
|
624
814
|
}
|
|
625
815
|
});
|
|
626
816
|
|
|
627
817
|
// Add new alignment class if not right (default)
|
|
628
|
-
if (alignment !==
|
|
629
|
-
component.structure.footer
|
|
818
|
+
if (alignment !== 'right') {
|
|
819
|
+
addClass(component.structure.footer, `${component.getClass('dialog-footer')}--${alignment}`);
|
|
630
820
|
}
|
|
631
821
|
}
|
|
632
822
|
}
|
|
@@ -645,15 +835,18 @@ export const withSize = () => component => {
|
|
|
645
835
|
* Sets dialog size
|
|
646
836
|
* @param size Size variant
|
|
647
837
|
*/
|
|
648
|
-
setSize(size:
|
|
838
|
+
setSize(size: string) {
|
|
839
|
+
// Define all possible sizes
|
|
840
|
+
const ALL_SIZES = ['small', 'medium', 'large', 'fullwidth', 'fullscreen'];
|
|
841
|
+
|
|
649
842
|
// Remove existing size classes
|
|
650
|
-
|
|
651
|
-
component.element
|
|
843
|
+
ALL_SIZES.forEach(sizeValue => {
|
|
844
|
+
removeClass(component.element, `${component.getClass('dialog')}--${sizeValue}`);
|
|
652
845
|
});
|
|
653
846
|
|
|
654
847
|
// Add new size class if not medium (default)
|
|
655
|
-
if (size !==
|
|
656
|
-
component.element
|
|
848
|
+
if (size !== 'medium') {
|
|
849
|
+
addClass(component.element, `${component.getClass('dialog')}--${size}`);
|
|
657
850
|
}
|
|
658
851
|
}
|
|
659
852
|
}
|
|
@@ -674,9 +867,10 @@ export const withConfirm = () => component => {
|
|
|
674
867
|
message,
|
|
675
868
|
confirmText = 'Yes',
|
|
676
869
|
cancelText = 'No',
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
870
|
+
// Use string literals directly
|
|
871
|
+
confirmVariant = 'filled',
|
|
872
|
+
cancelVariant = 'text',
|
|
873
|
+
size = 'small'
|
|
680
874
|
} = options;
|
|
681
875
|
|
|
682
876
|
// Set dialog properties
|