@tenphi/renderer 0.30.2 → 0.31.1
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/client/elements.d.ts +2 -2
- package/dist/client/elements.d.ts.map +1 -1
- package/dist/client/elements.js +4 -4
- package/dist/client/elements.js.map +1 -1
- package/dist/client/search.js +1 -1
- package/dist/client/search.js.map +1 -1
- package/dist/components/Header.styles.js +1 -1
- package/dist/components/MobileNavigationTabs.astro +3 -1
- package/dist/components/MobileNavigationTabs.styles.js +1 -1
- package/dist/components/Search.styles.js +1 -1
- package/dist/components/SelectPopover.astro +1 -1
- package/dist/overrides/Search.astro +11 -9
- package/package.json +4 -4
|
@@ -4,8 +4,8 @@ import { UniElement } from "@uniaria/elements";
|
|
|
4
4
|
//#region src/client/elements.d.ts
|
|
5
5
|
declare global {
|
|
6
6
|
interface HTMLElementTagNameMap {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
7
|
+
"cookbook-popover": UniElement<typeof popover>;
|
|
8
|
+
"cookbook-dialog": UniElement<typeof dialog>;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=elements.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elements.d.ts","names":[],"sources":["../../src/client/elements.ts"],"mappings":";;;;QAiBQ;YACI;IACR,
|
|
1
|
+
{"version":3,"file":"elements.d.ts","names":[],"sources":["../../src/client/elements.ts"],"mappings":";;;;QAiBQ;YACI;IACR,oBAAoB,kBAAkB;IACtC,mBAAmB,kBAAkB"}
|
package/dist/client/elements.js
CHANGED
|
@@ -4,12 +4,12 @@ import { popover } from "@uniaria/core/popover";
|
|
|
4
4
|
import { defineElement } from "@uniaria/elements";
|
|
5
5
|
//#region src/client/elements.ts
|
|
6
6
|
/**
|
|
7
|
-
* Register UniAria's behaviors as `
|
|
8
|
-
*
|
|
7
|
+
* Register UniAria's behaviors as `cookbook-*` light-DOM elements, using the
|
|
8
|
+
* same prefix as every other Cookbook-owned custom element.
|
|
9
9
|
*/
|
|
10
10
|
configure({ positioning: "css" });
|
|
11
|
-
defineElement(popover, { prefix: "
|
|
12
|
-
defineElement(dialog, { prefix: "
|
|
11
|
+
defineElement(popover, { prefix: "cookbook" });
|
|
12
|
+
defineElement(dialog, { prefix: "cookbook" });
|
|
13
13
|
//#endregion
|
|
14
14
|
export {};
|
|
15
15
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elements.js","names":[],"sources":["../../src/client/elements.ts"],"sourcesContent":["/**\n * Register UniAria's behaviors as `
|
|
1
|
+
{"version":3,"file":"elements.js","names":[],"sources":["../../src/client/elements.ts"],"sourcesContent":["/**\n * Register UniAria's behaviors as `cookbook-*` light-DOM elements, using the\n * same prefix as every other Cookbook-owned custom element.\n */\nimport { dialog } from \"@uniaria/core/dialog\";\nimport { configure } from \"@uniaria/core/dom\";\nimport { popover } from \"@uniaria/core/popover\";\nimport type { UniElement } from \"@uniaria/elements\";\nimport { defineElement } from \"@uniaria/elements\";\n\n// Panels keep the placement Cookbook's styles give them; UniAria only links\n// each one to its anchor and reads the side back.\nconfigure({ positioning: \"css\" });\n// Each returns undefined without `customElements` and skips a defined name.\ndefineElement(popover, { prefix: \"cookbook\" });\ndefineElement(dialog, { prefix: \"cookbook\" });\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"cookbook-popover\": UniElement<typeof popover>;\n \"cookbook-dialog\": UniElement<typeof dialog>;\n }\n}\n"],"mappings":";;;;;;;;;AAYA,UAAU,EAAE,aAAa,MAAM,CAAC;AAEhC,cAAc,SAAS,EAAE,QAAQ,WAAW,CAAC;AAC7C,cAAc,QAAQ,EAAE,QAAQ,WAAW,CAAC"}
|
package/dist/client/search.js
CHANGED
|
@@ -133,7 +133,7 @@ function initializeSearch(element, options, development, base) {
|
|
|
133
133
|
dialog.removeAttribute("data-open");
|
|
134
134
|
document.body.removeAttribute("data-search-modal-open");
|
|
135
135
|
const next = event.newDocument;
|
|
136
|
-
const nextRoot = persistenceKey ? [...next.querySelectorAll("
|
|
136
|
+
const nextRoot = persistenceKey ? [...next.querySelectorAll("cookbook-search")].find((root) => root.dataset.searchKey === persistenceKey) : void 0;
|
|
137
137
|
if (nextRoot) nextRoot.setAttribute("data-astro-transition-persist", persistenceKey);
|
|
138
138
|
else listeners.abort();
|
|
139
139
|
}, { signal: listeners.signal });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":[],"sources":["../../src/client/search.ts"],"sourcesContent":["type SearchResult = { url: string; sub_results?: SearchResult[] };\nimport type { TransitionBeforeSwapEvent } from \"astro:transitions/client\";\ntype PagefindOptions = Record<string, unknown> & {\n processResult?: (result: SearchResult) => SearchResult | void;\n};\n\n/** Own the dialog lifecycle; Pagefind owns indexing, filtering and result rendering. */\nexport function initializeSearch(\n element: HTMLElement,\n options: PagefindOptions,\n development: boolean,\n base: string,\n): void {\n if (element.dataset.initialized) return;\n element.dataset.initialized = \"true\";\n const listeners = new AbortController();\n // Astro strips transition attributes from unhydrated framework roots. Apply\n // the public persistence hook here and to the incoming matching search root.\n const persistenceKey = element.dataset.searchKey;\n if (persistenceKey)\n element.setAttribute(\"data-astro-transition-persist\", persistenceKey);\n const open = element.querySelector<HTMLButtonElement>(\"[data-open-modal]\")!;\n const close = element.querySelector<HTMLButtonElement>(\"[data-close-modal]\")!;\n const dialog = element.querySelector(\"dialog\")!;\n const frame = element.querySelector(\"[data-element=Frame]\")!;\n const status = element.querySelector<HTMLElement>(\"[data-search-status]\");\n const input = element.querySelector<HTMLInputElement>(\"[data-search-input]\");\n const clear = element.querySelector<HTMLButtonElement>(\"[data-clear-search]\");\n const shortcut = open.querySelector(\"kbd\")!;\n if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {\n shortcut.querySelector(\"kbd\")!.textContent = \"⌘\";\n open.setAttribute(\"aria-keyshortcuts\", \"Meta+K\");\n }\n delete shortcut.dataset.pending;\n let initialized: Promise<void> | undefined;\n let engineInput: HTMLInputElement | null = null;\n let returnFocus: HTMLElement | null = null;\n let closing = false;\n let generation = 0;\n const updateSearch = () => {\n if (clear) clear.hidden = !input?.value;\n if (engineInput) {\n engineInput.value = input?.value ?? \"\";\n engineInput.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n };\n input?.addEventListener(\"input\", updateSearch);\n clear?.addEventListener(\"click\", () => {\n if (!input) return;\n input.value = \"\";\n updateSearch();\n input.focus();\n });\n const initialize = () => {\n if (development) return Promise.resolve();\n return (initialized ??= (async () => {\n // @ts-expect-error Pagefind publishes no declarations for its default UI.\n const { PagefindUI } = await import(\"@pagefind/default-ui\");\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n // Pagefind names pages by their files: x/ for x/index.html, x.html otherwise.\n const format = (url: string) => {\n const trailingSlash = element.dataset.trailingSlash;\n if (trailingSlash === \"always\") return url;\n const page = url.replace(/\\.html(?=#|$)/, \"\");\n return trailingSlash === \"never\"\n ? page.replace(/(.)\\/(#.*)?$/, \"$1$2\")\n : page;\n };\n new PagefindUI({\n ...options,\n element: element.querySelector(\"[data-search-results]\"),\n baseUrl: base,\n bundlePath: `${base.replace(/\\/$/, \"\")}/pagefind/`,\n showImages: false,\n showSubResults: true,\n translations,\n processResult(result: SearchResult) {\n result = options.processResult?.(result) ?? result;\n result.url = format(result.url);\n result.sub_results?.forEach((child) => {\n child.url = format(child.url);\n });\n return result;\n },\n });\n // Pagefind generates and controls these nodes; its UI API exposes only classes.\n engineInput = element.querySelector(\".pagefind-ui__search-input\");\n element.querySelector(\".pagefind-ui__form\")?.removeAttribute(\"role\");\n // Cookbook owns the field so focus stays within the opening tap on mobile.\n // Pagefind still owns query processing and its lazily rendered results.\n element\n .querySelectorAll<HTMLElement>(\n \".pagefind-ui__search-input, .pagefind-ui__search-clear\",\n )\n .forEach((control) => {\n control.hidden = true;\n control.tabIndex = -1;\n });\n updateSearch();\n })().catch((error: unknown) => {\n initialized = undefined;\n if (status) {\n status.hidden = false;\n // Reuse the localized Pagefind error, with a plain fallback.\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n status.textContent =\n translations.error ?? \"Search could not load. Close and try again.\";\n }\n throw error;\n }));\n };\n const show = (trigger?: HTMLElement) => {\n if (dialog.open && !closing) return;\n generation += 1;\n closing = false;\n if (!dialog.open) {\n returnFocus =\n trigger ??\n (document.activeElement instanceof HTMLElement &&\n document.activeElement !== document.body\n ? document.activeElement\n : open);\n dialog.removeAttribute(\"data-open\");\n dialog.showModal();\n }\n // Do this synchronously, before the lazy import releases user activation.\n input?.focus({ preventScroll: true });\n // Establish the initial state after entering the top layer. The global\n // style renderer does not preserve @starting-style in server output.\n dialog.getBoundingClientRect();\n dialog.setAttribute(\"data-open\", \"\");\n document.body.setAttribute(\"data-search-modal-open\", \"\");\n if (!development && status) status.hidden = true;\n void initialize().catch(() => {\n /* Keep the close control usable when the search bundle fails. */\n });\n };\n const hide = async () => {\n if (!dialog.open || closing) return;\n closing = true;\n const current = ++generation;\n dialog.removeAttribute(\"data-open\");\n // Keep the modal in the top layer until its exit transition has finished.\n // This also works in browsers without discrete display/overlay transitions.\n await Promise.allSettled(\n dialog\n .getAnimations()\n .filter((animation) =>\n Number.isFinite(animation.effect?.getComputedTiming().endTime),\n )\n .map((animation) => animation.finished),\n );\n if (current === generation && dialog.open) dialog.close();\n };\n open.addEventListener(\"click\", () => {\n show(open);\n });\n open.disabled = false;\n close.addEventListener(\"click\", () => void hide());\n dialog.addEventListener(\"cancel\", (event) => {\n event.preventDefault();\n void hide();\n });\n dialog.addEventListener(\"click\", (event) => {\n if (!(event.target instanceof Element)) return;\n if (event.target.closest(\"a[href]\") || !frame.contains(event.target))\n void hide();\n });\n dialog.addEventListener(\"close\", () => {\n dialog.removeAttribute(\"data-open\");\n closing = false;\n document.body.removeAttribute(\"data-search-modal-open\");\n returnFocus?.focus();\n });\n document.addEventListener(\n \"astro:before-swap\",\n (event) => {\n // Keep the query and lazy engine for matching localized search shells,\n // while dismissing the modal before the destination content is displayed.\n generation += 1;\n returnFocus = null;\n if (dialog.open) dialog.close();\n dialog.removeAttribute(\"data-open\");\n document.body.removeAttribute(\"data-search-modal-open\");\n const next = (event as TransitionBeforeSwapEvent).newDocument;\n const nextRoot = persistenceKey\n ? [...next.querySelectorAll<HTMLElement>(\"site-search\")].find(\n (root) => root.dataset.searchKey === persistenceKey,\n )\n : undefined;\n if (nextRoot)\n nextRoot.setAttribute(\"data-astro-transition-persist\", persistenceKey!);\n else listeners.abort();\n },\n { signal: listeners.signal },\n );\n window.addEventListener(\n \"keydown\",\n (event) => {\n if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"k\") {\n event.preventDefault();\n if (dialog.open && !closing) void hide();\n else void show();\n }\n },\n { signal: listeners.signal },\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search.js","names":[],"sources":["../../src/client/search.ts"],"sourcesContent":["type SearchResult = { url: string; sub_results?: SearchResult[] };\nimport type { TransitionBeforeSwapEvent } from \"astro:transitions/client\";\ntype PagefindOptions = Record<string, unknown> & {\n processResult?: (result: SearchResult) => SearchResult | void;\n};\n\n/** Own the dialog lifecycle; Pagefind owns indexing, filtering and result rendering. */\nexport function initializeSearch(\n element: HTMLElement,\n options: PagefindOptions,\n development: boolean,\n base: string,\n): void {\n if (element.dataset.initialized) return;\n element.dataset.initialized = \"true\";\n const listeners = new AbortController();\n // Astro strips transition attributes from unhydrated framework roots. Apply\n // the public persistence hook here and to the incoming matching search root.\n const persistenceKey = element.dataset.searchKey;\n if (persistenceKey)\n element.setAttribute(\"data-astro-transition-persist\", persistenceKey);\n const open = element.querySelector<HTMLButtonElement>(\"[data-open-modal]\")!;\n const close = element.querySelector<HTMLButtonElement>(\"[data-close-modal]\")!;\n const dialog = element.querySelector(\"dialog\")!;\n const frame = element.querySelector(\"[data-element=Frame]\")!;\n const status = element.querySelector<HTMLElement>(\"[data-search-status]\");\n const input = element.querySelector<HTMLInputElement>(\"[data-search-input]\");\n const clear = element.querySelector<HTMLButtonElement>(\"[data-clear-search]\");\n const shortcut = open.querySelector(\"kbd\")!;\n if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {\n shortcut.querySelector(\"kbd\")!.textContent = \"⌘\";\n open.setAttribute(\"aria-keyshortcuts\", \"Meta+K\");\n }\n delete shortcut.dataset.pending;\n let initialized: Promise<void> | undefined;\n let engineInput: HTMLInputElement | null = null;\n let returnFocus: HTMLElement | null = null;\n let closing = false;\n let generation = 0;\n const updateSearch = () => {\n if (clear) clear.hidden = !input?.value;\n if (engineInput) {\n engineInput.value = input?.value ?? \"\";\n engineInput.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n };\n input?.addEventListener(\"input\", updateSearch);\n clear?.addEventListener(\"click\", () => {\n if (!input) return;\n input.value = \"\";\n updateSearch();\n input.focus();\n });\n const initialize = () => {\n if (development) return Promise.resolve();\n return (initialized ??= (async () => {\n // @ts-expect-error Pagefind publishes no declarations for its default UI.\n const { PagefindUI } = await import(\"@pagefind/default-ui\");\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n // Pagefind names pages by their files: x/ for x/index.html, x.html otherwise.\n const format = (url: string) => {\n const trailingSlash = element.dataset.trailingSlash;\n if (trailingSlash === \"always\") return url;\n const page = url.replace(/\\.html(?=#|$)/, \"\");\n return trailingSlash === \"never\"\n ? page.replace(/(.)\\/(#.*)?$/, \"$1$2\")\n : page;\n };\n new PagefindUI({\n ...options,\n element: element.querySelector(\"[data-search-results]\"),\n baseUrl: base,\n bundlePath: `${base.replace(/\\/$/, \"\")}/pagefind/`,\n showImages: false,\n showSubResults: true,\n translations,\n processResult(result: SearchResult) {\n result = options.processResult?.(result) ?? result;\n result.url = format(result.url);\n result.sub_results?.forEach((child) => {\n child.url = format(child.url);\n });\n return result;\n },\n });\n // Pagefind generates and controls these nodes; its UI API exposes only classes.\n engineInput = element.querySelector(\".pagefind-ui__search-input\");\n element.querySelector(\".pagefind-ui__form\")?.removeAttribute(\"role\");\n // Cookbook owns the field so focus stays within the opening tap on mobile.\n // Pagefind still owns query processing and its lazily rendered results.\n element\n .querySelectorAll<HTMLElement>(\n \".pagefind-ui__search-input, .pagefind-ui__search-clear\",\n )\n .forEach((control) => {\n control.hidden = true;\n control.tabIndex = -1;\n });\n updateSearch();\n })().catch((error: unknown) => {\n initialized = undefined;\n if (status) {\n status.hidden = false;\n // Reuse the localized Pagefind error, with a plain fallback.\n const translations = JSON.parse(element.dataset.translations ?? \"{}\");\n status.textContent =\n translations.error ?? \"Search could not load. Close and try again.\";\n }\n throw error;\n }));\n };\n const show = (trigger?: HTMLElement) => {\n if (dialog.open && !closing) return;\n generation += 1;\n closing = false;\n if (!dialog.open) {\n returnFocus =\n trigger ??\n (document.activeElement instanceof HTMLElement &&\n document.activeElement !== document.body\n ? document.activeElement\n : open);\n dialog.removeAttribute(\"data-open\");\n dialog.showModal();\n }\n // Do this synchronously, before the lazy import releases user activation.\n input?.focus({ preventScroll: true });\n // Establish the initial state after entering the top layer. The global\n // style renderer does not preserve @starting-style in server output.\n dialog.getBoundingClientRect();\n dialog.setAttribute(\"data-open\", \"\");\n document.body.setAttribute(\"data-search-modal-open\", \"\");\n if (!development && status) status.hidden = true;\n void initialize().catch(() => {\n /* Keep the close control usable when the search bundle fails. */\n });\n };\n const hide = async () => {\n if (!dialog.open || closing) return;\n closing = true;\n const current = ++generation;\n dialog.removeAttribute(\"data-open\");\n // Keep the modal in the top layer until its exit transition has finished.\n // This also works in browsers without discrete display/overlay transitions.\n await Promise.allSettled(\n dialog\n .getAnimations()\n .filter((animation) =>\n Number.isFinite(animation.effect?.getComputedTiming().endTime),\n )\n .map((animation) => animation.finished),\n );\n if (current === generation && dialog.open) dialog.close();\n };\n open.addEventListener(\"click\", () => {\n show(open);\n });\n open.disabled = false;\n close.addEventListener(\"click\", () => void hide());\n dialog.addEventListener(\"cancel\", (event) => {\n event.preventDefault();\n void hide();\n });\n dialog.addEventListener(\"click\", (event) => {\n if (!(event.target instanceof Element)) return;\n if (event.target.closest(\"a[href]\") || !frame.contains(event.target))\n void hide();\n });\n dialog.addEventListener(\"close\", () => {\n dialog.removeAttribute(\"data-open\");\n closing = false;\n document.body.removeAttribute(\"data-search-modal-open\");\n returnFocus?.focus();\n });\n document.addEventListener(\n \"astro:before-swap\",\n (event) => {\n // Keep the query and lazy engine for matching localized search shells,\n // while dismissing the modal before the destination content is displayed.\n generation += 1;\n returnFocus = null;\n if (dialog.open) dialog.close();\n dialog.removeAttribute(\"data-open\");\n document.body.removeAttribute(\"data-search-modal-open\");\n const next = (event as TransitionBeforeSwapEvent).newDocument;\n const nextRoot = persistenceKey\n ? [...next.querySelectorAll<HTMLElement>(\"cookbook-search\")].find(\n (root) => root.dataset.searchKey === persistenceKey,\n )\n : undefined;\n if (nextRoot)\n nextRoot.setAttribute(\"data-astro-transition-persist\", persistenceKey!);\n else listeners.abort();\n },\n { signal: listeners.signal },\n );\n window.addEventListener(\n \"keydown\",\n (event) => {\n if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"k\") {\n event.preventDefault();\n if (dialog.open && !closing) void hide();\n else void show();\n }\n },\n { signal: listeners.signal },\n );\n}\n"],"mappings":"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"}
|
|
@@ -71,7 +71,9 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
|
|
|
71
71
|
const initialize = () => {
|
|
72
72
|
if (
|
|
73
73
|
mobile.matches &&
|
|
74
|
-
document.querySelector(
|
|
74
|
+
document.querySelector(
|
|
75
|
+
"cookbook-popover[data-element=MobileNavigationTabs]",
|
|
76
|
+
)
|
|
75
77
|
)
|
|
76
78
|
void import("../client/elements.js");
|
|
77
79
|
};
|
|
@@ -13,7 +13,7 @@ const sectionSelectStyles = selectPopoverStyles({
|
|
|
13
13
|
export const MobileNavigationTabsRoot = defineComponent(
|
|
14
14
|
"MobileNavigationTabs",
|
|
15
15
|
{
|
|
16
|
-
as: "
|
|
16
|
+
as: "cookbook-popover",
|
|
17
17
|
"data-element": "MobileNavigationTabs",
|
|
18
18
|
styles: {
|
|
19
19
|
// Reuse the shared, server-only popover anatomy.
|
|
@@ -84,15 +84,17 @@ const translations = {
|
|
|
84
84
|
<script>
|
|
85
85
|
import { initializeSearch } from "../client/search.js";
|
|
86
86
|
function initialize(): void {
|
|
87
|
-
document
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
element
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
document
|
|
88
|
+
.querySelectorAll<HTMLElement>("cookbook-search")
|
|
89
|
+
.forEach((element) => {
|
|
90
|
+
if (element.dataset.searchBase !== import.meta.env.BASE_URL) return;
|
|
91
|
+
initializeSearch(
|
|
92
|
+
element,
|
|
93
|
+
{},
|
|
94
|
+
import.meta.env.DEV,
|
|
95
|
+
import.meta.env.BASE_URL,
|
|
96
|
+
);
|
|
97
|
+
});
|
|
96
98
|
}
|
|
97
99
|
initialize();
|
|
98
100
|
document.addEventListener("astro:page-load", initialize);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenphi/renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"description": "Astro renderer and Tasty theme for Cookbook",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
"@fontsource-variable/jetbrains-mono": "^5.3.0",
|
|
62
62
|
"@fontsource-variable/onest": "^5.3.0",
|
|
63
63
|
"@pagefind/default-ui": "1.5.2",
|
|
64
|
-
"@tenphi/docs": "0.
|
|
65
|
-
"@tenphi/eslint-plugin-tasty": "1.
|
|
64
|
+
"@tenphi/docs": "0.31.1",
|
|
65
|
+
"@tenphi/eslint-plugin-tasty": "1.14.0",
|
|
66
66
|
"@tenphi/glaze": "2.0.1",
|
|
67
|
-
"@tenphi/tasty": "3.
|
|
67
|
+
"@tenphi/tasty": "3.16.0",
|
|
68
68
|
"@uniaria/core": "0.3.0",
|
|
69
69
|
"@uniaria/elements": "0.3.0",
|
|
70
70
|
"beautiful-mermaid": "^1.1.3",
|