@rettangoli/ui 0.1.2-rc28 → 0.1.2-rc29
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 +42 -37
- package/package.json +1 -1
- package/src/components/form/form.handlers.js +25 -0
- package/src/components/form/form.store.js +23 -0
- package/src/components/form/form.view.yaml +68 -1
- 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/primitives/button.js +10 -0
- package/src/primitives/popover.js +7 -2
package/package.json
CHANGED
|
@@ -200,3 +200,28 @@ export const handleSelectAddOption = (e, deps) => {
|
|
|
200
200
|
}),
|
|
201
201
|
);
|
|
202
202
|
};
|
|
203
|
+
|
|
204
|
+
export const handleTooltipMouseEnter = (e, deps) => {
|
|
205
|
+
const { store, render, props } = deps;
|
|
206
|
+
const fieldName = e.currentTarget.id.replace('tooltip-icon-', '');
|
|
207
|
+
|
|
208
|
+
// Find the field with matching name to get tooltip content
|
|
209
|
+
const form = props.form;
|
|
210
|
+
const field = form.fields.find(f => f.name === fieldName);
|
|
211
|
+
|
|
212
|
+
if (field && field.tooltip) {
|
|
213
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
214
|
+
store.showTooltip({
|
|
215
|
+
x: rect.left + rect.width / 2,
|
|
216
|
+
y: rect.top - 8,
|
|
217
|
+
content: field.tooltip.content
|
|
218
|
+
});
|
|
219
|
+
render();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export const handleTooltipMouseLeave = (e, deps) => {
|
|
224
|
+
const { store, render } = deps;
|
|
225
|
+
store.hideTooltip();
|
|
226
|
+
render();
|
|
227
|
+
};
|
|
@@ -26,6 +26,12 @@ function pick(obj, keys) {
|
|
|
26
26
|
|
|
27
27
|
export const INITIAL_STATE = Object.freeze({
|
|
28
28
|
formValues: {},
|
|
29
|
+
tooltipState: {
|
|
30
|
+
open: false,
|
|
31
|
+
x: 0,
|
|
32
|
+
y: 0,
|
|
33
|
+
content: ''
|
|
34
|
+
},
|
|
29
35
|
});
|
|
30
36
|
|
|
31
37
|
// Lodash-like utility functions for nested property access
|
|
@@ -140,6 +146,7 @@ export const toViewData = ({ state, props, attrs }) => {
|
|
|
140
146
|
buttons: [],
|
|
141
147
|
},
|
|
142
148
|
formValues: state.formValues,
|
|
149
|
+
tooltipState: state.tooltipState,
|
|
143
150
|
};
|
|
144
151
|
};
|
|
145
152
|
|
|
@@ -174,3 +181,19 @@ export const setFormFieldValue = (state, { name, value, props }) => {
|
|
|
174
181
|
);
|
|
175
182
|
state.formValues = formValues;
|
|
176
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
|
+
};
|
|
@@ -33,6 +33,11 @@ propsSchema:
|
|
|
33
33
|
const: inputText
|
|
34
34
|
placeholder:
|
|
35
35
|
type: string
|
|
36
|
+
tooltip:
|
|
37
|
+
type: object
|
|
38
|
+
properties:
|
|
39
|
+
content:
|
|
40
|
+
type: string
|
|
36
41
|
required:
|
|
37
42
|
- name
|
|
38
43
|
- label
|
|
@@ -69,6 +74,11 @@ propsSchema:
|
|
|
69
74
|
required:
|
|
70
75
|
- label
|
|
71
76
|
- value
|
|
77
|
+
tooltip:
|
|
78
|
+
type: object
|
|
79
|
+
properties:
|
|
80
|
+
content:
|
|
81
|
+
type: string
|
|
72
82
|
required:
|
|
73
83
|
- name
|
|
74
84
|
- label
|
|
@@ -87,6 +97,11 @@ propsSchema:
|
|
|
87
97
|
const: colorPicker
|
|
88
98
|
value:
|
|
89
99
|
type: string
|
|
100
|
+
tooltip:
|
|
101
|
+
type: object
|
|
102
|
+
properties:
|
|
103
|
+
content:
|
|
104
|
+
type: string
|
|
90
105
|
required:
|
|
91
106
|
- name
|
|
92
107
|
- label
|
|
@@ -110,6 +125,11 @@ propsSchema:
|
|
|
110
125
|
type: number
|
|
111
126
|
value:
|
|
112
127
|
type: number
|
|
128
|
+
tooltip:
|
|
129
|
+
type: object
|
|
130
|
+
properties:
|
|
131
|
+
content:
|
|
132
|
+
type: string
|
|
113
133
|
required:
|
|
114
134
|
- name
|
|
115
135
|
- label
|
|
@@ -133,6 +153,11 @@ propsSchema:
|
|
|
133
153
|
type: number
|
|
134
154
|
value:
|
|
135
155
|
type: number
|
|
156
|
+
tooltip:
|
|
157
|
+
type: object
|
|
158
|
+
properties:
|
|
159
|
+
content:
|
|
160
|
+
type: string
|
|
136
161
|
required:
|
|
137
162
|
- name
|
|
138
163
|
- label
|
|
@@ -154,6 +179,11 @@ propsSchema:
|
|
|
154
179
|
type: number
|
|
155
180
|
placeholder:
|
|
156
181
|
type: string
|
|
182
|
+
tooltip:
|
|
183
|
+
type: object
|
|
184
|
+
properties:
|
|
185
|
+
content:
|
|
186
|
+
type: string
|
|
157
187
|
required:
|
|
158
188
|
- name
|
|
159
189
|
- label
|
|
@@ -179,6 +209,33 @@ propsSchema:
|
|
|
179
209
|
type: object
|
|
180
210
|
waveformData:
|
|
181
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
|
|
182
239
|
required:
|
|
183
240
|
- name
|
|
184
241
|
- label
|
|
@@ -205,6 +262,12 @@ refs:
|
|
|
205
262
|
eventListeners:
|
|
206
263
|
click:
|
|
207
264
|
handler: handleActionClick
|
|
265
|
+
tooltip-icon-*:
|
|
266
|
+
eventListeners:
|
|
267
|
+
mouseenter:
|
|
268
|
+
handler: handleTooltipMouseEnter
|
|
269
|
+
mouseleave:
|
|
270
|
+
handler: handleTooltipMouseLeave
|
|
208
271
|
input-*:
|
|
209
272
|
eventListeners:
|
|
210
273
|
input-change:
|
|
@@ -258,7 +321,10 @@ template:
|
|
|
258
321
|
- $for field, i in fields:
|
|
259
322
|
- rtgl-view g=md w=f:
|
|
260
323
|
- rtgl-view g=sm:
|
|
261
|
-
- rtgl-
|
|
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:
|
|
262
328
|
- rtgl-text s=sm c=mu-fg: ${field.description}
|
|
263
329
|
- $if field.inputType == "read-only-text":
|
|
264
330
|
- rtgl-text s=sm: ${field.defaultValue}
|
|
@@ -290,3 +356,4 @@ template:
|
|
|
290
356
|
- rtgl-view d=h ah=e g=sm w=f:
|
|
291
357
|
- $for button, i in actions.buttons:
|
|
292
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}":
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
elementName: rtgl-tooltip
|
|
2
|
+
|
|
3
|
+
viewDataSchema:
|
|
4
|
+
type: object
|
|
5
|
+
|
|
6
|
+
attrsSchema:
|
|
7
|
+
type: object
|
|
8
|
+
properties:
|
|
9
|
+
open:
|
|
10
|
+
type: string
|
|
11
|
+
x:
|
|
12
|
+
type: string
|
|
13
|
+
y:
|
|
14
|
+
type: string
|
|
15
|
+
placement:
|
|
16
|
+
type: string
|
|
17
|
+
content:
|
|
18
|
+
type: string
|
|
19
|
+
|
|
20
|
+
refs:
|
|
21
|
+
popover:
|
|
22
|
+
|
|
23
|
+
template:
|
|
24
|
+
- rtgl-popover#popover ?open=${open} x=${x} y=${y} placement=${placement} no-overlay:
|
|
25
|
+
- rtgl-view slot=content bgc=background bc=border br=md p=sm ah=c av=c:
|
|
26
|
+
- rtgl-text ta=c s=sm c=foreground: ${content}
|
|
27
|
+
|
package/src/primitives/button.js
CHANGED
|
@@ -296,6 +296,16 @@ class RettangoliButtonElement extends HTMLElement {
|
|
|
296
296
|
this._buttonElement.style.maxWidth = "";
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
|
+
|
|
300
|
+
// Public method to get the actual button's bounding rect
|
|
301
|
+
// This is needed because the host element has display: contents
|
|
302
|
+
getBoundingClientRect() {
|
|
303
|
+
if (this._buttonElement) {
|
|
304
|
+
return this._buttonElement.getBoundingClientRect();
|
|
305
|
+
}
|
|
306
|
+
// Fallback to host element
|
|
307
|
+
return super.getBoundingClientRect();
|
|
308
|
+
}
|
|
299
309
|
}
|
|
300
310
|
|
|
301
311
|
// Export factory function to maintain API compatibility
|
|
@@ -28,7 +28,7 @@ class RettangoliPopoverElement extends HTMLElement {
|
|
|
28
28
|
outline: none;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
:host([open]) .popover-overlay {
|
|
31
|
+
:host([open]:not([no-overlay])) .popover-overlay {
|
|
32
32
|
display: block;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -36,6 +36,11 @@ class RettangoliPopoverElement extends HTMLElement {
|
|
|
36
36
|
display: block;
|
|
37
37
|
visibility: hidden;
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
/* For no-overlay mode, make the container non-interactive */
|
|
41
|
+
:host([no-overlay]) .popover-container {
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
39
44
|
|
|
40
45
|
:host([open][positioned]) .popover-container {
|
|
41
46
|
visibility: visible;
|
|
@@ -96,7 +101,7 @@ class RettangoliPopoverElement extends HTMLElement {
|
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
static get observedAttributes() {
|
|
99
|
-
return ["open", "x", "y", "placement"];
|
|
104
|
+
return ["open", "x", "y", "placement", "no-overlay"];
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
connectedCallback() {
|