@rettangoli/ui 0.1.2-rc3 → 0.1.2-rc30
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/dist/rettangoli-iife-layout.min.js +115 -43
- package/dist/rettangoli-iife-ui.min.js +187 -67
- package/package.json +5 -3
- package/src/cli/buildSvg.js +86 -0
- package/src/cli/index.js +1 -0
- package/src/common.js +19 -0
- package/src/components/breadcrumb/breadcrumb.handlers.js +9 -0
- package/src/components/breadcrumb/breadcrumb.store.js +29 -0
- package/src/components/breadcrumb/breadcrumb.view.yaml +64 -0
- package/src/components/dropdownMenu/dropdownMenu.handlers.js +4 -4
- package/src/components/dropdownMenu/dropdownMenu.store.js +5 -17
- package/src/components/dropdownMenu/dropdownMenu.view.yaml +15 -13
- package/src/components/form/form.handlers.js +173 -25
- package/src/components/form/form.store.js +176 -22
- package/src/components/form/form.view.yaml +217 -33
- package/src/components/pageOutline/pageOutline.handlers.js +1 -1
- package/src/components/popoverInput/popoverInput.handlers.js +99 -0
- package/src/components/popoverInput/popoverInput.store.js +48 -0
- package/src/components/popoverInput/popoverInput.view.yaml +55 -0
- package/src/components/select/select.handlers.js +116 -11
- package/src/components/select/select.store.js +84 -18
- package/src/components/select/select.view.yaml +40 -10
- package/src/components/sidebar/sidebar.view.yaml +1 -1
- package/src/components/sliderInput/sliderInput.handlers.js +41 -0
- package/src/components/sliderInput/sliderInput.store.js +18 -0
- package/src/components/sliderInput/sliderInput.view.yaml +42 -0
- package/src/components/table/table.handlers.js +1 -1
- package/src/components/tabs/tabs.handlers.js +10 -0
- package/src/components/tabs/tabs.store.js +29 -0
- package/src/components/tabs/tabs.view.yaml +64 -0
- package/src/components/tooltip/tooltip.handlers.js +0 -0
- package/src/components/tooltip/tooltip.store.js +12 -0
- package/src/components/tooltip/tooltip.view.yaml +27 -0
- package/src/components/waveform/waveform.handlers.js +92 -0
- package/src/components/waveform/waveform.store.js +17 -0
- package/src/components/waveform/waveform.view.yaml +38 -0
- package/src/entry-iife-layout.js +3 -0
- package/src/entry-iife-ui.js +4 -0
- package/src/index.js +5 -1
- package/src/primitives/button.js +10 -0
- package/src/primitives/colorPicker.js +9 -0
- package/src/primitives/dialog.js +254 -0
- package/src/primitives/input.js +41 -11
- package/src/primitives/popover.js +280 -0
- package/src/primitives/slider.js +18 -9
- package/src/primitives/svg.js +2 -0
- package/src/primitives/textarea.js +25 -1
- package/src/styles/cursorStyles.js +38 -2
- package/src/components/dialog/dialog.handlers.js +0 -5
- package/src/components/dialog/dialog.store.js +0 -25
- package/src/components/dialog/dialog.view.yaml +0 -44
- package/src/components/popover/popover.handlers.js +0 -5
- package/src/components/popover/popover.store.js +0 -12
- package/src/components/popover/popover.view.yaml +0 -57
package/src/primitives/input.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
css,
|
|
1
|
+
import {
|
|
2
|
+
css,
|
|
3
3
|
dimensionWithUnit,
|
|
4
4
|
convertObjectToCssString,
|
|
5
5
|
styleMapKeys,
|
|
@@ -59,7 +59,7 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
59
59
|
RettangoliInputElement.initializeStyleSheet();
|
|
60
60
|
this.shadow = this.attachShadow({ mode: "closed" });
|
|
61
61
|
this.shadow.adoptedStyleSheets = [RettangoliInputElement.styleSheet];
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
// Initialize style tracking properties
|
|
64
64
|
this._styles = {
|
|
65
65
|
default: {},
|
|
@@ -69,11 +69,11 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
69
69
|
xl: {},
|
|
70
70
|
};
|
|
71
71
|
this._lastStyleString = "";
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
// Create initial DOM structure
|
|
74
74
|
this._inputElement = document.createElement('input');
|
|
75
75
|
this._styleElement = document.createElement('style');
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
this.shadow.appendChild(this._styleElement);
|
|
78
78
|
this.shadow.appendChild(this._inputElement);
|
|
79
79
|
|
|
@@ -83,10 +83,11 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
83
83
|
|
|
84
84
|
static get observedAttributes() {
|
|
85
85
|
return [
|
|
86
|
-
"key",
|
|
87
|
-
"type",
|
|
88
|
-
"placeholder",
|
|
86
|
+
"key",
|
|
87
|
+
"type",
|
|
88
|
+
"placeholder",
|
|
89
89
|
"disabled",
|
|
90
|
+
"value",
|
|
90
91
|
"s",
|
|
91
92
|
...permutateBreakpoints([
|
|
92
93
|
...styleMapKeys,
|
|
@@ -105,6 +106,14 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
105
106
|
return this._inputElement.value;
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
set value(newValue) {
|
|
110
|
+
this._inputElement.value = newValue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
focus() {
|
|
114
|
+
this._inputElement.focus();
|
|
115
|
+
}
|
|
116
|
+
|
|
108
117
|
_onChange = (event) => {
|
|
109
118
|
this.dispatchEvent(new CustomEvent('input-change', {
|
|
110
119
|
detail: {
|
|
@@ -114,8 +123,17 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
114
123
|
};
|
|
115
124
|
|
|
116
125
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
126
|
+
// Handle key attribute change - reset value
|
|
127
|
+
if (name === "key" && oldValue !== newValue) {
|
|
128
|
+
requestAnimationFrame((() => {
|
|
129
|
+
const value = this.getAttribute("value");
|
|
130
|
+
this._inputElement.value = value ?? "";
|
|
131
|
+
}))
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
117
135
|
// Handle input-specific attributes first
|
|
118
|
-
if (["type", "placeholder", "disabled", "s"].includes(name)) {
|
|
136
|
+
if (["type", "placeholder", "disabled", "value", "step", "s"].includes(name)) {
|
|
119
137
|
this._updateInputAttributes();
|
|
120
138
|
return;
|
|
121
139
|
}
|
|
@@ -188,16 +206,28 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
188
206
|
_updateInputAttributes() {
|
|
189
207
|
const type = this.getAttribute("type") || "text";
|
|
190
208
|
const placeholder = this.getAttribute("placeholder");
|
|
209
|
+
const value = this.getAttribute("value");
|
|
210
|
+
const step = this.getAttribute("step");
|
|
191
211
|
const isDisabled = this.hasAttribute('disabled');
|
|
192
212
|
|
|
193
213
|
this._inputElement.setAttribute("type", type);
|
|
194
|
-
|
|
214
|
+
|
|
195
215
|
if (placeholder !== null) {
|
|
196
216
|
this._inputElement.setAttribute("placeholder", placeholder);
|
|
197
217
|
} else {
|
|
198
218
|
this._inputElement.removeAttribute("placeholder");
|
|
199
219
|
}
|
|
200
|
-
|
|
220
|
+
|
|
221
|
+
if (value !== null) {
|
|
222
|
+
this._inputElement.value = value;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (step !== null) {
|
|
226
|
+
this._inputElement.setAttribute("step", step);
|
|
227
|
+
} else {
|
|
228
|
+
this._inputElement.removeAttribute("step");
|
|
229
|
+
}
|
|
230
|
+
|
|
201
231
|
if (isDisabled) {
|
|
202
232
|
this._inputElement.setAttribute("disabled", "");
|
|
203
233
|
} else {
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { css } from "../common.js";
|
|
2
|
+
|
|
3
|
+
class RettangoliPopoverElement extends HTMLElement {
|
|
4
|
+
static styleSheet = null;
|
|
5
|
+
|
|
6
|
+
static initializeStyleSheet() {
|
|
7
|
+
if (!RettangoliPopoverElement.styleSheet) {
|
|
8
|
+
RettangoliPopoverElement.styleSheet = new CSSStyleSheet();
|
|
9
|
+
RettangoliPopoverElement.styleSheet.replaceSync(css`
|
|
10
|
+
:host {
|
|
11
|
+
display: contents;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.popover-overlay {
|
|
15
|
+
position: fixed;
|
|
16
|
+
top: 0;
|
|
17
|
+
left: 0;
|
|
18
|
+
width: 100vw;
|
|
19
|
+
height: 100vh;
|
|
20
|
+
z-index: 999;
|
|
21
|
+
display: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.popover-container {
|
|
25
|
+
position: fixed;
|
|
26
|
+
z-index: 1000;
|
|
27
|
+
display: none;
|
|
28
|
+
outline: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:host([open]:not([no-overlay])) .popover-overlay {
|
|
32
|
+
display: block;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:host([open]) .popover-container {
|
|
36
|
+
display: block;
|
|
37
|
+
visibility: hidden;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* For no-overlay mode, make the container non-interactive */
|
|
41
|
+
:host([no-overlay]) .popover-container {
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
:host([open][positioned]) .popover-container {
|
|
46
|
+
visibility: visible;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
slot[name="content"] {
|
|
50
|
+
display: block;
|
|
51
|
+
background-color: var(--muted);
|
|
52
|
+
border: 1px solid var(--border);
|
|
53
|
+
border-radius: var(--border-radius-md);
|
|
54
|
+
padding: var(--spacing-md);
|
|
55
|
+
min-width: 200px;
|
|
56
|
+
max-width: 400px;
|
|
57
|
+
}
|
|
58
|
+
`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
constructor() {
|
|
63
|
+
super();
|
|
64
|
+
RettangoliPopoverElement.initializeStyleSheet();
|
|
65
|
+
this.shadow = this.attachShadow({ mode: "open" });
|
|
66
|
+
this.shadow.adoptedStyleSheets = [RettangoliPopoverElement.styleSheet];
|
|
67
|
+
|
|
68
|
+
// Create overlay
|
|
69
|
+
this._popoverOverlay = document.createElement('div');
|
|
70
|
+
this._popoverOverlay.className = 'popover-overlay';
|
|
71
|
+
this.shadow.appendChild(this._popoverOverlay);
|
|
72
|
+
|
|
73
|
+
// Handle overlay clicks to close popover
|
|
74
|
+
this._popoverOverlay.addEventListener('click', () => {
|
|
75
|
+
this.dispatchEvent(new CustomEvent('close', {
|
|
76
|
+
detail: {}
|
|
77
|
+
}));
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Handle right-click on overlay to close popover
|
|
81
|
+
this._popoverOverlay.addEventListener('contextmenu', (e) => {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
this.dispatchEvent(new CustomEvent('close', {
|
|
84
|
+
detail: {}
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Create popover container
|
|
89
|
+
this._popoverContainer = document.createElement('div');
|
|
90
|
+
this._popoverContainer.className = 'popover-container';
|
|
91
|
+
this.shadow.appendChild(this._popoverContainer);
|
|
92
|
+
|
|
93
|
+
// Store reference for content slot
|
|
94
|
+
this._slotElement = null;
|
|
95
|
+
|
|
96
|
+
// Track if we're open
|
|
97
|
+
this._isOpen = false;
|
|
98
|
+
|
|
99
|
+
// Bind event handlers
|
|
100
|
+
this._handleEscKey = this._handleEscKey.bind(this);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static get observedAttributes() {
|
|
104
|
+
return ["open", "x", "y", "placement", "no-overlay"];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
connectedCallback() {
|
|
108
|
+
// Check initial open attribute
|
|
109
|
+
if (this.hasAttribute('open')) {
|
|
110
|
+
this._show();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
disconnectedCallback() {
|
|
115
|
+
// Clean up event listeners
|
|
116
|
+
this._removeGlobalListeners();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
120
|
+
if (name === 'open') {
|
|
121
|
+
if (newValue !== null && !this._isOpen) {
|
|
122
|
+
this._show();
|
|
123
|
+
} else if (newValue === null && this._isOpen) {
|
|
124
|
+
this._hide();
|
|
125
|
+
}
|
|
126
|
+
} else if ((name === 'x' || name === 'y' || name === 'placement') && this._isOpen) {
|
|
127
|
+
this._updatePosition();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
_show() {
|
|
132
|
+
if (!this._isOpen) {
|
|
133
|
+
// Create and append slot for content only if it doesn't exist
|
|
134
|
+
if (!this._slotElement) {
|
|
135
|
+
this._slotElement = document.createElement('slot');
|
|
136
|
+
this._slotElement.setAttribute('name', 'content');
|
|
137
|
+
this._popoverContainer.appendChild(this._slotElement);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this._isOpen = true;
|
|
141
|
+
this._updatePosition();
|
|
142
|
+
this._addGlobalListeners();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
_hide() {
|
|
147
|
+
if (this._isOpen) {
|
|
148
|
+
this._isOpen = false;
|
|
149
|
+
|
|
150
|
+
// Remove slot to unmount content
|
|
151
|
+
if (this._slotElement) {
|
|
152
|
+
this._popoverContainer.removeChild(this._slotElement);
|
|
153
|
+
this._slotElement = null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this._removeGlobalListeners();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_updatePosition() {
|
|
161
|
+
const x = parseFloat(this.getAttribute('x') || '0');
|
|
162
|
+
const y = parseFloat(this.getAttribute('y') || '0');
|
|
163
|
+
const placement = this.getAttribute('placement') || 'bottom-start';
|
|
164
|
+
|
|
165
|
+
// Remove positioned attribute to hide during repositioning
|
|
166
|
+
this.removeAttribute('positioned');
|
|
167
|
+
|
|
168
|
+
// Calculate position based on placement
|
|
169
|
+
// We'll position after the popover is rendered to get its dimensions
|
|
170
|
+
requestAnimationFrame(() => {
|
|
171
|
+
const rect = this._popoverContainer.getBoundingClientRect();
|
|
172
|
+
const { left, top } = this._calculatePosition(x, y, rect.width, rect.height, placement);
|
|
173
|
+
|
|
174
|
+
// Set position first
|
|
175
|
+
this._popoverContainer.style.left = `${left}px`;
|
|
176
|
+
this._popoverContainer.style.top = `${top}px`;
|
|
177
|
+
|
|
178
|
+
// Then make visible in next frame to prevent flicker
|
|
179
|
+
requestAnimationFrame(() => {
|
|
180
|
+
this.setAttribute('positioned', '');
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
_calculatePosition(x, y, width, height, placement) {
|
|
186
|
+
const offset = 8; // Small offset from the cursor
|
|
187
|
+
let left = x;
|
|
188
|
+
let top = y;
|
|
189
|
+
|
|
190
|
+
switch (placement) {
|
|
191
|
+
case 'top':
|
|
192
|
+
left = x - width / 2;
|
|
193
|
+
top = y - height - offset;
|
|
194
|
+
break;
|
|
195
|
+
case 'top-start':
|
|
196
|
+
left = x;
|
|
197
|
+
top = y - height - offset;
|
|
198
|
+
break;
|
|
199
|
+
case 'top-end':
|
|
200
|
+
left = x - width;
|
|
201
|
+
top = y - height - offset;
|
|
202
|
+
break;
|
|
203
|
+
case 'right':
|
|
204
|
+
left = x + offset;
|
|
205
|
+
top = y - height / 2;
|
|
206
|
+
break;
|
|
207
|
+
case 'right-start':
|
|
208
|
+
left = x + offset;
|
|
209
|
+
top = y;
|
|
210
|
+
break;
|
|
211
|
+
case 'right-end':
|
|
212
|
+
left = x + offset;
|
|
213
|
+
top = y - height;
|
|
214
|
+
break;
|
|
215
|
+
case 'bottom':
|
|
216
|
+
left = x - width / 2;
|
|
217
|
+
top = y + offset;
|
|
218
|
+
break;
|
|
219
|
+
case 'bottom-start':
|
|
220
|
+
left = x;
|
|
221
|
+
top = y + offset;
|
|
222
|
+
break;
|
|
223
|
+
case 'bottom-end':
|
|
224
|
+
left = x - width;
|
|
225
|
+
top = y + offset;
|
|
226
|
+
break;
|
|
227
|
+
case 'left':
|
|
228
|
+
left = x - width - offset;
|
|
229
|
+
top = y - height / 2;
|
|
230
|
+
break;
|
|
231
|
+
case 'left-start':
|
|
232
|
+
left = x - width - offset;
|
|
233
|
+
top = y;
|
|
234
|
+
break;
|
|
235
|
+
case 'left-end':
|
|
236
|
+
left = x - width - offset;
|
|
237
|
+
top = y - height;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Ensure popover stays within viewport
|
|
242
|
+
const padding = 8;
|
|
243
|
+
left = Math.max(padding, Math.min(left, window.innerWidth - width - padding));
|
|
244
|
+
top = Math.max(padding, Math.min(top, window.innerHeight - height - padding));
|
|
245
|
+
|
|
246
|
+
return { left, top };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
_addGlobalListeners() {
|
|
250
|
+
// Use setTimeout to avoid immediate triggering
|
|
251
|
+
setTimeout(() => {
|
|
252
|
+
document.addEventListener('keydown', this._handleEscKey);
|
|
253
|
+
}, 0);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
_removeGlobalListeners() {
|
|
257
|
+
document.removeEventListener('keydown', this._handleEscKey);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
_handleEscKey(e) {
|
|
262
|
+
if (e.key === 'Escape') {
|
|
263
|
+
this.dispatchEvent(new CustomEvent('close', {
|
|
264
|
+
detail: {}
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Expose popover container for advanced usage
|
|
270
|
+
get popover() {
|
|
271
|
+
return this._popoverContainer;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Export factory function to maintain API compatibility
|
|
276
|
+
export default ({ render, html }) => {
|
|
277
|
+
// Note: render and html parameters are accepted but not used
|
|
278
|
+
// This maintains backward compatibility with existing code
|
|
279
|
+
return RettangoliPopoverElement;
|
|
280
|
+
};
|
package/src/primitives/slider.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
css,
|
|
1
|
+
import {
|
|
2
|
+
css,
|
|
3
3
|
dimensionWithUnit,
|
|
4
4
|
convertObjectToCssString,
|
|
5
5
|
styleMapKeys,
|
|
@@ -22,7 +22,6 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
22
22
|
input[type="range"] {
|
|
23
23
|
-webkit-appearance: none;
|
|
24
24
|
appearance: none;
|
|
25
|
-
width: 200px;
|
|
26
25
|
height: 8px;
|
|
27
26
|
background: var(--muted);
|
|
28
27
|
border-radius: var(--border-radius-full);
|
|
@@ -79,7 +78,7 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
79
78
|
RettangoliSliderElement.initializeStyleSheet();
|
|
80
79
|
this.shadow = this.attachShadow({ mode: "closed" });
|
|
81
80
|
this.shadow.adoptedStyleSheets = [RettangoliSliderElement.styleSheet];
|
|
82
|
-
|
|
81
|
+
|
|
83
82
|
// Initialize style tracking properties
|
|
84
83
|
this._styles = {
|
|
85
84
|
default: {},
|
|
@@ -89,12 +88,12 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
89
88
|
xl: {},
|
|
90
89
|
};
|
|
91
90
|
this._lastStyleString = "";
|
|
92
|
-
|
|
91
|
+
|
|
93
92
|
// Create initial DOM structure
|
|
94
93
|
this._inputElement = document.createElement('input');
|
|
95
94
|
this._inputElement.type = 'range';
|
|
96
95
|
this._styleElement = document.createElement('style');
|
|
97
|
-
|
|
96
|
+
|
|
98
97
|
this.shadow.appendChild(this._styleElement);
|
|
99
98
|
this.shadow.appendChild(this._inputElement);
|
|
100
99
|
|
|
@@ -105,7 +104,7 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
105
104
|
|
|
106
105
|
static get observedAttributes() {
|
|
107
106
|
return [
|
|
108
|
-
"key",
|
|
107
|
+
"key",
|
|
109
108
|
"value",
|
|
110
109
|
"min",
|
|
111
110
|
"max",
|
|
@@ -149,6 +148,16 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
149
148
|
};
|
|
150
149
|
|
|
151
150
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
151
|
+
// Handle key attribute change - reset value
|
|
152
|
+
if (name === "key" && oldValue !== newValue) {
|
|
153
|
+
requestAnimationFrame(() => {
|
|
154
|
+
const value = this.getAttribute("value");
|
|
155
|
+
const min = this.getAttribute("min") || "0";
|
|
156
|
+
this._inputElement.value = value ?? min;
|
|
157
|
+
});
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
152
161
|
// Handle input-specific attributes first
|
|
153
162
|
if (["value", "min", "max", "step", "disabled"].includes(name)) {
|
|
154
163
|
this._updateInputAttributes();
|
|
@@ -248,7 +257,7 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
248
257
|
} else {
|
|
249
258
|
this._inputElement.step = "1";
|
|
250
259
|
}
|
|
251
|
-
|
|
260
|
+
|
|
252
261
|
if (isDisabled) {
|
|
253
262
|
this._inputElement.setAttribute("disabled", "");
|
|
254
263
|
} else {
|
|
@@ -266,4 +275,4 @@ export default ({ render, html }) => {
|
|
|
266
275
|
// Note: render and html parameters are accepted but not used
|
|
267
276
|
// This maintains backward compatibility with existing code
|
|
268
277
|
return RettangoliSliderElement;
|
|
269
|
-
};
|
|
278
|
+
};
|
package/src/primitives/svg.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { css, dimensionWithUnit } from "../common.js";
|
|
2
2
|
import flexChildStyles from "../styles/flexChildStyles.js";
|
|
3
3
|
import paddingSvgStyles from "../styles/paddingSvgStyles.js";
|
|
4
|
+
import marginStyles from "../styles/marginStyles.js";
|
|
4
5
|
import cursorStyles from "../styles/cursorStyles.js";
|
|
5
6
|
import textColorStyles from "../styles/textColorStyles.js";
|
|
6
7
|
|
|
@@ -18,6 +19,7 @@ class RettangoliSvgElement extends HTMLElement {
|
|
|
18
19
|
}
|
|
19
20
|
${textColorStyles}
|
|
20
21
|
${paddingSvgStyles}
|
|
22
|
+
${marginStyles}
|
|
21
23
|
${flexChildStyles}
|
|
22
24
|
${cursorStyles}
|
|
23
25
|
`);
|
|
@@ -48,10 +48,21 @@ class RettangoliTextAreaElement extends HTMLElement {
|
|
|
48
48
|
this._textareaElement = document.createElement('textarea');
|
|
49
49
|
this._textareaElement.setAttribute('type', 'text');
|
|
50
50
|
this.shadow.appendChild(this._textareaElement);
|
|
51
|
+
|
|
52
|
+
// Bind event handler
|
|
53
|
+
this._textareaElement.addEventListener('input', this._onChange);
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
_onChange = (event) => {
|
|
57
|
+
this.dispatchEvent(new CustomEvent('textarea-change', {
|
|
58
|
+
detail: {
|
|
59
|
+
value: this._textareaElement.value,
|
|
60
|
+
},
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
63
|
+
|
|
53
64
|
static get observedAttributes() {
|
|
54
|
-
return ["key", "w", "ellipsis", "cols", "rows", "placeholder"];
|
|
65
|
+
return ["key", "w", "ellipsis", "cols", "rows", "placeholder", "value"];
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
get value() {
|
|
@@ -67,6 +78,14 @@ class RettangoliTextAreaElement extends HTMLElement {
|
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
81
|
+
// Handle key attribute change - reset value
|
|
82
|
+
if (name === "key" && oldValue !== newValue) {
|
|
83
|
+
requestAnimationFrame(() => {
|
|
84
|
+
const value = this.getAttribute("value");
|
|
85
|
+
this._textareaElement.value = value ?? "";
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
70
89
|
this._updateTextareaAttributes();
|
|
71
90
|
}
|
|
72
91
|
|
|
@@ -74,6 +93,7 @@ class RettangoliTextAreaElement extends HTMLElement {
|
|
|
74
93
|
const cols = this.getAttribute("cols");
|
|
75
94
|
const rows = this.getAttribute("rows");
|
|
76
95
|
const placeholder = this.getAttribute("placeholder");
|
|
96
|
+
const value = this.getAttribute("value");
|
|
77
97
|
|
|
78
98
|
if (cols !== null) {
|
|
79
99
|
this._textareaElement.setAttribute("cols", cols);
|
|
@@ -92,6 +112,10 @@ class RettangoliTextAreaElement extends HTMLElement {
|
|
|
92
112
|
} else {
|
|
93
113
|
this._textareaElement.removeAttribute("placeholder");
|
|
94
114
|
}
|
|
115
|
+
|
|
116
|
+
if (value !== null) {
|
|
117
|
+
this._textareaElement.value = value;
|
|
118
|
+
}
|
|
95
119
|
}
|
|
96
120
|
}
|
|
97
121
|
|
|
@@ -2,10 +2,46 @@ import { generateCSS } from '../common.js'
|
|
|
2
2
|
|
|
3
3
|
const styles = {
|
|
4
4
|
"cur": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"alias": "alias",
|
|
6
|
+
"all-scroll": "all-scroll",
|
|
7
|
+
"auto": "auto",
|
|
8
|
+
"cell": "cell",
|
|
9
|
+
"col-resize": "col-resize",
|
|
10
|
+
"context-menu": "context-menu",
|
|
11
|
+
"copy": "copy",
|
|
12
|
+
"crosshair": "crosshair",
|
|
13
|
+
"default": "default",
|
|
14
|
+
"e-resize": "e-resize",
|
|
15
|
+
"ew-resize": "ew-resize",
|
|
7
16
|
"grab": "grab",
|
|
8
17
|
"grabbing": "grabbing",
|
|
18
|
+
"help": "help",
|
|
19
|
+
"move": "move",
|
|
20
|
+
"n-resize": "n-resize",
|
|
21
|
+
"ne-resize": "ne-resize",
|
|
22
|
+
"nesw-resize": "nesw-resize",
|
|
23
|
+
"ns-resize": "ns-resize",
|
|
24
|
+
"nw-resize": "nw-resize",
|
|
25
|
+
"nwse-resize": "nwse-resize",
|
|
26
|
+
"no-drop": "no-drop",
|
|
27
|
+
"none": "none",
|
|
28
|
+
"not-allowed": "not-allowed",
|
|
29
|
+
"pointer": "pointer",
|
|
30
|
+
"progress": "progress",
|
|
31
|
+
"row-resize": "row-resize",
|
|
32
|
+
"s-resize": "s-resize",
|
|
33
|
+
"se-resize": "se-resize",
|
|
34
|
+
"sw-resize": "sw-resize",
|
|
35
|
+
"text": "text",
|
|
36
|
+
"url": "url",
|
|
37
|
+
"w-resize": "w-resize",
|
|
38
|
+
"wait": "wait",
|
|
39
|
+
"zoom-in": "zoom-in",
|
|
40
|
+
"zoom-out": "zoom-out",
|
|
41
|
+
|
|
42
|
+
// Keep short aliases for common cursors
|
|
43
|
+
"p": "pointer",
|
|
44
|
+
"m": "move",
|
|
9
45
|
},
|
|
10
46
|
};
|
|
11
47
|
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export const INITIAL_STATE = Object.freeze({
|
|
2
|
-
//
|
|
3
|
-
});
|
|
4
|
-
|
|
5
|
-
export const toViewData = ({ state, props }) => {
|
|
6
|
-
return {
|
|
7
|
-
isOpen: props.isOpen,
|
|
8
|
-
w: props.w || 600,
|
|
9
|
-
position: {
|
|
10
|
-
x: 0,
|
|
11
|
-
y: 0
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const selectState = ({ state }) => {
|
|
17
|
-
return state;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const setState = (state) => {
|
|
21
|
-
// do doSomething
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
elementName: rtgl-dialog
|
|
2
|
-
|
|
3
|
-
viewDataSchema:
|
|
4
|
-
type: object
|
|
5
|
-
|
|
6
|
-
propsSchema:
|
|
7
|
-
type: object
|
|
8
|
-
properties:
|
|
9
|
-
isOpen:
|
|
10
|
-
type: boolean
|
|
11
|
-
w:
|
|
12
|
-
type: string
|
|
13
|
-
|
|
14
|
-
refs:
|
|
15
|
-
dialog-overlay:
|
|
16
|
-
eventListeners:
|
|
17
|
-
click:
|
|
18
|
-
handler: handleClickDialogueOverlay
|
|
19
|
-
|
|
20
|
-
events:
|
|
21
|
-
close-dialogue:
|
|
22
|
-
type: object
|
|
23
|
-
properties: {}
|
|
24
|
-
|
|
25
|
-
styles:
|
|
26
|
-
# '@keyframes dialog-in':
|
|
27
|
-
# from:
|
|
28
|
-
# opacity: 0
|
|
29
|
-
# transform: scale(0.95)
|
|
30
|
-
# to:
|
|
31
|
-
# opacity: 1
|
|
32
|
-
# transform: scale(1)
|
|
33
|
-
|
|
34
|
-
# '#dialog-container':
|
|
35
|
-
# animation: dialog-in 150ms cubic-bezier(0.16, 1, 0.3, 1)
|
|
36
|
-
# transform-origin: top
|
|
37
|
-
|
|
38
|
-
template:
|
|
39
|
-
- $if isOpen:
|
|
40
|
-
- rtgl-view pos=fix cor=full ah=c:
|
|
41
|
-
- 'rtgl-view#dialog-overlay pos=fix cor=full ah=c av=c bgc=bg op=0.5':
|
|
42
|
-
- rtgl-view h=10vh:
|
|
43
|
-
- rtgl-view#dialog-container z=100 bw=xs p=lg bgc=bg w=${w} br=sm:
|
|
44
|
-
- slot name=content:
|