svelte-multiselect 11.5.0 → 11.5.2
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 +29 -0
- package/dist/CircleSpinner.svelte.d.ts +8 -0
- package/dist/CmdPalette.svelte +74 -0
- package/dist/CmdPalette.svelte.d.ts +76 -0
- package/dist/CodeExample.svelte +85 -0
- package/dist/CodeExample.svelte.d.ts +25 -0
- package/dist/CopyButton.svelte +67 -0
- package/dist/CopyButton.svelte.d.ts +25 -0
- package/dist/FileDetails.svelte +65 -0
- package/dist/FileDetails.svelte.d.ts +22 -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 +1725 -0
- package/dist/MultiSelect.svelte.d.ts +25 -0
- package/dist/Nav.svelte +627 -0
- package/dist/Nav.svelte.d.ts +43 -0
- package/dist/PrevNext.svelte +105 -0
- package/dist/PrevNext.svelte.d.ts +56 -0
- package/dist/Toggle.svelte +77 -0
- package/dist/Toggle.svelte.d.ts +11 -0
- package/dist/Wiggle.svelte +22 -0
- package/dist/Wiggle.svelte.d.ts +18 -0
- package/dist/attachments.d.ts +72 -0
- package/dist/attachments.js +698 -0
- package/dist/heading-anchors.d.ts +14 -0
- package/dist/heading-anchors.js +120 -0
- package/dist/icons.d.ts +55 -0
- package/dist/icons.js +54 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +43 -0
- package/dist/types.d.ts +246 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +63 -0
- package/package.json +20 -17
- package/readme.md +25 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">"use strict";
|
|
2
|
+
let { color = `cornflowerblue`, duration = `1.5s`, size = `1em` } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div
|
|
6
|
+
style="--duration: {duration}"
|
|
7
|
+
style:border-color="{color} transparent {color}
|
|
8
|
+
{color}"
|
|
9
|
+
style:width={size}
|
|
10
|
+
style:height={size}
|
|
11
|
+
>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<style>
|
|
15
|
+
div {
|
|
16
|
+
display: inline-block;
|
|
17
|
+
vertical-align: middle;
|
|
18
|
+
margin: 0 3pt;
|
|
19
|
+
border-width: calc(1em / 5);
|
|
20
|
+
border-style: solid;
|
|
21
|
+
border-radius: 50%;
|
|
22
|
+
animation: var(--duration) infinite rotate;
|
|
23
|
+
}
|
|
24
|
+
@keyframes rotate {
|
|
25
|
+
100% {
|
|
26
|
+
transform: rotate(360deg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script
|
|
2
|
+
lang="ts"
|
|
3
|
+
generics="Action extends { label: string; action: (label: string) => void; group?: string } & Record<string, unknown> = { label: string; action: (label: string) => void; group?: string }"
|
|
4
|
+
>import { fade } from 'svelte/transition';
|
|
5
|
+
import MultiSelect from './MultiSelect.svelte';
|
|
6
|
+
let { actions, triggers = [`k`], close_keys = [`Escape`], fade_duration = 200, dialog_style = ``, open = $bindable(false), dialog = $bindable(null), input = $bindable(null), placeholder = `Filter actions...`, dialog_props, ...rest } = $props();
|
|
7
|
+
$effect(() => {
|
|
8
|
+
if (open && input && document.activeElement !== input)
|
|
9
|
+
input.focus();
|
|
10
|
+
});
|
|
11
|
+
async function toggle(event) {
|
|
12
|
+
const is_trigger = triggers.includes(event.key) &&
|
|
13
|
+
(event.metaKey || event.ctrlKey);
|
|
14
|
+
if (is_trigger && !open)
|
|
15
|
+
open = true;
|
|
16
|
+
else if (close_keys.includes(event.key) && open)
|
|
17
|
+
open = false;
|
|
18
|
+
}
|
|
19
|
+
function close_if_outside(event) {
|
|
20
|
+
const target = event.target;
|
|
21
|
+
if (!target || !(target instanceof HTMLElement))
|
|
22
|
+
return;
|
|
23
|
+
if (open && !dialog?.contains(target) && !target.closest(`ul.options`)) {
|
|
24
|
+
open = false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function trigger_action_and_close({ option }) {
|
|
28
|
+
if (!option?.action)
|
|
29
|
+
return;
|
|
30
|
+
option.action(option.label);
|
|
31
|
+
open = false;
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<svelte:window onkeydown={toggle} onclick={close_if_outside} />
|
|
36
|
+
|
|
37
|
+
{#if open}
|
|
38
|
+
<dialog
|
|
39
|
+
open
|
|
40
|
+
bind:this={dialog}
|
|
41
|
+
transition:fade={{ duration: fade_duration }}
|
|
42
|
+
style={dialog_style}
|
|
43
|
+
{...dialog_props}
|
|
44
|
+
>
|
|
45
|
+
<MultiSelect
|
|
46
|
+
options={actions}
|
|
47
|
+
bind:input
|
|
48
|
+
{placeholder}
|
|
49
|
+
onadd={trigger_action_and_close}
|
|
50
|
+
onkeydown={toggle}
|
|
51
|
+
{...rest}
|
|
52
|
+
--sms-bg="var(--sms-options-bg)"
|
|
53
|
+
--sms-width="min(20em, 90vw)"
|
|
54
|
+
--sms-max-width="none"
|
|
55
|
+
--sms-placeholder-color="lightgray"
|
|
56
|
+
--sms-options-margin="1px 0"
|
|
57
|
+
--sms-options-border-radius="0 0 1ex 1ex"
|
|
58
|
+
/>
|
|
59
|
+
</dialog>
|
|
60
|
+
{/if}
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
:where(dialog) {
|
|
64
|
+
position: fixed;
|
|
65
|
+
top: 30%;
|
|
66
|
+
border: none;
|
|
67
|
+
padding: 0;
|
|
68
|
+
background-color: transparent;
|
|
69
|
+
display: flex;
|
|
70
|
+
color: light-dark(#222, #eee);
|
|
71
|
+
z-index: 10;
|
|
72
|
+
font-size: 2.4ex;
|
|
73
|
+
}
|
|
74
|
+
</style>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
declare function $$render<Action extends {
|
|
3
|
+
label: string;
|
|
4
|
+
action: (label: string) => void;
|
|
5
|
+
group?: string;
|
|
6
|
+
} & Record<string, unknown> = {
|
|
7
|
+
label: string;
|
|
8
|
+
action: (label: string) => void;
|
|
9
|
+
group?: string;
|
|
10
|
+
}>(): {
|
|
11
|
+
props: Omit<import("./types").MultiSelectProps<Action>, "options"> & {
|
|
12
|
+
actions: Action[];
|
|
13
|
+
triggers?: string[];
|
|
14
|
+
close_keys?: string[];
|
|
15
|
+
fade_duration?: number;
|
|
16
|
+
dialog_style?: string;
|
|
17
|
+
open?: boolean;
|
|
18
|
+
dialog?: HTMLDialogElement | null;
|
|
19
|
+
input?: HTMLInputElement | null;
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
dialog_props?: HTMLAttributes<HTMLDialogElement>;
|
|
22
|
+
};
|
|
23
|
+
exports: {};
|
|
24
|
+
bindings: "dialog" | "input" | "open";
|
|
25
|
+
slots: {};
|
|
26
|
+
events: {};
|
|
27
|
+
};
|
|
28
|
+
declare class __sveltets_Render<Action extends {
|
|
29
|
+
label: string;
|
|
30
|
+
action: (label: string) => void;
|
|
31
|
+
group?: string;
|
|
32
|
+
} & Record<string, unknown> = {
|
|
33
|
+
label: string;
|
|
34
|
+
action: (label: string) => void;
|
|
35
|
+
group?: string;
|
|
36
|
+
}> {
|
|
37
|
+
props(): ReturnType<typeof $$render<Action>>['props'];
|
|
38
|
+
events(): ReturnType<typeof $$render<Action>>['events'];
|
|
39
|
+
slots(): ReturnType<typeof $$render<Action>>['slots'];
|
|
40
|
+
bindings(): "dialog" | "input" | "open";
|
|
41
|
+
exports(): {};
|
|
42
|
+
}
|
|
43
|
+
interface $$IsomorphicComponent {
|
|
44
|
+
new <Action extends {
|
|
45
|
+
label: string;
|
|
46
|
+
action: (label: string) => void;
|
|
47
|
+
group?: string;
|
|
48
|
+
} & Record<string, unknown> = {
|
|
49
|
+
label: string;
|
|
50
|
+
action: (label: string) => void;
|
|
51
|
+
group?: string;
|
|
52
|
+
}>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Action>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Action>['props']>, ReturnType<__sveltets_Render<Action>['events']>, ReturnType<__sveltets_Render<Action>['slots']>> & {
|
|
53
|
+
$$bindings?: ReturnType<__sveltets_Render<Action>['bindings']>;
|
|
54
|
+
} & ReturnType<__sveltets_Render<Action>['exports']>;
|
|
55
|
+
<Action extends {
|
|
56
|
+
label: string;
|
|
57
|
+
action: (label: string) => void;
|
|
58
|
+
group?: string;
|
|
59
|
+
} & Record<string, unknown> = {
|
|
60
|
+
label: string;
|
|
61
|
+
action: (label: string) => void;
|
|
62
|
+
group?: string;
|
|
63
|
+
}>(internal: unknown, props: ReturnType<__sveltets_Render<Action>['props']> & {}): ReturnType<__sveltets_Render<Action>['exports']>;
|
|
64
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
65
|
+
}
|
|
66
|
+
declare const CmdPalette: $$IsomorphicComponent;
|
|
67
|
+
type CmdPalette<Action extends {
|
|
68
|
+
label: string;
|
|
69
|
+
action: (label: string) => void;
|
|
70
|
+
group?: string;
|
|
71
|
+
} & Record<string, unknown> = {
|
|
72
|
+
label: string;
|
|
73
|
+
action: (label: string) => void;
|
|
74
|
+
group?: string;
|
|
75
|
+
}> = InstanceType<typeof CmdPalette<Action>>;
|
|
76
|
+
export default CmdPalette;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<script lang="ts">import Icon from './Icon.svelte';
|
|
2
|
+
let { src = ``, meta = {}, open = $bindable(!meta.collapsible), title, example, code, link_props, // Applied after computed attributes (href, title, etc.), allowing override
|
|
3
|
+
button_props, } = $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
|
|
21
|
+
{href}
|
|
22
|
+
{...links}
|
|
23
|
+
title={icon}
|
|
24
|
+
style:display={cond ? `inline-block` : `none`}
|
|
25
|
+
{...link_props}
|
|
26
|
+
>
|
|
27
|
+
<Icon {icon} />
|
|
28
|
+
</a>
|
|
29
|
+
{/each}
|
|
30
|
+
{#if collapsible}
|
|
31
|
+
{@render title?.()}
|
|
32
|
+
<button onclick={() => (open = !open)} {...button_props}>
|
|
33
|
+
<Icon icon={open ? `Collapse` : `Expand`} />
|
|
34
|
+
{open ? `Close` : `View code`}
|
|
35
|
+
</button>
|
|
36
|
+
{/if}
|
|
37
|
+
</nav>
|
|
38
|
+
<!-- wrap in div with id for precise CSS selectors in playwright E2E tests -->
|
|
39
|
+
<div {id} class="code-example">
|
|
40
|
+
{#if !code_above}
|
|
41
|
+
{@render example?.()}
|
|
42
|
+
{/if}
|
|
43
|
+
|
|
44
|
+
<pre class:open><code>{#if code}{@render code()}{:else}{src}{/if}</code></pre>
|
|
45
|
+
|
|
46
|
+
{#if code_above}
|
|
47
|
+
{@render example?.()}
|
|
48
|
+
{/if}
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<style>
|
|
52
|
+
div.code-example {
|
|
53
|
+
margin: var(--code-example-margin, 1em auto);
|
|
54
|
+
position: relative;
|
|
55
|
+
}
|
|
56
|
+
nav {
|
|
57
|
+
display: flex;
|
|
58
|
+
justify-content: end;
|
|
59
|
+
align-items: center;
|
|
60
|
+
margin: var(--code-example-nav-margin, initial);
|
|
61
|
+
gap: var(--code-example-nav-gap, 1ex);
|
|
62
|
+
}
|
|
63
|
+
pre code {
|
|
64
|
+
background-color: transparent;
|
|
65
|
+
display: inline-block;
|
|
66
|
+
}
|
|
67
|
+
pre {
|
|
68
|
+
position: relative;
|
|
69
|
+
overflow-x: auto;
|
|
70
|
+
visibility: hidden;
|
|
71
|
+
opacity: 0;
|
|
72
|
+
max-height: 0;
|
|
73
|
+
transition: max-height, opacity, visibility;
|
|
74
|
+
transition-duration: var(--code-example-pre-transition-duration, 0.3s);
|
|
75
|
+
border-radius: var(--code-example-pre-border-radius, 4pt);
|
|
76
|
+
background-color: var(--code-example-pre-bg, var(--pre-bg));
|
|
77
|
+
padding: var(--code-example-pre-padding, 1ex 1em);
|
|
78
|
+
}
|
|
79
|
+
pre.open {
|
|
80
|
+
visibility: visible;
|
|
81
|
+
opacity: 1;
|
|
82
|
+
max-height: 9999vh;
|
|
83
|
+
margin: var(--code-example-pre-margin, 1em 0 0 0);
|
|
84
|
+
}
|
|
85
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
src?: string;
|
|
5
|
+
meta?: {
|
|
6
|
+
collapsible?: boolean;
|
|
7
|
+
code_above?: boolean;
|
|
8
|
+
id?: string;
|
|
9
|
+
repl?: string;
|
|
10
|
+
github?: string | boolean;
|
|
11
|
+
repo?: string;
|
|
12
|
+
Wrapper?: string;
|
|
13
|
+
example?: boolean;
|
|
14
|
+
file?: string;
|
|
15
|
+
};
|
|
16
|
+
open?: boolean;
|
|
17
|
+
title?: Snippet<[]>;
|
|
18
|
+
example?: Snippet<[]>;
|
|
19
|
+
code?: Snippet<[]>;
|
|
20
|
+
link_props?: HTMLAttributes<HTMLAnchorElement>;
|
|
21
|
+
button_props?: HTMLAttributes<HTMLButtonElement>;
|
|
22
|
+
};
|
|
23
|
+
declare const CodeExample: import("svelte").Component<$$ComponentProps, {}, "open">;
|
|
24
|
+
type CodeExample = ReturnType<typeof CodeExample>;
|
|
25
|
+
export default CodeExample;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts">import { mount } from 'svelte';
|
|
2
|
+
import CopyButton from './CopyButton.svelte';
|
|
3
|
+
import Icon from './Icon.svelte';
|
|
4
|
+
let { content = ``, state = $bindable(`ready`), global_selector = null, global = false, skip_selector = `button`, as = `button`, labels = {
|
|
5
|
+
ready: { icon: `Copy`, text: `` },
|
|
6
|
+
success: { icon: `Check`, text: `` },
|
|
7
|
+
error: { icon: `Alert`, text: `` },
|
|
8
|
+
}, children, ...rest } = $props();
|
|
9
|
+
$effect(() => {
|
|
10
|
+
if (!global && !global_selector)
|
|
11
|
+
return;
|
|
12
|
+
const apply_copy_buttons = () => {
|
|
13
|
+
const style = `position: absolute; top: 6pt; right: 6pt; ${rest.style ?? ``}`;
|
|
14
|
+
const skip_sel = skip_selector ?? as;
|
|
15
|
+
for (const code of document.querySelectorAll(global_selector ?? `pre > code`)) {
|
|
16
|
+
const pre = code.parentElement;
|
|
17
|
+
const content = code.textContent ?? ``;
|
|
18
|
+
if (pre && !pre.querySelector(`[data-sms-copy]`) &&
|
|
19
|
+
!(skip_sel && pre.querySelector(skip_sel))) {
|
|
20
|
+
mount(CopyButton, {
|
|
21
|
+
target: pre,
|
|
22
|
+
props: { content, as, labels, ...rest, style, 'data-sms-copy': `` },
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
apply_copy_buttons();
|
|
28
|
+
const observer = new MutationObserver(apply_copy_buttons);
|
|
29
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
30
|
+
return () => observer.disconnect();
|
|
31
|
+
});
|
|
32
|
+
async function copy() {
|
|
33
|
+
try {
|
|
34
|
+
await navigator.clipboard.writeText(content);
|
|
35
|
+
state = `success`;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error(err);
|
|
39
|
+
state = `error`;
|
|
40
|
+
}
|
|
41
|
+
setTimeout(() => (state = `ready`), 2000);
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
{#if !(global || global_selector)}
|
|
46
|
+
{@const { text, icon } = labels[state]}
|
|
47
|
+
<svelte:element
|
|
48
|
+
this={as}
|
|
49
|
+
onclick={copy}
|
|
50
|
+
onkeydown={(event) => {
|
|
51
|
+
if (event.key === `Enter` || event.key === ` `) {
|
|
52
|
+
event.preventDefault()
|
|
53
|
+
copy()
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
role="button"
|
|
57
|
+
tabindex={0}
|
|
58
|
+
data-sms-copy=""
|
|
59
|
+
{...rest}
|
|
60
|
+
>
|
|
61
|
+
{#if children}
|
|
62
|
+
{@render children({ state, icon, text })}
|
|
63
|
+
{:else}
|
|
64
|
+
<Icon {icon} />{@html text}
|
|
65
|
+
{/if}
|
|
66
|
+
</svelte:element>
|
|
67
|
+
{/if}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import CopyButton from './CopyButton.svelte';
|
|
4
|
+
import type { IconName } from './icons';
|
|
5
|
+
type State = `ready` | `success` | `error`;
|
|
6
|
+
type $$ComponentProps = Omit<HTMLAttributes<HTMLButtonElement>, `children`> & {
|
|
7
|
+
content?: string;
|
|
8
|
+
state?: State;
|
|
9
|
+
global_selector?: string | null;
|
|
10
|
+
global?: boolean;
|
|
11
|
+
skip_selector?: string | null;
|
|
12
|
+
as?: string;
|
|
13
|
+
labels?: Record<State, {
|
|
14
|
+
icon: IconName;
|
|
15
|
+
text: string;
|
|
16
|
+
}>;
|
|
17
|
+
children?: Snippet<[{
|
|
18
|
+
state: State;
|
|
19
|
+
icon: IconName;
|
|
20
|
+
text: string;
|
|
21
|
+
}]>;
|
|
22
|
+
};
|
|
23
|
+
declare const CopyButton: import("svelte").Component<$$ComponentProps, {}, "state">;
|
|
24
|
+
type CopyButton = ReturnType<typeof CopyButton>;
|
|
25
|
+
export default CopyButton;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts">let { files = $bindable([]), toggle_all_btn_title = `Toggle all`, default_lang = `typescript`, as = `ol`, title_snippet, button_props, details_props, ...rest } = $props();
|
|
2
|
+
// Use reactive state for node refs to avoid binding_property_non_reactive warning
|
|
3
|
+
let node_refs = $state([]);
|
|
4
|
+
// Trim stale refs when files shrink and sync node_refs back to files.node for external access
|
|
5
|
+
$effect(() => {
|
|
6
|
+
// Trim stale references when files array shrinks to prevent memory leaks
|
|
7
|
+
if (node_refs.length > files.length) {
|
|
8
|
+
node_refs.splice(files.length);
|
|
9
|
+
}
|
|
10
|
+
for (const [idx, node] of node_refs.entries()) {
|
|
11
|
+
if (files[idx])
|
|
12
|
+
files[idx].node = node;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
// Check if any nodes are open (for button text)
|
|
16
|
+
const any_open = $derived(node_refs.some((node) => node?.open));
|
|
17
|
+
function toggle_all() {
|
|
18
|
+
const should_close = node_refs.some((node) => node?.open);
|
|
19
|
+
for (const node of node_refs) {
|
|
20
|
+
if (!node)
|
|
21
|
+
continue;
|
|
22
|
+
node.open = !should_close;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
{#if files?.length > 1}
|
|
29
|
+
<button onclick={toggle_all} title={toggle_all_btn_title} {...button_props}>
|
|
30
|
+
{any_open ? `Close` : `Open`} all
|
|
31
|
+
</button>
|
|
32
|
+
{/if}
|
|
33
|
+
|
|
34
|
+
<svelte:element this={as} {...rest}>
|
|
35
|
+
{#each files as file, idx (file.title)}
|
|
36
|
+
{@const { title, content, language = default_lang } = file ?? {}}
|
|
37
|
+
<li>
|
|
38
|
+
<details bind:this={node_refs[idx]} {...details_props}>
|
|
39
|
+
{#if title || title_snippet}
|
|
40
|
+
<summary>
|
|
41
|
+
{#if title_snippet}
|
|
42
|
+
{@render title_snippet({ idx, ...file })}
|
|
43
|
+
{:else}
|
|
44
|
+
{@html title}
|
|
45
|
+
{/if}
|
|
46
|
+
</summary>
|
|
47
|
+
{/if}
|
|
48
|
+
|
|
49
|
+
<pre class="language-{language}"><code>{content}</code></pre>
|
|
50
|
+
</details>
|
|
51
|
+
</li>
|
|
52
|
+
{/each}
|
|
53
|
+
</svelte:element>
|
|
54
|
+
|
|
55
|
+
<style>
|
|
56
|
+
button {
|
|
57
|
+
float: right;
|
|
58
|
+
}
|
|
59
|
+
ol {
|
|
60
|
+
padding: 0;
|
|
61
|
+
}
|
|
62
|
+
ol > li {
|
|
63
|
+
margin: 1ex 0;
|
|
64
|
+
}
|
|
65
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes, HTMLDetailsAttributes } from 'svelte/elements';
|
|
3
|
+
type File = {
|
|
4
|
+
title: string;
|
|
5
|
+
content: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
node?: HTMLDetailsElement | null;
|
|
8
|
+
};
|
|
9
|
+
type $$ComponentProps = {
|
|
10
|
+
files?: File[];
|
|
11
|
+
toggle_all_btn_title?: string;
|
|
12
|
+
default_lang?: string;
|
|
13
|
+
as?: string;
|
|
14
|
+
title_snippet?: Snippet<[{
|
|
15
|
+
idx: number;
|
|
16
|
+
} & File]>;
|
|
17
|
+
button_props?: HTMLAttributes<HTMLButtonElement>;
|
|
18
|
+
details_props?: HTMLDetailsAttributes;
|
|
19
|
+
} & HTMLAttributes<HTMLOListElement>;
|
|
20
|
+
declare const FileDetails: import("svelte").Component<$$ComponentProps, {}, "files">;
|
|
21
|
+
type FileDetails = ReturnType<typeof FileDetails>;
|
|
22
|
+
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, 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 ?? title}
|
|
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, light-dark(#222, #eee));
|
|
37
|
+
color: var(--github-corner-color, light-dark(#fafafa, #1a1a1a));
|
|
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
|
+
type $$ComponentProps = {
|
|
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<$$ComponentProps, {}, "">;
|
|
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>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import { type IconName } from './icons';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<SVGSVGElement> & {
|
|
4
|
+
icon: IconName;
|
|
5
|
+
};
|
|
6
|
+
declare const Icon: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Icon = ReturnType<typeof Icon>;
|
|
8
|
+
export default Icon;
|