radiant-docs 0.1.41 → 0.1.42
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/package.json +1 -1
- package/template/astro.config.mjs +42 -40
- package/template/package-lock.json +7 -0
- package/template/package.json +1 -0
- package/template/src/components/Header.astro +150 -16
- package/template/src/components/MdxPage.astro +76 -22
- package/template/src/components/PagePagination.astro +44 -8
- package/template/src/components/Sidebar.astro +10 -1
- package/template/src/components/TableOfContents.astro +159 -53
- package/template/src/components/chat/AssistantDocsWidget.tsx +221 -8
- package/template/src/components/chat/AssistantEmbedPanel.tsx +1090 -104
- package/template/src/components/user/Accordion.astro +2 -2
- package/template/src/components/user/AccordionGroup.astro +1 -1
- package/template/src/components/user/Callout.astro +2 -2
- package/template/src/components/user/Card.astro +488 -0
- package/template/src/components/user/CardGradient.astro +964 -0
- package/template/src/components/user/CodeBlock.astro +1 -1
- package/template/src/components/user/CodeGroup.astro +1 -1
- package/template/src/components/user/Column.astro +25 -0
- package/template/src/components/user/Columns.astro +200 -0
- package/template/src/components/user/ComponentPreviewBlock.astro +1 -1
- package/template/src/components/user/Image.astro +1 -1
- package/template/src/components/user/Step.astro +1 -1
- package/template/src/components/user/Steps.astro +1 -1
- package/template/src/components/user/Tab.astro +1 -3
- package/template/src/components/user/Tabs.astro +2 -2
- package/template/src/layouts/Layout.astro +2 -4
- package/template/src/lib/assistant-chrome-defaults.ts +12 -0
- package/template/src/lib/assistant-embed-script.ts +209 -18
- package/template/src/lib/validation.ts +325 -75
- package/template/src/styles/global.css +81 -4
- package/template/src/components/chat/AskAiWidget.tsx +0 -2011
|
@@ -110,6 +110,9 @@ const AVAILABLE_COMPONENTS = [
|
|
|
110
110
|
"Step",
|
|
111
111
|
"Accordion",
|
|
112
112
|
"AccordionGroup",
|
|
113
|
+
"Card",
|
|
114
|
+
"Column",
|
|
115
|
+
"Columns",
|
|
113
116
|
"Image",
|
|
114
117
|
"CodeGroup",
|
|
115
118
|
"ComponentPreview",
|
|
@@ -166,6 +169,7 @@ export type NavbarItem = {
|
|
|
166
169
|
text: string;
|
|
167
170
|
href: string;
|
|
168
171
|
icon?: string | null;
|
|
172
|
+
color?: string | ThemeColorByMode;
|
|
169
173
|
};
|
|
170
174
|
export type HiddenPageRoute = {
|
|
171
175
|
filePath: string;
|
|
@@ -211,9 +215,21 @@ export type ThemeColorByMode = {
|
|
|
211
215
|
light?: string;
|
|
212
216
|
dark?: string;
|
|
213
217
|
};
|
|
218
|
+
export type CardCoverTheme = {
|
|
219
|
+
colors?: string[];
|
|
220
|
+
colorSeed?: string;
|
|
221
|
+
};
|
|
222
|
+
export type CardButtonTheme = {
|
|
223
|
+
color?: string | ThemeColorByMode;
|
|
224
|
+
};
|
|
225
|
+
export type CardTheme = {
|
|
226
|
+
cover?: CardCoverTheme;
|
|
227
|
+
button?: CardButtonTheme;
|
|
228
|
+
};
|
|
214
229
|
export type DocsTheme = {
|
|
215
230
|
baseColor?: BaseColorOption | BaseColorByMode;
|
|
216
231
|
themeColor?: string | ThemeColorByMode;
|
|
232
|
+
card?: CardTheme;
|
|
217
233
|
};
|
|
218
234
|
export type AssistantIcon = {
|
|
219
235
|
src?: string;
|
|
@@ -222,12 +238,18 @@ export type AssistantIcon = {
|
|
|
222
238
|
export type AssistantButtonSize = "small" | "default";
|
|
223
239
|
export type AssistantButtonConfig = {
|
|
224
240
|
size?: AssistantButtonSize;
|
|
241
|
+
color?: string | ThemeColorByMode;
|
|
242
|
+
};
|
|
243
|
+
export type AssistantNavbarButtonConfig = {
|
|
244
|
+
enabled?: boolean;
|
|
245
|
+
text?: string;
|
|
246
|
+
color?: string | ThemeColorByMode;
|
|
225
247
|
};
|
|
226
248
|
export type AssistantConfig = {
|
|
227
249
|
button?: AssistantButtonConfig;
|
|
250
|
+
navbarButton?: AssistantNavbarButtonConfig;
|
|
228
251
|
heading?: string;
|
|
229
252
|
questions?: string[];
|
|
230
|
-
themeColor?: string | ThemeColorByMode;
|
|
231
253
|
icon?: AssistantIcon;
|
|
232
254
|
};
|
|
233
255
|
export type DocsConfig = {
|
|
@@ -340,6 +362,93 @@ function normalizeHexColor(
|
|
|
340
362
|
return normalizedValue.toLowerCase();
|
|
341
363
|
}
|
|
342
364
|
|
|
365
|
+
function normalizeThemeColorConfig(
|
|
366
|
+
value: unknown,
|
|
367
|
+
currentPath: Path,
|
|
368
|
+
label: string,
|
|
369
|
+
): string | ThemeColorByMode {
|
|
370
|
+
if (typeof value === "string") {
|
|
371
|
+
return normalizeHexColor(value, currentPath, label);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
checkType(value, "object", currentPath, label);
|
|
375
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
376
|
+
throwConfigError(
|
|
377
|
+
`${label} must be a string or an object with light/dark values.`,
|
|
378
|
+
currentPath,
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const colorByMode = value as Record<string, unknown>;
|
|
383
|
+
const allowedKeys = new Set(["light", "dark"]);
|
|
384
|
+
for (const key of Object.keys(colorByMode)) {
|
|
385
|
+
if (!allowedKeys.has(key)) {
|
|
386
|
+
throwConfigError(`${label} object only supports 'light' and 'dark'.`, [
|
|
387
|
+
...currentPath,
|
|
388
|
+
key,
|
|
389
|
+
]);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const light =
|
|
394
|
+
colorByMode.light !== undefined
|
|
395
|
+
? normalizeHexColor(colorByMode.light, [...currentPath, "light"], label)
|
|
396
|
+
: undefined;
|
|
397
|
+
const dark =
|
|
398
|
+
colorByMode.dark !== undefined
|
|
399
|
+
? normalizeHexColor(colorByMode.dark, [...currentPath, "dark"], label)
|
|
400
|
+
: undefined;
|
|
401
|
+
|
|
402
|
+
if (light === undefined && dark === undefined) {
|
|
403
|
+
throwConfigError(
|
|
404
|
+
`${label} object must include 'light', 'dark', or both.`,
|
|
405
|
+
currentPath,
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return {
|
|
410
|
+
...(light !== undefined ? { light } : {}),
|
|
411
|
+
...(dark !== undefined ? { dark } : {}),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function normalizeHexColorArray(
|
|
416
|
+
value: unknown,
|
|
417
|
+
currentPath: Path,
|
|
418
|
+
label: string,
|
|
419
|
+
): string[] {
|
|
420
|
+
checkType(value, "array", currentPath, label);
|
|
421
|
+
if (!Array.isArray(value)) {
|
|
422
|
+
throwConfigError(`${label} must be an array.`, currentPath);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (value.length < 1 || value.length > 4) {
|
|
426
|
+
throwConfigError(`${label} must include 1 to 4 colors.`, currentPath);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return value.map((color, index) =>
|
|
430
|
+
normalizeHexColor(color, [...currentPath, index], `${label} ${index + 1}`),
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function normalizeSeedValue(
|
|
435
|
+
value: unknown,
|
|
436
|
+
currentPath: Path,
|
|
437
|
+
label: string,
|
|
438
|
+
): string {
|
|
439
|
+
checkType(value, "string", currentPath, label);
|
|
440
|
+
if (typeof value !== "string") {
|
|
441
|
+
throwConfigError(`${label} must be a string.`, currentPath);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const trimmedValue = value.trim();
|
|
445
|
+
if (trimmedValue.length === 0) {
|
|
446
|
+
throwConfigError(`${label} cannot be empty.`, currentPath);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return trimmedValue;
|
|
450
|
+
}
|
|
451
|
+
|
|
343
452
|
function validateFileExistence(filePath: string, currentPath: Path): void {
|
|
344
453
|
// Assuming relative path from DOCS_DIR and .mdx extension
|
|
345
454
|
const fullPath = path.join(DOCS_DIR, `${filePath}.mdx`);
|
|
@@ -1224,6 +1333,21 @@ function validateNavbarItem(
|
|
|
1224
1333
|
|
|
1225
1334
|
// Optional property
|
|
1226
1335
|
validateIcon(item.icon, [...currentPath, "icon"]);
|
|
1336
|
+
if (item.color !== undefined) {
|
|
1337
|
+
if (currentPath[0] !== "navbar" || currentPath[1] !== "primary") {
|
|
1338
|
+
throwConfigError(
|
|
1339
|
+
"Navbar item color is only supported on navbar.primary.",
|
|
1340
|
+
[...currentPath, "color"],
|
|
1341
|
+
);
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
item.color = normalizeThemeColorConfig(
|
|
1345
|
+
item.color,
|
|
1346
|
+
[...currentPath, "color"],
|
|
1347
|
+
"Navbar primary color",
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1227
1351
|
return hiddenPageRoute;
|
|
1228
1352
|
}
|
|
1229
1353
|
|
|
@@ -1594,6 +1718,116 @@ function validateTheme(theme: DocsConfig["theme"]): void {
|
|
|
1594
1718
|
}
|
|
1595
1719
|
}
|
|
1596
1720
|
|
|
1721
|
+
if (theme.card !== undefined) {
|
|
1722
|
+
checkType(theme.card, "object", ["theme", "card"], "Theme card");
|
|
1723
|
+
if (
|
|
1724
|
+
typeof theme.card !== "object" ||
|
|
1725
|
+
theme.card === null ||
|
|
1726
|
+
Array.isArray(theme.card)
|
|
1727
|
+
) {
|
|
1728
|
+
throwConfigError("Theme card must be an object.", ["theme", "card"]);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
const cardTheme = theme.card as CardTheme & Record<string, unknown>;
|
|
1732
|
+
const allowedCardKeys = new Set(["cover", "button"]);
|
|
1733
|
+
for (const key of Object.keys(cardTheme)) {
|
|
1734
|
+
if (!allowedCardKeys.has(key)) {
|
|
1735
|
+
throwConfigError(
|
|
1736
|
+
"Theme card configuration only supports 'cover' and 'button'.",
|
|
1737
|
+
["theme", "card", key],
|
|
1738
|
+
);
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
if (cardTheme.cover !== undefined) {
|
|
1743
|
+
checkType(
|
|
1744
|
+
cardTheme.cover,
|
|
1745
|
+
"object",
|
|
1746
|
+
["theme", "card", "cover"],
|
|
1747
|
+
"Theme card cover",
|
|
1748
|
+
);
|
|
1749
|
+
if (
|
|
1750
|
+
typeof cardTheme.cover !== "object" ||
|
|
1751
|
+
cardTheme.cover === null ||
|
|
1752
|
+
Array.isArray(cardTheme.cover)
|
|
1753
|
+
) {
|
|
1754
|
+
throwConfigError("Theme card cover must be an object.", [
|
|
1755
|
+
"theme",
|
|
1756
|
+
"card",
|
|
1757
|
+
"cover",
|
|
1758
|
+
]);
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
const coverTheme = cardTheme.cover as CardCoverTheme &
|
|
1762
|
+
Record<string, unknown>;
|
|
1763
|
+
const allowedCoverKeys = new Set(["colors", "colorSeed"]);
|
|
1764
|
+
for (const key of Object.keys(coverTheme)) {
|
|
1765
|
+
if (!allowedCoverKeys.has(key)) {
|
|
1766
|
+
throwConfigError(
|
|
1767
|
+
"Theme card cover configuration only supports 'colors' and 'colorSeed'.",
|
|
1768
|
+
["theme", "card", "cover", key],
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
if (coverTheme.colors !== undefined) {
|
|
1774
|
+
coverTheme.colors = normalizeHexColorArray(
|
|
1775
|
+
coverTheme.colors,
|
|
1776
|
+
["theme", "card", "cover", "colors"],
|
|
1777
|
+
"Theme card cover colors",
|
|
1778
|
+
);
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
if (coverTheme.colorSeed !== undefined) {
|
|
1782
|
+
coverTheme.colorSeed = normalizeSeedValue(
|
|
1783
|
+
coverTheme.colorSeed,
|
|
1784
|
+
["theme", "card", "cover", "colorSeed"],
|
|
1785
|
+
"Theme card cover color seed",
|
|
1786
|
+
);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
if (cardTheme.button !== undefined) {
|
|
1791
|
+
checkType(
|
|
1792
|
+
cardTheme.button,
|
|
1793
|
+
"object",
|
|
1794
|
+
["theme", "card", "button"],
|
|
1795
|
+
"Theme card button",
|
|
1796
|
+
);
|
|
1797
|
+
if (
|
|
1798
|
+
typeof cardTheme.button !== "object" ||
|
|
1799
|
+
cardTheme.button === null ||
|
|
1800
|
+
Array.isArray(cardTheme.button)
|
|
1801
|
+
) {
|
|
1802
|
+
throwConfigError("Theme card button must be an object.", [
|
|
1803
|
+
"theme",
|
|
1804
|
+
"card",
|
|
1805
|
+
"button",
|
|
1806
|
+
]);
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
const buttonTheme = cardTheme.button as CardButtonTheme &
|
|
1810
|
+
Record<string, unknown>;
|
|
1811
|
+
const allowedButtonKeys = new Set(["color"]);
|
|
1812
|
+
for (const key of Object.keys(buttonTheme)) {
|
|
1813
|
+
if (!allowedButtonKeys.has(key)) {
|
|
1814
|
+
throwConfigError(
|
|
1815
|
+
"Theme card button configuration only supports 'color'.",
|
|
1816
|
+
["theme", "card", "button", key],
|
|
1817
|
+
);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
if (buttonTheme.color !== undefined) {
|
|
1822
|
+
buttonTheme.color = normalizeThemeColorConfig(
|
|
1823
|
+
buttonTheme.color,
|
|
1824
|
+
["theme", "card", "button", "color"],
|
|
1825
|
+
"Theme card button color",
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1597
1831
|
if (theme.themeColor === undefined) {
|
|
1598
1832
|
return;
|
|
1599
1833
|
}
|
|
@@ -1677,15 +1911,15 @@ function validateAssistant(assistant: DocsConfig["assistant"]): void {
|
|
|
1677
1911
|
|
|
1678
1912
|
const allowedAssistantKeys = new Set([
|
|
1679
1913
|
"button",
|
|
1914
|
+
"navbarButton",
|
|
1680
1915
|
"heading",
|
|
1681
1916
|
"questions",
|
|
1682
|
-
"themeColor",
|
|
1683
1917
|
"icon",
|
|
1684
1918
|
]);
|
|
1685
1919
|
for (const key of Object.keys(assistant)) {
|
|
1686
1920
|
if (!allowedAssistantKeys.has(key)) {
|
|
1687
1921
|
throwConfigError(
|
|
1688
|
-
"Assistant configuration only supports 'button', '
|
|
1922
|
+
"Assistant configuration only supports 'button', 'navbarButton', 'heading', 'questions', and 'icon'.",
|
|
1689
1923
|
["assistant", key],
|
|
1690
1924
|
);
|
|
1691
1925
|
}
|
|
@@ -1709,11 +1943,11 @@ function validateAssistant(assistant: DocsConfig["assistant"]): void {
|
|
|
1709
1943
|
]);
|
|
1710
1944
|
}
|
|
1711
1945
|
|
|
1712
|
-
const allowedButtonKeys = new Set(["size"]);
|
|
1946
|
+
const allowedButtonKeys = new Set(["size", "color"]);
|
|
1713
1947
|
for (const key of Object.keys(assistant.button)) {
|
|
1714
1948
|
if (!allowedButtonKeys.has(key)) {
|
|
1715
1949
|
throwConfigError(
|
|
1716
|
-
"Assistant button configuration only supports 'size'.",
|
|
1950
|
+
"Assistant button configuration only supports 'size' and 'color'.",
|
|
1717
1951
|
["assistant", "button", key],
|
|
1718
1952
|
);
|
|
1719
1953
|
}
|
|
@@ -1743,6 +1977,92 @@ function validateAssistant(assistant: DocsConfig["assistant"]): void {
|
|
|
1743
1977
|
}
|
|
1744
1978
|
assistant.button.size = trimmedSize;
|
|
1745
1979
|
}
|
|
1980
|
+
|
|
1981
|
+
if (assistant.button.color !== undefined) {
|
|
1982
|
+
assistant.button.color = normalizeThemeColorConfig(
|
|
1983
|
+
assistant.button.color,
|
|
1984
|
+
["assistant", "button", "color"],
|
|
1985
|
+
"Assistant button color",
|
|
1986
|
+
);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
if (assistant.navbarButton !== undefined) {
|
|
1991
|
+
checkType(
|
|
1992
|
+
assistant.navbarButton,
|
|
1993
|
+
"object",
|
|
1994
|
+
["assistant", "navbarButton"],
|
|
1995
|
+
"Assistant navbar button configuration",
|
|
1996
|
+
);
|
|
1997
|
+
if (
|
|
1998
|
+
typeof assistant.navbarButton !== "object" ||
|
|
1999
|
+
assistant.navbarButton === null ||
|
|
2000
|
+
Array.isArray(assistant.navbarButton)
|
|
2001
|
+
) {
|
|
2002
|
+
throwConfigError(
|
|
2003
|
+
"Assistant navbar button configuration must be an object.",
|
|
2004
|
+
["assistant", "navbarButton"],
|
|
2005
|
+
);
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
const allowedNavbarButtonKeys = new Set(["enabled", "text", "color"]);
|
|
2009
|
+
for (const key of Object.keys(assistant.navbarButton)) {
|
|
2010
|
+
if (!allowedNavbarButtonKeys.has(key)) {
|
|
2011
|
+
throwConfigError(
|
|
2012
|
+
"Assistant navbar button configuration only supports 'enabled', 'text', and 'color'.",
|
|
2013
|
+
["assistant", "navbarButton", key],
|
|
2014
|
+
);
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
if (assistant.navbarButton.enabled !== undefined) {
|
|
2019
|
+
checkType(
|
|
2020
|
+
assistant.navbarButton.enabled,
|
|
2021
|
+
"boolean",
|
|
2022
|
+
["assistant", "navbarButton", "enabled"],
|
|
2023
|
+
"Assistant navbar button enabled",
|
|
2024
|
+
);
|
|
2025
|
+
if (typeof assistant.navbarButton.enabled !== "boolean") {
|
|
2026
|
+
throwConfigError(
|
|
2027
|
+
"Assistant navbar button enabled must be a boolean.",
|
|
2028
|
+
["assistant", "navbarButton", "enabled"],
|
|
2029
|
+
);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
if (assistant.navbarButton.text !== undefined) {
|
|
2034
|
+
checkType(
|
|
2035
|
+
assistant.navbarButton.text,
|
|
2036
|
+
"string",
|
|
2037
|
+
["assistant", "navbarButton", "text"],
|
|
2038
|
+
"Assistant navbar button text",
|
|
2039
|
+
);
|
|
2040
|
+
if (typeof assistant.navbarButton.text !== "string") {
|
|
2041
|
+
throwConfigError("Assistant navbar button text must be a string.", [
|
|
2042
|
+
"assistant",
|
|
2043
|
+
"navbarButton",
|
|
2044
|
+
"text",
|
|
2045
|
+
]);
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
const trimmedText = assistant.navbarButton.text.trim();
|
|
2049
|
+
if (trimmedText.length === 0) {
|
|
2050
|
+
throwConfigError("Assistant navbar button text cannot be empty.", [
|
|
2051
|
+
"assistant",
|
|
2052
|
+
"navbarButton",
|
|
2053
|
+
"text",
|
|
2054
|
+
]);
|
|
2055
|
+
}
|
|
2056
|
+
assistant.navbarButton.text = trimmedText;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
if (assistant.navbarButton.color !== undefined) {
|
|
2060
|
+
assistant.navbarButton.color = normalizeThemeColorConfig(
|
|
2061
|
+
assistant.navbarButton.color,
|
|
2062
|
+
["assistant", "navbarButton", "color"],
|
|
2063
|
+
"Assistant navbar button color",
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
1746
2066
|
}
|
|
1747
2067
|
|
|
1748
2068
|
if (assistant.heading !== undefined) {
|
|
@@ -1817,76 +2137,6 @@ function validateAssistant(assistant: DocsConfig["assistant"]): void {
|
|
|
1817
2137
|
});
|
|
1818
2138
|
}
|
|
1819
2139
|
|
|
1820
|
-
if (assistant.themeColor !== undefined) {
|
|
1821
|
-
if (typeof assistant.themeColor === "string") {
|
|
1822
|
-
assistant.themeColor = normalizeHexColor(
|
|
1823
|
-
assistant.themeColor,
|
|
1824
|
-
["assistant", "themeColor"],
|
|
1825
|
-
"Assistant theme color",
|
|
1826
|
-
);
|
|
1827
|
-
} else {
|
|
1828
|
-
checkType(
|
|
1829
|
-
assistant.themeColor,
|
|
1830
|
-
"object",
|
|
1831
|
-
["assistant", "themeColor"],
|
|
1832
|
-
"Assistant theme color",
|
|
1833
|
-
);
|
|
1834
|
-
if (
|
|
1835
|
-
typeof assistant.themeColor !== "object" ||
|
|
1836
|
-
assistant.themeColor === null ||
|
|
1837
|
-
Array.isArray(assistant.themeColor)
|
|
1838
|
-
) {
|
|
1839
|
-
throwConfigError(
|
|
1840
|
-
"Assistant theme color must be a string or an object with light/dark values.",
|
|
1841
|
-
["assistant", "themeColor"],
|
|
1842
|
-
);
|
|
1843
|
-
}
|
|
1844
|
-
|
|
1845
|
-
const assistantThemeColorByMode = assistant.themeColor as Record<
|
|
1846
|
-
string,
|
|
1847
|
-
unknown
|
|
1848
|
-
>;
|
|
1849
|
-
const allowedThemeColorKeys = new Set(["light", "dark"]);
|
|
1850
|
-
for (const key of Object.keys(assistantThemeColorByMode)) {
|
|
1851
|
-
if (!allowedThemeColorKeys.has(key)) {
|
|
1852
|
-
throwConfigError(
|
|
1853
|
-
"Assistant theme color object only supports 'light' and 'dark'.",
|
|
1854
|
-
["assistant", "themeColor", key],
|
|
1855
|
-
);
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
const light =
|
|
1860
|
-
assistantThemeColorByMode.light !== undefined
|
|
1861
|
-
? normalizeHexColor(
|
|
1862
|
-
assistantThemeColorByMode.light,
|
|
1863
|
-
["assistant", "themeColor", "light"],
|
|
1864
|
-
"Assistant theme color light",
|
|
1865
|
-
)
|
|
1866
|
-
: undefined;
|
|
1867
|
-
const dark =
|
|
1868
|
-
assistantThemeColorByMode.dark !== undefined
|
|
1869
|
-
? normalizeHexColor(
|
|
1870
|
-
assistantThemeColorByMode.dark,
|
|
1871
|
-
["assistant", "themeColor", "dark"],
|
|
1872
|
-
"Assistant theme color dark",
|
|
1873
|
-
)
|
|
1874
|
-
: undefined;
|
|
1875
|
-
|
|
1876
|
-
if (!light && !dark) {
|
|
1877
|
-
throwConfigError(
|
|
1878
|
-
"Assistant theme color object must include 'light', 'dark', or both.",
|
|
1879
|
-
["assistant", "themeColor"],
|
|
1880
|
-
);
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
|
-
assistant.themeColor = {
|
|
1884
|
-
...(light !== undefined ? { light } : {}),
|
|
1885
|
-
...(dark !== undefined ? { dark } : {}),
|
|
1886
|
-
};
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
|
|
1890
2140
|
if (assistant.icon === undefined) return;
|
|
1891
2141
|
|
|
1892
2142
|
checkType(
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
|
|
112
112
|
/* Prose styling */
|
|
113
113
|
.prose-rules {
|
|
114
|
-
@apply
|
|
114
|
+
@apply prose max-w-none *:my-6 *:first:mt-0 *:last:mb-0 prose-h2:mt-7 prose-h2:mb-2 prose-h2:scroll-mt-24 prose-h3:mb-2 prose-h3:scroll-mt-24 prose-headings:font-semibold prose-p:mt-0 prose-p:mb-4 prose-ol:mt-0 prose-ol:mb-5 prose-ul:mt-0 prose-ul:mb-5 prose-a:decoration-(--color-theme) prose-a:decoration-from-font prose-blockquote:border-(--color-theme)/30 dark:prose-blockquote:border-(--color-theme)/30;
|
|
115
115
|
--tw-prose-body: var(--color-neutral-700);
|
|
116
116
|
--tw-prose-headings: var(--color-neutral-900);
|
|
117
117
|
--tw-prose-lead: var(--color-neutral-600);
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
--tw-prose-pre-bg: var(--color-neutral-800);
|
|
135
135
|
--tw-prose-th-borders: var(--color-neutral-300);
|
|
136
136
|
--tw-prose-td-borders: var(--color-neutral-200);
|
|
137
|
-
--tw-prose-invert-body: var(--color-neutral-
|
|
137
|
+
--tw-prose-invert-body: var(--color-neutral-200);
|
|
138
138
|
--tw-prose-invert-headings: white;
|
|
139
139
|
--tw-prose-invert-lead: var(--color-neutral-400);
|
|
140
140
|
--tw-prose-invert-links: white;
|
|
@@ -175,7 +175,54 @@
|
|
|
175
175
|
--tw-prose-td-borders: var(--tw-prose-invert-td-borders);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
.prose-
|
|
178
|
+
.rd-prose-block {
|
|
179
|
+
margin-block: 1.5rem;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.prose-rules > .rd-accordion:has(+ .rd-accordion) {
|
|
183
|
+
margin-block-end: 0 !important;
|
|
184
|
+
margin-bottom: 0 !important;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.prose-rules > .rd-accordion + .rd-accordion {
|
|
188
|
+
margin-block-start: 0 !important;
|
|
189
|
+
margin-top: 0 !important;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.prose-rules > .react-renderer,
|
|
193
|
+
.prose-rules > [data-node-view-content-react],
|
|
194
|
+
.prose-rules > [data-node-view-content-react] > .react-renderer {
|
|
195
|
+
margin-block: 0 !important;
|
|
196
|
+
max-width: none !important;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@layer base {
|
|
200
|
+
.prose-rules > .rd-prose-block:first-child,
|
|
201
|
+
.prose-rules > .react-renderer:first-child > .rd-prose-block,
|
|
202
|
+
.prose-rules > [data-node-view-content-react]:first-child > :first-child,
|
|
203
|
+
.prose-rules > [data-node-view-content-react] > .rd-prose-block:first-child,
|
|
204
|
+
.prose-rules
|
|
205
|
+
> [data-node-view-content-react]
|
|
206
|
+
> .react-renderer:first-child
|
|
207
|
+
> .rd-prose-block {
|
|
208
|
+
margin-block-start: 0 !important;
|
|
209
|
+
margin-top: 0 !important;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.prose-rules > .rd-prose-block:last-child,
|
|
213
|
+
.prose-rules > .react-renderer:last-child > .rd-prose-block,
|
|
214
|
+
.prose-rules > [data-node-view-content-react]:last-child > :last-child,
|
|
215
|
+
.prose-rules > [data-node-view-content-react] > .rd-prose-block:last-child,
|
|
216
|
+
.prose-rules
|
|
217
|
+
> [data-node-view-content-react]
|
|
218
|
+
> .react-renderer:last-child
|
|
219
|
+
> .rd-prose-block {
|
|
220
|
+
margin-block-end: 0 !important;
|
|
221
|
+
margin-bottom: 0 !important;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.prose-rules :is(h2, h3) {
|
|
179
226
|
@apply relative;
|
|
180
227
|
padding-left: 0.375rem;
|
|
181
228
|
margin-left: -0.375rem;
|
|
@@ -197,8 +244,38 @@
|
|
|
197
244
|
@apply opacity-100;
|
|
198
245
|
}
|
|
199
246
|
|
|
247
|
+
.prose-rules
|
|
248
|
+
:is(h2, h3, h4, h5, h6)
|
|
249
|
+
> .heading-anchor[data-copy-state="copied"] {
|
|
250
|
+
@apply opacity-100 bg-green-500/5 text-green-700/80 dark:bg-green-900/20 dark:text-green-600/80;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.prose-rules .heading-anchor-icons {
|
|
254
|
+
@apply grid size-3.5 place-items-center;
|
|
255
|
+
}
|
|
256
|
+
|
|
200
257
|
.prose-rules .heading-anchor-icon {
|
|
201
|
-
@apply h-3.5 w-3.5;
|
|
258
|
+
@apply col-start-1 row-start-1 h-3.5 w-3.5 origin-center transition-all duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.prose-rules .heading-anchor-link-icon {
|
|
262
|
+
@apply scale-100 rotate-0 opacity-100;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.prose-rules .heading-anchor-check-icon {
|
|
266
|
+
@apply scale-50 rotate-6 opacity-0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.prose-rules
|
|
270
|
+
.heading-anchor[data-copy-state="copied"]
|
|
271
|
+
.heading-anchor-link-icon {
|
|
272
|
+
@apply scale-50 -rotate-6 opacity-0;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.prose-rules
|
|
276
|
+
.heading-anchor[data-copy-state="copied"]
|
|
277
|
+
.heading-anchor-check-icon {
|
|
278
|
+
@apply scale-110 rotate-0 opacity-100;
|
|
202
279
|
}
|
|
203
280
|
|
|
204
281
|
@media (max-width: 1023px) {
|