@antadesign/anta 0.3.10 → 0.3.12
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/components/Button.d.ts +4 -46
- package/dist/components/Button.js +7 -25
- package/dist/components/ButtonCopy.d.ts +45 -21
- package/dist/components/ButtonCopy.js +46 -4
- package/dist/components/Expander.js +1 -1
- package/dist/components/MenuItem.d.ts +2 -8
- package/dist/components/MenuItem.js +2 -14
- package/dist/components/MenuItemCopy.d.ts +23 -19
- package/dist/components/MenuItemCopy.js +38 -3
- package/dist/components/Select.d.ts +8 -0
- package/dist/components/Select.js +4 -0
- package/dist/components/SelectFaceted.d.ts +8 -0
- package/dist/components/SelectFaceted.js +4 -0
- package/dist/components/copy-props.d.ts +72 -0
- package/dist/components/copy-props.js +20 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-button.d.ts +0 -4
- package/dist/elements/a-button.js +7 -20
- package/dist/elements/a-copy.css +1 -0
- package/dist/elements/a-copy.d.ts +16 -0
- package/dist/elements/a-copy.js +148 -0
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.js +20 -19
- package/dist/elements/a-menu-item.d.ts +8 -1
- package/dist/elements/a-menu-item.js +7 -11
- package/dist/elements/a-menu.d.ts +6 -2
- package/dist/elements/a-menu.js +35 -5
- package/dist/elements/copy-behavior.d.ts +31 -13
- package/dist/elements/copy-behavior.js +20 -18
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/elements/key-activation.d.ts +28 -0
- package/dist/elements/key-activation.js +32 -0
- package/dist/general_types.d.ts +27 -37
- package/dist/index.d.ts +2 -1
- package/dist/jsx-runtime.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Copy-to-clipboard behavior for the `<a-copy>` element — the write half of the
|
|
3
|
+
* productized "copy button" / "copying menu item". `<a-copy>` (slotted inside a
|
|
4
|
+
* button or menu row) calls these on the host's activation: it performs the
|
|
5
|
+
* clipboard write itself (rather than a UI-thread callback) and reports the
|
|
6
|
+
* outcome with a `copydone` event; the JSX wrapper (`ButtonCopy` / `MenuItemCopy`)
|
|
7
|
+
* listens and orchestrates the visual feedback (icon + tone swap). Nothing here touches the
|
|
7
8
|
* DOM — no light-DOM mutation, no host attributes, no ElementInternals.
|
|
8
9
|
*
|
|
9
10
|
* Events are dispatched non-bubbling (`bubbles: false`): the wrapper binds on the
|
|
@@ -11,23 +12,40 @@
|
|
|
11
12
|
* nested copy row's `copydone` from flipping an ancestor copy row's feedback
|
|
12
13
|
* (the same point-to-point rule Anta's `statechange` follows).
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
+
* Modes, chosen by attribute:
|
|
15
16
|
* - `copy="<text>"` — copy the literal string on activation.
|
|
17
|
+
* - `copy-url` — copy the current page URL (`location.href`); no `copy` needed.
|
|
18
|
+
* - `copy-with-url` — prefix the copied `copy` string with `// URL: <href>`.
|
|
16
19
|
* - `copy-node` / `copy-node="<selector>"` — copy a DOM node as rich text
|
|
17
20
|
* (`text/html`) + plain text. Bare `copy-node` copies the nearest ancestor
|
|
18
21
|
* marked `[data-copy-source]`; a value is a selector resolved with `closest()`
|
|
19
22
|
* (an ancestor region). The copy control is stripped from the serialized
|
|
20
23
|
* output (`[data-copy-node-button]`).
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
*
|
|
25
|
+
* ## Lazy content (off-UI-thread safe)
|
|
26
|
+
*
|
|
27
|
+
* When the content isn't known ahead of time, the element emits a `copyrequest`
|
|
28
|
+
* event on **pointerdown** (`emitCopyRequest`, fired whenever a `copy` attribute
|
|
29
|
+
* is present). The consumer answers by setting the `copy` attribute to the
|
|
30
|
+
* freshly-computed value; the **click** then reads that value and writes it. The
|
|
31
|
+
* pointerdown→click gap absorbs the round-trip, so this works even when the
|
|
32
|
+
* consumer's handler runs off the UI thread (e.g. a worker-rendered app): only a
|
|
33
|
+
* serializable string crosses the boundary via the normal reconcile — no
|
|
34
|
+
* callback, and the write stays inside the click's transient activation. This is
|
|
35
|
+
* why there is no `provide`-function handoff and no `copy-lazy` marker.
|
|
26
36
|
*
|
|
27
37
|
* Precedence when several are set (the discriminated-union prop types make this
|
|
28
|
-
* unreachable from the wrappers, but hand-authored markup can): node →
|
|
29
|
-
* literal `copy
|
|
38
|
+
* unreachable from the wrappers, but hand-authored markup can): node → url →
|
|
39
|
+
* literal `copy` (with the optional URL prefix).
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Ask a lazy consumer to refresh the copy content, on pointerdown — dispatch a
|
|
43
|
+
* non-bubbling, payload-free `copyrequest`. The consumer answers by setting the
|
|
44
|
+
* `copy` attribute to the freshly-computed value before the click reads it (see
|
|
45
|
+
* the "Lazy content" note above). Fires only for string-copy controls; node/url
|
|
46
|
+
* modes resolve themselves at click time and need no request. No-op otherwise.
|
|
30
47
|
*/
|
|
48
|
+
export declare function emitCopyRequest(el: HTMLElement): void;
|
|
31
49
|
/**
|
|
32
50
|
* Perform a copy on activation (click / Enter / Space / menu select). Returns
|
|
33
51
|
* `true` if the element is a copy control (so the caller knows the copy path
|
|
@@ -37,32 +37,34 @@ function run(el, work) {
|
|
|
37
37
|
el.dispatchEvent(new CustomEvent("copydone", { bubbles: false, detail: { ok } }));
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
+
function currentUrl() {
|
|
41
|
+
return typeof location !== "undefined" ? location.href : "";
|
|
42
|
+
}
|
|
43
|
+
function resolveText(el) {
|
|
44
|
+
if (el.hasAttribute("copy-url")) return currentUrl();
|
|
45
|
+
const base = el.getAttribute("copy") ?? "";
|
|
46
|
+
if (el.hasAttribute("copy-with-url")) return `// URL: ${currentUrl()}
|
|
47
|
+
${base}`;
|
|
48
|
+
return base;
|
|
49
|
+
}
|
|
50
|
+
function isTextCopy(el) {
|
|
51
|
+
return el.hasAttribute("copy") || el.hasAttribute("copy-url");
|
|
52
|
+
}
|
|
53
|
+
function emitCopyRequest(el) {
|
|
54
|
+
if (!el.hasAttribute("copy")) return;
|
|
55
|
+
el.dispatchEvent(new CustomEvent("copyrequest", { bubbles: false }));
|
|
56
|
+
}
|
|
40
57
|
function runCopy(el) {
|
|
41
58
|
if (el.hasAttribute("copy-node")) {
|
|
42
59
|
const target = resolveNodeTarget(el);
|
|
43
60
|
run(el, target ? writeNode(target) : Promise.resolve(false));
|
|
44
61
|
return true;
|
|
45
62
|
}
|
|
46
|
-
if (el
|
|
47
|
-
|
|
48
|
-
el.dispatchEvent(
|
|
49
|
-
new CustomEvent("copyrequest", {
|
|
50
|
-
bubbles: false,
|
|
51
|
-
detail: {
|
|
52
|
-
provide(text) {
|
|
53
|
-
if (done) return;
|
|
54
|
-
done = true;
|
|
55
|
-
run(el, writeText(String(text ?? "")));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
);
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
if (!el.hasAttribute("copy")) return false;
|
|
63
|
-
run(el, writeText(el.getAttribute("copy") ?? ""));
|
|
63
|
+
if (!isTextCopy(el)) return false;
|
|
64
|
+
run(el, writeText(resolveText(el)));
|
|
64
65
|
return true;
|
|
65
66
|
}
|
|
66
67
|
export {
|
|
68
|
+
emitCopyRequest,
|
|
67
69
|
runCopy
|
|
68
70
|
};
|
package/dist/elements/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export { AProgressElement, register_a_progress } from './a-progress';
|
|
|
17
17
|
export { ATextElement, register_a_text } from './a-text';
|
|
18
18
|
export { AIconElement, register_a_icon } from './a-icon';
|
|
19
19
|
export { AButtonElement, register_a_button } from './a-button';
|
|
20
|
+
export { ACopyElement, register_a_copy } from './a-copy';
|
|
20
21
|
export { ACheckboxElement, register_a_checkbox } from './a-checkbox';
|
|
21
22
|
export { AExpanderElement, register_a_expander } from './a-expander';
|
|
22
23
|
export { ATooltipElement, register_a_tooltip } from './a-tooltip';
|
package/dist/elements/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AProgressElement, register_a_progress } from "./a-progress";
|
|
|
2
2
|
import { ATextElement, register_a_text } from "./a-text";
|
|
3
3
|
import { AIconElement, register_a_icon } from "./a-icon";
|
|
4
4
|
import { AButtonElement, register_a_button } from "./a-button";
|
|
5
|
+
import { ACopyElement, register_a_copy } from "./a-copy";
|
|
5
6
|
import { ACheckboxElement, register_a_checkbox } from "./a-checkbox";
|
|
6
7
|
import { AExpanderElement, register_a_expander } from "./a-expander";
|
|
7
8
|
import { ATooltipElement, register_a_tooltip } from "./a-tooltip";
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
ACalendarElement,
|
|
27
28
|
ACardElement,
|
|
28
29
|
ACheckboxElement,
|
|
30
|
+
ACopyElement,
|
|
29
31
|
ADialogElement,
|
|
30
32
|
AExpanderElement,
|
|
31
33
|
AIconElement,
|
|
@@ -47,6 +49,7 @@ export {
|
|
|
47
49
|
register_a_calendar,
|
|
48
50
|
register_a_card,
|
|
49
51
|
register_a_checkbox,
|
|
52
|
+
register_a_copy,
|
|
50
53
|
register_a_dialog,
|
|
51
54
|
register_a_expander,
|
|
52
55
|
register_a_icon,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared "activate on key release" for Enter / Space, used by `<a-button>` and
|
|
3
|
+
* `<a-menu-item>` (via one delegated keydown/keyup pair per document).
|
|
4
|
+
*
|
|
5
|
+
* Activation fires on **keyup**, not keydown. This matches the native `<button>`
|
|
6
|
+
* (Space already activates on release), makes activation **cancelable** (move
|
|
7
|
+
* focus between press and release → no fire), and opens a **keydown→keyup gap**.
|
|
8
|
+
* A slotted `<a-copy>` uses that gap for its own lazy pre-request (it runs its
|
|
9
|
+
* own keydown listener); this module just synthesizes the click on release.
|
|
10
|
+
*
|
|
11
|
+
* keydown: `preventDefault()` (stop Space scrolling the page and a link's own
|
|
12
|
+
* native Enter→click) and arm the release. keyup: `activate(el)` only if the
|
|
13
|
+
* same element is still armed.
|
|
14
|
+
*
|
|
15
|
+
* Idempotency is the caller's job (each guards with its own per-document flag);
|
|
16
|
+
* this just wires one keydown/keyup pair.
|
|
17
|
+
*/
|
|
18
|
+
export interface KeyActivation {
|
|
19
|
+
/** Keys that activate — `['Enter', ' ']` for buttons/menu items. */
|
|
20
|
+
keys: readonly string[];
|
|
21
|
+
/** Resolve the activatable element from the event target (e.g. `closest`). */
|
|
22
|
+
resolve(target: EventTarget | null): HTMLElement | null;
|
|
23
|
+
/** Blocked (disabled / loading) — swallow the key without activating. */
|
|
24
|
+
blocked?(el: HTMLElement): boolean;
|
|
25
|
+
/** Runs on keyup: the actual activation (a synthesized `click()`). */
|
|
26
|
+
activate(el: HTMLElement): void;
|
|
27
|
+
}
|
|
28
|
+
export declare function installKeyActivation(doc: Document, config: KeyActivation): void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function installKeyActivation(doc, config) {
|
|
2
|
+
let armed = null;
|
|
3
|
+
doc.addEventListener(
|
|
4
|
+
"keydown",
|
|
5
|
+
(e) => {
|
|
6
|
+
if (e.repeat || !config.keys.includes(e.key)) return;
|
|
7
|
+
const el = config.resolve(e.target);
|
|
8
|
+
if (!el) return;
|
|
9
|
+
e.preventDefault();
|
|
10
|
+
armed = config.blocked?.(el) ? null : el;
|
|
11
|
+
},
|
|
12
|
+
true
|
|
13
|
+
);
|
|
14
|
+
doc.addEventListener(
|
|
15
|
+
"keyup",
|
|
16
|
+
(e) => {
|
|
17
|
+
if (!config.keys.includes(e.key)) return;
|
|
18
|
+
const el = config.resolve(e.target);
|
|
19
|
+
if (!el || el !== armed) {
|
|
20
|
+
armed = null;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
armed = null;
|
|
24
|
+
if (config.blocked?.(el)) return;
|
|
25
|
+
config.activate(el);
|
|
26
|
+
},
|
|
27
|
+
true
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
installKeyActivation
|
|
32
|
+
};
|
package/dist/general_types.d.ts
CHANGED
|
@@ -727,26 +727,6 @@ export interface AMenuItemAttributes extends BaseAttributes {
|
|
|
727
727
|
* a `MouseEvent`, carrying the modifier keys (e.g. `altKey`). All-lowercase so
|
|
728
728
|
* React/Preact bind it to the CustomEvent. */
|
|
729
729
|
onmenuselect?: (e: MouseEvent) => void;
|
|
730
|
-
/** Text copied to the clipboard when the row is chosen (a "copying menu item").
|
|
731
|
-
* The element performs the write itself on `menuselect`. */
|
|
732
|
-
copy?: string;
|
|
733
|
-
/** Copy a DOM node instead of a string (rich `text/html` + plain text). Bare
|
|
734
|
-
* `copy-node` copies the nearest ancestor marked `[data-copy-source]`; a value
|
|
735
|
-
* is a CSS selector resolved with `closest()`. Presence-based for the boolean
|
|
736
|
-
* form. */
|
|
737
|
-
'copy-node'?: boolean | string;
|
|
738
|
-
/** Lazy copy: with an empty `copy`, activation dispatches `copyrequest` and the
|
|
739
|
-
* write completes once `copy` is set back (within the activation window).
|
|
740
|
-
* Presence-based. */
|
|
741
|
-
'copy-lazy'?: boolean | '';
|
|
742
|
-
/** Fired after a copy attempt (bubbling `copydone`, `detail: { ok }`).
|
|
743
|
-
* All-lowercase so it binds in React *and* Preact. */
|
|
744
|
-
oncopydone?: (e: CustomEvent<{
|
|
745
|
-
ok: boolean;
|
|
746
|
-
}>) => void;
|
|
747
|
-
/** Fired on a lazy copy activation to request the content (bubbling
|
|
748
|
-
* `copyrequest`). Answer by setting the `copy` attribute. All-lowercase. */
|
|
749
|
-
oncopyrequest?: (e: CustomEvent) => void;
|
|
750
730
|
}
|
|
751
731
|
/**
|
|
752
732
|
* Attributes for the `<a-menu-group>` styled element. For the typed JSX
|
|
@@ -790,32 +770,42 @@ export interface AButtonAttributes extends BaseAttributes {
|
|
|
790
770
|
form?: string;
|
|
791
771
|
/** Custom event name dispatched (bubbling) on click. */
|
|
792
772
|
'data-custom-event'?: string;
|
|
793
|
-
|
|
794
|
-
|
|
773
|
+
'aria-disabled'?: 'true' | 'false' | boolean;
|
|
774
|
+
'aria-busy'?: 'true' | 'false' | boolean;
|
|
775
|
+
}
|
|
776
|
+
/** `<a-copy>` — the copy-to-clipboard behavior, slotted inside an activatable
|
|
777
|
+
* control (`<a-button>`, `<a-menu-item>`, native `button`/`[role]`). It owns
|
|
778
|
+
* the whole feature; the base controls carry no copy knowledge. `ButtonCopy` /
|
|
779
|
+
* `MenuItemCopy` are the presets that drop it in. */
|
|
780
|
+
export interface ACopyAttributes extends BaseAttributes {
|
|
781
|
+
/** Text copied to the clipboard when the host control is activated. */
|
|
795
782
|
copy?: string;
|
|
796
783
|
/** Copy a DOM node instead of a string (rich `text/html` + plain text). Bare
|
|
797
784
|
* `copy-node` copies the nearest ancestor marked `[data-copy-source]`; a value
|
|
798
|
-
* is a CSS selector resolved with `closest()` (an ancestor region).
|
|
799
|
-
*
|
|
785
|
+
* is a CSS selector resolved with `closest()` (an ancestor region). The copy
|
|
786
|
+
* control is stripped from the serialized output. Presence-based for the
|
|
787
|
+
* boolean form. */
|
|
800
788
|
'copy-node'?: boolean | string;
|
|
801
|
-
/**
|
|
802
|
-
* `
|
|
803
|
-
|
|
804
|
-
|
|
789
|
+
/** Copy the current page URL (`location.href`) instead of a `copy` string; no
|
|
790
|
+
* `copy` needed. Presence-based. */
|
|
791
|
+
'copy-url'?: boolean | '';
|
|
792
|
+
/** Prefix the copied `copy` string with `// URL: <href>`. Presence-based. */
|
|
793
|
+
'copy-with-url'?: boolean | '';
|
|
794
|
+
/** Float a ghost of the host's content upward as visual feedback on a
|
|
795
|
+
* successful copy (rendered in the top layer so the host's overflow can't clip
|
|
796
|
+
* it). Presence-based. Opt-in — `ButtonCopy` sets it. */
|
|
797
|
+
toast?: boolean | '';
|
|
805
798
|
/** Fired after a copy attempt (`copydone`, `detail: { ok }`, non-bubbling so a
|
|
806
|
-
* nested copy
|
|
799
|
+
* nested copy control can't flip an ancestor's feedback). All-lowercase so it
|
|
807
800
|
* binds in React *and* Preact. */
|
|
808
801
|
oncopydone?: (e: CustomEvent<{
|
|
809
802
|
ok: boolean;
|
|
810
803
|
}>) => void;
|
|
811
|
-
/** Fired on a
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
}>) => void;
|
|
817
|
-
'aria-disabled'?: 'true' | 'false' | boolean;
|
|
818
|
-
'aria-busy'?: 'true' | 'false' | boolean;
|
|
804
|
+
/** Fired on **pointerdown** / keydown for a string-copy control (`copyrequest`,
|
|
805
|
+
* non-bubbling). Answer by setting the `copy` attribute to the freshly-computed
|
|
806
|
+
* value; the activation then copies it. The gap lets an off-UI-thread handler
|
|
807
|
+
* set `copy` in time. All-lowercase. */
|
|
808
|
+
oncopyrequest?: (e: CustomEvent) => void;
|
|
819
809
|
}
|
|
820
810
|
/**
|
|
821
811
|
* Attributes for the `<a-radio>` custom element — one option in a radio set.
|
package/dist/index.d.ts
CHANGED
|
@@ -27,9 +27,10 @@ export type { TagProps } from './components/Tag';
|
|
|
27
27
|
export { Icon } from './components/Icon';
|
|
28
28
|
export type { IconProps } from './components/Icon';
|
|
29
29
|
export { Button } from './components/Button';
|
|
30
|
-
export type { ButtonProps, BaseButtonProps, ContentMode, SubmitMode, PriorityMode,
|
|
30
|
+
export type { ButtonProps, BaseButtonProps, ContentMode, SubmitMode, PriorityMode, } from './components/Button';
|
|
31
31
|
export { ButtonCopy } from './components/ButtonCopy';
|
|
32
32
|
export type { ButtonCopyProps } from './components/ButtonCopy';
|
|
33
|
+
export type { CopyTarget } from './components/copy-props';
|
|
33
34
|
export { ICON_SHAPES, ICON_SYNONYMS } from './elements/a-icon.shapes';
|
|
34
35
|
export { Tooltip } from './components/Tooltip';
|
|
35
36
|
export type { TooltipProps } from './components/Tooltip';
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare function useMemo<T>(factory: () => T, deps: unknown[]): T;
|
|
|
41
41
|
export declare function jsx(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
|
|
42
42
|
export declare function jsxs(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
|
|
43
43
|
export { _Fragment as Fragment };
|
|
44
|
-
import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, AInputTimeAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, ADialogAttributes, ACardAttributes, BaseAttributes } from './general_types';
|
|
44
|
+
import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACopyAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, AInputTimeAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, ADialogAttributes, ACardAttributes, BaseAttributes } from './general_types';
|
|
45
45
|
export declare namespace JSX {
|
|
46
46
|
interface IntrinsicElements extends React.JSX.IntrinsicElements, AntaIntrinsicElements {
|
|
47
47
|
}
|
|
@@ -65,6 +65,7 @@ export interface AntaIntrinsicElements {
|
|
|
65
65
|
'a-icon': AIconAttributes;
|
|
66
66
|
'a-button': AButtonAttributes;
|
|
67
67
|
'a-button-label': BaseAttributes;
|
|
68
|
+
'a-copy': ACopyAttributes;
|
|
68
69
|
'a-checkbox': ACheckboxAttributes;
|
|
69
70
|
'a-checkbox-label': BaseAttributes;
|
|
70
71
|
'a-checkbox-hint': BaseAttributes;
|