svelte-multiselect 11.1.1 → 11.2.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/CircleSpinner.svelte +2 -1
- package/dist/CmdPalette.svelte +13 -7
- package/dist/CmdPalette.svelte.d.ts +4 -5
- package/dist/CodeExample.svelte +80 -0
- package/dist/CodeExample.svelte.d.ts +22 -0
- package/dist/CopyButton.svelte +47 -0
- package/dist/CopyButton.svelte.d.ts +25 -0
- package/dist/FileDetails.svelte +53 -0
- package/dist/FileDetails.svelte.d.ts +21 -0
- package/dist/GitHubCorner.svelte +82 -0
- package/dist/GitHubCorner.svelte.d.ts +13 -0
- package/dist/Icon.svelte +23 -0
- package/dist/Icon.svelte.d.ts +8 -0
- package/dist/MultiSelect.svelte +129 -75
- package/dist/MultiSelect.svelte.d.ts +2 -3
- package/dist/PrevNext.svelte +100 -0
- package/dist/PrevNext.svelte.d.ts +48 -0
- package/dist/RadioButtons.svelte +67 -0
- package/dist/RadioButtons.svelte.d.ts +44 -0
- package/dist/Toggle.svelte +78 -0
- package/dist/Toggle.svelte.d.ts +16 -0
- package/dist/icons.d.ts +47 -0
- package/dist/icons.js +46 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +10 -3
- package/dist/types.d.ts +141 -0
- package/dist/utils.d.ts +6 -22
- package/dist/utils.js +17 -25
- package/package.json +17 -35
- package/readme.md +287 -121
- package/dist/icons/ChevronExpand.svelte +0 -9
- package/dist/icons/ChevronExpand.svelte.d.ts +0 -4
- package/dist/icons/Cross.svelte +0 -10
- package/dist/icons/Cross.svelte.d.ts +0 -4
- package/dist/icons/Disabled.svelte +0 -10
- package/dist/icons/Disabled.svelte.d.ts +0 -4
- package/dist/icons/Octocat.svelte +0 -9
- package/dist/icons/Octocat.svelte.d.ts +0 -4
- package/dist/icons/index.d.ts +0 -4
- package/dist/icons/index.js +0 -4
- package/dist/props.d.ts +0 -143
- package/dist/props.js +0 -1
package/dist/CmdPalette.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
2
|
-
import
|
|
3
|
-
let { actions, triggers = [`k`], close_keys = [`Escape`], fade_duration = 200,
|
|
1
|
+
<script lang="ts">import { MultiSelect } from './';
|
|
2
|
+
import { fade } from 'svelte/transition';
|
|
3
|
+
let { actions, triggers = [`k`], close_keys = [`Escape`], fade_duration = 200, dialog_style = ``, open = $bindable(false), dialog = $bindable(null), input = $bindable(null), placeholder = `Filter actions...`, ...rest } = $props();
|
|
4
4
|
$effect(() => {
|
|
5
5
|
if (open && input)
|
|
6
6
|
input?.focus(); // focus input when palette is opened
|
|
@@ -18,8 +18,9 @@ function close_if_outside(event) {
|
|
|
18
18
|
open = false;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
function trigger_action_and_close(
|
|
22
|
-
|
|
21
|
+
function trigger_action_and_close(data) {
|
|
22
|
+
const { action, label } = data.option;
|
|
23
|
+
action(label);
|
|
23
24
|
open = false;
|
|
24
25
|
}
|
|
25
26
|
</script>
|
|
@@ -27,8 +28,13 @@ function trigger_action_and_close({ option }) {
|
|
|
27
28
|
<svelte:window onkeydown={toggle} onclick={close_if_outside} />
|
|
28
29
|
|
|
29
30
|
{#if open}
|
|
30
|
-
<dialog
|
|
31
|
-
|
|
31
|
+
<dialog
|
|
32
|
+
open
|
|
33
|
+
bind:this={dialog}
|
|
34
|
+
transition:fade={{ duration: fade_duration }}
|
|
35
|
+
style={dialog_style}
|
|
36
|
+
>
|
|
37
|
+
<MultiSelect
|
|
32
38
|
options={actions}
|
|
33
39
|
bind:input
|
|
34
40
|
{placeholder}
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import type { MultiSelectProps } from './
|
|
2
|
-
import type { ObjectOption } from './types';
|
|
1
|
+
import type { MultiSelectProps, ObjectOption } from './types';
|
|
3
2
|
interface Action extends ObjectOption {
|
|
4
3
|
label: string;
|
|
5
4
|
action: (label: string) => void;
|
|
6
5
|
}
|
|
7
|
-
interface Props extends Omit<MultiSelectProps<Action>, `options
|
|
6
|
+
interface Props extends Omit<MultiSelectProps<Action>, `options`> {
|
|
8
7
|
actions: Action[];
|
|
9
8
|
triggers?: string[];
|
|
10
9
|
close_keys?: string[];
|
|
11
10
|
fade_duration?: number;
|
|
12
|
-
|
|
11
|
+
dialog_style?: string;
|
|
13
12
|
open?: boolean;
|
|
14
13
|
dialog?: HTMLDialogElement | null;
|
|
15
14
|
input?: HTMLInputElement | null;
|
|
16
15
|
placeholder?: string;
|
|
17
16
|
}
|
|
18
|
-
declare const CmdPalette: import("svelte").Component<Props, {}, "open" | "
|
|
17
|
+
declare const CmdPalette: import("svelte").Component<Props, {}, "open" | "dialog" | "input">;
|
|
19
18
|
type CmdPalette = ReturnType<typeof CmdPalette>;
|
|
20
19
|
export default CmdPalette;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script lang="ts">// see svelte.config.js where this component is passed to mdsvexamples
|
|
2
|
+
import { Icon } from './';
|
|
3
|
+
let { src = ``, meta = {}, open = $bindable(!meta.collapsible), title, example, code, } = $props();
|
|
4
|
+
let { id, collapsible, code_above, repl, github, repo, file } = $derived(meta);
|
|
5
|
+
const links = { target: `_blank`, rel: `noreferrer` };
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<nav>
|
|
9
|
+
{#each [
|
|
10
|
+
{ cond: repl, href: repl, icon: `Svelte` },
|
|
11
|
+
{
|
|
12
|
+
cond: github && repo,
|
|
13
|
+
href: file ? `${repo}/blob/-/${github == true ? file : github}` : repo,
|
|
14
|
+
icon: `GitHub`,
|
|
15
|
+
},
|
|
16
|
+
] as const as
|
|
17
|
+
{ cond, href, icon }
|
|
18
|
+
(icon)
|
|
19
|
+
}
|
|
20
|
+
<a {href} {...links} title={icon} style:display={cond ? `inline-block` : `none`}>
|
|
21
|
+
<Icon {icon} />
|
|
22
|
+
</a>
|
|
23
|
+
{/each}
|
|
24
|
+
{#if collapsible}
|
|
25
|
+
{@render title?.()}
|
|
26
|
+
<button onclick={() => (open = !open)}>
|
|
27
|
+
<Icon icon={open ? `Collapse` : `Expand`} />
|
|
28
|
+
{open ? `Close` : `View code`}
|
|
29
|
+
</button>
|
|
30
|
+
{/if}
|
|
31
|
+
</nav>
|
|
32
|
+
<!-- wrap in div with id for precise CSS selectors in playwright E2E tests -->
|
|
33
|
+
<div {id} class="code-example">
|
|
34
|
+
{#if !code_above}
|
|
35
|
+
{@render example?.()}
|
|
36
|
+
{/if}
|
|
37
|
+
|
|
38
|
+
<pre class:open>
|
|
39
|
+
<code>{#if code}{@render code()}{:else}{src}{/if}</code></pre>
|
|
40
|
+
|
|
41
|
+
{#if code_above}
|
|
42
|
+
{@render example?.()}
|
|
43
|
+
{/if}
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<style>
|
|
47
|
+
div.code-example {
|
|
48
|
+
margin: var(--code-example-margin, 1em auto);
|
|
49
|
+
position: relative;
|
|
50
|
+
}
|
|
51
|
+
nav {
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: end;
|
|
54
|
+
align-items: center;
|
|
55
|
+
margin: var(--code-example-nav-margin, initial);
|
|
56
|
+
gap: var(--code-example-nav-gap, 1ex);
|
|
57
|
+
}
|
|
58
|
+
pre code {
|
|
59
|
+
background-color: transparent;
|
|
60
|
+
display: inline-block;
|
|
61
|
+
}
|
|
62
|
+
pre {
|
|
63
|
+
position: relative;
|
|
64
|
+
overflow-x: auto;
|
|
65
|
+
visibility: hidden;
|
|
66
|
+
opacity: 0;
|
|
67
|
+
max-height: 0;
|
|
68
|
+
transition: max-height, opacity, visibility;
|
|
69
|
+
transition-duration: var(--code-example-pre-transition-duration, 0.3s);
|
|
70
|
+
border-radius: var(--code-example-pre-border-radius, 4pt);
|
|
71
|
+
background-color: var(--code-example-pre-bg, var(--pre-bg));
|
|
72
|
+
padding: var(--code-example-pre-padding, 1em);
|
|
73
|
+
}
|
|
74
|
+
pre.open {
|
|
75
|
+
visibility: visible;
|
|
76
|
+
opacity: 1;
|
|
77
|
+
max-height: 9999vh;
|
|
78
|
+
margin: var(--code-example-pre-margin, 1em 0 0 0);
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
src?: string;
|
|
4
|
+
meta?: {
|
|
5
|
+
collapsible?: boolean;
|
|
6
|
+
code_above?: boolean;
|
|
7
|
+
id?: string;
|
|
8
|
+
repl?: string;
|
|
9
|
+
github?: string | boolean;
|
|
10
|
+
repo?: string;
|
|
11
|
+
Wrapper?: string;
|
|
12
|
+
example?: boolean;
|
|
13
|
+
file?: string;
|
|
14
|
+
};
|
|
15
|
+
open?: boolean;
|
|
16
|
+
title?: Snippet<[]>;
|
|
17
|
+
example?: Snippet<[]>;
|
|
18
|
+
code?: Snippet<[]>;
|
|
19
|
+
}
|
|
20
|
+
declare const CodeExample: import("svelte").Component<Props, {}, "open">;
|
|
21
|
+
type CodeExample = ReturnType<typeof CodeExample>;
|
|
22
|
+
export default CodeExample;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">import { CopyButton, Icon } from './';
|
|
2
|
+
import { mount } from 'svelte';
|
|
3
|
+
let { content = ``, state = $bindable(`ready`), global_selector = null, global = false, skip_selector = `button`, as = `button`, labels = {
|
|
4
|
+
ready: { icon: `Copy`, text: `` },
|
|
5
|
+
success: { icon: `Check`, text: `` },
|
|
6
|
+
error: { icon: `Alert`, text: `` },
|
|
7
|
+
}, children, ...rest } = $props();
|
|
8
|
+
$effect(() => {
|
|
9
|
+
if (global || global_selector) {
|
|
10
|
+
for (const node of document.querySelectorAll(global_selector ?? `pre > code`)) {
|
|
11
|
+
// skip if <pre> already contains a button (presumably for copy)
|
|
12
|
+
const pre = node.parentElement;
|
|
13
|
+
if (!pre || (skip_selector && pre.querySelector(skip_selector)))
|
|
14
|
+
continue;
|
|
15
|
+
mount(CopyButton, {
|
|
16
|
+
target: pre,
|
|
17
|
+
props: {
|
|
18
|
+
content: node.textContent ?? ``,
|
|
19
|
+
style: `position: absolute; top: 9pt; right: 9pt;`,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
async function copy() {
|
|
26
|
+
try {
|
|
27
|
+
await navigator.clipboard.writeText(content);
|
|
28
|
+
state = `success`;
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
console.error(err);
|
|
32
|
+
state = `error`;
|
|
33
|
+
}
|
|
34
|
+
setTimeout(() => (state = `ready`), 2000);
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
{#if !(global || global_selector)}
|
|
39
|
+
{@const { text, icon } = labels[state]}
|
|
40
|
+
<svelte:element this={as} onclick={copy} role="button" tabindex={0} {...rest}>
|
|
41
|
+
{#if children}
|
|
42
|
+
{@render children({ state, icon, text })}
|
|
43
|
+
{:else}
|
|
44
|
+
<Icon {icon} />{@html text}
|
|
45
|
+
{/if}
|
|
46
|
+
</svelte:element>
|
|
47
|
+
{/if}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CopyButton } from './';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { IconName } from './icons';
|
|
4
|
+
type State = `ready` | `success` | `error`;
|
|
5
|
+
interface Props {
|
|
6
|
+
content?: string;
|
|
7
|
+
state?: State;
|
|
8
|
+
global_selector?: string | null;
|
|
9
|
+
global?: boolean;
|
|
10
|
+
skip_selector?: string | null;
|
|
11
|
+
as?: string;
|
|
12
|
+
labels?: Record<State, {
|
|
13
|
+
icon: IconName;
|
|
14
|
+
text: string;
|
|
15
|
+
}>;
|
|
16
|
+
children?: Snippet<[{
|
|
17
|
+
state: State;
|
|
18
|
+
icon: IconName;
|
|
19
|
+
text: string;
|
|
20
|
+
}]>;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
declare const CopyButton: import("svelte").Component<Props, {}, "state">;
|
|
24
|
+
type CopyButton = ReturnType<typeof CopyButton>;
|
|
25
|
+
export default CopyButton;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script lang="ts">import hljs from 'highlight.js';
|
|
2
|
+
import 'highlight.js/styles/vs2015.css';
|
|
3
|
+
let { files = $bindable([]), toggle_all_btn_title = `Toggle all`, default_lang = `typescript`, as = `ol`, style = null, title_snippet, } = $props();
|
|
4
|
+
function toggle_all() {
|
|
5
|
+
const any_open = files.some((file) => file.node?.open);
|
|
6
|
+
for (const file of files) {
|
|
7
|
+
if (!file.node)
|
|
8
|
+
continue;
|
|
9
|
+
file.node.open = !any_open;
|
|
10
|
+
}
|
|
11
|
+
files = [...files]; // trigger reactivity
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#if files?.length > 1}
|
|
16
|
+
<button onclick={toggle_all} title={toggle_all_btn_title}>
|
|
17
|
+
{files.some((file) => file.node?.open) ? `Close` : `Open`} all
|
|
18
|
+
</button>
|
|
19
|
+
{/if}
|
|
20
|
+
|
|
21
|
+
<svelte:element this={as} {style}>
|
|
22
|
+
{#each files as file, idx (file.title)}
|
|
23
|
+
{@const { title, content, language = default_lang } = file ?? {}}
|
|
24
|
+
<li>
|
|
25
|
+
<!-- https://github.com/sveltejs/svelte/issues/12721#issuecomment-2269544690 -->
|
|
26
|
+
<details bind:this={file.node}>
|
|
27
|
+
{#if title || title_snippet}
|
|
28
|
+
<summary>
|
|
29
|
+
{#if title_snippet}
|
|
30
|
+
{@render title_snippet({ idx, ...file })}
|
|
31
|
+
{:else}
|
|
32
|
+
<code>{title.split(`/`).at(-1)}</code>
|
|
33
|
+
{/if}
|
|
34
|
+
</summary>
|
|
35
|
+
{/if}
|
|
36
|
+
|
|
37
|
+
<pre><code>{@html hljs.highlight(content, { language }).value}</code></pre>
|
|
38
|
+
</details>
|
|
39
|
+
</li>
|
|
40
|
+
{/each}
|
|
41
|
+
</svelte:element>
|
|
42
|
+
|
|
43
|
+
<style>
|
|
44
|
+
button {
|
|
45
|
+
float: right;
|
|
46
|
+
}
|
|
47
|
+
ol {
|
|
48
|
+
padding: 0;
|
|
49
|
+
}
|
|
50
|
+
ol > li {
|
|
51
|
+
margin: 1ex 0;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import 'highlight.js/styles/vs2015.css';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type File = {
|
|
4
|
+
title: string;
|
|
5
|
+
content: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
node?: HTMLDetailsElement | null;
|
|
8
|
+
};
|
|
9
|
+
interface Props {
|
|
10
|
+
files?: File[];
|
|
11
|
+
toggle_all_btn_title?: string;
|
|
12
|
+
default_lang?: string;
|
|
13
|
+
as?: string;
|
|
14
|
+
style?: string | null;
|
|
15
|
+
title_snippet?: Snippet<[{
|
|
16
|
+
idx: number;
|
|
17
|
+
} & File]>;
|
|
18
|
+
}
|
|
19
|
+
declare const FileDetails: import("svelte").Component<Props, {}, "files">;
|
|
20
|
+
type FileDetails = ReturnType<typeof FileDetails>;
|
|
21
|
+
export default FileDetails;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">"use strict";
|
|
2
|
+
// Display an animated Octocat in a corner of the screen to link to the GitHub repo.
|
|
3
|
+
let { href, title = `View code on GitHub`, aria_label = title, target = `_self`, color = null, fill = null, corner = `top-right`, style = ``, } = $props();
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<a
|
|
7
|
+
{href}
|
|
8
|
+
{target}
|
|
9
|
+
{title}
|
|
10
|
+
aria-label={aria_label}
|
|
11
|
+
{style}
|
|
12
|
+
class={corner}
|
|
13
|
+
style:color
|
|
14
|
+
style:fill
|
|
15
|
+
>
|
|
16
|
+
<svg viewBox="0 0 250 250" aria-hidden="true">
|
|
17
|
+
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" />
|
|
18
|
+
<path
|
|
19
|
+
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
|
20
|
+
fill="currentColor"
|
|
21
|
+
style="transform-origin: 130px 106px"
|
|
22
|
+
class="octo-arm"
|
|
23
|
+
/>
|
|
24
|
+
<path
|
|
25
|
+
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
|
|
26
|
+
fill="currentColor"
|
|
27
|
+
class="octo-body"
|
|
28
|
+
/>
|
|
29
|
+
</svg>
|
|
30
|
+
</a>
|
|
31
|
+
|
|
32
|
+
<style>
|
|
33
|
+
a {
|
|
34
|
+
position: fixed;
|
|
35
|
+
z-index: 1;
|
|
36
|
+
fill: var(--github-corner-bg, black);
|
|
37
|
+
color: var(--github-corner-color, white);
|
|
38
|
+
width: var(--github-corner-size, 70px);
|
|
39
|
+
}
|
|
40
|
+
a.top-right {
|
|
41
|
+
top: 0;
|
|
42
|
+
right: 0;
|
|
43
|
+
}
|
|
44
|
+
a.top-left {
|
|
45
|
+
top: 0;
|
|
46
|
+
left: 0;
|
|
47
|
+
transform: rotate(-90deg);
|
|
48
|
+
}
|
|
49
|
+
a.bottom-left {
|
|
50
|
+
bottom: 0;
|
|
51
|
+
left: 0;
|
|
52
|
+
transform: rotate(180deg);
|
|
53
|
+
}
|
|
54
|
+
a.bottom-right {
|
|
55
|
+
bottom: 0;
|
|
56
|
+
right: 0;
|
|
57
|
+
transform: rotate(90deg);
|
|
58
|
+
}
|
|
59
|
+
a:hover .octo-arm {
|
|
60
|
+
animation: octocat-wave 0.5s ease-in-out;
|
|
61
|
+
}
|
|
62
|
+
@keyframes octocat-wave {
|
|
63
|
+
0%,
|
|
64
|
+
100% {
|
|
65
|
+
transform: rotate(0);
|
|
66
|
+
}
|
|
67
|
+
20%,
|
|
68
|
+
60% {
|
|
69
|
+
transform: rotate(-25deg);
|
|
70
|
+
}
|
|
71
|
+
40%,
|
|
72
|
+
80% {
|
|
73
|
+
transform: rotate(10deg);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/* hide this component by default when printing since it would show up on every page */
|
|
77
|
+
@media print {
|
|
78
|
+
a {
|
|
79
|
+
display: var(--github-corner-print-display, none);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
href: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
aria_label?: string;
|
|
5
|
+
target?: `_self` | `_blank`;
|
|
6
|
+
color?: string | null;
|
|
7
|
+
fill?: string | null;
|
|
8
|
+
corner?: `top-left` | `top-right` | `bottom-left` | `bottom-right`;
|
|
9
|
+
style?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const GitHubCorner: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type GitHubCorner = ReturnType<typeof GitHubCorner>;
|
|
13
|
+
export default GitHubCorner;
|
package/dist/Icon.svelte
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">import { icon_data } from './icons';
|
|
2
|
+
let { icon, ...rest } = $props();
|
|
3
|
+
const data = $derived.by(() => {
|
|
4
|
+
if (!(icon in icon_data)) {
|
|
5
|
+
console.error(`Icon '${icon}' not found`);
|
|
6
|
+
return icon_data.Alert; // fallback
|
|
7
|
+
}
|
|
8
|
+
return icon_data[icon];
|
|
9
|
+
});
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<svg viewBox={data.viewBox} fill="currentColor" {...rest}>
|
|
13
|
+
<path d={data.path} />
|
|
14
|
+
</svg>
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
svg {
|
|
18
|
+
width: 1em;
|
|
19
|
+
height: 1em;
|
|
20
|
+
display: inline-block;
|
|
21
|
+
vertical-align: middle;
|
|
22
|
+
}
|
|
23
|
+
</style>
|