@rettangoli/ui 0.1.2-rc3 → 0.1.2-rc31
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 +115 -43
- package/dist/rettangoli-iife-ui.min.js +187 -67
- package/package.json +5 -3
- package/src/cli/buildSvg.js +86 -0
- package/src/cli/index.js +1 -0
- package/src/common.js +19 -0
- 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 +4 -4
- package/src/components/dropdownMenu/dropdownMenu.store.js +5 -17
- package/src/components/dropdownMenu/dropdownMenu.view.yaml +15 -13
- package/src/components/form/form.handlers.js +173 -25
- package/src/components/form/form.store.js +176 -22
- package/src/components/form/form.view.yaml +217 -33
- package/src/components/pageOutline/pageOutline.handlers.js +57 -17
- package/src/components/pageOutline/pageOutline.store.js +46 -1
- 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 +116 -11
- package/src/components/select/select.store.js +84 -18
- package/src/components/select/select.view.yaml +40 -10
- package/src/components/sidebar/sidebar.view.yaml +1 -1
- package/src/components/sliderInput/sliderInput.handlers.js +41 -0
- package/src/components/sliderInput/sliderInput.store.js +18 -0
- package/src/components/sliderInput/sliderInput.view.yaml +42 -0
- package/src/components/table/table.handlers.js +1 -1
- 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/entry-iife-layout.js +3 -0
- package/src/entry-iife-ui.js +4 -0
- package/src/index.js +5 -1
- package/src/primitives/button.js +10 -0
- package/src/primitives/colorPicker.js +9 -0
- package/src/primitives/dialog.js +254 -0
- package/src/primitives/input.js +41 -11
- package/src/primitives/popover.js +280 -0
- package/src/primitives/slider.js +18 -9
- package/src/primitives/svg.js +2 -0
- package/src/primitives/textarea.js +25 -1
- 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 -44
- 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,41 @@
|
|
|
1
|
+
export const handleBeforeMount = (deps) => {
|
|
2
|
+
const { store, attrs } = deps;
|
|
3
|
+
store.setValue(attrs.defaultValue || 0);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export const handleOnUpdate = (changes, deps) => {
|
|
7
|
+
const { oldAttrs, newAttrs } = changes;
|
|
8
|
+
const { store, render, attrs } = deps;
|
|
9
|
+
|
|
10
|
+
// Reset when key changes
|
|
11
|
+
if (oldAttrs?.key !== newAttrs?.key && newAttrs?.key) {
|
|
12
|
+
const defaultValue = newAttrs?.defaultValue || attrs?.defaultValue || 0;
|
|
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);
|
|
19
|
+
render();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const handleValueChange = (e, deps) => {
|
|
24
|
+
const { store, render, dispatchEvent } = deps;
|
|
25
|
+
const newValue = Number(e.detail.value);
|
|
26
|
+
|
|
27
|
+
store.setValue(newValue);
|
|
28
|
+
|
|
29
|
+
// Re-render to sync slider and input
|
|
30
|
+
render();
|
|
31
|
+
|
|
32
|
+
// Dispatch event for external listeners
|
|
33
|
+
dispatchEvent(
|
|
34
|
+
new CustomEvent("slider-input-value-change", {
|
|
35
|
+
detail: {
|
|
36
|
+
value: newValue,
|
|
37
|
+
},
|
|
38
|
+
bubbles: true,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const INITIAL_STATE = Object.freeze({
|
|
2
|
+
value: 0
|
|
3
|
+
});
|
|
4
|
+
|
|
5
|
+
export const toViewData = ({ state, attrs }) => {
|
|
6
|
+
return {
|
|
7
|
+
key: attrs.key,
|
|
8
|
+
value: state.value,
|
|
9
|
+
w: attrs.w || '',
|
|
10
|
+
min: attrs.min || 0,
|
|
11
|
+
max: attrs.max || 100,
|
|
12
|
+
step: attrs.step || 1
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const setValue = (state, newValue) => {
|
|
17
|
+
state.value = newValue;
|
|
18
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
elementName: rtgl-slider-input
|
|
2
|
+
|
|
3
|
+
viewDataSchema:
|
|
4
|
+
type: object
|
|
5
|
+
|
|
6
|
+
attrsSchema:
|
|
7
|
+
type: object
|
|
8
|
+
properties:
|
|
9
|
+
defaultValue:
|
|
10
|
+
type: string
|
|
11
|
+
default: '0'
|
|
12
|
+
w:
|
|
13
|
+
type: string
|
|
14
|
+
default: ''
|
|
15
|
+
min:
|
|
16
|
+
type: string
|
|
17
|
+
default: '0'
|
|
18
|
+
max:
|
|
19
|
+
type: string
|
|
20
|
+
default: '100'
|
|
21
|
+
step:
|
|
22
|
+
type: string
|
|
23
|
+
default: '1'
|
|
24
|
+
|
|
25
|
+
refs:
|
|
26
|
+
input:
|
|
27
|
+
eventListeners:
|
|
28
|
+
input-change:
|
|
29
|
+
handler: handleValueChange
|
|
30
|
+
slider:
|
|
31
|
+
eventListeners:
|
|
32
|
+
slider-change:
|
|
33
|
+
handler: handleValueChange
|
|
34
|
+
|
|
35
|
+
events:
|
|
36
|
+
form-change: {}
|
|
37
|
+
|
|
38
|
+
template:
|
|
39
|
+
- rtgl-view d=h av=c g=md w=${w}:
|
|
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}:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const INITIAL_STATE = Object.freeze({});
|
|
2
|
+
|
|
3
|
+
const blacklistedAttrs = ['id', 'class', 'style', 'slot'];
|
|
4
|
+
|
|
5
|
+
const stringifyAttrs = (attrs) => {
|
|
6
|
+
return Object.entries(attrs).filter(([key]) => !blacklistedAttrs.includes(key)).map(([key, value]) => `${key}=${value}`).join(' ');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const toViewData = ({ state, props, attrs }) => {
|
|
10
|
+
const containerAttrString = stringifyAttrs(attrs);
|
|
11
|
+
|
|
12
|
+
const items = props.items || [];
|
|
13
|
+
const selectedTab = attrs['selected-tab'];
|
|
14
|
+
|
|
15
|
+
// Mark selected tab with styling
|
|
16
|
+
const itemsWithSelection = items.map(item => ({
|
|
17
|
+
...item,
|
|
18
|
+
isSelected: item.id === selectedTab,
|
|
19
|
+
bgColor: item.id === selectedTab ? 'ac' : '',
|
|
20
|
+
borderColor: item.id === selectedTab ? '' : 'tr',
|
|
21
|
+
textColor: item.id === selectedTab ? '' : 'mu-fg'
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
containerAttrString,
|
|
26
|
+
items: itemsWithSelection,
|
|
27
|
+
selectedTab
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
elementName: rtgl-tabs
|
|
2
|
+
|
|
3
|
+
viewDataSchema:
|
|
4
|
+
type: object
|
|
5
|
+
properties:
|
|
6
|
+
containerAttrString:
|
|
7
|
+
type: string
|
|
8
|
+
items:
|
|
9
|
+
type: array
|
|
10
|
+
items:
|
|
11
|
+
type: object
|
|
12
|
+
properties:
|
|
13
|
+
label:
|
|
14
|
+
type: string
|
|
15
|
+
id:
|
|
16
|
+
type: string
|
|
17
|
+
isSelected:
|
|
18
|
+
type: boolean
|
|
19
|
+
bgColor:
|
|
20
|
+
type: string
|
|
21
|
+
textColor:
|
|
22
|
+
type: string
|
|
23
|
+
borderColor:
|
|
24
|
+
type: string
|
|
25
|
+
selectedTab:
|
|
26
|
+
type: string
|
|
27
|
+
|
|
28
|
+
propsSchema:
|
|
29
|
+
type: object
|
|
30
|
+
properties:
|
|
31
|
+
items:
|
|
32
|
+
type: array
|
|
33
|
+
items:
|
|
34
|
+
type: object
|
|
35
|
+
properties:
|
|
36
|
+
label:
|
|
37
|
+
type: string
|
|
38
|
+
id:
|
|
39
|
+
type: string
|
|
40
|
+
|
|
41
|
+
attrsSchema:
|
|
42
|
+
type: object
|
|
43
|
+
properties:
|
|
44
|
+
selected-tab:
|
|
45
|
+
type: string
|
|
46
|
+
|
|
47
|
+
refs:
|
|
48
|
+
tab-*:
|
|
49
|
+
eventListeners:
|
|
50
|
+
click:
|
|
51
|
+
handler: handleClickItem
|
|
52
|
+
|
|
53
|
+
events:
|
|
54
|
+
item-click:
|
|
55
|
+
type: object
|
|
56
|
+
properties:
|
|
57
|
+
id:
|
|
58
|
+
type: string
|
|
59
|
+
|
|
60
|
+
template:
|
|
61
|
+
- rtgl-view d=h g=sm bgc=mu p=sm br=lg ${containerAttrString}:
|
|
62
|
+
- $for item in items:
|
|
63
|
+
- rtgl-view#tab-${item.id} data-id=${item.id} cur=p bgc=${item.bgColor} bw=xs bc=${item.borderColor} pv=md ph=lg br=lg:
|
|
64
|
+
- rtgl-text s=sm c=${item.textColor}: "${item.label}"
|
|
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
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export const handleAfterMount = async (deps) => {
|
|
2
|
+
const { props, store, render, getRefIds, } = deps;
|
|
3
|
+
const { waveformData } = props;
|
|
4
|
+
|
|
5
|
+
store.setWaveformData(waveformData);
|
|
6
|
+
render();
|
|
7
|
+
|
|
8
|
+
const canvas = getRefIds().canvas?.elm;
|
|
9
|
+
if (canvas) {
|
|
10
|
+
renderWaveform(waveformData, canvas);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const handleOnUpdate = async (changes, deps) => {
|
|
15
|
+
const { store, render, getRefIds, props } = deps;
|
|
16
|
+
const { waveformData } = props;
|
|
17
|
+
|
|
18
|
+
if (!waveformData) {
|
|
19
|
+
console.log('waveform handleOnUpdate: no waveformData provided');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
store.setWaveformData(waveformData);
|
|
24
|
+
render();
|
|
25
|
+
|
|
26
|
+
const canvas = getRefIds().canvas?.elm;
|
|
27
|
+
if (canvas) {
|
|
28
|
+
renderWaveform(waveformData, canvas);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
async function renderWaveform(waveformData, canvas) {
|
|
33
|
+
const ctx = canvas.getContext("2d");
|
|
34
|
+
|
|
35
|
+
// Get the actual display size of the canvas
|
|
36
|
+
const rect = canvas.getBoundingClientRect();
|
|
37
|
+
const displayWidth = rect.width;
|
|
38
|
+
const displayHeight = rect.height;
|
|
39
|
+
|
|
40
|
+
// Set canvas internal resolution to match display size
|
|
41
|
+
canvas.width = displayWidth;
|
|
42
|
+
canvas.height = displayHeight;
|
|
43
|
+
|
|
44
|
+
const width = canvas.width;
|
|
45
|
+
const height = canvas.height;
|
|
46
|
+
|
|
47
|
+
// Clear canvas
|
|
48
|
+
ctx.clearRect(0, 0, width, height);
|
|
49
|
+
|
|
50
|
+
// Dark theme background
|
|
51
|
+
ctx.fillStyle = "#1a1a1a";
|
|
52
|
+
ctx.fillRect(0, 0, width, height);
|
|
53
|
+
|
|
54
|
+
if (!waveformData || !waveformData.data) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const data = waveformData.data;
|
|
59
|
+
const centerY = height / 2;
|
|
60
|
+
|
|
61
|
+
// Create gradient for waveform
|
|
62
|
+
const gradient = ctx.createLinearGradient(0, 0, 0, height);
|
|
63
|
+
gradient.addColorStop(0, "#404040");
|
|
64
|
+
gradient.addColorStop(0.5, "#A1A1A1");
|
|
65
|
+
gradient.addColorStop(1, "#404040");
|
|
66
|
+
|
|
67
|
+
// Draw waveform bars
|
|
68
|
+
const barWidth = Math.max(1, width / data.length);
|
|
69
|
+
const barSpacing = 0.2; // 20% spacing between bars
|
|
70
|
+
|
|
71
|
+
for (let i = 0; i < data.length; i++) {
|
|
72
|
+
const amplitude = data[i];
|
|
73
|
+
const barHeight = amplitude * (height * 0.85);
|
|
74
|
+
const x = i * barWidth;
|
|
75
|
+
const y = centerY - barHeight / 2;
|
|
76
|
+
|
|
77
|
+
ctx.fillStyle = gradient;
|
|
78
|
+
ctx.fillRect(x, y, Math.max(1, barWidth * (1 - barSpacing)), barHeight);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Draw subtle center line
|
|
82
|
+
ctx.strokeStyle = "rgba(255, 255, 255, 0.1)";
|
|
83
|
+
ctx.lineWidth = 1;
|
|
84
|
+
ctx.beginPath();
|
|
85
|
+
ctx.moveTo(0, centerY);
|
|
86
|
+
ctx.lineTo(width, centerY);
|
|
87
|
+
ctx.stroke();
|
|
88
|
+
|
|
89
|
+
// Add subtle glow effect
|
|
90
|
+
ctx.shadowBlur = 10;
|
|
91
|
+
ctx.shadowColor = "#2196F3";
|
|
92
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const INITIAL_STATE = Object.freeze({
|
|
2
|
+
waveformData: null,
|
|
3
|
+
});
|
|
4
|
+
|
|
5
|
+
export const setWaveformData = (state, data) => {
|
|
6
|
+
state.waveformData = data;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const toViewData = ({ state, attrs, props }) => {
|
|
10
|
+
return {
|
|
11
|
+
isLoading: props.isLoading,
|
|
12
|
+
w: attrs.w || "250",
|
|
13
|
+
h: attrs.h || "150",
|
|
14
|
+
cur: attrs.cur,
|
|
15
|
+
waveformData: props.waveformData,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
elementName: rtgl-waveform
|
|
2
|
+
|
|
3
|
+
attrsSchema:
|
|
4
|
+
type: object
|
|
5
|
+
properties:
|
|
6
|
+
w:
|
|
7
|
+
type: string
|
|
8
|
+
description: Width of the waveform visualizer
|
|
9
|
+
default: '250'
|
|
10
|
+
h:
|
|
11
|
+
type: string
|
|
12
|
+
description: Height of the waveform visualizer
|
|
13
|
+
default: '150'
|
|
14
|
+
cur:
|
|
15
|
+
type: string
|
|
16
|
+
description: cursor
|
|
17
|
+
|
|
18
|
+
propsSchema:
|
|
19
|
+
type: object
|
|
20
|
+
properties:
|
|
21
|
+
waveformData:
|
|
22
|
+
type: object
|
|
23
|
+
description: File ID of the waveform data in object storage
|
|
24
|
+
isLoading:
|
|
25
|
+
type: boolean
|
|
26
|
+
description: Whether the waveform data is currently being loaded
|
|
27
|
+
|
|
28
|
+
refs:
|
|
29
|
+
canvas:
|
|
30
|
+
selector: canvas
|
|
31
|
+
|
|
32
|
+
template:
|
|
33
|
+
- rtgl-view w=f h=f pos=rel w=${w} h=${h} cur=${cur}:
|
|
34
|
+
- $if isLoading:
|
|
35
|
+
- rtgl-view w=f h=f av=c ah=c:
|
|
36
|
+
- rtgl-text c=mu-fg: ...
|
|
37
|
+
$else:
|
|
38
|
+
- 'canvas#canvas style="width:100%; height:100%;"':
|
package/src/entry-iife-layout.js
CHANGED
|
@@ -5,6 +5,8 @@ import RettangoliImage from './primitives/image.js';
|
|
|
5
5
|
import RettangoliSvg from './primitives/svg.js';
|
|
6
6
|
import RettangoliInput from './primitives/input.js';
|
|
7
7
|
import RettangoliTextArea from './primitives/textarea.js';
|
|
8
|
+
import RettangoliDialog from './primitives/dialog.js';
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
customElements.define("rtgl-button", RettangoliButton({}));
|
|
10
12
|
customElements.define("rtgl-view", RettangoliView({}));
|
|
@@ -13,3 +15,4 @@ customElements.define("rtgl-image", RettangoliImage({}));
|
|
|
13
15
|
customElements.define("rtgl-svg", RettangoliSvg({}));
|
|
14
16
|
customElements.define("rtgl-input", RettangoliInput({}));
|
|
15
17
|
customElements.define("rtgl-textarea", RettangoliTextArea({}));
|
|
18
|
+
customElements.define("rtgl-dialog", RettangoliDialog({}));
|
package/src/entry-iife-ui.js
CHANGED
|
@@ -7,6 +7,8 @@ import RettangoliInput from './primitives/input.js';
|
|
|
7
7
|
import RettangoliTextArea from './primitives/textarea.js';
|
|
8
8
|
import RettangoliColorPicker from './primitives/colorPicker.js';
|
|
9
9
|
import RettangoliSlider from './primitives/slider.js';
|
|
10
|
+
import RettangoliDialog from './primitives/dialog.js';
|
|
11
|
+
import RettangoliPopover from './primitives/popover.js';
|
|
10
12
|
|
|
11
13
|
customElements.define("rtgl-button", RettangoliButton({}));
|
|
12
14
|
customElements.define("rtgl-view", RettangoliView({}));
|
|
@@ -17,6 +19,8 @@ customElements.define("rtgl-input", RettangoliInput({}));
|
|
|
17
19
|
customElements.define("rtgl-textarea", RettangoliTextArea({}));
|
|
18
20
|
customElements.define("rtgl-color-picker", RettangoliColorPicker({}));
|
|
19
21
|
customElements.define("rtgl-slider", RettangoliSlider({}));
|
|
22
|
+
customElements.define("rtgl-dialog", RettangoliDialog({}));
|
|
23
|
+
customElements.define("rtgl-popover", RettangoliPopover({}));
|
|
20
24
|
|
|
21
25
|
// built from rettangoli cli fe
|
|
22
26
|
import '../.temp/dynamicImport.js'
|
package/src/index.js
CHANGED
|
@@ -5,6 +5,8 @@ import RettangoliImage from './primitives/image.js';
|
|
|
5
5
|
import RettangoliSvg from './primitives/svg.js';
|
|
6
6
|
import RettangoliInput from './primitives/input.js';
|
|
7
7
|
import RettangoliTextArea from './primitives/textarea.js';
|
|
8
|
+
import RettangoliDialog from './primitives/dialog.js';
|
|
9
|
+
import RettangoliPopover from './primitives/popover.js';
|
|
8
10
|
|
|
9
11
|
export {
|
|
10
12
|
RettangoliButton,
|
|
@@ -14,4 +16,6 @@ export {
|
|
|
14
16
|
RettangoliSvg,
|
|
15
17
|
RettangoliInput,
|
|
16
18
|
RettangoliTextArea,
|
|
17
|
-
|
|
19
|
+
RettangoliDialog,
|
|
20
|
+
RettangoliPopover,
|
|
21
|
+
}
|
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
|
|
@@ -114,6 +114,15 @@ class RettangoliColorPickerElement extends HTMLElement {
|
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
117
|
+
// Handle key attribute change - reset value
|
|
118
|
+
if (name === "key" && oldValue !== newValue) {
|
|
119
|
+
requestAnimationFrame(() => {
|
|
120
|
+
const value = this.getAttribute("value");
|
|
121
|
+
this._inputElement.value = value ?? "#000000";
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
117
126
|
// Handle input-specific attributes first
|
|
118
127
|
if (["value", "disabled"].includes(name)) {
|
|
119
128
|
this._updateInputAttributes();
|