@rettangoli/ui 0.1.31 → 1.0.0-rc1
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 +20 -85
- package/dist/rettangoli-iife-layout.min.js +113 -173
- package/dist/rettangoli-iife-ui.min.js +123 -183
- package/package.json +5 -4
- package/src/common/dimensions.js +72 -0
- package/src/common/link.js +111 -0
- package/src/common/responsive.js +8 -0
- package/src/common.js +43 -8
- package/src/components/accordionItem/accordionItem.handlers.js +1 -1
- package/src/components/accordionItem/accordionItem.schema.yaml +14 -0
- package/src/components/accordionItem/accordionItem.store.js +8 -8
- package/src/components/accordionItem/accordionItem.view.yaml +5 -35
- package/src/components/breadcrumb/breadcrumb.handlers.js +24 -3
- package/src/components/breadcrumb/breadcrumb.schema.yaml +51 -0
- package/src/components/breadcrumb/breadcrumb.store.js +66 -10
- package/src/components/breadcrumb/breadcrumb.view.yaml +18 -58
- package/src/components/dropdownMenu/dropdownMenu.handlers.js +17 -3
- package/src/components/dropdownMenu/dropdownMenu.schema.yaml +64 -0
- package/src/components/dropdownMenu/dropdownMenu.store.js +48 -6
- package/src/components/dropdownMenu/dropdownMenu.view.yaml +24 -46
- package/src/components/form/form.handlers.js +25 -108
- package/src/components/form/form.schema.yaml +283 -0
- package/src/components/form/form.store.js +19 -14
- package/src/components/form/form.view.yaml +28 -319
- package/src/components/globalUi/globalUi.handlers.js +2 -2
- package/src/components/globalUi/globalUi.schema.yaml +8 -0
- package/src/components/globalUi/globalUi.store.js +8 -8
- package/src/components/globalUi/globalUi.view.yaml +9 -46
- package/src/components/navbar/navbar.handlers.js +1 -1
- package/src/components/navbar/navbar.schema.yaml +25 -0
- package/src/components/navbar/navbar.store.js +28 -14
- package/src/components/navbar/navbar.view.yaml +21 -65
- package/src/components/pageOutline/pageOutline.handlers.js +17 -11
- package/src/components/pageOutline/pageOutline.schema.yaml +16 -0
- package/src/components/pageOutline/pageOutline.store.js +6 -7
- package/src/components/pageOutline/pageOutline.view.yaml +1 -29
- package/src/components/popoverInput/popoverInput.handlers.js +31 -31
- package/src/components/popoverInput/popoverInput.schema.yaml +18 -0
- package/src/components/popoverInput/popoverInput.store.js +9 -9
- package/src/components/popoverInput/popoverInput.view.yaml +5 -22
- package/src/components/select/select.handlers.js +31 -35
- package/src/components/select/select.schema.yaml +36 -0
- package/src/components/select/select.store.js +34 -35
- package/src/components/select/select.view.yaml +13 -56
- package/src/components/sidebar/sidebar.handlers.js +5 -5
- package/src/components/sidebar/sidebar.schema.yaml +57 -0
- package/src/components/sidebar/sidebar.store.js +45 -23
- package/src/components/sidebar/sidebar.view.yaml +79 -174
- package/src/components/sliderInput/sliderInput.handlers.js +28 -8
- package/src/components/sliderInput/sliderInput.schema.yaml +27 -0
- package/src/components/sliderInput/sliderInput.store.js +9 -9
- package/src/components/sliderInput/sliderInput.view.yaml +8 -33
- package/src/components/table/table.handlers.js +3 -3
- package/src/components/table/table.schema.yaml +27 -0
- package/src/components/table/table.store.js +8 -8
- package/src/components/table/table.view.yaml +16 -62
- package/src/components/tabs/tabs.schema.yaml +26 -0
- package/src/components/tabs/tabs.store.js +12 -9
- package/src/components/tabs/tabs.view.yaml +4 -60
- package/src/components/tooltip/tooltip.schema.yaml +18 -0
- package/src/components/tooltip/tooltip.store.js +7 -7
- package/src/components/tooltip/tooltip.view.yaml +4 -22
- package/src/components/waveform/waveform.handlers.js +6 -6
- package/src/components/waveform/waveform.schema.yaml +25 -0
- package/src/components/waveform/waveform.store.js +6 -6
- package/src/components/waveform/waveform.view.yaml +6 -34
- package/src/deps/createGlobalUI.js +2 -2
- package/src/primitives/button.js +200 -114
- package/src/primitives/colorPicker.js +56 -50
- package/src/primitives/dialog.js +2 -1
- package/src/primitives/image.js +73 -103
- package/src/primitives/input-number.js +139 -93
- package/src/primitives/input.js +87 -64
- package/src/primitives/popover.js +36 -28
- package/src/primitives/slider.js +6 -4
- package/src/primitives/svg.js +9 -10
- package/src/primitives/text.js +26 -47
- package/src/primitives/textarea.js +25 -9
- package/src/primitives/view.js +49 -90
- package/src/setup.js +1 -7
- package/src/styles/buttonMarginStyles.js +1 -13
- package/src/styles/cursorStyles.js +1 -5
- package/src/styles/flexDirectionStyles.js +4 -4
- package/src/styles/marginStylesForTarget.js +13 -0
- package/src/styles/textColorStyles.js +14 -6
- package/src/styles/textStyles.js +4 -4
- package/src/styles/viewStyles.js +6 -6
- package/src/styles/viewStylesForTarget.js +58 -0
- package/src/styles/flexChildStyles.js +0 -43
package/src/primitives/button.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import { css, dimensionWithUnit } from "../common.js";
|
|
2
|
-
import flexChildStyles from "../styles/flexChildStyles.js";
|
|
1
|
+
import { css, dimensionWithUnit, applyLinkAttributes } from "../common.js";
|
|
3
2
|
import buttonMarginStyles from "../styles/buttonMarginStyles.js";
|
|
4
|
-
|
|
3
|
+
|
|
4
|
+
const responsiveSizeBreakpoints = [
|
|
5
|
+
{ prefix: "sm", maxWidth: 640 },
|
|
6
|
+
{ prefix: "md", maxWidth: 768 },
|
|
7
|
+
{ prefix: "lg", maxWidth: 1024 },
|
|
8
|
+
{ prefix: "xl", maxWidth: 1280 },
|
|
9
|
+
];
|
|
5
10
|
|
|
6
11
|
// Internal implementation without uhtml
|
|
7
12
|
class RettangoliButtonElement extends HTMLElement {
|
|
@@ -12,13 +17,13 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
12
17
|
RettangoliButtonElement.styleSheet = new CSSStyleSheet();
|
|
13
18
|
RettangoliButtonElement.styleSheet.replaceSync(css`
|
|
14
19
|
:host {
|
|
15
|
-
display:
|
|
20
|
+
display: inline-flex;
|
|
16
21
|
}
|
|
17
22
|
slot {
|
|
18
23
|
display: contents;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
.surface {
|
|
22
27
|
display: flex;
|
|
23
28
|
flex-direction: row;
|
|
24
29
|
align-items: center;
|
|
@@ -40,9 +45,19 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
40
45
|
|
|
41
46
|
background-color: var(--primary);
|
|
42
47
|
color: var(--primary-foreground);
|
|
48
|
+
text-decoration: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
a.surface,
|
|
52
|
+
a.surface:link,
|
|
53
|
+
a.surface:visited,
|
|
54
|
+
a.surface:hover,
|
|
55
|
+
a.surface:active {
|
|
56
|
+
color: inherit;
|
|
57
|
+
text-decoration: none;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
.surface:hover {
|
|
46
61
|
cursor: pointer;
|
|
47
62
|
background-color: color-mix(
|
|
48
63
|
in srgb,
|
|
@@ -51,11 +66,11 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
51
66
|
);
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
|
|
69
|
+
:host([disabled]) .surface {
|
|
55
70
|
cursor: not-allowed;
|
|
56
71
|
}
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
.surface:active {
|
|
59
74
|
cursor: pointer;
|
|
60
75
|
background-color: color-mix(
|
|
61
76
|
in srgb,
|
|
@@ -64,7 +79,7 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
64
79
|
);
|
|
65
80
|
}
|
|
66
81
|
|
|
67
|
-
:host([v="pr"])
|
|
82
|
+
:host([v="pr"]) .surface:hover {
|
|
68
83
|
background-color: color-mix(
|
|
69
84
|
in srgb,
|
|
70
85
|
var(--primary) 85%,
|
|
@@ -72,7 +87,7 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
72
87
|
);
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
:host([v="pr"])
|
|
90
|
+
:host([v="pr"]) .surface:active {
|
|
76
91
|
background-color: color-mix(
|
|
77
92
|
in srgb,
|
|
78
93
|
var(--primary) 80%,
|
|
@@ -80,7 +95,7 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
80
95
|
);
|
|
81
96
|
}
|
|
82
97
|
|
|
83
|
-
:host([v="se"])
|
|
98
|
+
:host([v="se"]) .surface:hover {
|
|
84
99
|
background-color: color-mix(
|
|
85
100
|
in srgb,
|
|
86
101
|
var(--secondary) 85%,
|
|
@@ -88,7 +103,7 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
88
103
|
);
|
|
89
104
|
}
|
|
90
105
|
|
|
91
|
-
:host([v="se"])
|
|
106
|
+
:host([v="se"]) .surface:active {
|
|
92
107
|
background-color: color-mix(
|
|
93
108
|
in srgb,
|
|
94
109
|
var(--secondary) 80%,
|
|
@@ -96,7 +111,7 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
96
111
|
);
|
|
97
112
|
}
|
|
98
113
|
|
|
99
|
-
:host([v="de"])
|
|
114
|
+
:host([v="de"]) .surface:hover {
|
|
100
115
|
background-color: color-mix(
|
|
101
116
|
in srgb,
|
|
102
117
|
var(--destructive) 85%,
|
|
@@ -104,7 +119,7 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
104
119
|
);
|
|
105
120
|
}
|
|
106
121
|
|
|
107
|
-
:host([v="de"])
|
|
122
|
+
:host([v="de"]) .surface:active {
|
|
108
123
|
background-color: color-mix(
|
|
109
124
|
in srgb,
|
|
110
125
|
var(--destructive) 80%,
|
|
@@ -112,48 +127,45 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
112
127
|
);
|
|
113
128
|
}
|
|
114
129
|
|
|
115
|
-
:host([v="ol"])
|
|
130
|
+
:host([v="ol"]) .surface:hover {
|
|
116
131
|
background-color: var(--accent);
|
|
117
132
|
}
|
|
118
133
|
|
|
119
|
-
:host([v="gh"])
|
|
134
|
+
:host([v="gh"]) .surface:hover {
|
|
120
135
|
background-color: var(--accent);
|
|
121
136
|
}
|
|
122
137
|
|
|
123
|
-
:host([v="lk"])
|
|
138
|
+
:host([v="lk"]) .surface:hover {
|
|
124
139
|
text-decoration: underline;
|
|
125
140
|
}
|
|
126
141
|
|
|
127
142
|
/* Square button styles */
|
|
128
|
-
:host([sq])
|
|
143
|
+
:host([sq]) .surface {
|
|
129
144
|
width: 32px;
|
|
130
145
|
height: 32px;
|
|
131
146
|
padding: 0;
|
|
132
147
|
gap: 0;
|
|
133
148
|
}
|
|
134
149
|
|
|
135
|
-
:host([sq][s="sm"])
|
|
150
|
+
:host([sq][s="sm"]) .surface {
|
|
136
151
|
width: 24px;
|
|
137
152
|
height: 24px;
|
|
138
153
|
padding: 0;
|
|
139
154
|
gap: 0;
|
|
140
155
|
}
|
|
141
156
|
|
|
142
|
-
:host([sq][s="lg"])
|
|
157
|
+
:host([sq][s="lg"]) .surface {
|
|
143
158
|
width: 40px;
|
|
144
159
|
height: 40px;
|
|
145
160
|
padding: 0;
|
|
146
161
|
gap: 0;
|
|
147
162
|
}
|
|
148
163
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
a {
|
|
152
|
-
display: contents;
|
|
164
|
+
.surface rtgl-svg {
|
|
165
|
+
color: inherit;
|
|
153
166
|
}
|
|
154
167
|
|
|
155
168
|
${buttonMarginStyles}
|
|
156
|
-
${flexChildStyles}
|
|
157
169
|
`);
|
|
158
170
|
}
|
|
159
171
|
}
|
|
@@ -166,118 +178,181 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
166
178
|
|
|
167
179
|
// Create initial DOM structure
|
|
168
180
|
this._containerElement = null;
|
|
169
|
-
this.
|
|
181
|
+
this._surfaceElement = document.createElement('button');
|
|
170
182
|
this._slotElement = document.createElement('slot');
|
|
171
|
-
this.
|
|
183
|
+
this._prefixIcon = null;
|
|
184
|
+
this._suffixIcon = null;
|
|
172
185
|
|
|
173
|
-
this.
|
|
186
|
+
this._surfaceElement.className = 'surface';
|
|
187
|
+
this._surfaceElement.appendChild(this._slotElement);
|
|
188
|
+
|
|
189
|
+
this._onWindowResize = this._onWindowResize.bind(this);
|
|
174
190
|
}
|
|
175
191
|
|
|
176
192
|
static get observedAttributes() {
|
|
177
|
-
return [
|
|
193
|
+
return [
|
|
194
|
+
"key",
|
|
195
|
+
"href",
|
|
196
|
+
"new-tab",
|
|
197
|
+
"rel",
|
|
198
|
+
"w",
|
|
199
|
+
"pre",
|
|
200
|
+
"suf",
|
|
201
|
+
"disabled",
|
|
202
|
+
"v",
|
|
203
|
+
"s",
|
|
204
|
+
"sq",
|
|
205
|
+
"sm-s",
|
|
206
|
+
"md-s",
|
|
207
|
+
"lg-s",
|
|
208
|
+
"xl-s",
|
|
209
|
+
];
|
|
178
210
|
}
|
|
179
211
|
|
|
180
212
|
connectedCallback() {
|
|
213
|
+
window.addEventListener("resize", this._onWindowResize);
|
|
181
214
|
this._updateButton();
|
|
182
215
|
}
|
|
183
216
|
|
|
217
|
+
disconnectedCallback() {
|
|
218
|
+
window.removeEventListener("resize", this._onWindowResize);
|
|
219
|
+
}
|
|
220
|
+
|
|
184
221
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
185
222
|
this._updateButton();
|
|
186
223
|
}
|
|
187
224
|
|
|
225
|
+
_onWindowResize() {
|
|
226
|
+
if (
|
|
227
|
+
this.hasAttribute("sm-s") ||
|
|
228
|
+
this.hasAttribute("md-s") ||
|
|
229
|
+
this.hasAttribute("lg-s") ||
|
|
230
|
+
this.hasAttribute("xl-s")
|
|
231
|
+
) {
|
|
232
|
+
this._updateIcon();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
_resolveResponsiveSizeToken() {
|
|
237
|
+
const viewportWidth = window.innerWidth;
|
|
238
|
+
|
|
239
|
+
for (const { prefix, maxWidth } of responsiveSizeBreakpoints) {
|
|
240
|
+
const responsiveAttrName = `${prefix}-s`;
|
|
241
|
+
if (viewportWidth <= maxWidth && this.hasAttribute(responsiveAttrName)) {
|
|
242
|
+
return this.getAttribute(responsiveAttrName);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return this.getAttribute("s");
|
|
247
|
+
}
|
|
248
|
+
|
|
188
249
|
_updateButton() {
|
|
189
250
|
// Clear shadow DOM
|
|
190
251
|
this.shadow.innerHTML = '';
|
|
191
|
-
|
|
192
|
-
// Update
|
|
252
|
+
|
|
253
|
+
// Update disabled state
|
|
254
|
+
const isDisabled = this.hasAttribute('disabled');
|
|
255
|
+
const href = this.getAttribute("href");
|
|
256
|
+
const newTab = this.hasAttribute("new-tab");
|
|
257
|
+
const rel = this.getAttribute("rel");
|
|
258
|
+
|
|
259
|
+
const shouldUseAnchor = href && !isDisabled;
|
|
260
|
+
const requiredTag = shouldUseAnchor ? "a" : "button";
|
|
261
|
+
if (this._surfaceElement.tagName.toLowerCase() !== requiredTag) {
|
|
262
|
+
const nextSurfaceElement = document.createElement(requiredTag);
|
|
263
|
+
nextSurfaceElement.className = 'surface';
|
|
264
|
+
nextSurfaceElement.appendChild(this._slotElement);
|
|
265
|
+
this._surfaceElement = nextSurfaceElement;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Update icon after surface element is finalized so icons are attached
|
|
269
|
+
// to the active tag (<button> or <a>) consistently.
|
|
193
270
|
this._updateIcon();
|
|
194
|
-
|
|
195
|
-
// Update width styling (skip for square buttons)
|
|
271
|
+
|
|
196
272
|
if (!this.hasAttribute('sq')) {
|
|
197
273
|
this._updateWidth();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Update disabled state
|
|
201
|
-
const isDisabled = this.hasAttribute('disabled');
|
|
202
|
-
if (isDisabled) {
|
|
203
|
-
this._buttonElement.setAttribute('disabled', '');
|
|
204
274
|
} else {
|
|
205
|
-
this.
|
|
275
|
+
this.style.width = "";
|
|
276
|
+
this.style.minWidth = "";
|
|
277
|
+
this.style.maxWidth = "";
|
|
278
|
+
this._surfaceElement.style.width = "";
|
|
279
|
+
this._surfaceElement.style.minWidth = "";
|
|
280
|
+
this._surfaceElement.style.maxWidth = "";
|
|
206
281
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if (target) {
|
|
217
|
-
anchorElement.setAttribute('target', target);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
anchorElement.appendChild(this._buttonElement);
|
|
221
|
-
this.shadow.appendChild(anchorElement);
|
|
222
|
-
this._containerElement = anchorElement;
|
|
282
|
+
|
|
283
|
+
if (shouldUseAnchor) {
|
|
284
|
+
applyLinkAttributes({
|
|
285
|
+
linkElement: this._surfaceElement,
|
|
286
|
+
href,
|
|
287
|
+
newTab,
|
|
288
|
+
rel,
|
|
289
|
+
});
|
|
290
|
+
this._surfaceElement.removeAttribute("disabled");
|
|
223
291
|
} else {
|
|
224
|
-
|
|
225
|
-
this.
|
|
226
|
-
this.
|
|
292
|
+
this._surfaceElement.removeAttribute("href");
|
|
293
|
+
this._surfaceElement.removeAttribute("target");
|
|
294
|
+
this._surfaceElement.removeAttribute("rel");
|
|
295
|
+
if (isDisabled) {
|
|
296
|
+
this._surfaceElement.setAttribute("disabled", "");
|
|
297
|
+
} else {
|
|
298
|
+
this._surfaceElement.removeAttribute("disabled");
|
|
299
|
+
}
|
|
227
300
|
}
|
|
301
|
+
|
|
302
|
+
this.shadow.appendChild(this._surfaceElement);
|
|
303
|
+
this._containerElement = this._surfaceElement;
|
|
228
304
|
}
|
|
229
305
|
|
|
230
306
|
_updateIcon() {
|
|
231
|
-
// Remove existing
|
|
232
|
-
if (this.
|
|
233
|
-
this.
|
|
234
|
-
this.
|
|
307
|
+
// Remove existing icons if any
|
|
308
|
+
if (this._prefixIcon) {
|
|
309
|
+
this._prefixIcon.remove();
|
|
310
|
+
this._prefixIcon = null;
|
|
235
311
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
312
|
+
if (this._suffixIcon) {
|
|
313
|
+
this._suffixIcon.remove();
|
|
314
|
+
this._suffixIcon = null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const iconSizeMap = {
|
|
318
|
+
sm: 14,
|
|
319
|
+
md: 18,
|
|
320
|
+
lg: 22
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// For square buttons, use button size token, otherwise use icon size token.
|
|
324
|
+
const resolvedSizeToken = this._resolveResponsiveSizeToken();
|
|
325
|
+
let size = 18; // default
|
|
326
|
+
if (this.hasAttribute('sq')) {
|
|
327
|
+
const buttonSizeMap = {
|
|
248
328
|
sm: 14,
|
|
249
|
-
md: 18,
|
|
250
329
|
lg: 22
|
|
251
330
|
};
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
} else {
|
|
278
|
-
// Insert icon after slot (right position - default)
|
|
279
|
-
this._buttonElement.appendChild(this._iconElement);
|
|
280
|
-
}
|
|
331
|
+
size = buttonSizeMap[resolvedSizeToken] || 18;
|
|
332
|
+
} else {
|
|
333
|
+
size = iconSizeMap[resolvedSizeToken] || 18;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Create prefix icon (before text)
|
|
337
|
+
const prefixIcon = this.getAttribute("pre");
|
|
338
|
+
if (prefixIcon) {
|
|
339
|
+
this._prefixIcon = document.createElement('rtgl-svg');
|
|
340
|
+
this._prefixIcon.setAttribute('svg', prefixIcon);
|
|
341
|
+
this._prefixIcon.setAttribute('wh', size.toString());
|
|
342
|
+
this._prefixIcon.style.color = "inherit";
|
|
343
|
+
// Insert before slot (left position)
|
|
344
|
+
this._surfaceElement.insertBefore(this._prefixIcon, this._slotElement);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Create suffix icon (after text)
|
|
348
|
+
const suffixIcon = this.getAttribute("suf");
|
|
349
|
+
if (suffixIcon) {
|
|
350
|
+
this._suffixIcon = document.createElement('rtgl-svg');
|
|
351
|
+
this._suffixIcon.setAttribute('svg', suffixIcon);
|
|
352
|
+
this._suffixIcon.setAttribute('wh', size.toString());
|
|
353
|
+
this._suffixIcon.style.color = "inherit";
|
|
354
|
+
// Insert after slot (right position)
|
|
355
|
+
this._surfaceElement.appendChild(this._suffixIcon);
|
|
281
356
|
}
|
|
282
357
|
}
|
|
283
358
|
|
|
@@ -285,23 +360,34 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
285
360
|
const width = dimensionWithUnit(this.getAttribute("w"));
|
|
286
361
|
|
|
287
362
|
if (width === "f") {
|
|
288
|
-
this.
|
|
363
|
+
this.style.width = "var(--width-stretch)";
|
|
364
|
+
this.style.minWidth = "";
|
|
365
|
+
this.style.maxWidth = "";
|
|
366
|
+
this._surfaceElement.style.width = "100%";
|
|
367
|
+
this._surfaceElement.style.minWidth = "";
|
|
368
|
+
this._surfaceElement.style.maxWidth = "";
|
|
289
369
|
} else if (width !== undefined && width !== null) {
|
|
290
|
-
this.
|
|
291
|
-
this.
|
|
292
|
-
this.
|
|
370
|
+
this.style.width = width;
|
|
371
|
+
this.style.minWidth = width;
|
|
372
|
+
this.style.maxWidth = width;
|
|
373
|
+
this._surfaceElement.style.width = "100%";
|
|
374
|
+
this._surfaceElement.style.minWidth = "";
|
|
375
|
+
this._surfaceElement.style.maxWidth = "";
|
|
293
376
|
} else {
|
|
294
|
-
this.
|
|
295
|
-
this.
|
|
296
|
-
this.
|
|
377
|
+
this.style.width = "";
|
|
378
|
+
this.style.minWidth = "";
|
|
379
|
+
this.style.maxWidth = "";
|
|
380
|
+
this._surfaceElement.style.width = "";
|
|
381
|
+
this._surfaceElement.style.minWidth = "";
|
|
382
|
+
this._surfaceElement.style.maxWidth = "";
|
|
297
383
|
}
|
|
298
384
|
}
|
|
299
385
|
|
|
300
386
|
// Public method to get the actual button's bounding rect
|
|
301
387
|
// This is needed because the host element has display: contents
|
|
302
388
|
getBoundingClientRect() {
|
|
303
|
-
if (this.
|
|
304
|
-
return this.
|
|
389
|
+
if (this._surfaceElement) {
|
|
390
|
+
return this._surfaceElement.getBoundingClientRect();
|
|
305
391
|
}
|
|
306
392
|
// Fallback to host element
|
|
307
393
|
return super.getBoundingClientRect();
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
css,
|
|
1
|
+
import {
|
|
2
|
+
css,
|
|
3
3
|
dimensionWithUnit,
|
|
4
4
|
convertObjectToCssString,
|
|
5
|
-
styleMapKeys,
|
|
6
5
|
permutateBreakpoints,
|
|
6
|
+
createResponsiveStyleBuckets,
|
|
7
|
+
responsiveStyleSizes,
|
|
8
|
+
applyDimensionToStyleBucket,
|
|
7
9
|
} from "../common.js";
|
|
8
10
|
import cursorStyles from "../styles/cursorStyles.js";
|
|
9
11
|
import marginStyles from "../styles/marginStyles.js";
|
|
10
12
|
|
|
13
|
+
const colorPickerStyleMapKeys = ["mt", "mr", "mb", "ml", "m", "mh", "mv", "cur"];
|
|
14
|
+
const HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
|
|
15
|
+
|
|
11
16
|
// Internal implementation without uhtml
|
|
12
17
|
class RettangoliColorPickerElement extends HTMLElement {
|
|
13
18
|
static styleSheet = null;
|
|
@@ -49,13 +54,7 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
49
54
|
this.shadow.adoptedStyleSheets = [RettangoliColorPickerElement.styleSheet];
|
|
50
55
|
|
|
51
56
|
// Initialize style tracking properties
|
|
52
|
-
this._styles =
|
|
53
|
-
default: {},
|
|
54
|
-
sm: {},
|
|
55
|
-
md: {},
|
|
56
|
-
lg: {},
|
|
57
|
-
xl: {},
|
|
58
|
-
};
|
|
57
|
+
this._styles = createResponsiveStyleBuckets();
|
|
59
58
|
this._lastStyleString = "";
|
|
60
59
|
|
|
61
60
|
// Create initial DOM structure
|
|
@@ -77,7 +76,7 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
77
76
|
"value",
|
|
78
77
|
"disabled",
|
|
79
78
|
...permutateBreakpoints([
|
|
80
|
-
...
|
|
79
|
+
...colorPickerStyleMapKeys,
|
|
81
80
|
"wh",
|
|
82
81
|
"w",
|
|
83
82
|
"h",
|
|
@@ -97,29 +96,32 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
97
96
|
this._inputElement.value = newValue;
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
_onChange = (
|
|
101
|
-
this.dispatchEvent(new CustomEvent('
|
|
99
|
+
_onChange = () => {
|
|
100
|
+
this.dispatchEvent(new CustomEvent('value-change', {
|
|
102
101
|
detail: {
|
|
103
102
|
value: this._inputElement.value,
|
|
104
103
|
},
|
|
104
|
+
bubbles: true,
|
|
105
105
|
}));
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
_onInput = (
|
|
109
|
-
this.dispatchEvent(new CustomEvent('
|
|
108
|
+
_onInput = () => {
|
|
109
|
+
this.dispatchEvent(new CustomEvent('value-input', {
|
|
110
110
|
detail: {
|
|
111
111
|
value: this._inputElement.value,
|
|
112
112
|
},
|
|
113
|
+
bubbles: true,
|
|
113
114
|
}));
|
|
114
115
|
};
|
|
115
116
|
|
|
116
117
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
118
|
+
if (oldValue === newValue) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
117
122
|
// Handle key attribute change - reset value
|
|
118
|
-
if (name === "key"
|
|
119
|
-
|
|
120
|
-
const value = this.getAttribute("value");
|
|
121
|
-
this._inputElement.value = value ?? "#000000";
|
|
122
|
-
});
|
|
123
|
+
if (name === "key") {
|
|
124
|
+
this._syncValueAttribute();
|
|
123
125
|
return;
|
|
124
126
|
}
|
|
125
127
|
|
|
@@ -129,16 +131,14 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
129
131
|
return;
|
|
130
132
|
}
|
|
131
133
|
|
|
134
|
+
this.updateStyles();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
updateStyles() {
|
|
132
138
|
// Reset styles for fresh calculation
|
|
133
|
-
this._styles =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
md: {},
|
|
137
|
-
lg: {},
|
|
138
|
-
xl: {},
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
["default", "sm", "md", "lg", "xl"].forEach((size) => {
|
|
139
|
+
this._styles = createResponsiveStyleBuckets();
|
|
140
|
+
|
|
141
|
+
responsiveStyleSizes.forEach((size) => {
|
|
142
142
|
const addSizePrefix = (tag) => {
|
|
143
143
|
return `${size === "default" ? "" : `${size}-`}${tag}`;
|
|
144
144
|
};
|
|
@@ -161,28 +161,26 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
161
161
|
this._styles[size].opacity = opacity;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
this._styles[size]
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
164
|
+
applyDimensionToStyleBucket({
|
|
165
|
+
styleBucket: this._styles[size],
|
|
166
|
+
axis: "width",
|
|
167
|
+
dimension: width,
|
|
168
|
+
fillValue: "var(--width-stretch)",
|
|
169
|
+
});
|
|
171
170
|
|
|
172
|
-
|
|
173
|
-
this._styles[size]
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
171
|
+
applyDimensionToStyleBucket({
|
|
172
|
+
styleBucket: this._styles[size],
|
|
173
|
+
axis: "height",
|
|
174
|
+
dimension: height,
|
|
175
|
+
fillValue: "100%",
|
|
176
|
+
});
|
|
179
177
|
|
|
180
178
|
if (this.hasAttribute(addSizePrefix("hide"))) {
|
|
181
|
-
this._styles[size].display = "none
|
|
179
|
+
this._styles[size].display = "none";
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
if (this.hasAttribute(addSizePrefix("show"))) {
|
|
185
|
-
this._styles[size].display = "block
|
|
183
|
+
this._styles[size].display = "block";
|
|
186
184
|
}
|
|
187
185
|
});
|
|
188
186
|
|
|
@@ -194,13 +192,20 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
194
192
|
}
|
|
195
193
|
}
|
|
196
194
|
|
|
197
|
-
|
|
195
|
+
_syncValueAttribute() {
|
|
198
196
|
const value = this.getAttribute("value");
|
|
197
|
+
if (value === null) {
|
|
198
|
+
this._inputElement.value = "#000000";
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
this._inputElement.value = HEX_COLOR_REGEX.test(value) ? value : "#000000";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
_updateInputAttributes() {
|
|
199
206
|
const isDisabled = this.hasAttribute('disabled');
|
|
200
207
|
|
|
201
|
-
|
|
202
|
-
this._inputElement.value = value;
|
|
203
|
-
}
|
|
208
|
+
this._syncValueAttribute();
|
|
204
209
|
|
|
205
210
|
if (isDisabled) {
|
|
206
211
|
this._inputElement.setAttribute("disabled", "");
|
|
@@ -211,6 +216,7 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
211
216
|
|
|
212
217
|
connectedCallback() {
|
|
213
218
|
this._updateInputAttributes();
|
|
219
|
+
this.updateStyles();
|
|
214
220
|
}
|
|
215
221
|
}
|
|
216
222
|
|
|
@@ -219,4 +225,4 @@ export default ({ render, html }) => {
|
|
|
219
225
|
// Note: render and html parameters are accepted but not used
|
|
220
226
|
// This maintains backward compatibility with existing code
|
|
221
227
|
return RettangoliColorPickerElement;
|
|
222
|
-
};
|
|
228
|
+
};
|