vite-plugin-react-shopify 2.1.1 → 2.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/index.js CHANGED
@@ -992,7 +992,7 @@ function shopifySSG(options) {
992
992
  if (id === "\0vite-plugin-shopify:runtime") {
993
993
  const exports = [
994
994
  `export { LiquidDataProvider, LiquidDataContext } from 'vite-plugin-shopify/runtime'`,
995
- `export { useLiquid, useLiquidValues, useSectionSettings, useBlockSettings, useSnippetParams, useBlockParams } from 'vite-plugin-shopify/runtime'`
995
+ `export { useLiquidValue, useLiquidValues, useSectionSettings, useBlockSettings, useSnippetParams, useBlockParams } from 'vite-plugin-shopify/runtime'`
996
996
  ];
997
997
  return exports.join("\n");
998
998
  }
@@ -1,13 +1,21 @@
1
1
  import * as react from 'react';
2
2
 
3
- declare function useLiquid(expr: string): {
4
- value: string | undefined;
5
- };
6
- declare function useLiquidValues<T extends Record<string, string>>(map: T): {
7
- values: {
8
- [K in keyof T]: string | undefined;
9
- };
3
+ declare function parseLiquidBoolean(value: string | boolean | undefined | null): boolean;
4
+ declare function parseLiquidNumber(value: string | number | undefined | null, defaultVal?: number): number;
5
+ type LiquidTypeMode = "string" | "number" | "boolean";
6
+ type Setter<T> = (val: T | ((prev: T) => T)) => void;
7
+ type ValueForMode<M extends LiquidTypeMode | undefined> = M extends "number" ? number : M extends "boolean" ? boolean : string | undefined;
8
+ declare function useLiquidValue(expr: string): [string | undefined, Setter<string | undefined>];
9
+ declare function useLiquidValue(expr: string, type: "string"): [string | undefined, Setter<string | undefined>];
10
+ declare function useLiquidValue(expr: string, type: "number"): [number, Setter<number>];
11
+ declare function useLiquidValue(expr: string, type: "boolean"): [boolean, Setter<boolean>];
12
+ type TypeModes<T extends Record<string, string>> = Partial<{
13
+ [K in keyof T & string]: LiquidTypeMode;
14
+ }>;
15
+ type InferValues<T extends Record<string, string>, Types extends TypeModes<T>> = {
16
+ [K in keyof T & string]: ValueForMode<Types[K]>;
10
17
  };
18
+ declare function useLiquidValues<T extends Record<string, string>, const Types extends TypeModes<T> = {}>(map: T, types?: Types): InferValues<T, Types>;
11
19
  declare function useSectionSettings(key: string): {
12
20
  value: string | undefined;
13
21
  };
@@ -21,12 +29,7 @@ declare function useBlockParams(key: string): {
21
29
  value: string | undefined;
22
30
  };
23
31
 
24
- /** SSR-safe boolean parser: treats Liquid expression strings as truthy, real booleans as-is */
25
- declare function parseLiquidBoolean(value: string | boolean | undefined | null): boolean;
26
- /** SSR-safe number parser: returns defaultVal for unparseable SSR placeholders */
27
- declare function parseLiquidNumber(value: string | number | undefined | null, defaultVal?: number): number;
28
-
29
32
  declare const LiquidDataContext: react.Context<Record<string, any>>;
30
33
  declare const LiquidDataProvider: react.Provider<Record<string, any>>;
31
34
 
32
- export { LiquidDataContext, LiquidDataProvider, parseLiquidBoolean, parseLiquidNumber, useBlockParams, useBlockSettings, useLiquid, useLiquidValues, useSectionSettings, useSnippetParams };
35
+ export { LiquidDataContext, LiquidDataProvider, type LiquidTypeMode, parseLiquidBoolean, parseLiquidNumber, useBlockParams, useBlockSettings, useLiquidValue, useLiquidValues, useSectionSettings, useSnippetParams };
@@ -1,5 +1,5 @@
1
1
  // src/runtime/hooks.ts
2
- import { useContext } from "react";
2
+ import { useContext, useEffect, useState } from "react";
3
3
 
4
4
  // src/runtime/provider.ts
5
5
  import { createContext } from "react";
@@ -7,19 +7,19 @@ var LiquidDataContext = createContext({});
7
7
  var LiquidDataProvider = LiquidDataContext.Provider;
8
8
 
9
9
  // src/runtime/hooks.ts
10
- function useLiquid(expr) {
10
+ function useLiquidRaw(expr) {
11
11
  const data = useContext(LiquidDataContext);
12
12
  if (typeof globalThis.document === "undefined") {
13
13
  const tracker = globalThis.__shopify_ssg_liquid_track;
14
14
  if (tracker) tracker.add(expr);
15
- return { value: `{{ ${expr} }}` };
15
+ return `{{ ${expr} }}`;
16
16
  }
17
17
  if (Object.prototype.hasOwnProperty.call(data, expr)) {
18
- return { value: data[expr] };
18
+ return data[expr];
19
19
  }
20
- return { value: void 0 };
20
+ return void 0;
21
21
  }
22
- function useLiquidValues(map) {
22
+ function useLiquidRawValues(map) {
23
23
  const data = useContext(LiquidDataContext);
24
24
  if (typeof globalThis.document === "undefined") {
25
25
  const tracker = globalThis.__shopify_ssg_liquid_track;
@@ -28,25 +28,13 @@ function useLiquidValues(map) {
28
28
  if (tracker) tracker.add(expr);
29
29
  values2[key] = `{{ ${expr} }}`;
30
30
  }
31
- return { values: values2 };
31
+ return values2;
32
32
  }
33
33
  const values = {};
34
34
  for (const [key, expr] of Object.entries(map)) {
35
35
  values[key] = Object.prototype.hasOwnProperty.call(data, expr) ? data[expr] : void 0;
36
36
  }
37
- return { values };
38
- }
39
- function useSectionSettings(key) {
40
- return useLiquid(`section.settings.${key}`);
41
- }
42
- function useBlockSettings(key) {
43
- return useLiquid(`block.settings.${key}`);
44
- }
45
- function useSnippetParams(key) {
46
- return useLiquid(key);
47
- }
48
- function useBlockParams(key) {
49
- return useLiquid(key);
37
+ return values;
50
38
  }
51
39
  function parseLiquidBoolean(value) {
52
40
  if (typeof value === "boolean") return value;
@@ -59,6 +47,76 @@ function parseLiquidNumber(value, defaultVal = 0) {
59
47
  const num = Number(value);
60
48
  return Number.isNaN(num) ? defaultVal : num;
61
49
  }
50
+ function useLiquidValue(expr, type = "string") {
51
+ const raw = useLiquidRaw(expr);
52
+ const isSSR = typeof globalThis.document === "undefined";
53
+ let initialVal;
54
+ if (type === "boolean") {
55
+ initialVal = false;
56
+ } else if (type === "number") {
57
+ initialVal = isSSR ? raw : parseLiquidNumber(raw, 0);
58
+ } else {
59
+ initialVal = raw;
60
+ }
61
+ const [val, setVal] = useState(initialVal);
62
+ useEffect(() => {
63
+ if (type === "number") setVal(parseLiquidNumber(raw, 0));
64
+ else if (type === "boolean") setVal(parseLiquidBoolean(raw));
65
+ else setVal(raw);
66
+ }, [raw]);
67
+ return [val, setVal];
68
+ }
69
+ function useLiquidValues(map, types) {
70
+ const raw = useLiquidRawValues(map);
71
+ const keys = Object.keys(map);
72
+ const rawDep = keys.map((k) => raw[k]).join("\0");
73
+ const isSSR = typeof globalThis.document === "undefined";
74
+ const [parsed, setParsed] = useState(() => {
75
+ const vals = {};
76
+ for (const k of keys) {
77
+ const mode = types?.[k] ?? "string";
78
+ if (mode === "boolean") {
79
+ vals[k] = false;
80
+ } else if (mode === "number") {
81
+ vals[k] = isSSR ? raw[k] : parseLiquidNumber(raw[k], 0);
82
+ } else {
83
+ vals[k] = raw[k];
84
+ }
85
+ }
86
+ return vals;
87
+ });
88
+ useEffect(() => {
89
+ setParsed((prev) => {
90
+ let changed = false;
91
+ const next = { ...prev };
92
+ for (const k of keys) {
93
+ const mode = types?.[k] ?? "string";
94
+ let v;
95
+ if (mode === "number") v = parseLiquidNumber(raw[k], 0);
96
+ else if (mode === "boolean") v = parseLiquidBoolean(raw[k]);
97
+ else v = raw[k];
98
+ if (v !== prev[k]) {
99
+ next[k] = v;
100
+ changed = true;
101
+ }
102
+ }
103
+ return changed ? next : prev;
104
+ });
105
+ }, [rawDep]);
106
+ return parsed;
107
+ }
108
+ function useSectionSettings(key) {
109
+ return { value: useLiquidRaw(`section.settings.${key}`) };
110
+ }
111
+ function useBlockSettings(key) {
112
+ return { value: useLiquidRaw(`block.settings.${key}`) };
113
+ }
114
+ function useSnippetParams(key) {
115
+ return { value: useLiquidRaw(key) };
116
+ }
117
+ function useBlockParams(key) {
118
+ return { value: useLiquidRaw(key) };
119
+ }
62
120
  export {
63
121
  LiquidDataContext,
64
122
  LiquidDataProvider,
@@ -66,7 +124,7 @@ export {
66
124
  parseLiquidNumber,
67
125
  useBlockParams,
68
126
  useBlockSettings,
69
- useLiquid,
127
+ useLiquidValue,
70
128
  useLiquidValues,
71
129
  useSectionSettings,
72
130
  useSnippetParams
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-react-shopify",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "Vite plugin for React Shopify themes",
5
5
  "files": [
6
6
  "dist"