@signal9/era-ui 2.14.0 → 2.16.0
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/ai/index.d.ts +1 -1
- package/dist/ai/index.js +2 -1
- package/dist/dev/audit/audits/_helpers.d.ts +9 -0
- package/dist/dev/audit/audits/_helpers.js +15 -1
- package/dist/dev/audit/audits/index.d.ts +2 -1
- package/dist/dev/audit/audits/index.js +3 -1
- package/dist/dev/audit/audits/radius-concentricity.d.ts +2 -0
- package/dist/dev/audit/audits/radius-concentricity.js +52 -0
- package/dist/dev/index.d.ts +1 -0
- package/dist/dev/index.js +1 -0
- package/dist/dev/measure.d.ts +75 -0
- package/dist/dev/measure.js +142 -0
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/copy-button.md +25 -0
- package/dist/generated-docs/llms-full.txt +38 -0
- package/dist/generated-docs/llms.txt +1 -1
- package/dist/generated-docs/manifest.json +19 -0
- package/dist/generated-docs/measurements.md +3 -0
- package/dist/ui/code-block/code-block.svelte +7 -24
- package/dist/ui/copy-button/copy-button.svelte +85 -0
- package/dist/ui/copy-button/copy-button.svelte.d.ts +23 -0
- package/dist/ui/copy-button/index.d.ts +1 -0
- package/dist/ui/copy-button/index.js +1 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +1 -0
- package/package.json +1 -1
- package/dist/ai/copy-button.svelte +0 -42
- package/dist/ai/copy-button.svelte.d.ts +0 -8
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
"sections": [],
|
|
17
17
|
"file": "surfaces.md"
|
|
18
18
|
},
|
|
19
|
+
{
|
|
20
|
+
"slug": "measurements",
|
|
21
|
+
"title": "Measurements",
|
|
22
|
+
"summary": "Every component measured as it renders — gaps, radii, and the laws they must obey.",
|
|
23
|
+
"tokenEstimate": 25,
|
|
24
|
+
"sections": [],
|
|
25
|
+
"file": "measurements.md"
|
|
26
|
+
},
|
|
19
27
|
{
|
|
20
28
|
"slug": "text",
|
|
21
29
|
"title": "Text",
|
|
@@ -166,6 +174,17 @@
|
|
|
166
174
|
],
|
|
167
175
|
"file": "code-block.md"
|
|
168
176
|
},
|
|
177
|
+
{
|
|
178
|
+
"slug": "copy-button",
|
|
179
|
+
"title": "Copy Button",
|
|
180
|
+
"summary": "An icon button that copies text and cross-fades to a result glyph.",
|
|
181
|
+
"tokenEstimate": 257,
|
|
182
|
+
"sections": [
|
|
183
|
+
"Import",
|
|
184
|
+
"Props"
|
|
185
|
+
],
|
|
186
|
+
"file": "copy-button.md"
|
|
187
|
+
},
|
|
169
188
|
{
|
|
170
189
|
"slug": "kv",
|
|
171
190
|
"title": "KV",
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
import { cn } from '../../utils/index.js';
|
|
5
|
-
import {
|
|
6
|
-
import Copy from '@lucide/svelte/icons/copy';
|
|
7
|
-
import Check from '@lucide/svelte/icons/check';
|
|
5
|
+
import { CopyButton } from '../copy-button/index.js';
|
|
8
6
|
|
|
9
7
|
let {
|
|
10
8
|
ref = $bindable(null),
|
|
@@ -20,16 +18,9 @@
|
|
|
20
18
|
children?: Snippet;
|
|
21
19
|
} = $props();
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const text = code ?? ref?.querySelector('code')?.textContent ?? '';
|
|
27
|
-
navigator.clipboard.writeText(text);
|
|
28
|
-
copied = true;
|
|
29
|
-
setTimeout(() => {
|
|
30
|
-
copied = false;
|
|
31
|
-
}, 1500);
|
|
32
|
-
}
|
|
21
|
+
// Resolved at click time: with a `children` snippet the text only exists in
|
|
22
|
+
// the DOM, so it can't be read during render.
|
|
23
|
+
const copyText = () => code ?? ref?.querySelector('code')?.textContent ?? '';
|
|
33
24
|
</script>
|
|
34
25
|
|
|
35
26
|
<div
|
|
@@ -42,17 +33,9 @@
|
|
|
42
33
|
>{#if children}{@render children()}{:else}{code}{/if}</code
|
|
43
34
|
></pre>
|
|
44
35
|
{#if copyable}
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
size="sm"
|
|
36
|
+
<CopyButton
|
|
37
|
+
text={copyText}
|
|
48
38
|
class="absolute top-[calc(var(--era-inset-md)+(var(--era-text)*1.625-var(--era-h-sm))/2)] right-[calc(var(--era-inset-md)+(var(--era-text)*1.625-var(--era-h-sm))/2)]"
|
|
49
|
-
|
|
50
|
-
>
|
|
51
|
-
{#if copied}
|
|
52
|
-
<Check class="size-(--era-h-xs)" />
|
|
53
|
-
{:else}
|
|
54
|
-
<Copy class="size-(--era-h-xs)" />
|
|
55
|
-
{/if}
|
|
56
|
-
</Button>
|
|
39
|
+
/>
|
|
57
40
|
{/if}
|
|
58
41
|
</div>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
import Copy from '@lucide/svelte/icons/copy';
|
|
4
|
+
import Check from '@lucide/svelte/icons/check';
|
|
5
|
+
import X from '@lucide/svelte/icons/x';
|
|
6
|
+
import { Button, type ButtonVariants } from '../button/index.js';
|
|
7
|
+
import { cn } from '../../utils/index.js';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
ref = $bindable(null),
|
|
11
|
+
text,
|
|
12
|
+
onCopy,
|
|
13
|
+
resetDelay = 1500,
|
|
14
|
+
label = 'Copy',
|
|
15
|
+
copiedLabel = 'Copied',
|
|
16
|
+
size = 'sm',
|
|
17
|
+
class: className,
|
|
18
|
+
...restProps
|
|
19
|
+
// Typed off the native button rather than bits-ui's Button.RootProps: the
|
|
20
|
+
// latter is a union whose Omit<> exceeds TS's representable-union limit
|
|
21
|
+
// (the same reason ButtonVariants is a standalone interface).
|
|
22
|
+
}: Omit<HTMLButtonAttributes, 'onclick' | 'children'> & {
|
|
23
|
+
ref?: HTMLElement | null;
|
|
24
|
+
} & ButtonVariants & {
|
|
25
|
+
/**
|
|
26
|
+
* The string written to the clipboard. Pass a function when the value
|
|
27
|
+
* is only knowable at click time (e.g. text read out of the DOM) — it
|
|
28
|
+
* is resolved on each click, not at render.
|
|
29
|
+
*/
|
|
30
|
+
text: string | (() => string);
|
|
31
|
+
/** Fires after the write settles, with the outcome. */
|
|
32
|
+
onCopy?: (status: 'success' | 'failure') => void;
|
|
33
|
+
/** How long the result icon holds before falling back to idle. */
|
|
34
|
+
resetDelay?: number;
|
|
35
|
+
/** Accessible name in the idle and failure states. */
|
|
36
|
+
label?: string;
|
|
37
|
+
/** Accessible name while the success icon is showing. */
|
|
38
|
+
copiedLabel?: string;
|
|
39
|
+
} = $props();
|
|
40
|
+
|
|
41
|
+
let status = $state<'idle' | 'success' | 'failure'>('idle');
|
|
42
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
43
|
+
|
|
44
|
+
// The reset timer outlives the click that armed it, so it has to be torn
|
|
45
|
+
// down on destroy — a handler-only clear fires on an unmounted component.
|
|
46
|
+
$effect(() => () => clearTimeout(timer));
|
|
47
|
+
|
|
48
|
+
async function copy() {
|
|
49
|
+
try {
|
|
50
|
+
await navigator.clipboard.writeText(typeof text === 'function' ? text() : text);
|
|
51
|
+
status = 'success';
|
|
52
|
+
} catch {
|
|
53
|
+
status = 'failure';
|
|
54
|
+
}
|
|
55
|
+
onCopy?.(status);
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
timer = setTimeout(() => (status = 'idle'), resetDelay);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// All three icons stay mounted and stack on one another, so the swap
|
|
61
|
+
// cross-fades in BOTH directions — an icon that unmounts can only animate
|
|
62
|
+
// its enter. The entering glyph scales up from 0.25 and unblurs while the
|
|
63
|
+
// leaving one does the reverse; timing rides the motion axis, so the swap
|
|
64
|
+
// snaps at instant, is decisive at normal, and overshoots at extra.
|
|
65
|
+
const iconBase =
|
|
66
|
+
'absolute inset-0 size-(--era-h-xs) transition-[opacity,scale,filter] duration-(--era-duration) ease-(--era-ease)';
|
|
67
|
+
const iconIn = 'scale-100 opacity-100 blur-none';
|
|
68
|
+
const iconOut = 'scale-25 opacity-0 blur-xs';
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<Button
|
|
72
|
+
bind:ref
|
|
73
|
+
icon
|
|
74
|
+
{size}
|
|
75
|
+
aria-label={status === 'success' ? copiedLabel : label}
|
|
76
|
+
class={className}
|
|
77
|
+
onclick={copy}
|
|
78
|
+
{...restProps}
|
|
79
|
+
>
|
|
80
|
+
<span class="relative block size-(--era-h-xs) shrink-0">
|
|
81
|
+
<Copy class={cn(iconBase, status === 'idle' ? iconIn : iconOut)} />
|
|
82
|
+
<Check class={cn(iconBase, 'text-success', status === 'success' ? iconIn : iconOut)} />
|
|
83
|
+
<X class={cn(iconBase, 'text-destructive', status === 'failure' ? iconIn : iconOut)} />
|
|
84
|
+
</span>
|
|
85
|
+
</Button>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
2
|
+
import { type ButtonVariants } from '../button/index.js';
|
|
3
|
+
type $$ComponentProps = Omit<HTMLButtonAttributes, 'onclick' | 'children'> & {
|
|
4
|
+
ref?: HTMLElement | null;
|
|
5
|
+
} & ButtonVariants & {
|
|
6
|
+
/**
|
|
7
|
+
* The string written to the clipboard. Pass a function when the value
|
|
8
|
+
* is only knowable at click time (e.g. text read out of the DOM) — it
|
|
9
|
+
* is resolved on each click, not at render.
|
|
10
|
+
*/
|
|
11
|
+
text: string | (() => string);
|
|
12
|
+
/** Fires after the write settles, with the outcome. */
|
|
13
|
+
onCopy?: (status: 'success' | 'failure') => void;
|
|
14
|
+
/** How long the result icon holds before falling back to idle. */
|
|
15
|
+
resetDelay?: number;
|
|
16
|
+
/** Accessible name in the idle and failure states. */
|
|
17
|
+
label?: string;
|
|
18
|
+
/** Accessible name while the success icon is showing. */
|
|
19
|
+
copiedLabel?: string;
|
|
20
|
+
};
|
|
21
|
+
declare const CopyButton: import("svelte").Component<$$ComponentProps, {}, "ref">;
|
|
22
|
+
type CopyButton = ReturnType<typeof CopyButton>;
|
|
23
|
+
export default CopyButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CopyButton } from './copy-button.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CopyButton } from './copy-button.svelte';
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { Badge } from './badge/index.js';
|
|
|
6
6
|
export * as Calendar from './calendar/index.js';
|
|
7
7
|
export { Chip } from './chip/index.js';
|
|
8
8
|
export { CodeBlock } from './code-block/index.js';
|
|
9
|
+
export { CopyButton } from './copy-button/index.js';
|
|
9
10
|
export * as Checkbox from './checkbox/index.js';
|
|
10
11
|
export * as Combobox from './combobox/index.js';
|
|
11
12
|
export * as Collapsible from './collapsible/index.js';
|
package/dist/ui/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { Badge } from './badge/index.js';
|
|
|
6
6
|
export * as Calendar from './calendar/index.js';
|
|
7
7
|
export { Chip } from './chip/index.js';
|
|
8
8
|
export { CodeBlock } from './code-block/index.js';
|
|
9
|
+
export { CopyButton } from './copy-button/index.js';
|
|
9
10
|
export * as Checkbox from './checkbox/index.js';
|
|
10
11
|
export * as Combobox from './combobox/index.js';
|
|
11
12
|
export * as Collapsible from './collapsible/index.js';
|
package/package.json
CHANGED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import Copy from '@lucide/svelte/icons/copy';
|
|
3
|
-
import Check from '@lucide/svelte/icons/check';
|
|
4
|
-
import X from '@lucide/svelte/icons/x';
|
|
5
|
-
import { Button } from '../ui/button/index.js';
|
|
6
|
-
import { cn } from '../utils/index.js';
|
|
7
|
-
|
|
8
|
-
let {
|
|
9
|
-
text,
|
|
10
|
-
onCopy,
|
|
11
|
-
class: className
|
|
12
|
-
}: {
|
|
13
|
-
text: string;
|
|
14
|
-
onCopy?: (status: 'success' | 'failure') => void;
|
|
15
|
-
class?: string;
|
|
16
|
-
} = $props();
|
|
17
|
-
|
|
18
|
-
let status = $state<'idle' | 'success' | 'failure'>('idle');
|
|
19
|
-
let timer: ReturnType<typeof setTimeout>;
|
|
20
|
-
|
|
21
|
-
async function copy() {
|
|
22
|
-
try {
|
|
23
|
-
await navigator.clipboard.writeText(text);
|
|
24
|
-
status = 'success';
|
|
25
|
-
} catch {
|
|
26
|
-
status = 'failure';
|
|
27
|
-
}
|
|
28
|
-
onCopy?.(status as 'success' | 'failure');
|
|
29
|
-
clearTimeout(timer);
|
|
30
|
-
timer = setTimeout(() => (status = 'idle'), 1500);
|
|
31
|
-
}
|
|
32
|
-
</script>
|
|
33
|
-
|
|
34
|
-
<Button icon size="icon" aria-label="Copy" class={cn(className)} onclick={copy}>
|
|
35
|
-
{#if status === 'success'}
|
|
36
|
-
<Check class="size-(--era-h-xs) text-success" />
|
|
37
|
-
{:else if status === 'failure'}
|
|
38
|
-
<X class="size-(--era-h-xs) text-destructive" />
|
|
39
|
-
{:else}
|
|
40
|
-
<Copy class="size-(--era-h-xs)" />
|
|
41
|
-
{/if}
|
|
42
|
-
</Button>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
type $$ComponentProps = {
|
|
2
|
-
text: string;
|
|
3
|
-
onCopy?: (status: 'success' | 'failure') => void;
|
|
4
|
-
class?: string;
|
|
5
|
-
};
|
|
6
|
-
declare const CopyButton: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
-
type CopyButton = ReturnType<typeof CopyButton>;
|
|
8
|
-
export default CopyButton;
|