@colletdev/core 0.1.7 → 0.1.9
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/custom-elements.json +2 -2
- package/generated/index.js +1 -1
- package/package.json +1 -1
- package/src/elements/code_block.js +32 -2
- package/src/elements/text.d.ts +1 -1
- package/src/elements/text.js +1 -1
- package/src/runtime.js +18 -1
- package/wasm/wasm_api_bg.wasm +0 -0
package/custom-elements.json
CHANGED
|
@@ -5205,12 +5205,12 @@
|
|
|
5205
5205
|
"fieldName": "id"
|
|
5206
5206
|
},
|
|
5207
5207
|
{
|
|
5208
|
-
"name": "role",
|
|
5208
|
+
"name": "text-role",
|
|
5209
5209
|
"type": {
|
|
5210
5210
|
"text": "'display' | 'h1' | 'h2' | 'h3' | 'label-lg' | 'label-md' | 'label-sm' | 'body-lg' | 'body-md' | 'body-sm' | 'overline' | 'caption' | 'code'"
|
|
5211
5211
|
},
|
|
5212
5212
|
"default": "\"\"",
|
|
5213
|
-
"fieldName": "
|
|
5213
|
+
"fieldName": "text_role"
|
|
5214
5214
|
},
|
|
5215
5215
|
{
|
|
5216
5216
|
"name": "align",
|
package/generated/index.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { initWasm, loadSharedStyles, loadInlineSharedStyles, loadMotionStyles, loadInlineMotionStyles, injectTokensToHead, injectFoucPrevention, CxElement, CxFormElement } from '../src/runtime.js';
|
|
24
24
|
|
|
25
25
|
// Package version — used for CDN fallback URL
|
|
26
|
-
const PKG_VERSION = '0.1.
|
|
26
|
+
const PKG_VERSION = '0.1.8';
|
|
27
27
|
|
|
28
28
|
// ─── Lazy WASM + CSS ───
|
|
29
29
|
// WASM glue and CSS strings are NOT imported at module level.
|
package/package.json
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Custom behavior for <cx-code-block> — copy-to-clipboard with visual feedback.
|
|
2
|
+
//
|
|
3
|
+
// The Rust component renders a [data-copy-code] button in the titlebar
|
|
4
|
+
// (Standard variant) or as a group-hover overlay (Minimal variant).
|
|
5
|
+
// This Custom Element adds clipboard write + icon swap on click.
|
|
6
|
+
//
|
|
2
7
|
// Source: crates/wasm-api/src/code_block.rs
|
|
3
8
|
|
|
4
9
|
export function defineCxCodeBlock(wasmFn, baseClass) {
|
|
@@ -7,8 +12,33 @@ export function defineCxCodeBlock(wasmFn, baseClass) {
|
|
|
7
12
|
static _booleanAttrs = new Set(['line-numbers', 'copy-button', 'traffic-lights', 'slotted']);
|
|
8
13
|
static _hostDisplay = 'block';
|
|
9
14
|
|
|
10
|
-
|
|
11
15
|
connectedCallback() {
|
|
16
|
+
if (!this._isInitialized) {
|
|
17
|
+
this._markInitialized();
|
|
18
|
+
|
|
19
|
+
// Copy button click → clipboard write → icon swap feedback.
|
|
20
|
+
this._shadow.addEventListener('click', (e) => {
|
|
21
|
+
const copyBtn = e.target.closest('[data-copy-code]');
|
|
22
|
+
if (!copyBtn) return;
|
|
23
|
+
|
|
24
|
+
const codeEl = this._shadow.querySelector('[data-code-content]');
|
|
25
|
+
if (!codeEl) return;
|
|
26
|
+
|
|
27
|
+
const text = codeEl.textContent || '';
|
|
28
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
29
|
+
const iconSpan = copyBtn.querySelector('span');
|
|
30
|
+
if (!iconSpan) return;
|
|
31
|
+
const original = iconSpan.innerHTML;
|
|
32
|
+
iconSpan.innerHTML = '<svg class="size-full" aria-hidden="true"><use href="#icon-check"></use></svg>';
|
|
33
|
+
copyBtn.setAttribute('aria-label', 'Copied!');
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
iconSpan.innerHTML = original;
|
|
36
|
+
copyBtn.setAttribute('aria-label', 'Copy code');
|
|
37
|
+
}, 2000);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
} // end _isInitialized guard
|
|
41
|
+
|
|
12
42
|
super.connectedCallback();
|
|
13
43
|
}
|
|
14
44
|
|
package/src/elements/text.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
export interface CxTextAttributes {
|
|
5
5
|
id?: string;
|
|
6
|
-
|
|
6
|
+
textRole?: 'display' | 'h1' | 'h2' | 'h3' | 'label-lg' | 'label-md' | 'label-sm' | 'body-lg' | 'body-md' | 'body-sm' | 'overline' | 'caption' | 'code';
|
|
7
7
|
content?: string;
|
|
8
8
|
align?: 'start' | 'center' | 'end';
|
|
9
9
|
color?: 'primary' | 'inverse' | 'muted';
|
package/src/elements/text.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
export function defineCxText(wasmFn, baseClass) {
|
|
5
5
|
class CxText extends baseClass {
|
|
6
|
-
static observedAttributes = ['id', 'role', 'align', 'color', 'muted', 'strong', 'italic', 'underline', 'underline-strong', 'truncate', 'line-clamp', 'balance', 'prose', 'element-as'];
|
|
6
|
+
static observedAttributes = ['id', 'text-role', 'align', 'color', 'muted', 'strong', 'italic', 'underline', 'underline-strong', 'truncate', 'line-clamp', 'balance', 'prose', 'element-as'];
|
|
7
7
|
static _booleanAttrs = new Set(['muted', 'strong', 'italic', 'underline', 'underline-strong', 'truncate', 'balance', 'prose']);
|
|
8
8
|
static _numericAttrs = new Set(['line-clamp']);
|
|
9
9
|
static _focusable = false;
|
package/src/runtime.js
CHANGED
|
@@ -694,23 +694,38 @@ export class CxElement extends HTMLElementBase {
|
|
|
694
694
|
const rect = trigger.getBoundingClientRect();
|
|
695
695
|
const gap = opts?.gap ?? 4;
|
|
696
696
|
const vh = window.innerHeight;
|
|
697
|
+
const vw = window.innerWidth;
|
|
697
698
|
const below = vh - rect.bottom - gap;
|
|
698
699
|
const above = rect.top - gap;
|
|
699
700
|
const openAbove = below < 120 && above > below;
|
|
700
701
|
|
|
701
702
|
panel.style.position = 'fixed';
|
|
702
703
|
panel.style.zIndex = '50';
|
|
703
|
-
|
|
704
|
+
|
|
705
|
+
// Width: match trigger or use min-width
|
|
704
706
|
if (opts?.matchWidth) panel.style.width = rect.width + 'px';
|
|
705
707
|
else panel.style.minWidth = rect.width + 'px';
|
|
706
708
|
|
|
709
|
+
// Horizontal: clamp left edge so panel doesn't overflow right viewport edge.
|
|
710
|
+
// Also prevent negative left (overflow left edge).
|
|
711
|
+
const panelWidth = opts?.matchWidth ? rect.width : Math.max(rect.width, panel.offsetWidth || 200);
|
|
712
|
+
let left = rect.left;
|
|
713
|
+
if (left + panelWidth > vw - 8) left = Math.max(8, vw - panelWidth - 8);
|
|
714
|
+
if (left < 8) left = 8;
|
|
715
|
+
panel.style.left = left + 'px';
|
|
716
|
+
|
|
717
|
+
// Vertical: position above or below with max-height constraint.
|
|
718
|
+
// Reserves 8px margin from viewport edge so panels never touch the edge.
|
|
707
719
|
if (openAbove) {
|
|
708
720
|
panel.style.top = '';
|
|
709
721
|
panel.style.bottom = (vh - rect.top + gap) + 'px';
|
|
722
|
+
panel.style.maxHeight = (above - 8) + 'px';
|
|
710
723
|
} else {
|
|
711
724
|
panel.style.top = (rect.bottom + gap) + 'px';
|
|
712
725
|
panel.style.bottom = '';
|
|
726
|
+
panel.style.maxHeight = (below - 8) + 'px';
|
|
713
727
|
}
|
|
728
|
+
panel.style.overflowY = 'auto';
|
|
714
729
|
|
|
715
730
|
panel.setAttribute('data-placement', openAbove ? 'top' : 'bottom');
|
|
716
731
|
return openAbove ? 'top' : 'bottom';
|
|
@@ -726,6 +741,8 @@ export class CxElement extends HTMLElementBase {
|
|
|
726
741
|
panel.style.bottom = '';
|
|
727
742
|
panel.style.width = '';
|
|
728
743
|
panel.style.minWidth = '';
|
|
744
|
+
panel.style.maxHeight = '';
|
|
745
|
+
panel.style.overflowY = '';
|
|
729
746
|
panel.removeAttribute('data-placement');
|
|
730
747
|
}
|
|
731
748
|
}
|
package/wasm/wasm_api_bg.wasm
CHANGED
|
Binary file
|