@tenphi/starlight 0.4.0 → 0.6.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/components/Card.astro +5 -3
- package/dist/components/GlobalStyles.js +785 -0
- package/dist/components/LayoutComponents.js +752 -0
- package/dist/components/Logo.astro +39 -0
- package/dist/components/MobileNavigationTabs.astro +7 -2
- package/dist/components/NavigationTree.astro +6 -2
- package/dist/components/PackageVersion.astro +22 -0
- package/dist/components/Preview.astro +21 -10
- package/dist/components/Steps.astro +5 -1
- package/dist/components/Tabs.astro +9 -2
- package/dist/components/TastyComponents.js +156 -0
- package/dist/components/component-styles.test.ts +75 -0
- package/dist/components/component-styles.ts +79 -0
- package/dist/components/customize-component.js +10 -0
- package/dist/components/svg-icon.test.ts +11 -0
- package/dist/components/svg-icon.ts +11 -0
- package/dist/components/tasty-states.d.ts +2 -0
- package/dist/components/tasty-states.js +21 -0
- package/dist/components-public.d.ts +1 -0
- package/dist/components.d.ts +2 -1
- package/dist/components.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +238 -139
- package/dist/index.js.map +1 -1
- package/dist/overrides/Header.astro +28 -5
- package/dist/overrides/MobileMenuFooter.astro +15 -0
- package/dist/overrides/ThemeSelect.astro +69 -0
- package/dist/routes/DocsPage.astro +71 -30
- package/package.json +5 -8
- package/dist/styles.css +0 -1346
- package/dist/styles.d.ts +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { LogoRoot } from "./LayoutComponents.js";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
label?: string;
|
|
6
|
+
decorative?: boolean;
|
|
7
|
+
class?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
label = "Cookbook",
|
|
12
|
+
decorative = false,
|
|
13
|
+
class: className,
|
|
14
|
+
} = Astro.props;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<LogoRoot
|
|
18
|
+
className={className}
|
|
19
|
+
aria-hidden={decorative ? "true" : undefined}
|
|
20
|
+
data-tasty-anatomy="Logo"
|
|
21
|
+
>
|
|
22
|
+
<svg
|
|
23
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
24
|
+
viewBox="0 0 64 64"
|
|
25
|
+
role={decorative ? undefined : "img"}
|
|
26
|
+
aria-label={decorative ? undefined : label}
|
|
27
|
+
focusable="false"
|
|
28
|
+
>
|
|
29
|
+
<rect width="64" height="64" rx="14" fill="currentColor"></rect>
|
|
30
|
+
<path
|
|
31
|
+
fill="#fff"
|
|
32
|
+
d="M14.8 16c6.7.2 12.3 2 16.7 5.4v28.4c-4.4-3.1-10-4.7-16.6-4.9a3 3 0 0 1-2.9-3V19a3 3 0 0 1 2.8-3Z"
|
|
33
|
+
></path>
|
|
34
|
+
<path
|
|
35
|
+
fill="#fff"
|
|
36
|
+
d="M49.2 16c-6.7.2-12.3 2-16.7 5.4v28.4c4.4-3.1 10-4.7 16.6-4.9a3 3 0 0 0 2.9-3V19a3 3 0 0 0-2.8-3Z"
|
|
37
|
+
></path>
|
|
38
|
+
</svg>
|
|
39
|
+
</LogoRoot>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { layout } from "virtual:cookbook/layout";
|
|
3
3
|
import { activeNavigationTab, navigationPath } from "../navigation.js";
|
|
4
|
+
import { MobileNavigationTabsRoot } from "./LayoutComponents.js";
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
base?: string;
|
|
@@ -21,7 +22,11 @@ function tabHref(link: string): string {
|
|
|
21
22
|
|
|
22
23
|
{
|
|
23
24
|
layout.tabs.length > 0 && (
|
|
24
|
-
<
|
|
25
|
+
<MobileNavigationTabsRoot
|
|
26
|
+
className="td-mobile-tabs print:hidden"
|
|
27
|
+
aria-label="Sections"
|
|
28
|
+
data-tasty-anatomy="MobileNavigationTabs"
|
|
29
|
+
>
|
|
25
30
|
<span class="td-mobile-tabs__label">Sections</span>
|
|
26
31
|
<ul>
|
|
27
32
|
{layout.tabs.map((tab, index) => (
|
|
@@ -35,6 +40,6 @@ function tabHref(link: string): string {
|
|
|
35
40
|
</li>
|
|
36
41
|
))}
|
|
37
42
|
</ul>
|
|
38
|
-
</
|
|
43
|
+
</MobileNavigationTabsRoot>
|
|
39
44
|
)
|
|
40
45
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { DocsRoute, NavigationItem } from "@tenphi/docs";
|
|
3
3
|
import { normalizeNavigationPath } from "../navigation.js";
|
|
4
|
+
import { NavigationTreeRoot } from "./LayoutComponents.js";
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
items: NavigationItem[];
|
|
@@ -36,7 +37,10 @@ const generatedItems = (directory: string): NavigationItem[] => {
|
|
|
36
37
|
};
|
|
37
38
|
---
|
|
38
39
|
|
|
39
|
-
<
|
|
40
|
+
<NavigationTreeRoot
|
|
41
|
+
className={nested ? undefined : "td-shell__nav-root"}
|
|
42
|
+
data-tasty-anatomy="NavigationTree"
|
|
43
|
+
>
|
|
40
44
|
{
|
|
41
45
|
items.map((item) => {
|
|
42
46
|
if (typeof item === "string") {
|
|
@@ -95,4 +99,4 @@ const generatedItems = (directory: string): NavigationItem[] => {
|
|
|
95
99
|
);
|
|
96
100
|
})
|
|
97
101
|
}
|
|
98
|
-
</
|
|
102
|
+
</NavigationTreeRoot>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { PackageVersionRoot } from "./LayoutComponents.js";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
version?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const version = Astro.props.version?.trim();
|
|
9
|
+
const label = version?.startsWith("v") ? version : version ? `v${version}` : "";
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
{
|
|
13
|
+
label && (
|
|
14
|
+
<PackageVersionRoot
|
|
15
|
+
className="td-package-version"
|
|
16
|
+
aria-label={`Version ${version}`}
|
|
17
|
+
data-tasty-anatomy="PackageVersion"
|
|
18
|
+
>
|
|
19
|
+
{label}
|
|
20
|
+
</PackageVersionRoot>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { PreviewRoot } from "./TastyComponents.js";
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
title: string;
|
|
4
6
|
html?: string;
|
|
@@ -10,22 +12,31 @@ const { title, html = "", css = "", javascript } = Astro.props;
|
|
|
10
12
|
const source = `<!doctype html><meta charset="utf-8"><style>${css}</style>${html}${javascript ? `<script>${javascript}<\/script>` : ""}`;
|
|
11
13
|
---
|
|
12
14
|
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
+
<PreviewRoot
|
|
16
|
+
className="td-preview"
|
|
17
|
+
aria-label={title}
|
|
18
|
+
data-tasty-anatomy="Preview"
|
|
19
|
+
>
|
|
20
|
+
<PreviewRoot.Caption><strong>{title}</strong></PreviewRoot.Caption>
|
|
15
21
|
{
|
|
16
22
|
javascript ? (
|
|
17
|
-
<
|
|
23
|
+
<PreviewRoot.Frame
|
|
24
|
+
className="td-preview__frame"
|
|
25
|
+
title={title}
|
|
26
|
+
sandbox="allow-scripts"
|
|
27
|
+
srcDoc={source}
|
|
28
|
+
/>
|
|
18
29
|
) : (
|
|
19
|
-
<
|
|
30
|
+
<PreviewRoot.Stage className="td-preview__stage">
|
|
20
31
|
<template
|
|
21
32
|
shadowrootmode="open"
|
|
22
33
|
set:html={`<style>${css}</style>${html}`}
|
|
23
34
|
/>
|
|
24
|
-
</
|
|
35
|
+
</PreviewRoot.Stage>
|
|
25
36
|
)
|
|
26
37
|
}
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
</
|
|
31
|
-
</
|
|
38
|
+
<PreviewRoot.Code className="td-preview__code">
|
|
39
|
+
<PreviewRoot.Summary>View source</PreviewRoot.Summary>
|
|
40
|
+
<PreviewRoot.Pre><code>{source}</code></PreviewRoot.Pre>
|
|
41
|
+
</PreviewRoot.Code>
|
|
42
|
+
</PreviewRoot>
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { TabsRoot } from "./TastyComponents.js";
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
label?: string;
|
|
4
6
|
}
|
|
5
7
|
const { label = "Examples" } = Astro.props;
|
|
6
8
|
---
|
|
7
9
|
|
|
8
|
-
<
|
|
10
|
+
<TabsRoot
|
|
11
|
+
className="td-tabs"
|
|
12
|
+
role="group"
|
|
13
|
+
aria-label={label}
|
|
14
|
+
data-tasty-anatomy="Tabs"
|
|
15
|
+
>
|
|
9
16
|
<slot />
|
|
10
|
-
</
|
|
17
|
+
</TabsRoot>
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { tasty } from "@tenphi/tasty";
|
|
2
|
+
import { customizeComponent } from "./customize-component.js";
|
|
3
|
+
import { configureCookbookStates } from "./tasty-states.js";
|
|
4
|
+
|
|
5
|
+
configureCookbookStates();
|
|
6
|
+
|
|
7
|
+
export const CardRoot = customizeComponent(
|
|
8
|
+
"Card",
|
|
9
|
+
{ as: "article" },
|
|
10
|
+
tasty({
|
|
11
|
+
as: "article",
|
|
12
|
+
styles: {
|
|
13
|
+
display: "grid",
|
|
14
|
+
gap: "1.5x",
|
|
15
|
+
padding: "2.5x",
|
|
16
|
+
color: "#text",
|
|
17
|
+
textDecoration: "none",
|
|
18
|
+
border: true,
|
|
19
|
+
radius: "1cr",
|
|
20
|
+
fill: "#surface-2",
|
|
21
|
+
shadow: "0 1px 2px #shadow",
|
|
22
|
+
transition: "fill 120ms ease, shadow 120ms ease, translate 120ms ease",
|
|
23
|
+
|
|
24
|
+
Heading2: {
|
|
25
|
+
$: "h2",
|
|
26
|
+
margin: "0",
|
|
27
|
+
},
|
|
28
|
+
Heading3: {
|
|
29
|
+
$: "h3",
|
|
30
|
+
margin: "0",
|
|
31
|
+
},
|
|
32
|
+
Paragraph: {
|
|
33
|
+
$: "p",
|
|
34
|
+
margin: "0",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
export const CardLink = tasty(CardRoot, {
|
|
41
|
+
as: "a",
|
|
42
|
+
styles: {
|
|
43
|
+
fill: {
|
|
44
|
+
"": "#surface-2",
|
|
45
|
+
":hover": "#surface-2-hover",
|
|
46
|
+
":active": "#surface-2-pressed",
|
|
47
|
+
},
|
|
48
|
+
shadow: {
|
|
49
|
+
"": "0 1px 2px #shadow",
|
|
50
|
+
":hover": "0 .75x 2x #shadow",
|
|
51
|
+
},
|
|
52
|
+
translate: {
|
|
53
|
+
"": "0",
|
|
54
|
+
":hover": "0 -1px",
|
|
55
|
+
":active": "0",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const previewElements = {
|
|
61
|
+
Caption: "figcaption",
|
|
62
|
+
Stage: "div",
|
|
63
|
+
Frame: "iframe",
|
|
64
|
+
Code: "details",
|
|
65
|
+
Summary: "summary",
|
|
66
|
+
Pre: "pre",
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const PreviewRoot = customizeComponent(
|
|
70
|
+
"Preview",
|
|
71
|
+
{ as: "figure", elements: previewElements },
|
|
72
|
+
tasty({
|
|
73
|
+
as: "figure",
|
|
74
|
+
styles: {
|
|
75
|
+
margin: "0",
|
|
76
|
+
overflow: "clip",
|
|
77
|
+
color: "#text",
|
|
78
|
+
border: true,
|
|
79
|
+
radius: "1cr",
|
|
80
|
+
fill: "#surface",
|
|
81
|
+
shadow: "0 1px 2px #shadow",
|
|
82
|
+
|
|
83
|
+
Caption: {
|
|
84
|
+
padding: "1.5x 2x",
|
|
85
|
+
preset: "small",
|
|
86
|
+
fill: "#surface-2",
|
|
87
|
+
},
|
|
88
|
+
Stage: {
|
|
89
|
+
padding: "3x",
|
|
90
|
+
fill: "#surface",
|
|
91
|
+
},
|
|
92
|
+
Frame: {
|
|
93
|
+
display: "block",
|
|
94
|
+
width: "100%",
|
|
95
|
+
height: "min 18rem",
|
|
96
|
+
border: "0",
|
|
97
|
+
fill: "#surface",
|
|
98
|
+
},
|
|
99
|
+
Code: {
|
|
100
|
+
border: "1bw top #border",
|
|
101
|
+
},
|
|
102
|
+
Summary: {
|
|
103
|
+
padding: "1.5x 2x",
|
|
104
|
+
preset: "small",
|
|
105
|
+
fill: "#surface-2",
|
|
106
|
+
cursor: "pointer",
|
|
107
|
+
},
|
|
108
|
+
Pre: {
|
|
109
|
+
margin: "0",
|
|
110
|
+
radius: "0",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
elements: previewElements,
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
export const StepsRoot = customizeComponent(
|
|
118
|
+
"Steps",
|
|
119
|
+
{ as: "ol" },
|
|
120
|
+
tasty({
|
|
121
|
+
as: "ol",
|
|
122
|
+
styles: {
|
|
123
|
+
display: "grid",
|
|
124
|
+
gap: "2x",
|
|
125
|
+
padding: "4x left",
|
|
126
|
+
border: "1bw left #border",
|
|
127
|
+
|
|
128
|
+
Item: {
|
|
129
|
+
$: "> li",
|
|
130
|
+
padding: "1x left",
|
|
131
|
+
},
|
|
132
|
+
Marker: {
|
|
133
|
+
$: "> li::marker",
|
|
134
|
+
color: "#accent-text",
|
|
135
|
+
preset: "bold",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
export const TabsRoot = customizeComponent(
|
|
142
|
+
"Tabs",
|
|
143
|
+
{ as: "div" },
|
|
144
|
+
tasty({
|
|
145
|
+
as: "div",
|
|
146
|
+
styles: {
|
|
147
|
+
display: "flex",
|
|
148
|
+
flow: "row wrap",
|
|
149
|
+
gap: "1x",
|
|
150
|
+
padding: "1x",
|
|
151
|
+
border: true,
|
|
152
|
+
radius: "1cr",
|
|
153
|
+
fill: "#surface-2",
|
|
154
|
+
},
|
|
155
|
+
}),
|
|
156
|
+
);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
configureComponentStyles,
|
|
4
|
+
resolveLegacyAnatomyStyles,
|
|
5
|
+
resolveComponentStyleOverride,
|
|
6
|
+
resolveComponentStyles,
|
|
7
|
+
} from "./component-styles.js";
|
|
8
|
+
|
|
9
|
+
const defaults = {
|
|
10
|
+
color: "#text",
|
|
11
|
+
padding: "2x",
|
|
12
|
+
Label: { color: "#text-soft", fontWeight: 500 },
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
afterEach(() => configureComponentStyles(undefined));
|
|
16
|
+
|
|
17
|
+
describe("component style configuration", () => {
|
|
18
|
+
it("extends defaults with a plain Tasty style object", () => {
|
|
19
|
+
configureComponentStyles({
|
|
20
|
+
Card: { padding: "3x", Label: { color: "#accent-text" } },
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(resolveComponentStyles("Card", defaults)).toEqual({
|
|
24
|
+
color: "#text",
|
|
25
|
+
padding: "3x",
|
|
26
|
+
Label: { color: "#accent-text", fontWeight: 500 },
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("supports explicit extension and complete replacement", () => {
|
|
31
|
+
configureComponentStyles({
|
|
32
|
+
Card: { mode: "extend", styles: { radius: "1cr" } },
|
|
33
|
+
});
|
|
34
|
+
expect(resolveComponentStyles("Card", defaults)).toMatchObject({
|
|
35
|
+
color: "#text",
|
|
36
|
+
radius: "1cr",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
configureComponentStyles({
|
|
40
|
+
Card: { mode: "replace", styles: { display: "grid" } },
|
|
41
|
+
});
|
|
42
|
+
expect(resolveComponentStyles("Card", defaults)).toEqual({
|
|
43
|
+
display: "grid",
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("normalizes configured component overrides for Tasty composition", () => {
|
|
48
|
+
expect(resolveComponentStyleOverride("Card")).toBeUndefined();
|
|
49
|
+
|
|
50
|
+
configureComponentStyles({ Card: { padding: "3x" } });
|
|
51
|
+
expect(resolveComponentStyleOverride("Card")).toEqual({
|
|
52
|
+
mode: "extend",
|
|
53
|
+
styles: { padding: "3x" },
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
configureComponentStyles({
|
|
57
|
+
Card: { mode: "replace", styles: { display: "grid" } },
|
|
58
|
+
});
|
|
59
|
+
expect(resolveComponentStyleOverride("Card")).toEqual({
|
|
60
|
+
mode: "replace",
|
|
61
|
+
styles: { display: "grid" },
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("keeps custom anatomy styles on the compatibility bridge", () => {
|
|
66
|
+
expect(
|
|
67
|
+
resolveLegacyAnatomyStyles({
|
|
68
|
+
ThemeSelect: { padding: "1x" },
|
|
69
|
+
ProductBadge: { color: "#accent-text" },
|
|
70
|
+
}),
|
|
71
|
+
).toEqual({
|
|
72
|
+
'[data-tasty-anatomy="ProductBadge"]': { color: "#accent-text" },
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { mergeStyles, type Styles } from "@tenphi/tasty/core";
|
|
2
|
+
import {
|
|
3
|
+
COOKBOOK_COMPONENT_NAMES,
|
|
4
|
+
type ComponentStyleConfig,
|
|
5
|
+
type ComponentStylesConfig,
|
|
6
|
+
type CookbookComponentName,
|
|
7
|
+
} from "@tenphi/docs";
|
|
8
|
+
|
|
9
|
+
// Astro can load the integration and renderer through separate module graphs.
|
|
10
|
+
// Keep their component configuration on the shared process global.
|
|
11
|
+
const sharedConfiguration = globalThis as typeof globalThis & {
|
|
12
|
+
__tenphiCookbookComponentStyles?: ComponentStylesConfig;
|
|
13
|
+
};
|
|
14
|
+
const cookbookComponentNames = new Set<string>(COOKBOOK_COMPONENT_NAMES);
|
|
15
|
+
|
|
16
|
+
export function configureComponentStyles(
|
|
17
|
+
styles: ComponentStylesConfig | undefined,
|
|
18
|
+
): void {
|
|
19
|
+
sharedConfiguration.__tenphiCookbookComponentStyles = styles ?? {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function resolveComponentStyles(
|
|
23
|
+
name: CookbookComponentName,
|
|
24
|
+
defaults: Styles,
|
|
25
|
+
): Styles {
|
|
26
|
+
const configured = sharedConfiguration.__tenphiCookbookComponentStyles?.[
|
|
27
|
+
name
|
|
28
|
+
] as ComponentStyleConfig | undefined;
|
|
29
|
+
if (!configured) return defaults;
|
|
30
|
+
if (isModeConfig(configured)) {
|
|
31
|
+
const styles = configured.styles as Styles;
|
|
32
|
+
return configured.mode === "replace"
|
|
33
|
+
? styles
|
|
34
|
+
: mergeStyles(defaults, styles);
|
|
35
|
+
}
|
|
36
|
+
return mergeStyles(defaults, configured as Styles);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function resolveComponentStyleOverride(
|
|
40
|
+
name: CookbookComponentName,
|
|
41
|
+
): { mode: "extend" | "replace"; styles: Styles } | undefined {
|
|
42
|
+
const configured = sharedConfiguration.__tenphiCookbookComponentStyles?.[
|
|
43
|
+
name
|
|
44
|
+
] as ComponentStyleConfig | undefined;
|
|
45
|
+
if (!configured) return undefined;
|
|
46
|
+
if (isModeConfig(configured)) {
|
|
47
|
+
return { mode: configured.mode, styles: configured.styles as Styles };
|
|
48
|
+
}
|
|
49
|
+
return { mode: "extend", styles: configured as Styles };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Preserve custom anatomy names from the pre-component style API. */
|
|
53
|
+
export function resolveLegacyAnatomyStyles(
|
|
54
|
+
styles: ComponentStylesConfig | undefined,
|
|
55
|
+
): Record<string, Styles> | undefined {
|
|
56
|
+
if (!styles) return undefined;
|
|
57
|
+
const entries = Object.entries(styles)
|
|
58
|
+
.filter(
|
|
59
|
+
(entry): entry is [string, ComponentStyleConfig] =>
|
|
60
|
+
!cookbookComponentNames.has(entry[0]) && entry[1] !== undefined,
|
|
61
|
+
)
|
|
62
|
+
.map(([name, value]) => [
|
|
63
|
+
`[data-tasty-anatomy="${name}"]`,
|
|
64
|
+
isModeConfig(value) ? value.styles : value,
|
|
65
|
+
]);
|
|
66
|
+
return entries.length
|
|
67
|
+
? (Object.fromEntries(entries) as Record<string, Styles>)
|
|
68
|
+
: undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function isModeConfig(
|
|
72
|
+
value: ComponentStyleConfig,
|
|
73
|
+
): value is Extract<ComponentStyleConfig, { mode: string }> {
|
|
74
|
+
return (
|
|
75
|
+
"mode" in value &&
|
|
76
|
+
(value.mode === "extend" || value.mode === "replace") &&
|
|
77
|
+
"styles" in value
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { tasty } from "@tenphi/tasty";
|
|
2
|
+
import { resolveComponentStyleOverride } from "./component-styles.js";
|
|
3
|
+
|
|
4
|
+
export function customizeComponent(name, options, base) {
|
|
5
|
+
const override = resolveComponentStyleOverride(name);
|
|
6
|
+
if (!override) return base;
|
|
7
|
+
return override.mode === "replace"
|
|
8
|
+
? tasty({ ...options, styles: override.styles })
|
|
9
|
+
: tasty(base, { styles: override.styles });
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { svgIconUrl } from "./svg-icon.js";
|
|
3
|
+
|
|
4
|
+
describe("svgIconUrl", () => {
|
|
5
|
+
it("preserves case-sensitive SVG data when Tasty lowercases the style", () => {
|
|
6
|
+
const svg = '<svg viewBox="0 0 24 24"><path d="M1 2H3Z"/></svg>';
|
|
7
|
+
const [, payload] = svgIconUrl(svg).toLowerCase().split(",", 2);
|
|
8
|
+
|
|
9
|
+
expect(decodeURIComponent(payload ?? "")).toBe(svg);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Encode an SVG data URL that remains valid after Tasty lowercases styles. */
|
|
2
|
+
export function svgIconUrl(svg: string): string {
|
|
3
|
+
const encoded = encodeURIComponent(svg).replace(
|
|
4
|
+
/%[0-9A-F]{2}|[A-Z]/g,
|
|
5
|
+
(token) =>
|
|
6
|
+
token.startsWith("%")
|
|
7
|
+
? token.toLowerCase()
|
|
8
|
+
: `%${token.charCodeAt(0).toString(16)}`,
|
|
9
|
+
);
|
|
10
|
+
return `data:image/svg+xml,${encoded}`;
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { configure } from "@tenphi/tasty";
|
|
2
|
+
|
|
3
|
+
export const cookbookStates = {
|
|
4
|
+
"@mobile": "@media(w < 50rem)",
|
|
5
|
+
"@desktop": "@media(w >= 50rem)",
|
|
6
|
+
"@small": "@media(w <= 40rem)",
|
|
7
|
+
"@shell-mobile": "@media(w <= 48rem)",
|
|
8
|
+
"@shell-desktop": "@media(w > 48rem)",
|
|
9
|
+
"@narrow-layout": "@media(w < 72rem)",
|
|
10
|
+
"@medium-layout": "@media(w >= 50rem) & @media(w < 72rem)",
|
|
11
|
+
"@reduced-motion": "@media(prefers-reduced-motion: reduce)",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let configured = false;
|
|
15
|
+
|
|
16
|
+
/** Configure aliases in the renderer's Tasty module before styles are parsed. */
|
|
17
|
+
export function configureCookbookStates() {
|
|
18
|
+
if (configured) return;
|
|
19
|
+
configure({ states: cookbookStates });
|
|
20
|
+
configured = true;
|
|
21
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AstroComponentFactory } from "astro/runtime/server/index.js";
|
|
2
2
|
|
|
3
3
|
export const Card: AstroComponentFactory;
|
|
4
|
+
export const Logo: AstroComponentFactory;
|
|
4
5
|
export const Preview: AstroComponentFactory;
|
|
5
6
|
export const Steps: AstroComponentFactory;
|
|
6
7
|
export const Tabs: AstroComponentFactory;
|
package/dist/components.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Card from "./components/Card.astro";
|
|
2
|
+
import Logo from "./components/Logo.astro";
|
|
2
3
|
import Preview from "./components/Preview.astro";
|
|
3
4
|
import Steps from "./components/Steps.astro";
|
|
4
5
|
import Tabs from "./components/Tabs.astro";
|
|
5
|
-
export { Card, Preview, Steps, Tabs };
|
|
6
|
+
export { Card, Logo, Preview, Steps, Tabs };
|
package/dist/components.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Card from "./components/Card.astro";
|
|
2
|
+
import Logo from "./components/Logo.astro";
|
|
2
3
|
import Preview from "./components/Preview.astro";
|
|
3
4
|
import Steps from "./components/Steps.astro";
|
|
4
5
|
import Tabs from "./components/Tabs.astro";
|
|
5
|
-
export { Card, Preview, Steps, Tabs };
|
|
6
|
+
export { Card, Logo, Preview, Steps, Tabs };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,6 @@ declare function tastyStarlight(config: Parameters<typeof starlight>[0]): AstroI
|
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region src/theme/index.d.ts
|
|
24
24
|
interface ResolvedDocsTheme {
|
|
25
|
-
css: string;
|
|
26
25
|
colors: {
|
|
27
26
|
surface: Record<string, string>;
|
|
28
27
|
surface2: Record<string, string>;
|
|
@@ -33,6 +32,7 @@ interface ResolvedDocsTheme {
|
|
|
33
32
|
accentSurface: Record<string, string>;
|
|
34
33
|
accentSurfaceText: Record<string, string>;
|
|
35
34
|
focus: Record<string, string>;
|
|
35
|
+
shadow: Record<string, string>;
|
|
36
36
|
};
|
|
37
37
|
tokens: ThemeTokens;
|
|
38
38
|
presets: Record<string, TypographyPreset>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/starlight-runtime.d.ts","../src/integration.ts","../src/theme/index.ts","../src/theme/defaults.ts"],"mappings":";;;;UAEiB;EACf;EACA;EACA;EACA,mBAAmB;EACnB;GACC;;iBAGqB,UAAU,SAAS,mBAAmB;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/starlight-runtime.d.ts","../src/integration.ts","../src/theme/index.ts","../src/theme/defaults.ts"],"mappings":";;;;UAEiB;EACf;EACA;EACA;EACA,mBAAmB;EACnB;GACC;;iBAGqB,UAAU,SAAS,mBAAmB;;;UCoC7C;EACf,SAAS;EACT;;iBAGsB,SACtB,UAAS,kBACR;iBAsaa,eACd,QAAQ,kBAAkB,gBACzB;;;UC5cc;EACf;IACE,SAAS;IACT,UAAU;IACV,UAAU;IACV,MAAM;IACN,UAAU;IACV,YAAY;IACZ,eAAe;IACf,mBAAmB;IACnB,OAAO;IACP,QAAQ;;EAEV,QAAQ;EACR,SAAS,eAAe;EACxB;IACE;IACA;IACA;IACA;;EAEF,aAAa;;iBAGC,iBAAiB,QAAO,cAAmB;;;cCpC9C;;;;;;;;;;;;cAkBA,4BAA4B,eAAe"}
|