@rettangoli/ui 0.1.2-rc9 → 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 +3 -2
- 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
|
@@ -1,45 +1,199 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { parseAndRender } from "jempl";
|
|
2
|
+
|
|
3
|
+
const encode = (input) => {
|
|
4
|
+
function escapeHtml(text) {
|
|
5
|
+
const map = {
|
|
6
|
+
'&': '&',
|
|
7
|
+
'<': '<',
|
|
8
|
+
'>': '>',
|
|
9
|
+
'"': '"',
|
|
10
|
+
"'": '''
|
|
11
|
+
};
|
|
12
|
+
return text.replace(/[&<>"']/g, char => map[char]);
|
|
13
|
+
}
|
|
14
|
+
if (input === undefined || input === null) {
|
|
15
|
+
return ""
|
|
16
|
+
}
|
|
17
|
+
return `"${escapeHtml(String(input))}"`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function pick(obj, keys) {
|
|
21
|
+
return keys.reduce((acc, key) => {
|
|
22
|
+
if (key in obj) acc[key] = obj[key];
|
|
23
|
+
return acc;
|
|
24
|
+
}, {});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const createInitialState = () => Object.freeze({
|
|
28
|
+
formValues: {},
|
|
29
|
+
tooltipState: {
|
|
30
|
+
open: false,
|
|
31
|
+
x: 0,
|
|
32
|
+
y: 0,
|
|
33
|
+
content: ''
|
|
34
|
+
},
|
|
3
35
|
});
|
|
4
36
|
|
|
5
|
-
|
|
37
|
+
// Lodash-like utility functions for nested property access
|
|
38
|
+
const get = (obj, path, defaultValue = undefined) => {
|
|
39
|
+
if (!path) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const keys = path.split(/[\[\].]/).filter((key) => key !== "");
|
|
43
|
+
let current = obj;
|
|
44
|
+
|
|
45
|
+
for (const key of keys) {
|
|
46
|
+
if (current === null || current === undefined || !(key in current)) {
|
|
47
|
+
return defaultValue;
|
|
48
|
+
}
|
|
49
|
+
current = current[key];
|
|
50
|
+
}
|
|
51
|
+
return current;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const set = (obj, path, value) => {
|
|
55
|
+
const keys = path.split(/[\[\].]/).filter((key) => key !== "");
|
|
56
|
+
|
|
57
|
+
// If path contains array notation, delete the original flat key
|
|
58
|
+
if (path.includes("[") && path in obj) {
|
|
59
|
+
delete obj[path];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let current = obj;
|
|
63
|
+
|
|
64
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
65
|
+
const key = keys[i];
|
|
66
|
+
if (
|
|
67
|
+
!(key in current) ||
|
|
68
|
+
typeof current[key] !== "object" ||
|
|
69
|
+
current[key] === null
|
|
70
|
+
) {
|
|
71
|
+
// Check if next key is a number to create array
|
|
72
|
+
const nextKey = keys[i + 1];
|
|
73
|
+
const isArrayIndex = /^\d+$/.test(nextKey);
|
|
74
|
+
current[key] = isArrayIndex ? [] : {};
|
|
75
|
+
}
|
|
76
|
+
current = current[key];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
current[keys[keys.length - 1]] = value;
|
|
80
|
+
return obj;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const blacklistedAttrs = ["id", "class", "style", "slot"];
|
|
6
84
|
|
|
7
85
|
const stringifyAttrs = (attrs) => {
|
|
8
|
-
return Object.entries(attrs)
|
|
9
|
-
|
|
86
|
+
return Object.entries(attrs)
|
|
87
|
+
.filter(([key]) => !blacklistedAttrs.includes(key))
|
|
88
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
89
|
+
.join(" ");
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const selectForm = ({ state, props }) => {
|
|
93
|
+
const { form } = props;
|
|
94
|
+
const { context } = props;
|
|
95
|
+
|
|
96
|
+
if (context) {
|
|
97
|
+
return parseAndRender(form, context);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return form;
|
|
101
|
+
};
|
|
10
102
|
|
|
11
|
-
|
|
103
|
+
|
|
104
|
+
export const selectViewData = ({ state, props, attrs }) => {
|
|
12
105
|
const containerAttrString = stringifyAttrs(attrs);
|
|
13
|
-
const fields = structuredClone(props.form.fields || []);
|
|
14
106
|
const defaultValues = props.defaultValues || {};
|
|
107
|
+
|
|
108
|
+
const form = selectForm({ state, props });
|
|
109
|
+
const fields = structuredClone(form.fields || []);
|
|
15
110
|
fields.forEach((field) => {
|
|
16
|
-
|
|
17
|
-
|
|
111
|
+
// Use formValues from state if available, otherwise fall back to defaultValues from props
|
|
112
|
+
const defaultValue = get(state.formValues, field.name) ?? get(defaultValues, field.name)
|
|
113
|
+
if (["popover-input", "select", "read-only-text"].includes(field.inputType)) {
|
|
114
|
+
field.defaultValue = defaultValue
|
|
115
|
+
} else {
|
|
116
|
+
field.defaultValue = encode(defaultValue);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (["inputText"].includes(field.inputType)) {
|
|
120
|
+
field.placeholder = encode(field.placeholder)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (field.inputType === "image") {
|
|
124
|
+
const src = field.src;
|
|
125
|
+
// Only set imageSrc if src exists and is not empty
|
|
126
|
+
field.imageSrc = src && src.trim() ? src : null;
|
|
127
|
+
// Set placeholder text
|
|
128
|
+
field.placeholderText = field.placeholder || "No Image";
|
|
129
|
+
}
|
|
130
|
+
if (field.inputType === "waveform") {
|
|
131
|
+
const waveformData = field.waveformData;
|
|
132
|
+
// Only set waveformData if it exists
|
|
133
|
+
field.waveformData = waveformData || null;
|
|
134
|
+
// Set placeholder text
|
|
135
|
+
field.placeholderText = field.placeholder || "No Waveform";
|
|
136
|
+
}
|
|
137
|
+
});
|
|
18
138
|
|
|
19
139
|
return {
|
|
140
|
+
key: attrs?.key,
|
|
20
141
|
containerAttrString,
|
|
21
|
-
title:
|
|
22
|
-
description:
|
|
142
|
+
title: form?.title || "",
|
|
143
|
+
description: form?.description || "",
|
|
23
144
|
fields: fields,
|
|
24
145
|
actions: props?.form?.actions || {
|
|
25
|
-
buttons: []
|
|
146
|
+
buttons: [],
|
|
26
147
|
},
|
|
27
148
|
formValues: state.formValues,
|
|
149
|
+
tooltipState: state.tooltipState,
|
|
28
150
|
};
|
|
29
|
-
}
|
|
151
|
+
};
|
|
30
152
|
|
|
31
153
|
export const selectState = ({ state }) => {
|
|
32
154
|
return state;
|
|
33
|
-
}
|
|
155
|
+
};
|
|
34
156
|
|
|
35
|
-
export const selectFormValues = ({ state }) => {
|
|
36
|
-
|
|
37
|
-
|
|
157
|
+
export const selectFormValues = ({ state, props }) => {
|
|
158
|
+
const form = selectForm({ state, props });
|
|
159
|
+
|
|
160
|
+
return pick(
|
|
161
|
+
state.formValues,
|
|
162
|
+
form.fields.map((field) => field.name),
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const getFormFieldValue = ({ state }, name) => {
|
|
167
|
+
return get(state.formValues, name);
|
|
168
|
+
};
|
|
38
169
|
|
|
39
170
|
export const setFormValues = (state, defaultValues) => {
|
|
40
171
|
state.formValues = defaultValues || {};
|
|
41
|
-
}
|
|
172
|
+
};
|
|
42
173
|
|
|
43
|
-
export const setFormFieldValue = (state, { name, value }) => {
|
|
44
|
-
state.formValues
|
|
45
|
-
|
|
174
|
+
export const setFormFieldValue = (state, { name, value, props }) => {
|
|
175
|
+
set(state.formValues, name, value);
|
|
176
|
+
// remove non visible values
|
|
177
|
+
const form = selectForm({ state, props });
|
|
178
|
+
const formValues = pick(
|
|
179
|
+
state.formValues,
|
|
180
|
+
form.fields.map((field) => field.name),
|
|
181
|
+
);
|
|
182
|
+
state.formValues = formValues;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const showTooltip = (state, { x, y, content }) => {
|
|
186
|
+
state.tooltipState = {
|
|
187
|
+
open: true,
|
|
188
|
+
x: x,
|
|
189
|
+
y: y,
|
|
190
|
+
content: content
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const hideTooltip = (state) => {
|
|
195
|
+
state.tooltipState = {
|
|
196
|
+
...state.tooltipState,
|
|
197
|
+
open: false
|
|
198
|
+
};
|
|
199
|
+
};
|
|
@@ -8,6 +8,8 @@ propsSchema:
|
|
|
8
8
|
properties:
|
|
9
9
|
defaultValues:
|
|
10
10
|
type: object
|
|
11
|
+
context:
|
|
12
|
+
type: object
|
|
11
13
|
form:
|
|
12
14
|
type: object
|
|
13
15
|
properties:
|
|
@@ -31,6 +33,11 @@ propsSchema:
|
|
|
31
33
|
const: inputText
|
|
32
34
|
placeholder:
|
|
33
35
|
type: string
|
|
36
|
+
tooltip:
|
|
37
|
+
type: object
|
|
38
|
+
properties:
|
|
39
|
+
content:
|
|
40
|
+
type: string
|
|
34
41
|
required:
|
|
35
42
|
- name
|
|
36
43
|
- label
|
|
@@ -48,21 +55,30 @@ propsSchema:
|
|
|
48
55
|
const: select
|
|
49
56
|
placeholder:
|
|
50
57
|
type: string
|
|
58
|
+
noClear:
|
|
59
|
+
type: boolean
|
|
60
|
+
addOption:
|
|
61
|
+
type: object
|
|
62
|
+
properties:
|
|
63
|
+
label:
|
|
64
|
+
type: string
|
|
51
65
|
options:
|
|
52
66
|
type: array
|
|
53
67
|
items:
|
|
54
68
|
type: object
|
|
55
69
|
properties:
|
|
56
|
-
id:
|
|
57
|
-
type: string
|
|
58
70
|
label:
|
|
59
71
|
type: string
|
|
60
72
|
value:
|
|
61
73
|
type: any
|
|
62
74
|
required:
|
|
63
|
-
- id
|
|
64
75
|
- label
|
|
65
76
|
- value
|
|
77
|
+
tooltip:
|
|
78
|
+
type: object
|
|
79
|
+
properties:
|
|
80
|
+
content:
|
|
81
|
+
type: string
|
|
66
82
|
required:
|
|
67
83
|
- name
|
|
68
84
|
- label
|
|
@@ -81,6 +97,11 @@ propsSchema:
|
|
|
81
97
|
const: colorPicker
|
|
82
98
|
value:
|
|
83
99
|
type: string
|
|
100
|
+
tooltip:
|
|
101
|
+
type: object
|
|
102
|
+
properties:
|
|
103
|
+
content:
|
|
104
|
+
type: string
|
|
84
105
|
required:
|
|
85
106
|
- name
|
|
86
107
|
- label
|
|
@@ -104,6 +125,11 @@ propsSchema:
|
|
|
104
125
|
type: number
|
|
105
126
|
value:
|
|
106
127
|
type: number
|
|
128
|
+
tooltip:
|
|
129
|
+
type: object
|
|
130
|
+
properties:
|
|
131
|
+
content:
|
|
132
|
+
type: string
|
|
107
133
|
required:
|
|
108
134
|
- name
|
|
109
135
|
- label
|
|
@@ -127,6 +153,89 @@ propsSchema:
|
|
|
127
153
|
type: number
|
|
128
154
|
value:
|
|
129
155
|
type: number
|
|
156
|
+
tooltip:
|
|
157
|
+
type: object
|
|
158
|
+
properties:
|
|
159
|
+
content:
|
|
160
|
+
type: string
|
|
161
|
+
required:
|
|
162
|
+
- name
|
|
163
|
+
- label
|
|
164
|
+
- inputType
|
|
165
|
+
additionalProperties: false
|
|
166
|
+
- type: object
|
|
167
|
+
properties:
|
|
168
|
+
name:
|
|
169
|
+
type: string
|
|
170
|
+
label:
|
|
171
|
+
type: string
|
|
172
|
+
description:
|
|
173
|
+
type: string
|
|
174
|
+
inputType:
|
|
175
|
+
const: image
|
|
176
|
+
width:
|
|
177
|
+
type: number
|
|
178
|
+
height:
|
|
179
|
+
type: number
|
|
180
|
+
placeholder:
|
|
181
|
+
type: string
|
|
182
|
+
tooltip:
|
|
183
|
+
type: object
|
|
184
|
+
properties:
|
|
185
|
+
content:
|
|
186
|
+
type: string
|
|
187
|
+
required:
|
|
188
|
+
- name
|
|
189
|
+
- label
|
|
190
|
+
- inputType
|
|
191
|
+
additionalProperties: false
|
|
192
|
+
- type: object
|
|
193
|
+
properties:
|
|
194
|
+
name:
|
|
195
|
+
type: string
|
|
196
|
+
label:
|
|
197
|
+
type: string
|
|
198
|
+
description:
|
|
199
|
+
type: string
|
|
200
|
+
inputType:
|
|
201
|
+
const: waveform
|
|
202
|
+
width:
|
|
203
|
+
type: number
|
|
204
|
+
height:
|
|
205
|
+
type: number
|
|
206
|
+
placeholder:
|
|
207
|
+
type: string
|
|
208
|
+
defaultValue:
|
|
209
|
+
type: object
|
|
210
|
+
waveformData:
|
|
211
|
+
type: object
|
|
212
|
+
tooltip:
|
|
213
|
+
type: object
|
|
214
|
+
properties:
|
|
215
|
+
content:
|
|
216
|
+
type: string
|
|
217
|
+
required:
|
|
218
|
+
- name
|
|
219
|
+
- label
|
|
220
|
+
- inputType
|
|
221
|
+
additionalProperties: false
|
|
222
|
+
- type: object
|
|
223
|
+
properties:
|
|
224
|
+
name:
|
|
225
|
+
type: string
|
|
226
|
+
label:
|
|
227
|
+
type: string
|
|
228
|
+
description:
|
|
229
|
+
type: string
|
|
230
|
+
inputType:
|
|
231
|
+
const: popover-input
|
|
232
|
+
placeholder:
|
|
233
|
+
type: string
|
|
234
|
+
tooltip:
|
|
235
|
+
type: object
|
|
236
|
+
properties:
|
|
237
|
+
content:
|
|
238
|
+
type: string
|
|
130
239
|
required:
|
|
131
240
|
- name
|
|
132
241
|
- label
|
|
@@ -153,6 +262,12 @@ refs:
|
|
|
153
262
|
eventListeners:
|
|
154
263
|
click:
|
|
155
264
|
handler: handleActionClick
|
|
265
|
+
tooltip-icon-*:
|
|
266
|
+
eventListeners:
|
|
267
|
+
mouseenter:
|
|
268
|
+
handler: handleTooltipMouseEnter
|
|
269
|
+
mouseleave:
|
|
270
|
+
handler: handleTooltipMouseLeave
|
|
156
271
|
input-*:
|
|
157
272
|
eventListeners:
|
|
158
273
|
input-change:
|
|
@@ -161,6 +276,8 @@ refs:
|
|
|
161
276
|
eventListeners:
|
|
162
277
|
select-change:
|
|
163
278
|
handler: handleSelectChange
|
|
279
|
+
add-option-selected:
|
|
280
|
+
handler: handleSelectAddOption
|
|
164
281
|
colorpicker-*:
|
|
165
282
|
eventListeners:
|
|
166
283
|
colorpicker-change:
|
|
@@ -173,32 +290,70 @@ refs:
|
|
|
173
290
|
eventListeners:
|
|
174
291
|
slider-input-value-change:
|
|
175
292
|
handler: handleSliderInputChange
|
|
293
|
+
image-*:
|
|
294
|
+
eventListeners:
|
|
295
|
+
click:
|
|
296
|
+
handler: handleImageClick
|
|
297
|
+
contextmenu:
|
|
298
|
+
handler: handleImageClick
|
|
299
|
+
waveform-*:
|
|
300
|
+
eventListeners:
|
|
301
|
+
click:
|
|
302
|
+
handler: handleWaveformClick
|
|
303
|
+
contextmenu:
|
|
304
|
+
handler: handleWaveformClick
|
|
305
|
+
popover-input-*:
|
|
306
|
+
eventListeners:
|
|
307
|
+
input-change:
|
|
308
|
+
handler: handlePopoverInputChange
|
|
176
309
|
|
|
177
310
|
events:
|
|
178
311
|
form-change: {}
|
|
312
|
+
extra-event: {}
|
|
313
|
+
action-click: {}
|
|
179
314
|
|
|
180
315
|
template:
|
|
181
|
-
- rtgl-view w=f
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
316
|
+
- rtgl-view w=f p=md g=lg ${containerAttrString}:
|
|
317
|
+
- rtgl-view g=sm w=f:
|
|
318
|
+
- rtgl-text s=lg: ${title}
|
|
319
|
+
- rtgl-text c=mu-fg: ${description}
|
|
320
|
+
- rtgl-view g=lg w=f:
|
|
321
|
+
- $for field, i in fields:
|
|
322
|
+
- rtgl-view g=md w=f:
|
|
323
|
+
- rtgl-view g=sm:
|
|
324
|
+
- rtgl-view d=h g=md av=c:
|
|
325
|
+
- rtgl-text: ${field.label}
|
|
326
|
+
- $if field.tooltip:
|
|
327
|
+
- rtgl-svg#tooltip-icon-${field.name} svg="info" wh=16 c=mu-fg cur=help ml=xs:
|
|
328
|
+
- rtgl-text s=sm c=mu-fg: ${field.description}
|
|
329
|
+
- $if field.inputType == "read-only-text":
|
|
330
|
+
- rtgl-text s=sm: ${field.defaultValue}
|
|
331
|
+
- $if field.inputType == "inputText":
|
|
332
|
+
- rtgl-input#input-${field.name} key=${key} w=f placeholder=${field.placeholder} value=${field.defaultValue}:
|
|
333
|
+
- $if field.inputType == "popover-input":
|
|
334
|
+
- rtgl-popover-input#popover-input-${field.name} label="${field.label}" .defaultValue=fields[${i}].defaultValue:
|
|
335
|
+
- $if field.inputType == "select":
|
|
336
|
+
- rtgl-select#select-${field.name} key=${key} w=f .options=fields[${i}].options .placeholder=fields[${i}].placeholder .selectedValue=fields[${i}].defaultValue ?no-clear=fields[${i}].noClear .addOption=fields[${i}].addOption:
|
|
337
|
+
- $if field.inputType == "colorPicker":
|
|
338
|
+
- rtgl-color-picker#colorpicker-${field.name} key=${key} value=${field.defaultValue}:
|
|
339
|
+
- $if field.inputType == "slider":
|
|
340
|
+
- rtgl-slider#slider-${field.name} key=${key} w=f min=${field.min} max=${field.max} step=${field.step} value=${field.defaultValue}:
|
|
341
|
+
- $if field.inputType == "slider-input":
|
|
342
|
+
- rtgl-slider-input#slider-input-${field.name} key=${key} w=f min=${field.min} max=${field.max} step=${field.step} defaultValue=${field.defaultValue}:
|
|
343
|
+
- $if field.inputType == "image" && field.imageSrc:
|
|
344
|
+
- rtgl-image#image-${field.name} src=${field.imageSrc} w=${field.width} h=${field.height} cur=p:
|
|
345
|
+
- $if field.inputType == "image" && !field.imageSrc:
|
|
346
|
+
- rtgl-view#image-${field.name} w=${field.width} h=${field.height} bc=ac bw=sm ah=c av=c cur=p p=md:
|
|
347
|
+
- rtgl-text c=mu-fg ta=c: ${field.placeholderText}
|
|
348
|
+
- $if field.inputType == "waveform" && field.waveformData:
|
|
349
|
+
- rtgl-waveform#waveform-${field.name} .waveformData=fields[${i}].waveformData w=${field.width} h=${field.height} cur=p:
|
|
350
|
+
- $if field.inputType == "waveform" && !field.waveformData:
|
|
351
|
+
- rtgl-view#waveform-${field.name} w=${field.width} h=${field.height} bc=ac bw=sm ah=c av=c cur=p p=md:
|
|
352
|
+
- rtgl-text c=mu-fg ta=c: ${field.placeholder}
|
|
353
|
+
- $if field.inputType == "slot":
|
|
354
|
+
- 'slot#slot-${field.slotName} name=${field.slot} style="display: contents;"':
|
|
355
|
+
- rtgl-view g=sm w=f:
|
|
356
|
+
- rtgl-view d=h ah=e g=sm w=f:
|
|
357
|
+
- $for button, i in actions.buttons:
|
|
358
|
+
- rtgl-button#action-${button.id}: ${button.content}
|
|
359
|
+
- rtgl-tooltip ?open=${tooltipState.open} x=${tooltipState.x} y=${tooltipState.y} placement="top" content="${tooltipState.content}":
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const handleDialogClose = (_, deps) => {
|
|
2
|
+
const { store, render } = deps;
|
|
3
|
+
|
|
4
|
+
store.closeDialog();
|
|
5
|
+
render();
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const handleConfirm = (_, deps) => {
|
|
9
|
+
const { store, render, globalUI } = deps;
|
|
10
|
+
|
|
11
|
+
store.closeDialog();
|
|
12
|
+
render();
|
|
13
|
+
globalUI.emit('event', true);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const handleCancel = (_, deps) => {
|
|
17
|
+
const { store, render, globalUI } = deps;
|
|
18
|
+
|
|
19
|
+
store.closeDialog();
|
|
20
|
+
render();
|
|
21
|
+
globalUI.emit('event', false);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const showAlert = (options, deps) => {
|
|
25
|
+
const { store, render } = deps;
|
|
26
|
+
|
|
27
|
+
if (store.selectIsOpen()) {
|
|
28
|
+
throw new Error("A dialog is already open");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
store.setAlertConfig(options);
|
|
32
|
+
render();
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const showConfirm = async (options, deps) => {
|
|
36
|
+
const { store, render, globalUI } = deps;
|
|
37
|
+
|
|
38
|
+
if (store.selectIsOpen()) {
|
|
39
|
+
throw new Error("A dialog is already open");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
store.setConfirmConfig(options);
|
|
43
|
+
render();
|
|
44
|
+
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
globalUI.once('event', (result) => {
|
|
47
|
+
// result contains info of whehter is confirm of cancel
|
|
48
|
+
resolve(result)
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const createInitialState = () => Object.freeze({
|
|
2
|
+
isOpen: false,
|
|
3
|
+
config: {
|
|
4
|
+
status: undefined, // undefined | info | warning | error
|
|
5
|
+
title: "",
|
|
6
|
+
message: "",
|
|
7
|
+
confirmText: "OK",
|
|
8
|
+
cancelText: "Cancel",
|
|
9
|
+
mode: "alert", // alert | confirm
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const setAlertConfig = (state, options) => {
|
|
14
|
+
if (!options.message) {
|
|
15
|
+
throw new Error("message is required for showAlert");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
state.config = {
|
|
19
|
+
status: options.status || undefined,
|
|
20
|
+
title: options.title || "",
|
|
21
|
+
message: options.message,
|
|
22
|
+
confirmText: options.confirmText || "OK",
|
|
23
|
+
cancelText: "",
|
|
24
|
+
mode: "alert",
|
|
25
|
+
};
|
|
26
|
+
state.isOpen = true;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const setConfirmConfig = (state, options) => {
|
|
30
|
+
if (!options.message) {
|
|
31
|
+
throw new Error("message is required for showConfirm");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
state.config = {
|
|
35
|
+
status: options.status || undefined,
|
|
36
|
+
title: options.title || "",
|
|
37
|
+
message: options.message,
|
|
38
|
+
confirmText: options.confirmText || "Yes",
|
|
39
|
+
cancelText: options.cancelText || "Cancel",
|
|
40
|
+
mode: "confirm",
|
|
41
|
+
};
|
|
42
|
+
state.isOpen = true;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const closeDialog = (state) => {
|
|
46
|
+
state.isOpen = false;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const selectConfig = ({ state }) => state.config;
|
|
50
|
+
export const selectIsOpen = ({ state }) => state.isOpen;
|
|
51
|
+
|
|
52
|
+
export const selectViewData = ({ state }) => {
|
|
53
|
+
return {
|
|
54
|
+
isOpen: state.isOpen,
|
|
55
|
+
config: state.config,
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
elementName: rtgl-global-ui
|
|
2
|
+
|
|
3
|
+
viewDataSchema:
|
|
4
|
+
type: object
|
|
5
|
+
properties:
|
|
6
|
+
isOpen:
|
|
7
|
+
type: boolean
|
|
8
|
+
config:
|
|
9
|
+
type: object
|
|
10
|
+
properties:
|
|
11
|
+
status:
|
|
12
|
+
type: string
|
|
13
|
+
title:
|
|
14
|
+
type: string
|
|
15
|
+
message:
|
|
16
|
+
type: string
|
|
17
|
+
confirmText:
|
|
18
|
+
type: string
|
|
19
|
+
cancelText:
|
|
20
|
+
type: string
|
|
21
|
+
mode:
|
|
22
|
+
type: string
|
|
23
|
+
|
|
24
|
+
refs:
|
|
25
|
+
dialog:
|
|
26
|
+
eventListeners:
|
|
27
|
+
close:
|
|
28
|
+
handler: handleDialogClose
|
|
29
|
+
confirm-button:
|
|
30
|
+
eventListeners:
|
|
31
|
+
click:
|
|
32
|
+
handler: handleConfirm
|
|
33
|
+
cancel-button:
|
|
34
|
+
eventListeners:
|
|
35
|
+
click:
|
|
36
|
+
handler: handleCancel
|
|
37
|
+
|
|
38
|
+
template:
|
|
39
|
+
- rtgl-dialog#dialog ?open=${isOpen} s=sm:
|
|
40
|
+
- rtgl-view slot=content g=lg p=lg:
|
|
41
|
+
- rtgl-view d=h g=md:
|
|
42
|
+
- rtgl-view d=h ah=c av=c g=md:
|
|
43
|
+
- rtgl-view g=md:
|
|
44
|
+
- rtgl-view h=24 av=c:
|
|
45
|
+
- rtgl-text fw=600: ${config.title}
|
|
46
|
+
- rtgl-text: ${config.message}
|
|
47
|
+
- rtgl-view d=h g=md mt=lg w=f ah=e:
|
|
48
|
+
- $if config.mode == 'confirm':
|
|
49
|
+
- rtgl-button#cancel-button v=se: ${config.cancelText}
|
|
50
|
+
- rtgl-button#confirm-button v=pr: ${config.confirmText}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const createInitialState = () => Object.freeze({});
|
|
2
2
|
|
|
3
3
|
const blacklistedAttrs = ['id', 'class', 'style', 'slot'];
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ const stringifyAttrs = (attrs) => {
|
|
|
6
6
|
return Object.entries(attrs).filter(([key]) => !blacklistedAttrs.includes(key)).map(([key, value]) => `${key}=${value}`).join(' ');
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export const
|
|
9
|
+
export const selectViewData = ({ state, props, attrs }) => {
|
|
10
10
|
console.log('attrs', {
|
|
11
11
|
attrs,
|
|
12
12
|
entries: Object.entries(attrs)
|