@rudra-js/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/README.md +17 -7
- package/dist/blocks/product-card.d.ts +3 -3
- package/dist/blocks/product-card.js +3 -3
- package/dist/render-context.d.ts +2 -2
- package/dist/render-context.js +3 -4
- package/dist/render-context.js.map +1 -1
- package/package.json +4 -4
- package/src/blocks/product-card.tsx +3 -3
- package/src/render-context.ts +6 -6
package/README.md
CHANGED
|
@@ -31,13 +31,23 @@ your catalog.
|
|
|
31
31
|
|
|
32
32
|
## What comes from where
|
|
33
33
|
|
|
34
|
-
This split is
|
|
34
|
+
This split is what a rendered component rests on. The model decides how things
|
|
35
|
+
are arranged and what the words are; every fact about a product is read from
|
|
36
|
+
your catalog when the page is served, and the model's own words are rendered as
|
|
37
|
+
text and escaped by React.
|
|
38
|
+
|
|
39
|
+
| Decided by the model | Decided by your catalog |
|
|
40
|
+
| ------------------------------------------------------------------- | ----------------------- |
|
|
41
|
+
| Which layout, in what order | Every product title |
|
|
42
|
+
| Tone, headline, the words in each block | Every price |
|
|
43
|
+
| Only in per-shopper mode: which products, and how each is described | Every image and link |
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
In the default cohort mode the products, their order and the reason under each
|
|
46
|
+
are filled in per request, not by the model, and a badge the model wrote is
|
|
47
|
+
dropped. The model chooses those only under `generation: 'per-shopper'`. The
|
|
48
|
+
one thing it still picks in either mode is the product a hero names, and the
|
|
49
|
+
full split is in
|
|
50
|
+
[What the model decides, by mode](https://github.com/clivedsouza1010/rudra-js/tree/main/packages/core#what-the-model-decides-by-mode).
|
|
41
51
|
|
|
42
52
|
The specification has no field carrying a title, a price, an image or a URL.
|
|
43
53
|
Product facts are resolved at render time from `products`, keyed by a SKU
|
|
@@ -60,7 +70,7 @@ the starting point, not a fault.
|
|
|
60
70
|
|
|
61
71
|
`examples/shop/public/demo-styles.css` is a working stylesheet written against
|
|
62
72
|
nothing but the table below — copy it as a starting point. The example shop
|
|
63
|
-
|
|
73
|
+
applies it by default; `?styles=off` shows the raw markup.
|
|
64
74
|
|
|
65
75
|
Every element it emits carries a class, and this is all of them:
|
|
66
76
|
|
|
@@ -4,9 +4,9 @@ import type { BlockRenderContext } from '../render-context.js';
|
|
|
4
4
|
* One product.
|
|
5
5
|
*
|
|
6
6
|
* Every fact here — the title, the price, the image, the link — is read from
|
|
7
|
-
* the catalog, not from the specification. The
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* the catalog, not from the specification. The specification contributes only
|
|
8
|
+
* `reason`, `badge` and `emphasis`, and React escapes all three on the way
|
|
9
|
+
* into the markup.
|
|
10
10
|
*/
|
|
11
11
|
export declare function ProductCard({ reference, context, }: {
|
|
12
12
|
reference: ProductReference;
|
|
@@ -3,9 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
* One product.
|
|
4
4
|
*
|
|
5
5
|
* Every fact here — the title, the price, the image, the link — is read from
|
|
6
|
-
* the catalog, not from the specification. The
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* the catalog, not from the specification. The specification contributes only
|
|
7
|
+
* `reason`, `badge` and `emphasis`, and React escapes all three on the way
|
|
8
|
+
* into the markup.
|
|
9
9
|
*/
|
|
10
10
|
export function ProductCard({ reference, context, }) {
|
|
11
11
|
const product = context.products.get(reference.sku);
|
package/dist/render-context.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import type { Bundle, Product } from '@rudra-js/core';
|
|
|
8
8
|
* the model did not invent — both in stock at the time. A bundle member's SKU
|
|
9
9
|
* comes from the set the shop supplied, not from the model. That division
|
|
10
10
|
* is the whole reason a generated component is safe to put in a page — the
|
|
11
|
-
* model decides
|
|
12
|
-
*
|
|
11
|
+
* model decides how the component reads, and the shop decides what is true
|
|
12
|
+
* about a product.
|
|
13
13
|
*/
|
|
14
14
|
export interface BlockRenderContext {
|
|
15
15
|
/** The host's catalog, keyed by SKU. Read-only: it is the caller's own map. */
|
package/dist/render-context.js
CHANGED
|
@@ -53,16 +53,15 @@ export function defaultFormatBundlePrice(bundle, locale) {
|
|
|
53
53
|
throw new TypeError(`price for bundle ${bundle.id} is ${String(bundle.price)}, not a finite number — ` +
|
|
54
54
|
'bundle objects must satisfy bundleSchema from @rudra-js/core');
|
|
55
55
|
}
|
|
56
|
+
let formatter;
|
|
56
57
|
try {
|
|
57
|
-
|
|
58
|
-
style: 'currency',
|
|
59
|
-
currency: bundle.currency,
|
|
60
|
-
}).format(bundle.price);
|
|
58
|
+
formatter = new Intl.NumberFormat(locale, { style: 'currency', currency: bundle.currency });
|
|
61
59
|
}
|
|
62
60
|
catch {
|
|
63
61
|
// A bad locale, or a currency code Intl rejects on a hand-built bundle,
|
|
64
62
|
// should not crash the page. A price nobody can punctuate is still a price.
|
|
65
63
|
return `${bundle.currency} ${bundle.price}`;
|
|
66
64
|
}
|
|
65
|
+
return formatter.format(bundle.price);
|
|
67
66
|
}
|
|
68
67
|
//# sourceMappingURL=render-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-context.js","sourceRoot":"","sources":["../src/render-context.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,YAAY,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB,EAAE,MAAe;IAClE,4EAA4E;IAC5E,2EAA2E;IAC3E,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CACjB,iBAAiB,OAAO,CAAC,GAAG,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B;YAChF,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,SAA4B,CAAC;IACjC,IAAI,CAAC;QACH,2EAA2E;QAC3E,4EAA4E;QAC5E,mBAAmB;QACnB,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,yEAAyE;QACzE,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,4CAA4C;QAC5C,OAAO,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,MAAe;IACtE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,SAAS,CACjB,oBAAoB,MAAM,CAAC,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B;YAChF,8DAA8D,CACjE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,
|
|
1
|
+
{"version":3,"file":"render-context.js","sourceRoot":"","sources":["../src/render-context.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,YAAY,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB,EAAE,MAAe;IAClE,4EAA4E;IAC5E,2EAA2E;IAC3E,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CACjB,iBAAiB,OAAO,CAAC,GAAG,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B;YAChF,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,SAA4B,CAAC;IACjC,IAAI,CAAC;QACH,2EAA2E;QAC3E,4EAA4E;QAC5E,mBAAmB;QACnB,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,yEAAyE;QACzE,uEAAuE;QACvE,uEAAuE;QACvE,kEAAkE;QAClE,4CAA4C;QAC5C,OAAO,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,MAAe;IACtE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,SAAS,CACjB,oBAAoB,MAAM,CAAC,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B;YAChF,8DAA8D,CACjE,CAAC;IACJ,CAAC;IAED,IAAI,SAA4B,CAAC;IACjC,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9F,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,4EAA4E;QAC5E,OAAO,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;IAC9C,CAAC;IAED,OAAO,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rudra-js/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Renders a rudra component specification as React Server Components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"directory": "packages/react"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
|
26
|
-
"node": "
|
|
26
|
+
"node": ">=22.12.0"
|
|
27
27
|
},
|
|
28
28
|
"type": "module",
|
|
29
29
|
"main": "./dist/index.js",
|
|
@@ -51,13 +51,13 @@
|
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@rudra-js/core": "^0.
|
|
54
|
+
"@rudra-js/core": "^0.2.0",
|
|
55
55
|
"react": "^19.0.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@rudra-js/core": "0.1.0",
|
|
59
59
|
"@types/react": "^19.2.18",
|
|
60
|
-
"@types/react-dom": "^19.2.
|
|
60
|
+
"@types/react-dom": "^19.2.7",
|
|
61
61
|
"react": "^19.2.8",
|
|
62
62
|
"react-dom": "^19.2.8"
|
|
63
63
|
}
|
|
@@ -5,9 +5,9 @@ import type { BlockRenderContext } from '../render-context.js';
|
|
|
5
5
|
* One product.
|
|
6
6
|
*
|
|
7
7
|
* Every fact here — the title, the price, the image, the link — is read from
|
|
8
|
-
* the catalog, not from the specification. The
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* the catalog, not from the specification. The specification contributes only
|
|
9
|
+
* `reason`, `badge` and `emphasis`, and React escapes all three on the way
|
|
10
|
+
* into the markup.
|
|
11
11
|
*/
|
|
12
12
|
export function ProductCard({
|
|
13
13
|
reference,
|
package/src/render-context.ts
CHANGED
|
@@ -9,8 +9,8 @@ import type { Bundle, Product } from '@rudra-js/core';
|
|
|
9
9
|
* the model did not invent — both in stock at the time. A bundle member's SKU
|
|
10
10
|
* comes from the set the shop supplied, not from the model. That division
|
|
11
11
|
* is the whole reason a generated component is safe to put in a page — the
|
|
12
|
-
* model decides
|
|
13
|
-
*
|
|
12
|
+
* model decides how the component reads, and the shop decides what is true
|
|
13
|
+
* about a product.
|
|
14
14
|
*/
|
|
15
15
|
export interface BlockRenderContext {
|
|
16
16
|
/** The host's catalog, keyed by SKU. Read-only: it is the caller's own map. */
|
|
@@ -86,14 +86,14 @@ export function defaultFormatBundlePrice(bundle: Bundle, locale?: string): strin
|
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
let formatter: Intl.NumberFormat;
|
|
89
90
|
try {
|
|
90
|
-
|
|
91
|
-
style: 'currency',
|
|
92
|
-
currency: bundle.currency,
|
|
93
|
-
}).format(bundle.price);
|
|
91
|
+
formatter = new Intl.NumberFormat(locale, { style: 'currency', currency: bundle.currency });
|
|
94
92
|
} catch {
|
|
95
93
|
// A bad locale, or a currency code Intl rejects on a hand-built bundle,
|
|
96
94
|
// should not crash the page. A price nobody can punctuate is still a price.
|
|
97
95
|
return `${bundle.currency} ${bundle.price}`;
|
|
98
96
|
}
|
|
97
|
+
|
|
98
|
+
return formatter.format(bundle.price);
|
|
99
99
|
}
|