@rettangoli/ui 0.1.13 → 0.1.15
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 +8 -8
- package/dist/rettangoli-iife-ui.min.js +23 -23
- package/package.json +1 -1
- package/src/components/form/form.handlers.js +74 -33
- package/src/components/form/form.store.js +7 -14
- package/src/components/form/form.view.yaml +11 -23
- package/src/components/popoverInput/popoverInput.handlers.js +9 -9
- package/src/components/popoverInput/popoverInput.store.js +3 -5
- package/src/components/popoverInput/popoverInput.view.yaml +6 -16
- package/src/components/select/select.handlers.js +11 -4
- package/src/components/select/select.store.js +7 -8
- package/src/components/select/select.view.yaml +6 -2
- package/src/components/sliderInput/sliderInput.handlers.js +5 -11
- package/src/components/sliderInput/sliderInput.view.yaml +10 -9
- package/src/primitives/input.js +15 -16
- package/src/primitives/slider.js +6 -4
package/package.json
CHANGED
|
@@ -1,17 +1,79 @@
|
|
|
1
|
+
|
|
2
|
+
const updateAttributes = ({ form, defaultValues = {}, refs }) => {
|
|
3
|
+
const { fields = [] } = form;
|
|
4
|
+
fields.forEach((field) => {
|
|
5
|
+
const ref = refs[`field-${field.name}`]?.elm;
|
|
6
|
+
|
|
7
|
+
if (!ref) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (['inputText', 'colorPicker', 'slider', 'slider-input', 'popover-input'].includes(field.inputType)) {
|
|
12
|
+
const defaultValue = defaultValues[field.name];
|
|
13
|
+
if (defaultValue === undefined || defaultValue === null) {
|
|
14
|
+
ref.removeAttribute('value')
|
|
15
|
+
} else {
|
|
16
|
+
ref.setAttribute('value', defaultValue)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (field.inputType === 'inputText' && field.placeholder) {
|
|
20
|
+
const currentPlaceholder = ref.getAttribute('placeholder')
|
|
21
|
+
if (currentPlaceholder !== field.placeholder) {
|
|
22
|
+
if (field.placeholder === undefined || field.placeholder === null) {
|
|
23
|
+
ref.removeAttribute('placeholder');
|
|
24
|
+
} else {
|
|
25
|
+
ref.setAttribute('placeholder', field.placeholder);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (field.inputType === 'select' && field.placeholder) {
|
|
30
|
+
if (ref.placeholder !== field.placeholder) {
|
|
31
|
+
ref.placeholder = field.placeholder;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (field.inputType === 'select') {
|
|
35
|
+
if (field.placeholder !== ref.getAttribute('placeholder')) {
|
|
36
|
+
if (field.placeholder !== undefined) {
|
|
37
|
+
ref.setAttribute('placeholder', field.placeholder)
|
|
38
|
+
} else {
|
|
39
|
+
ref.removeAttribute('placeholder');
|
|
40
|
+
}
|
|
41
|
+
ref.render();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const defaultValue = defaultValues[field.name]
|
|
45
|
+
if (defaultValue !== ref.selectedValue) {
|
|
46
|
+
ref.selectedValue = defaultValue;
|
|
47
|
+
ref.render();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
1
53
|
export const handleBeforeMount = (deps) => {
|
|
2
54
|
const { store, props } = deps;
|
|
3
55
|
store.setFormValues(props.defaultValues);
|
|
4
56
|
};
|
|
5
57
|
|
|
58
|
+
export const handleAfterMount = (deps) => {
|
|
59
|
+
const { props, getRefIds, render } = deps;
|
|
60
|
+
const { form = {}, defaultValues } = props;
|
|
61
|
+
const refs = getRefIds();
|
|
62
|
+
updateAttributes({ form, defaultValues, refs });
|
|
63
|
+
render();
|
|
64
|
+
};
|
|
65
|
+
|
|
6
66
|
export const handleOnUpdate = (deps, payload) => {
|
|
7
67
|
const { oldAttrs, newAttrs, newProps } = payload;
|
|
8
|
-
const { store, render } = deps;
|
|
9
|
-
|
|
10
|
-
if (oldAttrs?.key
|
|
68
|
+
const { store, render, getRefIds } = deps;
|
|
69
|
+
const { form = {}, defaultValues } = newProps;
|
|
70
|
+
if (oldAttrs?.key !== newAttrs?.key) {
|
|
71
|
+
const refs = getRefIds();
|
|
72
|
+
updateAttributes({ form, defaultValues, refs });
|
|
73
|
+
store.setFormValues(defaultValues);
|
|
74
|
+
render();
|
|
11
75
|
return;
|
|
12
76
|
}
|
|
13
|
-
|
|
14
|
-
store.setFormValues(newProps.defaultValues);
|
|
15
77
|
render();
|
|
16
78
|
};
|
|
17
79
|
|
|
@@ -44,28 +106,7 @@ export const handleActionClick = (deps, payload) => {
|
|
|
44
106
|
export const handleInputChange = (deps, payload) => {
|
|
45
107
|
const { store, dispatchEvent, props } = deps;
|
|
46
108
|
const event = payload._event;
|
|
47
|
-
|
|
48
|
-
// TODO fix double event
|
|
49
|
-
if (name && event.detail.value !== undefined) {
|
|
50
|
-
store.setFormFieldValue({
|
|
51
|
-
name: name,
|
|
52
|
-
value: event.detail.value,
|
|
53
|
-
props,
|
|
54
|
-
});
|
|
55
|
-
dispatchFormChange(
|
|
56
|
-
name,
|
|
57
|
-
event.detail.value,
|
|
58
|
-
store.selectFormValues(),
|
|
59
|
-
dispatchEvent,
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const handlePopoverInputChange = (deps, payload) => {
|
|
65
|
-
const { store, dispatchEvent, props } = deps;
|
|
66
|
-
const event = payload._event;
|
|
67
|
-
const name = event.currentTarget.id.replace("popover-input-", "");
|
|
68
|
-
// TODO fix double event
|
|
109
|
+
let name = event.currentTarget.id.replace("field-", "");
|
|
69
110
|
if (name && event.detail.value !== undefined) {
|
|
70
111
|
store.setFormFieldValue({
|
|
71
112
|
name: name,
|
|
@@ -84,7 +125,7 @@ export const handlePopoverInputChange = (deps, payload) => {
|
|
|
84
125
|
export const handleSelectChange = (deps, payload) => {
|
|
85
126
|
const { store, dispatchEvent, render, props } = deps;
|
|
86
127
|
const event = payload._event;
|
|
87
|
-
const name = event.currentTarget.id.replace("
|
|
128
|
+
const name = event.currentTarget.id.replace("field-", "");
|
|
88
129
|
if (name) {
|
|
89
130
|
store.setFormFieldValue({
|
|
90
131
|
name: name,
|
|
@@ -104,7 +145,7 @@ export const handleSelectChange = (deps, payload) => {
|
|
|
104
145
|
export const handleColorPickerChange = (deps, payload) => {
|
|
105
146
|
const { store, dispatchEvent, props } = deps;
|
|
106
147
|
const event = payload._event;
|
|
107
|
-
const name = event.currentTarget.id.replace("
|
|
148
|
+
const name = event.currentTarget.id.replace("field-", "");
|
|
108
149
|
if (name && event.detail.value !== undefined) {
|
|
109
150
|
store.setFormFieldValue({
|
|
110
151
|
name: name,
|
|
@@ -123,7 +164,7 @@ export const handleColorPickerChange = (deps, payload) => {
|
|
|
123
164
|
export const handleSliderChange = (deps, payload) => {
|
|
124
165
|
const { store, dispatchEvent, props } = deps;
|
|
125
166
|
const event = payload._event;
|
|
126
|
-
const name = event.currentTarget.id.replace("
|
|
167
|
+
const name = event.currentTarget.id.replace("field-", "");
|
|
127
168
|
if (name && event.detail.value !== undefined) {
|
|
128
169
|
store.setFormFieldValue({
|
|
129
170
|
name: name,
|
|
@@ -142,7 +183,7 @@ export const handleSliderChange = (deps, payload) => {
|
|
|
142
183
|
export const handleSliderInputChange = (deps, payload) => {
|
|
143
184
|
const { store, dispatchEvent, props } = deps;
|
|
144
185
|
const event = payload._event;
|
|
145
|
-
const name = event.currentTarget.id.replace("
|
|
186
|
+
const name = event.currentTarget.id.replace("field-", "");
|
|
146
187
|
if (name && event.detail.value !== undefined) {
|
|
147
188
|
store.setFormFieldValue({
|
|
148
189
|
name: name,
|
|
@@ -199,7 +240,7 @@ export const handleWaveformClick = (deps, payload) => {
|
|
|
199
240
|
export const handleSelectAddOption = (deps, payload) => {
|
|
200
241
|
const { store, dispatchEvent } = deps;
|
|
201
242
|
const event = payload._event;
|
|
202
|
-
const name = event.currentTarget.id.replace("
|
|
243
|
+
const name = event.currentTarget.id.replace("field-", "");
|
|
203
244
|
dispatchEvent(
|
|
204
245
|
new CustomEvent("action-click", {
|
|
205
246
|
detail: {
|
|
@@ -231,7 +272,7 @@ export const handleTooltipMouseEnter = (deps, payload) => {
|
|
|
231
272
|
}
|
|
232
273
|
};
|
|
233
274
|
|
|
234
|
-
export const handleTooltipMouseLeave = (deps
|
|
275
|
+
export const handleTooltipMouseLeave = (deps) => {
|
|
235
276
|
const { store, render } = deps;
|
|
236
277
|
store.hideTooltip();
|
|
237
278
|
render();
|
|
@@ -11,7 +11,7 @@ const encode = (input) => {
|
|
|
11
11
|
};
|
|
12
12
|
return text.replace(/[&<>"']/g, char => map[char]);
|
|
13
13
|
}
|
|
14
|
-
if (input === undefined || input === null) {
|
|
14
|
+
if (input === undefined || input === null || input === "") {
|
|
15
15
|
return ""
|
|
16
16
|
}
|
|
17
17
|
return `"${escapeHtml(String(input))}"`;
|
|
@@ -89,12 +89,13 @@ const stringifyAttrs = (attrs) => {
|
|
|
89
89
|
.join(" ");
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
-
export const selectForm = ({
|
|
93
|
-
const { form } = props;
|
|
92
|
+
export const selectForm = ({ props }) => {
|
|
93
|
+
const { form = {} } = props;
|
|
94
94
|
const { context } = props;
|
|
95
95
|
|
|
96
96
|
if (context) {
|
|
97
|
-
|
|
97
|
+
const result = parseAndRender(form, context);
|
|
98
|
+
return result
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
return form;
|
|
@@ -103,23 +104,15 @@ export const selectForm = ({ state, props }) => {
|
|
|
103
104
|
|
|
104
105
|
export const selectViewData = ({ state, props, attrs }) => {
|
|
105
106
|
const containerAttrString = stringifyAttrs(attrs);
|
|
106
|
-
const defaultValues = state.formValues;
|
|
107
107
|
|
|
108
108
|
const form = selectForm({ state, props });
|
|
109
109
|
const fields = structuredClone(form.fields || []);
|
|
110
110
|
fields.forEach((field) => {
|
|
111
111
|
// Use formValues from state if available, otherwise fall back to defaultValues from props
|
|
112
|
-
const defaultValue = get(state.formValues, field.name)
|
|
113
|
-
if (["
|
|
112
|
+
const defaultValue = get(state.formValues, field.name)
|
|
113
|
+
if (["read-only-text"].includes(field.inputType)) {
|
|
114
114
|
field.defaultValue = defaultValue
|
|
115
|
-
} else {
|
|
116
|
-
field.defaultValue = encode(defaultValue);
|
|
117
115
|
}
|
|
118
|
-
|
|
119
|
-
if (["inputText"].includes(field.inputType)) {
|
|
120
|
-
field.placeholder = encode(field.placeholder)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
116
|
if (field.inputType === "image") {
|
|
124
117
|
const src = field.src;
|
|
125
118
|
// Only set imageSrc if src exists and is not empty
|
|
@@ -268,26 +268,18 @@ refs:
|
|
|
268
268
|
handler: handleTooltipMouseEnter
|
|
269
269
|
mouseleave:
|
|
270
270
|
handler: handleTooltipMouseLeave
|
|
271
|
-
|
|
271
|
+
field-*:
|
|
272
272
|
eventListeners:
|
|
273
273
|
input-change:
|
|
274
274
|
handler: handleInputChange
|
|
275
|
-
select-*:
|
|
276
|
-
eventListeners:
|
|
277
275
|
select-change:
|
|
278
276
|
handler: handleSelectChange
|
|
279
277
|
add-option-selected:
|
|
280
278
|
handler: handleSelectAddOption
|
|
281
|
-
colorpicker-*:
|
|
282
|
-
eventListeners:
|
|
283
279
|
colorpicker-change:
|
|
284
280
|
handler: handleColorPickerChange
|
|
285
|
-
slider-*:
|
|
286
|
-
eventListeners:
|
|
287
281
|
slider-change:
|
|
288
282
|
handler: handleSliderChange
|
|
289
|
-
slider-input-*:
|
|
290
|
-
eventListeners:
|
|
291
283
|
slider-input-value-change:
|
|
292
284
|
handler: handleSliderInputChange
|
|
293
285
|
image-*:
|
|
@@ -302,10 +294,6 @@ refs:
|
|
|
302
294
|
handler: handleWaveformClick
|
|
303
295
|
contextmenu:
|
|
304
296
|
handler: handleWaveformClick
|
|
305
|
-
popover-input-*:
|
|
306
|
-
eventListeners:
|
|
307
|
-
input-change:
|
|
308
|
-
handler: handlePopoverInputChange
|
|
309
297
|
|
|
310
298
|
events:
|
|
311
299
|
form-change: {}
|
|
@@ -329,29 +317,29 @@ template:
|
|
|
329
317
|
- $if field.inputType == "read-only-text":
|
|
330
318
|
- rtgl-text s=sm: ${field.defaultValue}
|
|
331
319
|
- $if field.inputType == "inputText":
|
|
332
|
-
- rtgl-input#
|
|
320
|
+
- rtgl-input#field-${field.name} w=f:
|
|
333
321
|
- $if field.inputType == "popover-input":
|
|
334
|
-
- rtgl-popover-input#
|
|
322
|
+
- rtgl-popover-input#field-${field.name} label="${field.label}":
|
|
335
323
|
- $if field.inputType == "select":
|
|
336
|
-
- rtgl-select#
|
|
324
|
+
- rtgl-select#field-${field.name} key=${key} w=f .options=fields[${i}].options ?no-clear=fields[${i}].noClear .addOption=fields[${i}].addOption:
|
|
337
325
|
- $if field.inputType == "colorPicker":
|
|
338
|
-
- rtgl-color-picker#
|
|
326
|
+
- rtgl-color-picker#field-${field.name} key=${key}:
|
|
339
327
|
- $if field.inputType == "slider":
|
|
340
|
-
- rtgl-slider#
|
|
328
|
+
- rtgl-slider#field-${field.name} key=${key} w=f min=${field.min} max=${field.max} step=${field.step}:
|
|
341
329
|
- $if field.inputType == "slider-input":
|
|
342
|
-
- rtgl-slider-input#
|
|
330
|
+
- rtgl-slider-input#field-${field.name} w=f min=${field.min} max=${field.max} step=${field.step}:
|
|
343
331
|
- $if field.inputType == "image" && field.imageSrc:
|
|
344
332
|
- rtgl-image#image-${field.name} src=${field.imageSrc} w=${field.width} h=${field.height} cur=p:
|
|
345
333
|
- $if field.inputType == "image" && !field.imageSrc:
|
|
346
|
-
- rtgl-view#
|
|
334
|
+
- rtgl-view#field-${field.name} w=${field.width} h=${field.height} bc=ac bw=sm ah=c av=c cur=p p=md:
|
|
347
335
|
- rtgl-text c=mu-fg ta=c: ${field.placeholderText}
|
|
348
336
|
- $if field.inputType == "waveform" && field.waveformData:
|
|
349
|
-
- rtgl-waveform#
|
|
337
|
+
- rtgl-waveform#field-${field.name} .waveformData=fields[${i}].waveformData w=${field.width} h=${field.height} cur=p:
|
|
350
338
|
- $if field.inputType == "waveform" && !field.waveformData:
|
|
351
|
-
- rtgl-view#
|
|
339
|
+
- rtgl-view#field-${field.name} w=${field.width} h=${field.height} bc=ac bw=sm ah=c av=c cur=p p=md:
|
|
352
340
|
- rtgl-text c=mu-fg ta=c: ${field.placeholder}
|
|
353
341
|
- $if field.inputType == "slot":
|
|
354
|
-
- 'slot#
|
|
342
|
+
- 'slot#field-${field.slotName} name=${field.slot} style="display: contents;"':
|
|
355
343
|
- rtgl-view g=sm w=f:
|
|
356
344
|
- rtgl-view d=h ah=e g=sm w=f:
|
|
357
345
|
- $for button, i in actions.buttons:
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
export const handleBeforeMount = (deps) => {
|
|
2
|
-
const { store,
|
|
2
|
+
const { store, attrs } = deps;
|
|
3
3
|
|
|
4
|
-
if (
|
|
5
|
-
store.setValue(
|
|
4
|
+
if (attrs.value !== undefined) {
|
|
5
|
+
store.setValue(attrs.value || '');
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export const handleOnUpdate = (deps, payload) => {
|
|
10
|
-
const {
|
|
11
|
-
const { store,
|
|
10
|
+
const { oldAttrs, newAttrs } = payload;
|
|
11
|
+
const { store, render } = deps;
|
|
12
12
|
|
|
13
|
-
if (
|
|
14
|
-
|
|
13
|
+
if (oldAttrs?.value !== newAttrs?.value) {
|
|
14
|
+
const value = newAttrs?.value ?? '';
|
|
15
|
+
store.setValue(value);
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
render();
|
|
@@ -63,9 +64,8 @@ export const handleInputChange = (deps, payload) => {
|
|
|
63
64
|
render();
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
export const handleSubmitClick = (deps
|
|
67
|
+
export const handleSubmitClick = (deps) => {
|
|
67
68
|
const { store, render, dispatchEvent, getRefIds } = deps;
|
|
68
|
-
const event = payload._event;
|
|
69
69
|
const { input } = getRefIds()
|
|
70
70
|
const value = input.elm.value;
|
|
71
71
|
|
|
@@ -8,16 +8,15 @@ export const createInitialState = () => Object.freeze({
|
|
|
8
8
|
tempValue: '',
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
export const selectViewData = ({ attrs, state
|
|
12
|
-
// Use state's current value if it has been modified, otherwise use props
|
|
11
|
+
export const selectViewData = ({ attrs, state }) => {
|
|
13
12
|
const value = state.value || '-';
|
|
14
13
|
|
|
15
14
|
return {
|
|
16
15
|
isOpen: state.isOpen,
|
|
17
16
|
position: state.position,
|
|
18
|
-
value: value
|
|
17
|
+
value: value,
|
|
19
18
|
tempValue: state.tempValue,
|
|
20
|
-
placeholder:
|
|
19
|
+
placeholder: attrs.placeholder ?? '',
|
|
21
20
|
label: attrs.label,
|
|
22
21
|
};
|
|
23
22
|
}
|
|
@@ -30,7 +29,6 @@ export const openPopover = (state, payload) => {
|
|
|
30
29
|
const { position } = payload;
|
|
31
30
|
state.position = position;
|
|
32
31
|
state.isOpen = true;
|
|
33
|
-
// Reset the current value to match the display value when opening
|
|
34
32
|
state.hasUnsavedChanges = false;
|
|
35
33
|
}
|
|
36
34
|
|
|
@@ -4,22 +4,12 @@ viewDataSchema:
|
|
|
4
4
|
type: object
|
|
5
5
|
|
|
6
6
|
attrsSchema:
|
|
7
|
-
type: object
|
|
8
|
-
properties:
|
|
9
|
-
auto-focus:
|
|
10
|
-
type: boolean
|
|
11
|
-
|
|
12
|
-
propsSchema:
|
|
13
7
|
type: object
|
|
14
8
|
properties:
|
|
15
9
|
value:
|
|
16
10
|
type: string
|
|
17
|
-
defaultValue:
|
|
18
|
-
type: string
|
|
19
11
|
placeholder:
|
|
20
12
|
type: string
|
|
21
|
-
onChange:
|
|
22
|
-
type: function
|
|
23
13
|
|
|
24
14
|
refs:
|
|
25
15
|
text-display:
|
|
@@ -46,10 +36,10 @@ events:
|
|
|
46
36
|
|
|
47
37
|
template:
|
|
48
38
|
- rtgl-view#text-display w=f cur=p:
|
|
49
|
-
|
|
39
|
+
- rtgl-text: ${value}
|
|
50
40
|
- rtgl-popover#popover ?open=${isOpen} x=${position.x} y=${position.y}:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
- rtgl-view g=md w=240 slot=content bgc=background br=md:
|
|
42
|
+
- rtgl-text: ${label}
|
|
43
|
+
- rtgl-input#input w=f placeholder=${placeholder}:
|
|
44
|
+
- rtgl-view w=f ah=e:
|
|
45
|
+
- rtgl-button#submit: Submit
|
|
@@ -6,7 +6,9 @@ export const handleBeforeMount = (deps) => {
|
|
|
6
6
|
if (props.selectedValue !== null && props.selectedValue !== undefined && props.options) {
|
|
7
7
|
const selectedOption = props.options.find(opt => deepEqual(opt.value, props.selectedValue));
|
|
8
8
|
if (selectedOption) {
|
|
9
|
-
store.
|
|
9
|
+
store.updateSelectedValue({
|
|
10
|
+
value: selectedOption?.value
|
|
11
|
+
});
|
|
10
12
|
render();
|
|
11
13
|
}
|
|
12
14
|
}
|
|
@@ -28,10 +30,15 @@ export const handleOnUpdate = (deps, payload) => {
|
|
|
28
30
|
if (selectedValue !== null && selectedValue !== undefined && options) {
|
|
29
31
|
const selectedOption = options.find(opt => deepEqual(opt.value, selectedValue));
|
|
30
32
|
if (selectedOption) {
|
|
31
|
-
store.
|
|
33
|
+
store.updateSelectedValue({
|
|
34
|
+
value: selectedOption.value
|
|
35
|
+
});
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
render();
|
|
39
|
+
} else if (oldProps.selectedValue !== newProps.selectedValue) {
|
|
40
|
+
store.updateSelectedValue(newProps.selectedValue);
|
|
41
|
+
render();
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
44
|
|
|
@@ -65,7 +72,7 @@ export const handleButtonClick = (deps, payload) => {
|
|
|
65
72
|
render();
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
export const handleClickOptionsPopoverOverlay = (deps
|
|
75
|
+
export const handleClickOptionsPopoverOverlay = (deps) => {
|
|
69
76
|
const { store, render } = deps;
|
|
70
77
|
store.closeOptionsPopover();
|
|
71
78
|
render();
|
|
@@ -80,7 +87,7 @@ export const handleOptionClick = (deps, payload) => {
|
|
|
80
87
|
const option = props.options[id];
|
|
81
88
|
|
|
82
89
|
// Update internal state
|
|
83
|
-
store.
|
|
90
|
+
store.updateSelectedValue({ value: option?.value });
|
|
84
91
|
|
|
85
92
|
// Call onChange if provided
|
|
86
93
|
if (props.onChange && typeof props.onChange === 'function') {
|
|
@@ -3,13 +3,13 @@ import { deepEqual } from '../../common.js';
|
|
|
3
3
|
// Attributes that should not be passed through to the container
|
|
4
4
|
// These are either handled internally or have special meaning
|
|
5
5
|
const blacklistedAttrs = [
|
|
6
|
-
"id",
|
|
7
|
-
"class",
|
|
8
|
-
"style",
|
|
6
|
+
"id",
|
|
7
|
+
"class",
|
|
8
|
+
"style",
|
|
9
9
|
"slot",
|
|
10
10
|
// Select-specific props that are handled separately
|
|
11
11
|
"placeholder",
|
|
12
|
-
"selectedValue",
|
|
12
|
+
"selectedValue",
|
|
13
13
|
"selected-value",
|
|
14
14
|
"onChange",
|
|
15
15
|
"on-change",
|
|
@@ -42,7 +42,7 @@ export const selectViewData = ({ state, props, attrs }) => {
|
|
|
42
42
|
const currentValue = state.selectedValue !== null ? state.selectedValue : props.selectedValue;
|
|
43
43
|
|
|
44
44
|
// Calculate display label from value
|
|
45
|
-
let displayLabel =
|
|
45
|
+
let displayLabel = attrs.placeholder || 'Select an option';
|
|
46
46
|
let isPlaceholderLabel = true;
|
|
47
47
|
if (currentValue !== null && currentValue !== undefined && props.options) {
|
|
48
48
|
const selectedOption = props.options.find(opt => deepEqual(opt.value, currentValue));
|
|
@@ -71,7 +71,6 @@ export const selectViewData = ({ state, props, attrs }) => {
|
|
|
71
71
|
selectedValue: currentValue,
|
|
72
72
|
selectedLabel: displayLabel,
|
|
73
73
|
selectedLabelColor: isPlaceholderLabel ? "mu-fg" : "fg",
|
|
74
|
-
placeholder: props.placeholder || 'Select an option',
|
|
75
74
|
hasValue: currentValue !== null && currentValue !== undefined,
|
|
76
75
|
showClear: !attrs['no-clear'] && !props['no-clear'] && (currentValue !== null && currentValue !== undefined),
|
|
77
76
|
showAddOption: !!props.addOption,
|
|
@@ -102,8 +101,8 @@ export const closeOptionsPopover = (state) => {
|
|
|
102
101
|
state.isOpen = false;
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
export const
|
|
106
|
-
state.selectedValue =
|
|
104
|
+
export const updateSelectedValue = (state, payload) => {
|
|
105
|
+
state.selectedValue = payload.value;
|
|
107
106
|
state.isOpen = false;
|
|
108
107
|
}
|
|
109
108
|
|
|
@@ -3,6 +3,12 @@ elementName: rtgl-select
|
|
|
3
3
|
viewDataSchema:
|
|
4
4
|
type: object
|
|
5
5
|
|
|
6
|
+
attrsSchema:
|
|
7
|
+
type: object
|
|
8
|
+
properties:
|
|
9
|
+
placeholder:
|
|
10
|
+
type: string
|
|
11
|
+
|
|
6
12
|
propsSchema:
|
|
7
13
|
type: object
|
|
8
14
|
properties:
|
|
@@ -17,8 +23,6 @@ propsSchema:
|
|
|
17
23
|
type: any
|
|
18
24
|
selectedValue:
|
|
19
25
|
type: any
|
|
20
|
-
placeholder:
|
|
21
|
-
type: string
|
|
22
26
|
onChange:
|
|
23
27
|
type: function
|
|
24
28
|
no-clear:
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
export const handleBeforeMount = (deps) => {
|
|
2
2
|
const { store, attrs } = deps;
|
|
3
|
-
store.setValue(attrs.
|
|
3
|
+
store.setValue(attrs.value ?? 0);
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export const handleOnUpdate = (deps, payload) => {
|
|
7
7
|
const { oldAttrs, newAttrs } = payload;
|
|
8
|
-
const { store, render
|
|
8
|
+
const { store, render } = deps;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
store.setValue(defaultValue);
|
|
14
|
-
render();
|
|
15
|
-
} else if (oldAttrs?.defaultValue !== newAttrs?.defaultValue) {
|
|
16
|
-
// Also reset when defaultValue changes
|
|
17
|
-
const defaultValue = newAttrs?.defaultValue || 0;
|
|
18
|
-
store.setValue(defaultValue);
|
|
10
|
+
if (oldAttrs?.value !== newAttrs?.value) {
|
|
11
|
+
const value = newAttrs?.value ?? 0;
|
|
12
|
+
store.setValue(value);
|
|
19
13
|
render();
|
|
20
14
|
}
|
|
21
15
|
}
|
|
@@ -6,21 +6,21 @@ viewDataSchema:
|
|
|
6
6
|
attrsSchema:
|
|
7
7
|
type: object
|
|
8
8
|
properties:
|
|
9
|
-
|
|
9
|
+
value:
|
|
10
10
|
type: string
|
|
11
|
-
default:
|
|
11
|
+
default: "0"
|
|
12
12
|
w:
|
|
13
13
|
type: string
|
|
14
|
-
default:
|
|
14
|
+
default: ""
|
|
15
15
|
min:
|
|
16
16
|
type: string
|
|
17
|
-
default:
|
|
17
|
+
default: "0"
|
|
18
18
|
max:
|
|
19
19
|
type: string
|
|
20
|
-
default:
|
|
20
|
+
default: "100"
|
|
21
21
|
step:
|
|
22
22
|
type: string
|
|
23
|
-
default:
|
|
23
|
+
default: "1"
|
|
24
24
|
|
|
25
25
|
refs:
|
|
26
26
|
input:
|
|
@@ -37,6 +37,7 @@ events:
|
|
|
37
37
|
|
|
38
38
|
template:
|
|
39
39
|
- rtgl-view d=h av=c g=md w=${w}:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
- rtgl-slider#slider key=${key} w=f type=range min=${min} max=${max} step=${step} value=${value}:
|
|
41
|
+
- rtgl-view w=84:
|
|
42
|
+
- rtgl-input#input key=${key} w=f type=number min=${min} max=${max} step=${step} value=${value}:
|
|
43
|
+
|
package/src/primitives/input.js
CHANGED
|
@@ -123,17 +123,26 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
123
123
|
};
|
|
124
124
|
|
|
125
125
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
126
|
-
|
|
127
|
-
if (name === "key" && oldValue !== newValue) {
|
|
126
|
+
if (name === 'value') {
|
|
128
127
|
requestAnimationFrame((() => {
|
|
129
128
|
const value = this.getAttribute("value");
|
|
130
129
|
this._inputElement.value = value ?? "";
|
|
131
130
|
}))
|
|
132
|
-
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (name === 'placeholder') {
|
|
134
|
+
requestAnimationFrame((() => {
|
|
135
|
+
const placeholder = this.getAttribute("placeholder");
|
|
136
|
+
if (placeholder === undefined || placeholder === 'null') {
|
|
137
|
+
this._inputElement.removeAttribute('placeholder');
|
|
138
|
+
} else {
|
|
139
|
+
this._inputElement.setAttribute('placeholder', placeholder ?? "");
|
|
140
|
+
}
|
|
141
|
+
}))
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
// Handle input-specific attributes first
|
|
136
|
-
if (["type", "
|
|
145
|
+
if (["type", "disabled", "step", "s"].includes(name)) {
|
|
137
146
|
this._updateInputAttributes();
|
|
138
147
|
return;
|
|
139
148
|
}
|
|
@@ -205,23 +214,13 @@ class RettangoliInputElement extends HTMLElement {
|
|
|
205
214
|
|
|
206
215
|
_updateInputAttributes() {
|
|
207
216
|
const type = this.getAttribute("type") || "text";
|
|
208
|
-
const placeholder = this.getAttribute("placeholder");
|
|
209
|
-
const value = this.getAttribute("value");
|
|
217
|
+
// const placeholder = this.getAttribute("placeholder");
|
|
218
|
+
// const value = this.getAttribute("value");
|
|
210
219
|
const step = this.getAttribute("step");
|
|
211
220
|
const isDisabled = this.hasAttribute('disabled');
|
|
212
221
|
|
|
213
222
|
this._inputElement.setAttribute("type", type);
|
|
214
223
|
|
|
215
|
-
if (placeholder !== null) {
|
|
216
|
-
this._inputElement.setAttribute("placeholder", placeholder);
|
|
217
|
-
} else {
|
|
218
|
-
this._inputElement.removeAttribute("placeholder");
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (value !== null) {
|
|
222
|
-
this._inputElement.value = value;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
224
|
if (step !== null) {
|
|
226
225
|
this._inputElement.setAttribute("step", step);
|
|
227
226
|
} else {
|