@shop-on/theme-react 0.1.0 → 0.2.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/template-renderer.d.ts +5 -0
- package/dist/template-renderer.js +20 -6
- package/package.json +10 -10
|
@@ -15,6 +15,11 @@ export interface AppSectionProps {
|
|
|
15
15
|
}
|
|
16
16
|
export type AppSectionComponent = ComponentType<AppSectionProps>;
|
|
17
17
|
export declare function loadAppScript(src: string): Promise<void>;
|
|
18
|
+
/** The current shop's handle, read from the root route's loader data: every
|
|
19
|
+
* theme's root loader returns `fetchShopInfo()` as `shop`. An app's element
|
|
20
|
+
* can't derive it from `location.hostname`, since a custom domain doesn't carry
|
|
21
|
+
* it. Exported for a theme that overrides `AppSection`. */
|
|
22
|
+
export declare function useShopHandle(): string | undefined;
|
|
18
23
|
export interface TemplateRendererLoaders {
|
|
19
24
|
/** type-name → dynamic-import factory. Each theme registers its own file
|
|
20
25
|
* tree (typically `import.meta.glob("./sections/*.tsx", { import: "default" })`
|
|
@@ -2,6 +2,7 @@ import { escapeAttrValue, scopeCustomCss } from "./custom-css.js";
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createContext, createElement, useContext, useEffect } from "react";
|
|
4
4
|
import { collectTypes, selectRenderableChildren, selectRenderableSections } from "@shop-on/theme-contract";
|
|
5
|
+
import { rootRouteId, useMatch } from "@tanstack/react-router";
|
|
5
6
|
//#region src/template-renderer.tsx
|
|
6
7
|
const EMPTY_BLOCK_PATH = [];
|
|
7
8
|
const SectionIdContext = createContext(void 0);
|
|
@@ -30,22 +31,35 @@ function loadAppScript(src) {
|
|
|
30
31
|
appScriptPromises.set(src, p);
|
|
31
32
|
return p;
|
|
32
33
|
}
|
|
34
|
+
function shopHandleOf(loaderData) {
|
|
35
|
+
const shop = loaderData?.shop;
|
|
36
|
+
return typeof shop?.handle === "string" && shop.handle ? shop.handle : void 0;
|
|
37
|
+
}
|
|
38
|
+
/** The current shop's handle, read from the root route's loader data: every
|
|
39
|
+
* theme's root loader returns `fetchShopInfo()` as `shop`. An app's element
|
|
40
|
+
* can't derive it from `location.hostname`, since a custom domain doesn't carry
|
|
41
|
+
* it. Exported for a theme that overrides `AppSection`. */
|
|
42
|
+
function useShopHandle() {
|
|
43
|
+
return useMatch({
|
|
44
|
+
from: rootRouteId,
|
|
45
|
+
shouldThrow: false,
|
|
46
|
+
select: (match) => shopHandleOf(match.loaderData)
|
|
47
|
+
});
|
|
48
|
+
}
|
|
33
49
|
function DefaultAppSection({ section, sectionId }) {
|
|
34
50
|
const { tag, scriptUrl } = section;
|
|
35
51
|
const settings = section.settings ?? {};
|
|
52
|
+
const shopHandle = useShopHandle();
|
|
36
53
|
useEffect(() => {
|
|
37
54
|
if (scriptUrl) loadAppScript(scriptUrl).catch(() => {});
|
|
38
55
|
}, [scriptUrl]);
|
|
39
56
|
if (!tag) return null;
|
|
40
|
-
const heading = typeof settings.heading === "string" ? settings.heading.trim() : "";
|
|
41
57
|
return createElement(tag, {
|
|
42
58
|
"data-settings": JSON.stringify(settings),
|
|
43
59
|
"data-app-section-id": sectionId,
|
|
60
|
+
"data-shop-handle": shopHandle,
|
|
44
61
|
suppressHydrationWarning: true
|
|
45
|
-
}
|
|
46
|
-
"data-app-fallback": "",
|
|
47
|
-
children: heading
|
|
48
|
-
}) : null);
|
|
62
|
+
});
|
|
49
63
|
}
|
|
50
64
|
/** `collectTypes` over every template, merged. */
|
|
51
65
|
function collectTemplateTypes(templates) {
|
|
@@ -204,4 +218,4 @@ function createTemplateRenderer(loaders, opts) {
|
|
|
204
218
|
};
|
|
205
219
|
}
|
|
206
220
|
//#endregion
|
|
207
|
-
export { collectTemplateTypes, createTemplateRenderer, loadAppScript };
|
|
221
|
+
export { collectTemplateTypes, createTemplateRenderer, loadAppScript, useShopHandle };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shop-on/theme-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "SEE LICENSE IN dist/LICENSE.md",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -29,27 +29,27 @@
|
|
|
29
29
|
"./package.json": "./package.json"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@shop-on/theme-contract": "0.
|
|
33
|
-
"@shop-on/theme-runtime": "0.
|
|
32
|
+
"@shop-on/theme-contract": "0.2.0",
|
|
33
|
+
"@shop-on/theme-runtime": "0.2.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@tanstack/react-router": "1.170.
|
|
36
|
+
"@tanstack/react-router": "1.170.45",
|
|
37
37
|
"@testing-library/react": "16.3.3",
|
|
38
38
|
"@types/react": "19.3.0",
|
|
39
39
|
"@types/react-dom": "19.3.0",
|
|
40
|
-
"happy-dom": "
|
|
41
|
-
"react": "19.3.
|
|
42
|
-
"react-dom": "19.3.
|
|
40
|
+
"happy-dom": "21.0.4",
|
|
41
|
+
"react": "19.3.1",
|
|
42
|
+
"react-dom": "19.3.1",
|
|
43
43
|
"typescript": "7.0.2",
|
|
44
|
-
"vitest": "5.0.
|
|
44
|
+
"vitest": "5.0.5"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@tanstack/react-router": "~1.170.
|
|
47
|
+
"@tanstack/react-router": "~1.170.45",
|
|
48
48
|
"react": ">=19.0.0",
|
|
49
49
|
"react-dom": ">=19.0.0"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"check-types": "tsc --noEmit",
|
|
53
|
-
"test": "vitest run"
|
|
53
|
+
"test": "vitest run --maxWorkers=2"
|
|
54
54
|
}
|
|
55
55
|
}
|