@colletdev/core 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/README.md +77 -0
- package/custom-elements.json +6037 -0
- package/generated/.gitattributes +2 -0
- package/generated/index.d.ts +120 -0
- package/generated/index.js +521 -0
- package/generated/styles.js +2845 -0
- package/package.json +56 -0
- package/src/elements/accordion.d.ts +20 -0
- package/src/elements/accordion.js +92 -0
- package/src/elements/activity_group.d.ts +19 -0
- package/src/elements/activity_group.js +27 -0
- package/src/elements/alert.d.ts +24 -0
- package/src/elements/alert.js +40 -0
- package/src/elements/autocomplete.d.ts +30 -0
- package/src/elements/autocomplete.js +671 -0
- package/src/elements/avatar.d.ts +18 -0
- package/src/elements/avatar.js +28 -0
- package/src/elements/backdrop.d.ts +14 -0
- package/src/elements/backdrop.js +28 -0
- package/src/elements/badge.d.ts +21 -0
- package/src/elements/badge.js +42 -0
- package/src/elements/breadcrumb.d.ts +17 -0
- package/src/elements/breadcrumb.js +41 -0
- package/src/elements/button.d.ts +24 -0
- package/src/elements/button.js +36 -0
- package/src/elements/card.d.ts +21 -0
- package/src/elements/card.js +67 -0
- package/src/elements/carousel.d.ts +23 -0
- package/src/elements/carousel.js +895 -0
- package/src/elements/chat_input.d.ts +22 -0
- package/src/elements/chat_input.js +78 -0
- package/src/elements/checkbox.d.ts +21 -0
- package/src/elements/checkbox.js +114 -0
- package/src/elements/code_block.d.ts +21 -0
- package/src/elements/code_block.js +27 -0
- package/src/elements/collapsible.d.ts +20 -0
- package/src/elements/collapsible.js +93 -0
- package/src/elements/date_picker.d.ts +30 -0
- package/src/elements/date_picker.js +528 -0
- package/src/elements/dialog.d.ts +20 -0
- package/src/elements/dialog.js +314 -0
- package/src/elements/drawer.d.ts +20 -0
- package/src/elements/drawer.js +318 -0
- package/src/elements/fab.d.ts +22 -0
- package/src/elements/fab.js +36 -0
- package/src/elements/file_upload.d.ts +26 -0
- package/src/elements/file_upload.js +59 -0
- package/src/elements/listbox.d.ts +19 -0
- package/src/elements/listbox.js +250 -0
- package/src/elements/menu.d.ts +20 -0
- package/src/elements/menu.js +224 -0
- package/src/elements/message_bubble.d.ts +23 -0
- package/src/elements/message_bubble.js +29 -0
- package/src/elements/message_group.d.ts +18 -0
- package/src/elements/message_group.js +28 -0
- package/src/elements/message_part.d.ts +35 -0
- package/src/elements/message_part.js +153 -0
- package/src/elements/pagination.d.ts +22 -0
- package/src/elements/pagination.js +36 -0
- package/src/elements/popover.d.ts +26 -0
- package/src/elements/popover.js +191 -0
- package/src/elements/profile_menu.d.ts +20 -0
- package/src/elements/profile_menu.js +213 -0
- package/src/elements/progress.d.ts +18 -0
- package/src/elements/progress.js +31 -0
- package/src/elements/radio_group.d.ts +22 -0
- package/src/elements/radio_group.js +70 -0
- package/src/elements/scrollbar.d.ts +19 -0
- package/src/elements/scrollbar.js +299 -0
- package/src/elements/search_bar.d.ts +27 -0
- package/src/elements/search_bar.js +98 -0
- package/src/elements/select.d.ts +26 -0
- package/src/elements/select.js +485 -0
- package/src/elements/sidebar.d.ts +21 -0
- package/src/elements/sidebar.js +322 -0
- package/src/elements/skeleton.d.ts +17 -0
- package/src/elements/skeleton.js +31 -0
- package/src/elements/slider.d.ts +28 -0
- package/src/elements/slider.js +93 -0
- package/src/elements/speed_dial.d.ts +23 -0
- package/src/elements/speed_dial.js +370 -0
- package/src/elements/spinner.d.ts +15 -0
- package/src/elements/spinner.js +28 -0
- package/src/elements/split_button.d.ts +23 -0
- package/src/elements/split_button.js +281 -0
- package/src/elements/stepper.d.ts +20 -0
- package/src/elements/stepper.js +31 -0
- package/src/elements/switch.d.ts +22 -0
- package/src/elements/switch.js +129 -0
- package/src/elements/table.d.ts +29 -0
- package/src/elements/table.js +371 -0
- package/src/elements/tabs.d.ts +19 -0
- package/src/elements/tabs.js +139 -0
- package/src/elements/text.d.ts +26 -0
- package/src/elements/text.js +32 -0
- package/src/elements/text_input.d.ts +36 -0
- package/src/elements/text_input.js +121 -0
- package/src/elements/thinking.d.ts +17 -0
- package/src/elements/thinking.js +28 -0
- package/src/elements/toast.d.ts +23 -0
- package/src/elements/toast.js +209 -0
- package/src/elements/toggle_group.d.ts +22 -0
- package/src/elements/toggle_group.js +176 -0
- package/src/elements/tooltip.d.ts +18 -0
- package/src/elements/tooltip.js +64 -0
- package/src/markdown.d.ts +24 -0
- package/src/markdown.js +66 -0
- package/src/runtime.d.ts +35 -0
- package/src/runtime.js +790 -0
- package/src/server.d.ts +69 -0
- package/src/server.js +176 -0
- package/src/streaming-markdown.js +43 -0
- package/src/vite-plugin.d.ts +46 -0
- package/src/vite-plugin.js +221 -0
- package/wasm/package.json +16 -0
- package/wasm/wasm_api.d.ts +72 -0
- package/wasm/wasm_api.js +593 -0
- package/wasm/wasm_api_bg.wasm +0 -0
- package/wasm/wasm_api_bg.wasm.d.ts +10 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/chat_input.rs
|
|
3
|
+
|
|
4
|
+
export interface CxChatInputAttributes {
|
|
5
|
+
id?: string;
|
|
6
|
+
shape?: 'sharp' | 'rounded' | 'pill';
|
|
7
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
maxRows?: number;
|
|
12
|
+
showActionButton?: boolean;
|
|
13
|
+
actionLabel?: string;
|
|
14
|
+
submitLabel?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare global {
|
|
19
|
+
interface HTMLElementTagNameMap {
|
|
20
|
+
'cx-chat-input': HTMLElement & CxChatInputAttributes;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Custom behavior for <cx-chat-input> — textarea auto-grow, submit, imperative focus.
|
|
2
|
+
//
|
|
3
|
+
// The Rust component renders a textarea inside shadow DOM.
|
|
4
|
+
// This Custom Element adds:
|
|
5
|
+
// - Public focus() method that delegates to the inner textarea
|
|
6
|
+
// - Input event delegation for cx-input
|
|
7
|
+
// - Submit button click delegation
|
|
8
|
+
//
|
|
9
|
+
// Source: crates/wasm-api/src/chat_input.rs
|
|
10
|
+
|
|
11
|
+
export function defineCxChatInput(wasmFn, baseClass) {
|
|
12
|
+
class CxChatInput extends baseClass {
|
|
13
|
+
static observedAttributes = ['id', 'shape', 'size', 'placeholder', 'value', 'disabled', 'show-action-button', 'action-label', 'submit-label', 'label', 'slotted'];
|
|
14
|
+
static _booleanAttrs = new Set(['disabled', 'show-action-button', 'slotted']);
|
|
15
|
+
|
|
16
|
+
set max_rows(v) { this._setProp('max_rows', v); }
|
|
17
|
+
get max_rows() { return this._props.max_rows; }
|
|
18
|
+
|
|
19
|
+
connectedCallback() {
|
|
20
|
+
if (!this._isInitialized) {
|
|
21
|
+
this._markInitialized();
|
|
22
|
+
|
|
23
|
+
// Input event delegation for cx-input
|
|
24
|
+
this._shadow.addEventListener('input', (e) => {
|
|
25
|
+
if (e.target.tagName === 'TEXTAREA') {
|
|
26
|
+
this._emit('cx-input', { value: e.target.value });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Submit button delegation
|
|
31
|
+
this._shadow.addEventListener('click', (e) => {
|
|
32
|
+
const btn = e.target.closest('[data-chat-submit]');
|
|
33
|
+
if (btn) {
|
|
34
|
+
const textarea = this._shadow.querySelector('textarea');
|
|
35
|
+
this._emit('cx-input', { value: textarea?.value || '', submit: true });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Forward focus events from inner interactive elements
|
|
40
|
+
this._shadow.addEventListener('focusin', (e) => {
|
|
41
|
+
this._emit('cx-focus', { relatedTarget: e.relatedTarget });
|
|
42
|
+
});
|
|
43
|
+
this._shadow.addEventListener('focusout', (e) => {
|
|
44
|
+
this._emit('cx-blur', { relatedTarget: e.relatedTarget });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Forward keyboard events from inner interactive elements
|
|
48
|
+
this._shadow.addEventListener('keydown', (e) => {
|
|
49
|
+
this._emit('cx-keydown', { key: e.key, code: e.code, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey, metaKey: e.metaKey });
|
|
50
|
+
});
|
|
51
|
+
this._shadow.addEventListener('keyup', (e) => {
|
|
52
|
+
this._emit('cx-keyup', { key: e.key, code: e.code, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey, metaKey: e.metaKey });
|
|
53
|
+
});
|
|
54
|
+
} // end _isInitialized guard
|
|
55
|
+
|
|
56
|
+
super.connectedCallback();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ── Public imperative API ──
|
|
60
|
+
focus() {
|
|
61
|
+
const el = this._shadow.querySelector('textarea');
|
|
62
|
+
if (el) el.focus(); else super.focus();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
_doRender() {
|
|
66
|
+
try {
|
|
67
|
+
this._props.slotted = true;
|
|
68
|
+
const result = wasmFn(this._props);
|
|
69
|
+
this._injectHtml(result);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error('[cx-chat-input]', e);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
customElements.define('cx-chat-input', CxChatInput);
|
|
77
|
+
return CxChatInput;
|
|
78
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/checkbox.rs
|
|
3
|
+
|
|
4
|
+
export interface CxCheckboxAttributes {
|
|
5
|
+
id?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
shape?: 'sharp' | 'rounded';
|
|
8
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
9
|
+
checked?: '' | 'checked' | 'indeterminate';
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
helperText?: string;
|
|
13
|
+
error?: string;
|
|
14
|
+
unlabeled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare global {
|
|
18
|
+
interface HTMLElementTagNameMap {
|
|
19
|
+
'cx-checkbox': HTMLElement & CxCheckboxAttributes;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/checkbox.rs
|
|
3
|
+
|
|
4
|
+
export function defineCxCheckbox(wasmFn, baseClass) {
|
|
5
|
+
class CxCheckbox extends baseClass {
|
|
6
|
+
static observedAttributes = ['id', 'label', 'shape', 'size', 'checked', 'disabled', 'required', 'helper-text', 'error', 'unlabeled'];
|
|
7
|
+
static _booleanAttrs = new Set(['disabled', 'required', 'unlabeled']);
|
|
8
|
+
static _hostDisplay = 'inline-flex';
|
|
9
|
+
|
|
10
|
+
// Override: Rust config expects checked as String ("checked"/"indeterminate"),
|
|
11
|
+
// but the base class converts boolean HTML attributes to true/false.
|
|
12
|
+
attributeChangedCallback(name, old, value) {
|
|
13
|
+
if (name === 'checked') {
|
|
14
|
+
// Normalize all checked representations to Rust-compatible strings:
|
|
15
|
+
// <cx-checkbox checked> → "" → "checked"
|
|
16
|
+
// <cx-checkbox checked="checked"> → "checked"
|
|
17
|
+
// <cx-checkbox checked="indeterminate"> → "indeterminate"
|
|
18
|
+
// <cx-checkbox checked="true"> → "checked" (React boolean coercion)
|
|
19
|
+
// <cx-checkbox checked="false"> → "" (React boolean coercion)
|
|
20
|
+
// attribute removed → null → ""
|
|
21
|
+
let str;
|
|
22
|
+
if (value === null || value === 'false') {
|
|
23
|
+
str = '';
|
|
24
|
+
} else if (value === '' || value === 'true' || value === 'checked') {
|
|
25
|
+
str = 'checked';
|
|
26
|
+
} else {
|
|
27
|
+
str = value; // "indeterminate" or other
|
|
28
|
+
}
|
|
29
|
+
// Skip re-render if the change handler already synced this value.
|
|
30
|
+
// Without this guard, React's attribute echo after onInput triggers
|
|
31
|
+
// a full shadow DOM innerHTML replacement that kills the CSS
|
|
32
|
+
// peer-checked transition mid-animation.
|
|
33
|
+
if (this._props.checked === str) return;
|
|
34
|
+
this._props.checked = str;
|
|
35
|
+
if (this.isConnected) this._scheduleRender();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
super.attributeChangedCallback(name, old, value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
connectedCallback() {
|
|
42
|
+
if (!this._isInitialized) {
|
|
43
|
+
this._markInitialized();
|
|
44
|
+
const shadow = this._shadow;
|
|
45
|
+
|
|
46
|
+
// Checkbox toggle: sync checked state back to props on change.
|
|
47
|
+
// The Rust component uses CSS-only peer-checked toggle (hidden input +
|
|
48
|
+
// label), so native click-on-label works. But we need to sync state
|
|
49
|
+
// back to _props so re-renders don't reset the toggle.
|
|
50
|
+
// IMPORTANT: Rust config expects checked: String ("checked"/"indeterminate"/""),
|
|
51
|
+
// NOT a boolean. The attributeChangedCallback may send true/false for
|
|
52
|
+
// boolean HTML attributes — we normalize here.
|
|
53
|
+
shadow.addEventListener('change', (e) => {
|
|
54
|
+
const input = e.target.closest('input[type="checkbox"]');
|
|
55
|
+
if (input) {
|
|
56
|
+
this._props.checked = input.checked ? 'checked' : '';
|
|
57
|
+
this._setFormValue(input.checked ? 'on' : '');
|
|
58
|
+
this._emit('cx-input', { checked: input.checked });
|
|
59
|
+
this._emit('cx-change', { checked: input.checked });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Forward focus events from inner interactive elements
|
|
64
|
+
shadow.addEventListener('focusin', (e) => {
|
|
65
|
+
this._emit('cx-focus', { relatedTarget: e.relatedTarget });
|
|
66
|
+
});
|
|
67
|
+
shadow.addEventListener('focusout', (e) => {
|
|
68
|
+
this._emit('cx-blur', { relatedTarget: e.relatedTarget });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Forward keyboard events from inner interactive elements
|
|
72
|
+
shadow.addEventListener('keydown', (e) => {
|
|
73
|
+
this._emit('cx-keydown', { key: e.key, code: e.code, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey, metaKey: e.metaKey });
|
|
74
|
+
});
|
|
75
|
+
shadow.addEventListener('keyup', (e) => {
|
|
76
|
+
this._emit('cx-keyup', { key: e.key, code: e.code, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey, metaKey: e.metaKey });
|
|
77
|
+
});
|
|
78
|
+
} // end _isInitialized guard
|
|
79
|
+
super.connectedCallback();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ── Property: checked (boolean | string) ──
|
|
83
|
+
// Accepts boolean (true/false) or string ("checked"/"indeterminate"/"")
|
|
84
|
+
// for programmatic use: el.checked = true
|
|
85
|
+
set checked(v) {
|
|
86
|
+
if (typeof v === 'boolean') {
|
|
87
|
+
this.attributeChangedCallback('checked', null, v ? 'checked' : '');
|
|
88
|
+
} else {
|
|
89
|
+
this.attributeChangedCallback('checked', null, v);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
get checked() { return this._props.checked === 'checked'; }
|
|
93
|
+
|
|
94
|
+
// ── Public imperative API ──
|
|
95
|
+
focus() { const el = this._shadow.querySelector('input[type="checkbox"]'); if (el) el.focus(); else super.focus(); }
|
|
96
|
+
|
|
97
|
+
_doRender() {
|
|
98
|
+
try {
|
|
99
|
+
const result = wasmFn(this._props);
|
|
100
|
+
this._injectHtml(result);
|
|
101
|
+
// Sync form value after render. Event delegation on shadow root
|
|
102
|
+
// avoids duplicate listeners (innerHTML replaces old DOM nodes,
|
|
103
|
+
// but shadow root persists — delegation handles new inputs).
|
|
104
|
+
const input = this._shadow.querySelector('input, textarea, select');
|
|
105
|
+
if (input) this._setFormValue(input.value || '');
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.error('[cx-checkbox]', e);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
customElements.define('cx-checkbox', CxCheckbox);
|
|
113
|
+
return CxCheckbox;
|
|
114
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/code_block.rs
|
|
3
|
+
|
|
4
|
+
export interface CxCodeBlockAttributes {
|
|
5
|
+
id?: string;
|
|
6
|
+
content?: string;
|
|
7
|
+
variant?: string;
|
|
8
|
+
shape?: string;
|
|
9
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
10
|
+
language?: string;
|
|
11
|
+
filename?: string;
|
|
12
|
+
lineNumbers?: boolean;
|
|
13
|
+
copyButton?: boolean;
|
|
14
|
+
trafficLights?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare global {
|
|
18
|
+
interface HTMLElementTagNameMap {
|
|
19
|
+
'cx-code-block': HTMLElement & CxCodeBlockAttributes;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/code_block.rs
|
|
3
|
+
|
|
4
|
+
export function defineCxCodeBlock(wasmFn, baseClass) {
|
|
5
|
+
class CxCodeBlock extends baseClass {
|
|
6
|
+
static observedAttributes = ['id', 'content', 'variant', 'shape', 'size', 'language', 'filename', 'line-numbers', 'copy-button', 'traffic-lights', 'slotted'];
|
|
7
|
+
static _booleanAttrs = new Set(['line-numbers', 'copy-button', 'traffic-lights', 'slotted']);
|
|
8
|
+
static _hostDisplay = 'block';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
connectedCallback() {
|
|
12
|
+
super.connectedCallback();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
_doRender() {
|
|
16
|
+
try {
|
|
17
|
+
const result = wasmFn(this._props);
|
|
18
|
+
this._injectHtml(result);
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.error('[cx-code-block]', e);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
customElements.define('cx-code-block', CxCodeBlock);
|
|
26
|
+
return CxCodeBlock;
|
|
27
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/collapsible.rs
|
|
3
|
+
|
|
4
|
+
export interface CxCollapsibleAttributes {
|
|
5
|
+
id?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
content?: string;
|
|
8
|
+
triggerHtml?: string;
|
|
9
|
+
open?: boolean;
|
|
10
|
+
icon?: string;
|
|
11
|
+
noIcon?: boolean;
|
|
12
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare global {
|
|
17
|
+
interface HTMLElementTagNameMap {
|
|
18
|
+
'cx-collapsible': HTMLElement & CxCollapsibleAttributes;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Custom behavior for <cx-collapsible> — toggle expanded/collapsed state.
|
|
2
|
+
// Mirrors static/_behaviors/collapsible.js but operates inside shadow DOM.
|
|
3
|
+
// Source: crates/wasm-api/src/collapsible.rs
|
|
4
|
+
|
|
5
|
+
export function defineCxCollapsible(wasmFn, baseClass) {
|
|
6
|
+
class CxCollapsible extends baseClass {
|
|
7
|
+
static observedAttributes = ['id', 'label', 'trigger-html', 'open', 'icon', 'no-icon', 'size', 'disabled'];
|
|
8
|
+
static _booleanAttrs = new Set(['open', 'no-icon', 'disabled']);
|
|
9
|
+
|
|
10
|
+
connectedCallback() {
|
|
11
|
+
if (!this._isInitialized) {
|
|
12
|
+
this._markInitialized();
|
|
13
|
+
const shadow = this._shadow;
|
|
14
|
+
|
|
15
|
+
// Click: toggle collapsible trigger
|
|
16
|
+
shadow.addEventListener('click', (e) => {
|
|
17
|
+
const trigger = e.target.closest('[data-collapsible-trigger]');
|
|
18
|
+
if (!trigger || trigger.disabled) return;
|
|
19
|
+
|
|
20
|
+
const expanded = trigger.getAttribute('aria-expanded') === 'true';
|
|
21
|
+
const newOpen = !expanded;
|
|
22
|
+
|
|
23
|
+
// Mutate shadow DOM directly for smooth CSS animation
|
|
24
|
+
// (WASM re-render via innerHTML would destroy DOM and kill transition)
|
|
25
|
+
this.#setOpen(trigger, newOpen);
|
|
26
|
+
|
|
27
|
+
// Sync host prop — single source of truth for WASM re-renders.
|
|
28
|
+
// Direct _props mutation avoids triggering a re-render that would
|
|
29
|
+
// destroy DOM state and kill the panel animation. External attribute
|
|
30
|
+
// changes (e.g., React setting open={false}) still trigger WASM
|
|
31
|
+
// re-render via attributeChangedCallback.
|
|
32
|
+
this._props.open = newOpen;
|
|
33
|
+
|
|
34
|
+
this._emit('cx-change', { open: newOpen });
|
|
35
|
+
});
|
|
36
|
+
} // end _isInitialized guard
|
|
37
|
+
|
|
38
|
+
super.connectedCallback();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ── Public imperative API ──
|
|
42
|
+
// These manipulate DOM state directly instead of simulating clicks,
|
|
43
|
+
// so they do NOT emit cx-change events (the caller already knows).
|
|
44
|
+
// Each method syncs the host prop to prevent stale state on re-render.
|
|
45
|
+
open() {
|
|
46
|
+
const trigger = this._shadow.querySelector('[data-collapsible-trigger]');
|
|
47
|
+
if (!trigger || trigger.getAttribute('aria-expanded') === 'true') return;
|
|
48
|
+
this.#setOpen(trigger, true);
|
|
49
|
+
this._props.open = true;
|
|
50
|
+
}
|
|
51
|
+
close() {
|
|
52
|
+
const trigger = this._shadow.querySelector('[data-collapsible-trigger]');
|
|
53
|
+
if (!trigger || trigger.getAttribute('aria-expanded') !== 'true') return;
|
|
54
|
+
this.#setOpen(trigger, false);
|
|
55
|
+
this._props.open = false;
|
|
56
|
+
}
|
|
57
|
+
toggle() {
|
|
58
|
+
const trigger = this._shadow.querySelector('[data-collapsible-trigger]');
|
|
59
|
+
if (!trigger) return;
|
|
60
|
+
const newOpen = trigger.getAttribute('aria-expanded') !== 'true';
|
|
61
|
+
this.#setOpen(trigger, newOpen);
|
|
62
|
+
this._props.open = newOpen;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#setOpen(trigger, open) {
|
|
66
|
+
trigger.setAttribute('aria-expanded', String(open));
|
|
67
|
+
const root = this._shadow.querySelector('[data-collapsible]');
|
|
68
|
+
const panel = this._shadow.querySelector('[data-collapsible-panel]');
|
|
69
|
+
if (panel) {
|
|
70
|
+
if (open) {
|
|
71
|
+
panel.removeAttribute('data-collapsed');
|
|
72
|
+
if (root) root.setAttribute('data-state', 'open');
|
|
73
|
+
} else {
|
|
74
|
+
panel.setAttribute('data-collapsed', '');
|
|
75
|
+
if (root) root.setAttribute('data-state', 'closed');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
_doRender() {
|
|
81
|
+
try {
|
|
82
|
+
this._props.slotted = true;
|
|
83
|
+
const result = wasmFn(this._props);
|
|
84
|
+
this._injectHtml(result);
|
|
85
|
+
} catch (e) {
|
|
86
|
+
console.error('[cx-collapsible]', e);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
customElements.define('cx-collapsible', CxCollapsible);
|
|
92
|
+
return CxCollapsible;
|
|
93
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Auto-generated by scripts/generate-elements.mjs — DO NOT EDIT
|
|
2
|
+
// Source: crates/wasm-api/src/date_picker.rs
|
|
3
|
+
|
|
4
|
+
export interface CxDatePickerAttributes {
|
|
5
|
+
id?: string;
|
|
6
|
+
label: string;
|
|
7
|
+
variant?: 'outline' | 'filled' | 'ghost';
|
|
8
|
+
shape?: 'sharp' | 'rounded';
|
|
9
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
10
|
+
selected?: string;
|
|
11
|
+
min?: string;
|
|
12
|
+
max?: string;
|
|
13
|
+
disabledDates?: string;
|
|
14
|
+
format?: 'iso' | 'us-short' | 'eu-short' | 'eu-dot';
|
|
15
|
+
firstDay?: 'monday' | 'sunday';
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
helperText?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
required?: boolean;
|
|
21
|
+
readonly?: boolean;
|
|
22
|
+
name?: string;
|
|
23
|
+
onChange?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare global {
|
|
27
|
+
interface HTMLElementTagNameMap {
|
|
28
|
+
'cx-date-picker': HTMLElement & CxDatePickerAttributes;
|
|
29
|
+
}
|
|
30
|
+
}
|