@rettangoli/ui 0.1.2-rc8 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rettangoli-iife-layout.min.js +128 -56
- package/dist/rettangoli-iife-ui.min.js +187 -66
- package/package.json +5 -3
- package/src/cli/buildSvg.js +86 -0
- package/src/cli/index.js +1 -0
- package/src/common.js +30 -2
- 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 +6 -6
- package/src/components/dropdownMenu/dropdownMenu.store.js +6 -18
- package/src/components/dropdownMenu/dropdownMenu.view.yaml +15 -13
- package/src/components/form/form.handlers.js +170 -33
- package/src/components/form/form.store.js +175 -21
- package/src/components/form/form.view.yaml +182 -27
- package/src/components/globalUi/globalUi.handlers.js +51 -0
- package/src/components/globalUi/globalUi.store.js +57 -0
- package/src/components/globalUi/globalUi.view.yaml +50 -0
- package/src/components/navbar/navbar.handlers.js +1 -1
- package/src/components/navbar/navbar.store.js +2 -2
- package/src/components/pageOutline/pageOutline.handlers.js +57 -17
- package/src/components/pageOutline/pageOutline.store.js +48 -3
- package/src/components/pageOutline/pageOutline.view.yaml +7 -5
- 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 +120 -12
- package/src/components/select/select.store.js +86 -20
- package/src/components/select/select.view.yaml +40 -10
- package/src/components/sidebar/sidebar.handlers.js +6 -6
- package/src/components/sidebar/sidebar.store.js +6 -6
- package/src/components/sidebar/sidebar.view.yaml +1 -1
- package/src/components/sliderInput/sliderInput.handlers.js +23 -6
- package/src/components/sliderInput/sliderInput.store.js +3 -2
- package/src/components/sliderInput/sliderInput.view.yaml +3 -2
- package/src/components/table/table.handlers.js +10 -10
- package/src/components/table/table.store.js +4 -4
- 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/deps/createGlobalUI.js +39 -0
- package/src/entry-iife-layout.js +3 -0
- package/src/entry-iife-ui.js +4 -0
- package/src/index.js +7 -1
- package/src/primitives/button.js +10 -0
- package/src/primitives/colorPicker.js +13 -4
- package/src/primitives/dialog.js +254 -0
- package/src/primitives/image.js +4 -3
- package/src/primitives/input.js +17 -4
- package/src/primitives/popover.js +280 -0
- package/src/primitives/slider.js +14 -4
- package/src/primitives/svg.js +2 -0
- package/src/primitives/textarea.js +25 -1
- package/src/primitives/view.js +132 -13
- package/src/setup.js +7 -2
- 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 -48
- 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
|
@@ -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
|
@@ -115,8 +115,8 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
115
115
|
"wh",
|
|
116
116
|
"w",
|
|
117
117
|
"h",
|
|
118
|
-
"
|
|
119
|
-
"
|
|
118
|
+
"hide",
|
|
119
|
+
"show",
|
|
120
120
|
"op",
|
|
121
121
|
"z",
|
|
122
122
|
])
|
|
@@ -148,6 +148,16 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
148
148
|
};
|
|
149
149
|
|
|
150
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
|
+
|
|
151
161
|
// Handle input-specific attributes first
|
|
152
162
|
if (["value", "min", "max", "step", "disabled"].includes(name)) {
|
|
153
163
|
this._updateInputAttributes();
|
|
@@ -202,11 +212,11 @@ class RettangoliSliderElement extends HTMLElement {
|
|
|
202
212
|
this._styles[size]["max-height"] = height;
|
|
203
213
|
}
|
|
204
214
|
|
|
205
|
-
if (this.hasAttribute(addSizePrefix("
|
|
215
|
+
if (this.hasAttribute(addSizePrefix("hide"))) {
|
|
206
216
|
this._styles[size].display = "none !important";
|
|
207
217
|
}
|
|
208
218
|
|
|
209
|
-
if (this.hasAttribute(addSizePrefix("
|
|
219
|
+
if (this.hasAttribute(addSizePrefix("show"))) {
|
|
210
220
|
this._styles[size].display = "block !important";
|
|
211
221
|
}
|
|
212
222
|
});
|
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
|
|
package/src/primitives/view.js
CHANGED
|
@@ -89,10 +89,17 @@ class RettangoliViewElement extends HTMLElement {
|
|
|
89
89
|
"wh",
|
|
90
90
|
"w",
|
|
91
91
|
"h",
|
|
92
|
-
"
|
|
92
|
+
"hide",
|
|
93
|
+
"show",
|
|
93
94
|
"sh",
|
|
94
95
|
"sv",
|
|
95
|
-
"z"
|
|
96
|
+
"z",
|
|
97
|
+
"d",
|
|
98
|
+
"ah",
|
|
99
|
+
"av",
|
|
100
|
+
"flex",
|
|
101
|
+
"fw",
|
|
102
|
+
"overflow"
|
|
96
103
|
]),
|
|
97
104
|
];
|
|
98
105
|
}
|
|
@@ -136,14 +143,13 @@ class RettangoliViewElement extends HTMLElement {
|
|
|
136
143
|
this._linkElement = null;
|
|
137
144
|
}
|
|
138
145
|
}
|
|
146
|
+
|
|
147
|
+
connectedCallback() {
|
|
148
|
+
// Force update styles when connected to ensure responsive attributes are processed
|
|
149
|
+
this.updateStyles();
|
|
150
|
+
}
|
|
139
151
|
|
|
140
|
-
|
|
141
|
-
// Handle href and target changes
|
|
142
|
-
if (name === "href" || name === "target") {
|
|
143
|
-
this._updateDOM();
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
152
|
+
updateStyles() {
|
|
147
153
|
// Reset styles for fresh calculation
|
|
148
154
|
this._styles = {
|
|
149
155
|
default: {},
|
|
@@ -158,6 +164,7 @@ class RettangoliViewElement extends HTMLElement {
|
|
|
158
164
|
return `${size === "default" ? "" : `${size}-`}${tag}`;
|
|
159
165
|
};
|
|
160
166
|
|
|
167
|
+
|
|
161
168
|
const wh = this.getAttribute(addSizePrefix("wh"));
|
|
162
169
|
const width = dimensionWithUnit(
|
|
163
170
|
wh === null ? this.getAttribute(addSizePrefix("w")) : wh,
|
|
@@ -192,12 +199,110 @@ class RettangoliViewElement extends HTMLElement {
|
|
|
192
199
|
this._styles[size]["max-height"] = height;
|
|
193
200
|
}
|
|
194
201
|
|
|
195
|
-
if (this.hasAttribute(addSizePrefix("
|
|
196
|
-
this._styles[size].display = "none
|
|
202
|
+
if (this.hasAttribute(addSizePrefix("hide"))) {
|
|
203
|
+
this._styles[size].display = "none";
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (this.hasAttribute(addSizePrefix("show"))) {
|
|
207
|
+
this._styles[size].display = "flex";
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Handle flex direction and alignment
|
|
211
|
+
const direction = this.getAttribute(addSizePrefix("d"));
|
|
212
|
+
const alignHorizontal = this.getAttribute(addSizePrefix("ah"));
|
|
213
|
+
const alignVertical = this.getAttribute(addSizePrefix("av"));
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
if (direction === "h") {
|
|
217
|
+
this._styles[size]["flex-direction"] = "row";
|
|
218
|
+
} else if (direction === "v") {
|
|
219
|
+
this._styles[size]["flex-direction"] = "column";
|
|
220
|
+
} else if (size === "default" && !direction) {
|
|
221
|
+
// Check if any responsive direction attributes exist
|
|
222
|
+
const hasResponsiveDirection = ["sm", "md", "lg", "xl"].some(
|
|
223
|
+
breakpoint => this.hasAttribute(`${breakpoint}-d`)
|
|
224
|
+
);
|
|
225
|
+
if (hasResponsiveDirection) {
|
|
226
|
+
// Explicitly set column for default to ensure responsive overrides work
|
|
227
|
+
this._styles[size]["flex-direction"] = "column";
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Handle alignment based on direction
|
|
232
|
+
const isHorizontal = direction === "h";
|
|
233
|
+
const isVerticalOrDefault = direction === "v" || !direction;
|
|
234
|
+
|
|
235
|
+
// For horizontal direction: ah controls justify-content, av controls align-items
|
|
236
|
+
if (isHorizontal) {
|
|
237
|
+
if (alignHorizontal === "c") {
|
|
238
|
+
this._styles[size]["justify-content"] = "center";
|
|
239
|
+
} else if (alignHorizontal === "e") {
|
|
240
|
+
this._styles[size]["justify-content"] = "flex-end";
|
|
241
|
+
} else if (alignHorizontal === "s") {
|
|
242
|
+
this._styles[size]["justify-content"] = "flex-start";
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (alignVertical === "c") {
|
|
246
|
+
this._styles[size]["align-items"] = "center";
|
|
247
|
+
this._styles[size]["align-content"] = "center";
|
|
248
|
+
} else if (alignVertical === "e") {
|
|
249
|
+
this._styles[size]["align-items"] = "flex-end";
|
|
250
|
+
this._styles[size]["align-content"] = "flex-end";
|
|
251
|
+
} else if (alignVertical === "s") {
|
|
252
|
+
this._styles[size]["align-items"] = "flex-start";
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// For vertical/default direction: ah controls align-items, av controls justify-content
|
|
257
|
+
if (isVerticalOrDefault && (alignHorizontal !== null || alignVertical !== null)) {
|
|
258
|
+
if (alignHorizontal === "c") {
|
|
259
|
+
this._styles[size]["align-items"] = "center";
|
|
260
|
+
} else if (alignHorizontal === "e") {
|
|
261
|
+
this._styles[size]["align-items"] = "flex-end";
|
|
262
|
+
} else if (alignHorizontal === "s") {
|
|
263
|
+
this._styles[size]["align-items"] = "flex-start";
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (alignVertical === "c") {
|
|
267
|
+
this._styles[size]["justify-content"] = "center";
|
|
268
|
+
} else if (alignVertical === "e") {
|
|
269
|
+
this._styles[size]["justify-content"] = "flex-end";
|
|
270
|
+
} else if (alignVertical === "s") {
|
|
271
|
+
this._styles[size]["justify-content"] = "flex-start";
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Handle flex property
|
|
276
|
+
const flex = this.getAttribute(addSizePrefix("flex"));
|
|
277
|
+
if (flex !== null) {
|
|
278
|
+
this._styles[size]["flex"] = flex;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Handle flex-wrap
|
|
282
|
+
const flexWrap = this.getAttribute(addSizePrefix("fw"));
|
|
283
|
+
if (flexWrap === "w") {
|
|
284
|
+
this._styles[size]["flex-wrap"] = "wrap";
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Handle scroll properties
|
|
288
|
+
const scrollHorizontal = this.hasAttribute(addSizePrefix("sh"));
|
|
289
|
+
const scrollVertical = this.hasAttribute(addSizePrefix("sv"));
|
|
290
|
+
const overflow = this.getAttribute(addSizePrefix("overflow"));
|
|
291
|
+
|
|
292
|
+
if (scrollHorizontal && scrollVertical) {
|
|
293
|
+
this._styles[size]["overflow"] = "scroll";
|
|
294
|
+
this._styles[size]["flex-wrap"] = "nowrap";
|
|
295
|
+
} else if (scrollHorizontal) {
|
|
296
|
+
this._styles[size]["overflow-x"] = "scroll";
|
|
297
|
+
this._styles[size]["flex-wrap"] = "nowrap";
|
|
298
|
+
} else if (scrollVertical) {
|
|
299
|
+
this._styles[size]["overflow-y"] = "scroll";
|
|
300
|
+
this._styles[size]["flex-wrap"] = "nowrap";
|
|
197
301
|
}
|
|
198
302
|
|
|
199
|
-
if (
|
|
200
|
-
this._styles[size]
|
|
303
|
+
if (overflow === "hidden") {
|
|
304
|
+
this._styles[size]["overflow"] = "hidden";
|
|
305
|
+
this._styles[size]["flex-wrap"] = "nowrap";
|
|
201
306
|
}
|
|
202
307
|
});
|
|
203
308
|
|
|
@@ -207,6 +312,20 @@ class RettangoliViewElement extends HTMLElement {
|
|
|
207
312
|
this._styleElement.textContent = newStyleString;
|
|
208
313
|
this._lastStyleString = newStyleString;
|
|
209
314
|
}
|
|
315
|
+
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
319
|
+
// Handle href and target changes
|
|
320
|
+
if (name === "href" || name === "target") {
|
|
321
|
+
this._updateDOM();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Update styles for all other attributes
|
|
326
|
+
if (oldValue !== newValue) {
|
|
327
|
+
this.updateStyles();
|
|
328
|
+
}
|
|
210
329
|
}
|
|
211
330
|
}
|
|
212
331
|
|
package/src/setup.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { createWebPatch } from '@rettangoli/fe';
|
|
2
|
+
import createGlobalUI from './deps/createGlobalUI';
|
|
2
3
|
import { h } from 'snabbdom/build/h';
|
|
3
4
|
|
|
4
|
-
const
|
|
5
|
+
const globalUI = createGlobalUI();
|
|
6
|
+
|
|
7
|
+
const componentDependencies = {
|
|
8
|
+
globalUI: globalUI
|
|
9
|
+
}
|
|
5
10
|
|
|
6
11
|
const deps = {
|
|
7
12
|
components: componentDependencies,
|
|
@@ -13,4 +18,4 @@ export {
|
|
|
13
18
|
h,
|
|
14
19
|
patch,
|
|
15
20
|
deps,
|
|
16
|
-
}
|
|
21
|
+
}
|
|
@@ -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 = ({ props, attrs }) => {
|
|
6
|
-
return {
|
|
7
|
-
isOpen: props.isOpen,
|
|
8
|
-
w: attrs.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
|
-
|