@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.
@@ -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
- }, heading ? /* @__PURE__ */ jsx("p", {
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.1.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.1.0",
33
- "@shop-on/theme-runtime": "0.1.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.41",
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": "20.10.6",
41
- "react": "19.3.0",
42
- "react-dom": "19.3.0",
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.3"
44
+ "vitest": "5.0.5"
45
45
  },
46
46
  "peerDependencies": {
47
- "@tanstack/react-router": "~1.170.41",
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
  }