@rettangoli/ui 0.1.2-rc9 → 0.1.4

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.
Files changed (66) hide show
  1. package/dist/rettangoli-iife-layout.min.js +128 -56
  2. package/dist/rettangoli-iife-ui.min.js +187 -66
  3. package/package.json +3 -2
  4. package/src/common.js +30 -2
  5. package/src/components/breadcrumb/breadcrumb.handlers.js +10 -0
  6. package/src/components/breadcrumb/breadcrumb.store.js +29 -0
  7. package/src/components/breadcrumb/breadcrumb.view.yaml +64 -0
  8. package/src/components/dropdownMenu/dropdownMenu.handlers.js +7 -6
  9. package/src/components/dropdownMenu/dropdownMenu.store.js +6 -18
  10. package/src/components/dropdownMenu/dropdownMenu.view.yaml +15 -13
  11. package/src/components/form/form.handlers.js +181 -33
  12. package/src/components/form/form.store.js +175 -21
  13. package/src/components/form/form.view.yaml +182 -27
  14. package/src/components/globalUi/globalUi.handlers.js +53 -0
  15. package/src/components/globalUi/globalUi.store.js +57 -0
  16. package/src/components/globalUi/globalUi.view.yaml +50 -0
  17. package/src/components/navbar/navbar.handlers.js +2 -1
  18. package/src/components/navbar/navbar.store.js +2 -2
  19. package/src/components/pageOutline/pageOutline.handlers.js +57 -17
  20. package/src/components/pageOutline/pageOutline.store.js +48 -3
  21. package/src/components/pageOutline/pageOutline.view.yaml +7 -5
  22. package/src/components/popoverInput/popoverInput.handlers.js +103 -0
  23. package/src/components/popoverInput/popoverInput.store.js +48 -0
  24. package/src/components/popoverInput/popoverInput.view.yaml +55 -0
  25. package/src/components/select/select.handlers.js +124 -12
  26. package/src/components/select/select.store.js +86 -20
  27. package/src/components/select/select.view.yaml +40 -10
  28. package/src/components/sidebar/sidebar.handlers.js +8 -6
  29. package/src/components/sidebar/sidebar.store.js +6 -6
  30. package/src/components/sidebar/sidebar.view.yaml +1 -1
  31. package/src/components/sliderInput/sliderInput.handlers.js +24 -6
  32. package/src/components/sliderInput/sliderInput.store.js +3 -2
  33. package/src/components/sliderInput/sliderInput.view.yaml +3 -2
  34. package/src/components/table/table.handlers.js +12 -10
  35. package/src/components/table/table.store.js +4 -4
  36. package/src/components/tabs/tabs.handlers.js +11 -0
  37. package/src/components/tabs/tabs.store.js +29 -0
  38. package/src/components/tabs/tabs.view.yaml +64 -0
  39. package/src/components/tooltip/tooltip.handlers.js +0 -0
  40. package/src/components/tooltip/tooltip.store.js +12 -0
  41. package/src/components/tooltip/tooltip.view.yaml +27 -0
  42. package/src/components/waveform/waveform.handlers.js +92 -0
  43. package/src/components/waveform/waveform.store.js +17 -0
  44. package/src/components/waveform/waveform.view.yaml +38 -0
  45. package/src/deps/createGlobalUI.js +39 -0
  46. package/src/entry-iife-layout.js +3 -0
  47. package/src/entry-iife-ui.js +4 -0
  48. package/src/index.js +7 -1
  49. package/src/primitives/button.js +10 -0
  50. package/src/primitives/colorPicker.js +13 -4
  51. package/src/primitives/dialog.js +254 -0
  52. package/src/primitives/image.js +4 -3
  53. package/src/primitives/input.js +17 -4
  54. package/src/primitives/popover.js +280 -0
  55. package/src/primitives/slider.js +14 -4
  56. package/src/primitives/svg.js +2 -0
  57. package/src/primitives/textarea.js +25 -1
  58. package/src/primitives/view.js +132 -13
  59. package/src/setup.js +7 -2
  60. package/src/styles/cursorStyles.js +38 -2
  61. package/src/components/dialog/dialog.handlers.js +0 -5
  62. package/src/components/dialog/dialog.store.js +0 -25
  63. package/src/components/dialog/dialog.view.yaml +0 -48
  64. package/src/components/popover/popover.handlers.js +0 -5
  65. package/src/components/popover/popover.store.js +0 -12
  66. package/src/components/popover/popover.view.yaml +0 -57
@@ -1,45 +1,199 @@
1
- export const INITIAL_STATE = Object.freeze({
2
- formValues: {}
1
+ import { parseAndRender } from "jempl";
2
+
3
+ const encode = (input) => {
4
+ function escapeHtml(text) {
5
+ const map = {
6
+ '&': '&',
7
+ '<': '&lt;',
8
+ '>': '&gt;',
9
+ '"': '&quot;',
10
+ "'": '&#39;'
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
- const blacklistedAttrs = ['id', 'class', 'style', 'slot'];
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).filter(([key]) => !blacklistedAttrs.includes(key)).map(([key, value]) => `${key}=${value}`).join(' ');
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
- export const toViewData = ({ state, props, attrs }) => {
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
- field.defaultValue = defaultValues[field.name]
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: props.form?.title || '',
22
- description: props?.form?.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
- return state.formValues;
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[name] = value;
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 h=f p=md g=lg ${containerAttrString}:
182
- - rtgl-view g=sm w=f:
183
- - rtgl-text s=lg: ${title}
184
- - rtgl-text c=mu-fg: ${description}
185
- - rtgl-view g=lg w=f:
186
- - $for field, i in fields:
187
- - rtgl-view g=md w=f:
188
- - rtgl-view g=sm:
189
- - rtgl-text: ${field.label}
190
- - rtgl-text s=sm c=mu-fg: ${field.description}
191
- - $if field.inputType == "inputText":
192
- - rtgl-input#input-${field.name} w=f placeholder=${field.placeholder} value=${field.defaultValue}:
193
- - $if field.inputType == "select":
194
- - rtgl-select#select-${field.name} w=f .options=fields[${i}].options .placeholder=fields[${i}].placeholder .selectedValue=fields[${i}].defaultValue:
195
- - $if field.inputType == "colorPicker":
196
- - rtgl-color-picker#colorpicker-${field.name} value=${field.defaultValue}:
197
- - $if field.inputType == "slider":
198
- - rtgl-slider#slider-${field.name} w=f min=${field.min} max=${field.max} step=${field.step} value=${field.defaultValue}:
199
- - $if field.inputType == "slider-input":
200
- - rtgl-slider-input#slider-input-${field.name} w=f min=${field.min} max=${field.max} step=${field.step} defaultValue=${field.defaultValue}:
201
- - rtgl-view g=sm w=f:
202
- - rtgl-view d=h ah=e g=sm w=f:
203
- - $for button, i in actions.buttons:
204
- - rtgl-button#action-${button.id}: ${button.content}
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,53 @@
1
+ export const handleDialogClose = (deps, payload) => {
2
+ const { store, render } = deps;
3
+
4
+ store.closeDialog();
5
+ render();
6
+ };
7
+
8
+ export const handleConfirm = (deps, payload) => {
9
+ const { store, render, globalUI } = deps;
10
+
11
+ store.closeDialog();
12
+ render();
13
+ globalUI.emit('event', true);
14
+ };
15
+
16
+ export const handleCancel = (deps, payload) => {
17
+ const { store, render, globalUI } = deps;
18
+
19
+ store.closeDialog();
20
+ render();
21
+ globalUI.emit('event', false);
22
+ };
23
+
24
+ export const showAlert = (deps, payload) => {
25
+ const { store, render } = deps;
26
+ const options = payload;
27
+
28
+ if (store.selectIsOpen()) {
29
+ throw new Error("A dialog is already open");
30
+ }
31
+
32
+ store.setAlertConfig(options);
33
+ render();
34
+ };
35
+
36
+ export const showConfirm = async (deps, payload) => {
37
+ const { store, render, globalUI } = deps;
38
+ const options = payload;
39
+
40
+ if (store.selectIsOpen()) {
41
+ throw new Error("A dialog is already open");
42
+ }
43
+
44
+ store.setConfirmConfig(options);
45
+ render();
46
+
47
+ return new Promise((resolve) => {
48
+ globalUI.once('event', (result) => {
49
+ // result contains info of whehter is confirm of cancel
50
+ resolve(result)
51
+ });
52
+ });
53
+ };
@@ -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,6 +1,7 @@
1
1
 
2
- export const handleClickStart = (e, deps) => {
2
+ export const handleClickStart = (deps, payload) => {
3
3
  const { dispatchEvent, store } = deps;
4
+ const event = payload._event;
4
5
  console.log('handle click start', store.selectPath());
5
6
  dispatchEvent(new CustomEvent('clickStart', {
6
7
  detail: {
@@ -1,4 +1,4 @@
1
- export const INITIAL_STATE = Object.freeze({});
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 toViewData = ({ state, props, attrs }) => {
9
+ export const selectViewData = ({ state, props, attrs }) => {
10
10
  console.log('attrs', {
11
11
  attrs,
12
12
  entries: Object.entries(attrs)