@axerity/cli 0.1.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/LICENSE +21 -0
- package/README.md +1 -0
- package/axerity.default.json +135 -0
- package/axerity.schema.json +268 -0
- package/bin/axerity.js +305 -0
- package/mdsvex.config.js +261 -0
- package/package.json +103 -0
- package/scripts/prepare-engine.mjs +20 -0
- package/src/app.d.ts +17 -0
- package/src/app.html +39 -0
- package/src/content/demo/api/meta.json +5 -0
- package/src/content/demo/api/pet/add-pet.md +105 -0
- package/src/content/demo/api/pet/delete-pet.md +70 -0
- package/src/content/demo/api/pet/find-by-status.md +72 -0
- package/src/content/demo/api/pet/find-by-tags.md +64 -0
- package/src/content/demo/api/pet/get-pet.md +99 -0
- package/src/content/demo/api/pet/meta.json +15 -0
- package/src/content/demo/api/pet/pet-object.md +112 -0
- package/src/content/demo/api/pet/update-pet-with-form.md +69 -0
- package/src/content/demo/api/pet/update-pet.md +79 -0
- package/src/content/demo/api/pet/upload-image.md +79 -0
- package/src/content/demo/api/store/delete-order.md +62 -0
- package/src/content/demo/api/store/get-order.md +70 -0
- package/src/content/demo/api/store/inventory.md +54 -0
- package/src/content/demo/api/store/meta.json +5 -0
- package/src/content/demo/api/store/order-object.md +77 -0
- package/src/content/demo/api/store/place-order.md +83 -0
- package/src/content/demo/api/user/create-user.md +69 -0
- package/src/content/demo/api/user/create-with-list.md +57 -0
- package/src/content/demo/api/user/delete-user.md +61 -0
- package/src/content/demo/api/user/get-user.md +69 -0
- package/src/content/demo/api/user/login.md +80 -0
- package/src/content/demo/api/user/logout.md +45 -0
- package/src/content/demo/api/user/meta.json +14 -0
- package/src/content/demo/api/user/update-user.md +69 -0
- package/src/content/demo/api/user/user-object.md +85 -0
- package/src/content/demo/changelog.md +44 -0
- package/src/content/demo/components/accordion.md +70 -0
- package/src/content/demo/components/api.md +185 -0
- package/src/content/demo/components/badge.md +34 -0
- package/src/content/demo/components/callout.md +83 -0
- package/src/content/demo/components/cards.md +88 -0
- package/src/content/demo/components/code-group.md +55 -0
- package/src/content/demo/components/columns.md +42 -0
- package/src/content/demo/components/frame.md +51 -0
- package/src/content/demo/components/icon.md +54 -0
- package/src/content/demo/components/kbd.md +28 -0
- package/src/content/demo/components/meta.json +26 -0
- package/src/content/demo/components/roadmap.md +86 -0
- package/src/content/demo/components/steps.md +72 -0
- package/src/content/demo/components/tabs.md +146 -0
- package/src/content/demo/components/tooltip.md +44 -0
- package/src/content/demo/components/tree.md +83 -0
- package/src/content/demo/components/type-table.md +77 -0
- package/src/content/demo/components/update.md +48 -0
- package/src/content/demo/components/video.md +56 -0
- package/src/content/demo/components/webhooks.md +109 -0
- package/src/content/demo/components/websockets.md +101 -0
- package/src/content/demo/configuration/ai.md +40 -0
- package/src/content/demo/configuration/cli.md +46 -0
- package/src/content/demo/configuration/deployment.md +105 -0
- package/src/content/demo/configuration/index.md +92 -0
- package/src/content/demo/configuration/layouts.md +51 -0
- package/src/content/demo/configuration/meta.json +5 -0
- package/src/content/demo/configuration/navigation.md +167 -0
- package/src/content/demo/configuration/openapi.md +103 -0
- package/src/content/demo/configuration/search.md +36 -0
- package/src/content/demo/index.md +59 -0
- package/src/content/demo/installation.md +49 -0
- package/src/content/demo/meta.json +15 -0
- package/src/content/demo/quick-start.md +47 -0
- package/src/content/demo/theming/advanced.md +116 -0
- package/src/content/demo/theming/code.md +66 -0
- package/src/content/demo/theming/colors.md +103 -0
- package/src/content/demo/theming/index.md +88 -0
- package/src/content/demo/theming/layout.md +71 -0
- package/src/content/demo/theming/meta.json +5 -0
- package/src/content/demo/theming/themes.md +99 -0
- package/src/content/demo/theming/typography.md +83 -0
- package/src/content/demo/writing/code-blocks.md +154 -0
- package/src/content/demo/writing/diagrams.md +44 -0
- package/src/content/demo/writing/frontmatter.md +33 -0
- package/src/content/demo/writing/markdown.md +62 -0
- package/src/content/demo/writing/meta.json +5 -0
- package/src/hooks.server.ts +49 -0
- package/src/lib/assets/favicon.svg +1 -0
- package/src/lib/base.ts +12 -0
- package/src/lib/components/DynamicIcon.svelte +26 -0
- package/src/lib/components/docs/Analytics.svelte +38 -0
- package/src/lib/components/docs/Banner.svelte +44 -0
- package/src/lib/components/docs/Breadcrumbs.svelte +38 -0
- package/src/lib/components/docs/CopyPageMenu.svelte +119 -0
- package/src/lib/components/docs/DocsLayout.svelte +192 -0
- package/src/lib/components/docs/Footer.svelte +60 -0
- package/src/lib/components/docs/Mermaid.svelte +39 -0
- package/src/lib/components/docs/Navbar.svelte +144 -0
- package/src/lib/components/docs/PageMeta.svelte +35 -0
- package/src/lib/components/docs/PageNav.svelte +44 -0
- package/src/lib/components/docs/SearchDialog.svelte +182 -0
- package/src/lib/components/docs/Sidebar.svelte +85 -0
- package/src/lib/components/docs/SidebarDropdown.svelte +56 -0
- package/src/lib/components/docs/SidebarFooterLinks.svelte +19 -0
- package/src/lib/components/docs/SidebarGroup.svelte +54 -0
- package/src/lib/components/docs/SidebarLink.svelte +67 -0
- package/src/lib/components/docs/TableOfContents.svelte +77 -0
- package/src/lib/components/docs/ThemeToggle.svelte +19 -0
- package/src/lib/components/docs/VersionSwitcher.svelte +80 -0
- package/src/lib/components/kit/Accordion.svelte +60 -0
- package/src/lib/components/kit/AccordionGroup.svelte +13 -0
- package/src/lib/components/kit/Badge.svelte +32 -0
- package/src/lib/components/kit/Callout.svelte +51 -0
- package/src/lib/components/kit/Card.svelte +72 -0
- package/src/lib/components/kit/CardGroup.svelte +21 -0
- package/src/lib/components/kit/CodeGroup.svelte +65 -0
- package/src/lib/components/kit/Columns.svelte +26 -0
- package/src/lib/components/kit/Event.svelte +23 -0
- package/src/lib/components/kit/EventList.svelte +9 -0
- package/src/lib/components/kit/File.svelte +15 -0
- package/src/lib/components/kit/Folder.svelte +46 -0
- package/src/lib/components/kit/Frame.svelte +81 -0
- package/src/lib/components/kit/Icon.svelte +17 -0
- package/src/lib/components/kit/Kbd.svelte +11 -0
- package/src/lib/components/kit/Roadmap.svelte +15 -0
- package/src/lib/components/kit/RoadmapItem.svelte +109 -0
- package/src/lib/components/kit/Step.svelte +63 -0
- package/src/lib/components/kit/Steps.svelte +16 -0
- package/src/lib/components/kit/Tab.svelte +27 -0
- package/src/lib/components/kit/Tabs.svelte +75 -0
- package/src/lib/components/kit/Tooltip.svelte +33 -0
- package/src/lib/components/kit/Tree.svelte +11 -0
- package/src/lib/components/kit/TypeTable.svelte +187 -0
- package/src/lib/components/kit/Update.svelte +32 -0
- package/src/lib/components/kit/Video.svelte +64 -0
- package/src/lib/components/kit/accordion-context.ts +1 -0
- package/src/lib/components/kit/api/Api.svelte +80 -0
- package/src/lib/components/kit/api/ApiExamplePanel.svelte +100 -0
- package/src/lib/components/kit/api/ApiField.svelte +124 -0
- package/src/lib/components/kit/api/Channel.svelte +121 -0
- package/src/lib/components/kit/api/Endpoint.svelte +116 -0
- package/src/lib/components/kit/api/Enum.svelte +44 -0
- package/src/lib/components/kit/api/EnumValues.svelte +35 -0
- package/src/lib/components/kit/api/Expandable.svelte +70 -0
- package/src/lib/components/kit/api/Message.svelte +67 -0
- package/src/lib/components/kit/api/ObjectExample.svelte +11 -0
- package/src/lib/components/kit/api/RequestExample.svelte +11 -0
- package/src/lib/components/kit/api/ResponseExample.svelte +11 -0
- package/src/lib/components/kit/api/Webhook.svelte +115 -0
- package/src/lib/components/kit/api/api-context.ts +15 -0
- package/src/lib/components/kit/tabs-context.ts +8 -0
- package/src/lib/components/kit/tabs-store.svelte.ts +28 -0
- package/src/lib/config/site.ts +34 -0
- package/src/lib/content/index.ts +50 -0
- package/src/lib/content/raw.ts +21 -0
- package/src/lib/content/tree.ts +169 -0
- package/src/lib/index.ts +79 -0
- package/src/lib/nav-match.ts +23 -0
- package/src/lib/openapi/generate.ts +629 -0
- package/src/lib/server/og.ts +140 -0
- package/src/lib/state/search.svelte.ts +9 -0
- package/src/lib/state/theme.svelte.ts +58 -0
- package/src/lib/types.ts +216 -0
- package/src/params/docpage.ts +3 -0
- package/src/params/mdfile.ts +3 -0
- package/src/routes/+error.svelte +46 -0
- package/src/routes/+layout.svelte +25 -0
- package/src/routes/[...path=mdfile]/+server.ts +21 -0
- package/src/routes/[...slug=docpage]/+page.svelte +63 -0
- package/src/routes/[...slug=docpage]/+page.ts +44 -0
- package/src/routes/layout.css +897 -0
- package/src/routes/llms-full.txt/+server.ts +22 -0
- package/src/routes/llms.txt/+server.ts +20 -0
- package/src/routes/og/[...slug]/+server.ts +77 -0
- package/src/routes/rss.xml/+server.ts +65 -0
- package/src/routes/search.json/+server.ts +54 -0
- package/src/routes/sitemap.xml/+server.ts +21 -0
- package/static/favicon-dark.svg +6 -0
- package/static/favicon-light.svg +6 -0
- package/static/favicon.svg +14 -0
- package/static/fonts/geist-400.ttf +0 -0
- package/static/fonts/geist-600.ttf +0 -0
- package/static/fonts/geist-700.ttf +0 -0
- package/static/og-image.png +0 -0
- package/static/robots.txt +4 -0
- package/svelte.config.js +35 -0
- package/tsconfig.json +20 -0
- package/vite.config.ts +46 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { getContext, untrack } from 'svelte';
|
|
4
|
+
import { slide } from 'svelte/transition';
|
|
5
|
+
import ChevronDown from '@lucide/svelte/icons/chevron-down';
|
|
6
|
+
import DynamicIcon from '$lib/components/DynamicIcon.svelte';
|
|
7
|
+
import { ACCORDION_GROUP } from './accordion-context';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
title,
|
|
11
|
+
icon,
|
|
12
|
+
open = false,
|
|
13
|
+
children
|
|
14
|
+
}: { title: string; icon?: string; open?: boolean; children: Snippet } = $props();
|
|
15
|
+
|
|
16
|
+
// `open` is an uncontrolled initial value; toggling afterwards is internal.
|
|
17
|
+
let isOpen = $state(untrack(() => open));
|
|
18
|
+
|
|
19
|
+
const grouped = getContext(ACCORDION_GROUP) === true;
|
|
20
|
+
|
|
21
|
+
// Standalone accordions are self-contained cards; grouped ones inherit the
|
|
22
|
+
// group's border and dividers.
|
|
23
|
+
const wrapperClass = grouped ? 'bg-surface' : 'my-5 rounded-xl border border-border bg-surface';
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div class={wrapperClass}>
|
|
27
|
+
<button
|
|
28
|
+
type="button"
|
|
29
|
+
onclick={() => (isOpen = !isOpen)}
|
|
30
|
+
aria-expanded={isOpen}
|
|
31
|
+
class="flex w-full items-center gap-3 px-4 py-3 text-left text-sm font-medium text-fg transition hover:bg-bg-subtle"
|
|
32
|
+
>
|
|
33
|
+
{#if icon}
|
|
34
|
+
<DynamicIcon name={icon} size={18} class="shrink-0 text-accent" />
|
|
35
|
+
{/if}
|
|
36
|
+
<span class="flex-1">{title}</span>
|
|
37
|
+
<ChevronDown
|
|
38
|
+
size={18}
|
|
39
|
+
class="shrink-0 text-fg-subtle transition-transform duration-200 {isOpen ? 'rotate-180' : ''}"
|
|
40
|
+
/>
|
|
41
|
+
</button>
|
|
42
|
+
|
|
43
|
+
{#if isOpen}
|
|
44
|
+
<div transition:slide={{ duration: 200 }}>
|
|
45
|
+
<div class="accordion-body px-4 pb-4 text-sm text-fg-muted">
|
|
46
|
+
{@render children()}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
{/if}
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<style>
|
|
53
|
+
/* Trim stray margins from markdown rendered inside the panel. */
|
|
54
|
+
.accordion-body :global(> :first-child) {
|
|
55
|
+
margin-top: 0;
|
|
56
|
+
}
|
|
57
|
+
.accordion-body :global(> :last-child) {
|
|
58
|
+
margin-bottom: 0;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { setContext } from 'svelte';
|
|
4
|
+
import { ACCORDION_GROUP } from './accordion-context';
|
|
5
|
+
|
|
6
|
+
let { children }: { children: Snippet } = $props();
|
|
7
|
+
|
|
8
|
+
setContext(ACCORDION_GROUP, true);
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div class="my-5 divide-y divide-border overflow-hidden rounded-xl border border-border">
|
|
12
|
+
{@render children()}
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type Color = 'neutral' | 'info' | 'success' | 'warn' | 'error';
|
|
5
|
+
|
|
6
|
+
let { color = 'neutral', children }: { color?: Color; children: Snippet } = $props();
|
|
7
|
+
|
|
8
|
+
const variants = {
|
|
9
|
+
neutral: 'border-border bg-bg-subtle text-fg-muted',
|
|
10
|
+
info: 'border-transparent bg-(--c)/15 text-(--c)',
|
|
11
|
+
success: 'border-transparent bg-(--c)/15 text-(--c)',
|
|
12
|
+
warn: 'border-transparent bg-(--c)/15 text-(--c)',
|
|
13
|
+
error: 'border-transparent bg-(--c)/15 text-(--c)'
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
const colors = {
|
|
17
|
+
neutral: 'var(--fg-muted)',
|
|
18
|
+
info: 'oklch(0.62 0.2 250)',
|
|
19
|
+
success: 'oklch(0.6 0.16 155)',
|
|
20
|
+
warn: 'oklch(0.7 0.16 75)',
|
|
21
|
+
error: 'oklch(0.62 0.22 25)'
|
|
22
|
+
} as const;
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<span
|
|
26
|
+
class="inline-flex items-center rounded-full border px-2 py-0.5 align-middle text-xs font-medium {variants[
|
|
27
|
+
color
|
|
28
|
+
]}"
|
|
29
|
+
style="--c: {colors[color]};"
|
|
30
|
+
>
|
|
31
|
+
{@render children()}
|
|
32
|
+
</span>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
import Info from '@lucide/svelte/icons/info';
|
|
5
|
+
import Lightbulb from '@lucide/svelte/icons/lightbulb';
|
|
6
|
+
import CircleCheck from '@lucide/svelte/icons/circle-check';
|
|
7
|
+
import TriangleAlert from '@lucide/svelte/icons/triangle-alert';
|
|
8
|
+
import CircleX from '@lucide/svelte/icons/circle-x';
|
|
9
|
+
|
|
10
|
+
type CalloutType = 'info' | 'tip' | 'success' | 'warn' | 'warning' | 'error';
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
type = 'info',
|
|
14
|
+
title,
|
|
15
|
+
children
|
|
16
|
+
}: { type?: CalloutType; title?: string; children: Snippet } = $props();
|
|
17
|
+
|
|
18
|
+
const variants = {
|
|
19
|
+
info: { icon: Info, color: 'var(--fg-muted)' },
|
|
20
|
+
tip: { icon: Lightbulb, color: 'oklch(0.62 0.2 300)' },
|
|
21
|
+
success: { icon: CircleCheck, color: 'oklch(0.6 0.16 155)' },
|
|
22
|
+
warn: { icon: TriangleAlert, color: 'oklch(0.7 0.16 75)' },
|
|
23
|
+
error: { icon: CircleX, color: 'oklch(0.62 0.22 25)' }
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
const variant = $derived(variants[type === 'warning' ? 'warn' : type]);
|
|
27
|
+
const Icon = $derived(variant.icon);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div
|
|
31
|
+
class="callout my-5 flex gap-2.5 rounded-lg border border-(--c)/25 bg-(--c)/[0.07] px-4 py-3"
|
|
32
|
+
style="--c: {variant.color};"
|
|
33
|
+
role="note"
|
|
34
|
+
>
|
|
35
|
+
<Icon size={18} class="mt-0.5 shrink-0 text-(--c)" />
|
|
36
|
+
<div class="callout-body min-w-0 flex-1 text-sm leading-relaxed text-(--c)">
|
|
37
|
+
{#if title}
|
|
38
|
+
<p class="mb-0.5 font-semibold">{title}</p>
|
|
39
|
+
{/if}
|
|
40
|
+
{@render children()}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
.callout-body :global(> :first-child) {
|
|
46
|
+
margin-top: 0;
|
|
47
|
+
}
|
|
48
|
+
.callout-body :global(> :last-child) {
|
|
49
|
+
margin-bottom: 0;
|
|
50
|
+
}
|
|
51
|
+
</style>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import ArrowRight from '@lucide/svelte/icons/arrow-right';
|
|
4
|
+
import DynamicIcon from '$lib/components/DynamicIcon.svelte';
|
|
5
|
+
import { withBase } from '$lib/base';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
title,
|
|
9
|
+
icon,
|
|
10
|
+
href,
|
|
11
|
+
horizontal = false,
|
|
12
|
+
children
|
|
13
|
+
}: {
|
|
14
|
+
title: string;
|
|
15
|
+
icon?: string;
|
|
16
|
+
href?: string;
|
|
17
|
+
horizontal?: boolean;
|
|
18
|
+
children?: Snippet;
|
|
19
|
+
} = $props();
|
|
20
|
+
|
|
21
|
+
const isLink = $derived(!!href);
|
|
22
|
+
const external = $derived(!!href && /^https?:\/\//.test(href));
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<svelte:element
|
|
26
|
+
this={href ? 'a' : 'div'}
|
|
27
|
+
href={withBase(href) || undefined}
|
|
28
|
+
target={external ? '_blank' : undefined}
|
|
29
|
+
rel={external ? 'noreferrer' : undefined}
|
|
30
|
+
class="card-root group block rounded-lg border border-border bg-surface p-4 transition
|
|
31
|
+
{isLink ? 'hover:border-border-strong hover:bg-bg-subtle' : ''}
|
|
32
|
+
{horizontal ? 'flex items-start gap-3.5' : ''}"
|
|
33
|
+
>
|
|
34
|
+
{#if icon}
|
|
35
|
+
<div
|
|
36
|
+
class="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-border bg-bg-subtle text-fg
|
|
37
|
+
{horizontal ? '' : 'mb-3'}"
|
|
38
|
+
>
|
|
39
|
+
<DynamicIcon name={icon} size={17} />
|
|
40
|
+
</div>
|
|
41
|
+
{/if}
|
|
42
|
+
|
|
43
|
+
<div class="min-w-0 flex-1">
|
|
44
|
+
<div class="flex items-center gap-1.5">
|
|
45
|
+
<span class="font-semibold text-fg">{title}</span>
|
|
46
|
+
{#if isLink}
|
|
47
|
+
<ArrowRight
|
|
48
|
+
size={15}
|
|
49
|
+
class="text-fg-subtle transition-transform group-hover:translate-x-0.5"
|
|
50
|
+
/>
|
|
51
|
+
{/if}
|
|
52
|
+
</div>
|
|
53
|
+
{#if children}
|
|
54
|
+
<div class="card-body mt-1 text-sm text-fg-muted">
|
|
55
|
+
{@render children()}
|
|
56
|
+
</div>
|
|
57
|
+
{/if}
|
|
58
|
+
</div>
|
|
59
|
+
</svelte:element>
|
|
60
|
+
|
|
61
|
+
<style>
|
|
62
|
+
.card-root,
|
|
63
|
+
.card-root:hover {
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
}
|
|
66
|
+
.card-body :global(> :first-child) {
|
|
67
|
+
margin-top: 0;
|
|
68
|
+
}
|
|
69
|
+
.card-body :global(> :last-child) {
|
|
70
|
+
margin-bottom: 0;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { cols = 2, children }: { cols?: number; children: Snippet } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="card-group my-5 grid gap-3" style="--cols: {cols};">
|
|
8
|
+
{@render children()}
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<style>
|
|
12
|
+
.card-group {
|
|
13
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (min-width: 640px) {
|
|
17
|
+
.card-group {
|
|
18
|
+
grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { children }: { children: Snippet } = $props();
|
|
5
|
+
|
|
6
|
+
let container = $state<HTMLElement>();
|
|
7
|
+
let tabs = $state<string[]>([]);
|
|
8
|
+
let active = $state(0);
|
|
9
|
+
|
|
10
|
+
let blocks: HTMLElement[] = [];
|
|
11
|
+
let initialized = false;
|
|
12
|
+
|
|
13
|
+
$effect(() => {
|
|
14
|
+
if (!container || initialized) return;
|
|
15
|
+
const found = Array.from(
|
|
16
|
+
container.querySelectorAll('.cg-blocks > .code-block')
|
|
17
|
+
) as HTMLElement[];
|
|
18
|
+
if (!found.length) return;
|
|
19
|
+
|
|
20
|
+
blocks = found;
|
|
21
|
+
tabs = found.map((block, index) => {
|
|
22
|
+
const title = block.querySelector('.code-title')?.textContent?.trim();
|
|
23
|
+
block.querySelector('.code-header')?.classList.add('hidden');
|
|
24
|
+
return title || `Tab ${index + 1}`;
|
|
25
|
+
});
|
|
26
|
+
select(0);
|
|
27
|
+
initialized = true;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function select(index: number) {
|
|
31
|
+
active = index;
|
|
32
|
+
blocks.forEach((block, i) => block.classList.toggle('hidden', i !== index));
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<div class="code-group my-5 overflow-hidden rounded-lg border border-border" bind:this={container}>
|
|
37
|
+
{#if tabs.length}
|
|
38
|
+
<div class="cg-tabs flex items-center gap-1 border-b border-border bg-bg-subtle px-1.5 py-1.5">
|
|
39
|
+
{#each tabs as tab, index (index)}
|
|
40
|
+
<button
|
|
41
|
+
type="button"
|
|
42
|
+
onclick={() => select(index)}
|
|
43
|
+
class="rounded-md px-2.5 py-1 font-mono text-xs transition
|
|
44
|
+
{index === active ? 'bg-surface text-fg' : 'text-fg-muted hover:text-fg'}"
|
|
45
|
+
>
|
|
46
|
+
{tab}
|
|
47
|
+
</button>
|
|
48
|
+
{/each}
|
|
49
|
+
</div>
|
|
50
|
+
{/if}
|
|
51
|
+
<div class="cg-blocks">
|
|
52
|
+
{@render children()}
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
.code-group :global(.code-block) {
|
|
58
|
+
margin: 0;
|
|
59
|
+
border-radius: 0;
|
|
60
|
+
}
|
|
61
|
+
.code-group :global(.code-block pre) {
|
|
62
|
+
border: 0;
|
|
63
|
+
border-radius: 0;
|
|
64
|
+
}
|
|
65
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { cols = 2, children }: { cols?: number; children: Snippet } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="columns-grid" style="--cols: {cols};">
|
|
8
|
+
{@render children()}
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<style>
|
|
12
|
+
.columns-grid {
|
|
13
|
+
display: grid;
|
|
14
|
+
gap: 1rem;
|
|
15
|
+
grid-template-columns: 1fr;
|
|
16
|
+
margin: 1.25rem 0;
|
|
17
|
+
}
|
|
18
|
+
@media (min-width: 640px) {
|
|
19
|
+
.columns-grid {
|
|
20
|
+
grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
.columns-grid :global(> *) {
|
|
24
|
+
margin: 0;
|
|
25
|
+
}
|
|
26
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import ArrowRight from '@lucide/svelte/icons/arrow-right';
|
|
4
|
+
import { withBase } from '$lib/base';
|
|
5
|
+
|
|
6
|
+
let { name, href, children }: { name: string; href?: string; children?: Snippet } = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<svelte:element
|
|
10
|
+
this={href ? 'a' : 'div'}
|
|
11
|
+
href={href ? withBase(href) : undefined}
|
|
12
|
+
class="event-item flex items-center gap-3 px-4 py-3 text-sm transition {href
|
|
13
|
+
? 'hover:bg-bg-subtle'
|
|
14
|
+
: ''}"
|
|
15
|
+
>
|
|
16
|
+
<code class="shrink-0 font-mono text-fg">{name}</code>
|
|
17
|
+
{#if children}
|
|
18
|
+
<span class="min-w-0 flex-1 truncate text-fg-muted">{@render children()}</span>
|
|
19
|
+
{/if}
|
|
20
|
+
{#if href}
|
|
21
|
+
<ArrowRight size={15} class="ml-auto shrink-0 text-fg-subtle" />
|
|
22
|
+
{/if}
|
|
23
|
+
</svelte:element>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { children }: { children: Snippet } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="event-list my-5 divide-y divide-border overflow-hidden rounded-lg border border-border">
|
|
8
|
+
{@render children()}
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import FileIcon from '@lucide/svelte/icons/file';
|
|
3
|
+
import DynamicIcon from '$lib/components/DynamicIcon.svelte';
|
|
4
|
+
|
|
5
|
+
let { name, icon }: { name: string; icon?: string } = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div class="tree-file flex items-center gap-1.5 rounded-md py-1 pr-1.5 pl-[1.625rem] text-fg-muted">
|
|
9
|
+
{#if icon}
|
|
10
|
+
<DynamicIcon name={icon} size={16} class="shrink-0 text-fg-subtle" />
|
|
11
|
+
{:else}
|
|
12
|
+
<FileIcon size={16} class="shrink-0 text-fg-subtle" />
|
|
13
|
+
{/if}
|
|
14
|
+
<span class="truncate">{name}</span>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { untrack } from 'svelte';
|
|
4
|
+
import { slide } from 'svelte/transition';
|
|
5
|
+
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
|
6
|
+
import FolderClosed from '@lucide/svelte/icons/folder';
|
|
7
|
+
import FolderOpen from '@lucide/svelte/icons/folder-open';
|
|
8
|
+
import DynamicIcon from '$lib/components/DynamicIcon.svelte';
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
name,
|
|
12
|
+
icon,
|
|
13
|
+
defaultOpen = false,
|
|
14
|
+
children
|
|
15
|
+
}: { name: string; icon?: string; defaultOpen?: boolean; children?: Snippet } = $props();
|
|
16
|
+
|
|
17
|
+
let isOpen = $state(untrack(() => defaultOpen));
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div class="tree-folder">
|
|
21
|
+
<button
|
|
22
|
+
type="button"
|
|
23
|
+
onclick={() => (isOpen = !isOpen)}
|
|
24
|
+
aria-expanded={isOpen}
|
|
25
|
+
class="flex w-full items-center gap-1.5 rounded-md px-1.5 py-1 text-left transition hover:bg-surface-raised"
|
|
26
|
+
>
|
|
27
|
+
<ChevronRight
|
|
28
|
+
size={14}
|
|
29
|
+
class="shrink-0 text-fg-subtle transition-transform duration-150 {isOpen ? 'rotate-90' : ''}"
|
|
30
|
+
/>
|
|
31
|
+
{#if icon}
|
|
32
|
+
<DynamicIcon name={icon} size={16} class="shrink-0 text-fg-muted" />
|
|
33
|
+
{:else if isOpen}
|
|
34
|
+
<FolderOpen size={16} class="shrink-0 text-fg-muted" />
|
|
35
|
+
{:else}
|
|
36
|
+
<FolderClosed size={16} class="shrink-0 text-fg-muted" />
|
|
37
|
+
{/if}
|
|
38
|
+
<span class="truncate">{name}</span>
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
{#if isOpen && children}
|
|
42
|
+
<div transition:slide={{ duration: 150 }} class="ml-[0.6875rem] border-l border-border pl-2">
|
|
43
|
+
{@render children()}
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
46
|
+
</div>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { fade, scale } from 'svelte/transition';
|
|
4
|
+
import { browser } from '$app/environment';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
caption,
|
|
8
|
+
zoom = true,
|
|
9
|
+
children
|
|
10
|
+
}: { caption?: string; zoom?: boolean; children: Snippet } = $props();
|
|
11
|
+
|
|
12
|
+
let open = $state(false);
|
|
13
|
+
|
|
14
|
+
function onkeydown(event: KeyboardEvent) {
|
|
15
|
+
if (event.key === 'Escape') open = false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
$effect(() => {
|
|
19
|
+
if (!browser) return;
|
|
20
|
+
document.body.style.overflow = open ? 'hidden' : '';
|
|
21
|
+
return () => {
|
|
22
|
+
document.body.style.overflow = '';
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<svelte:window {onkeydown} />
|
|
28
|
+
|
|
29
|
+
<figure class="frame my-6">
|
|
30
|
+
{#if zoom}
|
|
31
|
+
<button
|
|
32
|
+
type="button"
|
|
33
|
+
onclick={() => (open = true)}
|
|
34
|
+
class="frame-inner flex w-full cursor-zoom-in justify-center rounded-xl border border-border bg-surface-raised p-4 transition hover:border-border-strong"
|
|
35
|
+
>
|
|
36
|
+
{@render children()}
|
|
37
|
+
</button>
|
|
38
|
+
{:else}
|
|
39
|
+
<div
|
|
40
|
+
class="frame-inner flex justify-center rounded-xl border border-border bg-surface-raised p-4"
|
|
41
|
+
>
|
|
42
|
+
{@render children()}
|
|
43
|
+
</div>
|
|
44
|
+
{/if}
|
|
45
|
+
{#if caption}
|
|
46
|
+
<figcaption class="mt-2.5 text-center text-sm text-fg-subtle">{caption}</figcaption>
|
|
47
|
+
{/if}
|
|
48
|
+
</figure>
|
|
49
|
+
|
|
50
|
+
{#if open}
|
|
51
|
+
<button
|
|
52
|
+
type="button"
|
|
53
|
+
onclick={() => (open = false)}
|
|
54
|
+
aria-label="Close expanded view"
|
|
55
|
+
class="frame-overlay fixed inset-0 z-100 flex cursor-zoom-out items-center justify-center bg-black/80 p-6 backdrop-blur-sm"
|
|
56
|
+
transition:fade={{ duration: 150 }}
|
|
57
|
+
>
|
|
58
|
+
<span class="frame-overlay-inner block max-h-full max-w-5xl" transition:scale={{ start: 0.96 }}>
|
|
59
|
+
{@render children()}
|
|
60
|
+
</span>
|
|
61
|
+
</button>
|
|
62
|
+
{/if}
|
|
63
|
+
|
|
64
|
+
<style>
|
|
65
|
+
.frame-inner :global(img),
|
|
66
|
+
.frame-inner :global(video) {
|
|
67
|
+
margin: 0;
|
|
68
|
+
border-radius: 0.5rem;
|
|
69
|
+
max-width: 100%;
|
|
70
|
+
height: auto;
|
|
71
|
+
}
|
|
72
|
+
.frame-overlay-inner :global(img),
|
|
73
|
+
.frame-overlay-inner :global(video) {
|
|
74
|
+
margin: 0;
|
|
75
|
+
border-radius: 0.5rem;
|
|
76
|
+
max-height: 85vh;
|
|
77
|
+
max-width: 100%;
|
|
78
|
+
width: auto;
|
|
79
|
+
height: auto;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import DynamicIcon from '$lib/components/DynamicIcon.svelte';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
icon,
|
|
6
|
+
size = 16,
|
|
7
|
+
color,
|
|
8
|
+
class: className = ''
|
|
9
|
+
}: { icon: string; size?: number; color?: string; class?: string } = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<span
|
|
13
|
+
class="inline-icon inline-flex align-middle {className}"
|
|
14
|
+
style={color ? `color: ${color};` : undefined}
|
|
15
|
+
>
|
|
16
|
+
<DynamicIcon name={icon} {size} />
|
|
17
|
+
</span>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { children }: { children: Snippet } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<kbd
|
|
8
|
+
class="inline-flex min-w-5 items-center justify-center rounded border border-b-2 border-border bg-bg-subtle px-1.5 py-0.5 font-mono text-xs text-fg-muted"
|
|
9
|
+
>
|
|
10
|
+
{@render children()}
|
|
11
|
+
</kbd>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { children }: { children: Snippet } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="roadmap">
|
|
8
|
+
{@render children()}
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<style>
|
|
12
|
+
.roadmap {
|
|
13
|
+
margin: 1.5rem 0;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type Status = 'planned' | 'exploring' | 'in-progress' | 'shipped';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
title,
|
|
8
|
+
status = 'planned',
|
|
9
|
+
eta,
|
|
10
|
+
children
|
|
11
|
+
}: {
|
|
12
|
+
title: string;
|
|
13
|
+
status?: Status;
|
|
14
|
+
eta?: string;
|
|
15
|
+
children?: Snippet;
|
|
16
|
+
} = $props();
|
|
17
|
+
|
|
18
|
+
const meta = {
|
|
19
|
+
planned: { label: 'Planned', color: 'var(--fg-subtle)' },
|
|
20
|
+
exploring: { label: 'Exploring', color: 'oklch(0.62 0.2 295)' },
|
|
21
|
+
'in-progress': { label: 'In progress', color: 'oklch(0.7 0.16 75)' },
|
|
22
|
+
shipped: { label: 'Shipped', color: 'oklch(0.6 0.16 155)' }
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
const current = $derived(meta[status] ?? meta.planned);
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<div class="item" style="--c: {current.color};">
|
|
29
|
+
<span class="dot" aria-hidden="true"></span>
|
|
30
|
+
<div class="content">
|
|
31
|
+
<div class="head">
|
|
32
|
+
<span class="title">{title}</span>
|
|
33
|
+
<span class="status">{current.label}</span>
|
|
34
|
+
{#if eta}
|
|
35
|
+
<span class="eta">· {eta}</span>
|
|
36
|
+
{/if}
|
|
37
|
+
</div>
|
|
38
|
+
{#if children}
|
|
39
|
+
<div class="body">
|
|
40
|
+
{@render children()}
|
|
41
|
+
</div>
|
|
42
|
+
{/if}
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<style>
|
|
47
|
+
.item {
|
|
48
|
+
display: flex;
|
|
49
|
+
gap: 0.875rem;
|
|
50
|
+
padding-bottom: 1.5rem;
|
|
51
|
+
}
|
|
52
|
+
.item:last-child {
|
|
53
|
+
padding-bottom: 0;
|
|
54
|
+
}
|
|
55
|
+
.dot {
|
|
56
|
+
position: relative;
|
|
57
|
+
margin-top: 0.35rem;
|
|
58
|
+
height: 0.5rem;
|
|
59
|
+
width: 0.5rem;
|
|
60
|
+
flex-shrink: 0;
|
|
61
|
+
border-radius: 9999px;
|
|
62
|
+
background-color: var(--c);
|
|
63
|
+
}
|
|
64
|
+
.item:not(:last-child) .dot::after {
|
|
65
|
+
content: '';
|
|
66
|
+
position: absolute;
|
|
67
|
+
top: 0.9rem;
|
|
68
|
+
left: 50%;
|
|
69
|
+
height: calc(100% + 1.5rem);
|
|
70
|
+
width: 1px;
|
|
71
|
+
transform: translateX(-50%);
|
|
72
|
+
background-color: var(--border);
|
|
73
|
+
}
|
|
74
|
+
.content {
|
|
75
|
+
min-width: 0;
|
|
76
|
+
flex: 1;
|
|
77
|
+
}
|
|
78
|
+
.head {
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-wrap: wrap;
|
|
81
|
+
align-items: baseline;
|
|
82
|
+
gap: 0.25rem 0.5rem;
|
|
83
|
+
}
|
|
84
|
+
.title {
|
|
85
|
+
font-size: 0.95rem;
|
|
86
|
+
font-weight: 600;
|
|
87
|
+
color: var(--fg);
|
|
88
|
+
}
|
|
89
|
+
.status {
|
|
90
|
+
font-size: 0.8rem;
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
color: var(--c);
|
|
93
|
+
}
|
|
94
|
+
.eta {
|
|
95
|
+
font-size: 0.8rem;
|
|
96
|
+
color: var(--fg-subtle);
|
|
97
|
+
}
|
|
98
|
+
.body {
|
|
99
|
+
margin-top: 0.2rem;
|
|
100
|
+
font-size: 0.875rem;
|
|
101
|
+
color: var(--fg-muted);
|
|
102
|
+
}
|
|
103
|
+
.body :global(> :first-child) {
|
|
104
|
+
margin-top: 0;
|
|
105
|
+
}
|
|
106
|
+
.body :global(> :last-child) {
|
|
107
|
+
margin-bottom: 0;
|
|
108
|
+
}
|
|
109
|
+
</style>
|