Skip to content

Commit 8a89f8e

Browse files
authored
refactor: rewrite radix label template with jsx (#4665)
- added radix templates to components panel - support interpolations in css tagged template - added theme with static values
1 parent 58a339e commit 8a89f8e

File tree

10 files changed

+132
-23
lines changed

10 files changed

+132
-23
lines changed

apps/builder/app/canvas/canvas.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import * as baseComponentTemplates from "@webstudio-is/sdk-components-react/temp
1717
import * as radixComponents from "@webstudio-is/sdk-components-react-radix";
1818
import * as radixComponentMetas from "@webstudio-is/sdk-components-react-radix/metas";
1919
import * as radixComponentPropsMetas from "@webstudio-is/sdk-components-react-radix/props";
20+
import * as radixTemplates from "@webstudio-is/sdk-components-react-radix/templates";
2021
import { hooks as radixComponentHooks } from "@webstudio-is/sdk-components-react-radix/hooks";
2122
import { ErrorMessage } from "~/shared/error";
2223
import { $publisher, publish } from "~/shared/pubsub";
@@ -244,7 +245,7 @@ export const Canvas = () => {
244245
metas: radixComponentMetas,
245246
propsMetas: radixComponentPropsMetas,
246247
hooks: radixComponentHooks,
247-
templates: {},
248+
templates: radixTemplates,
248249
});
249250
});
250251

packages/sdk-components-react-radix/package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@
3232
"webstudio": "./src/hooks.ts",
3333
"types": "./lib/types/hooks.d.ts",
3434
"import": "./lib/hooks.js"
35+
},
36+
"./templates": {
37+
"webstudio": "./src/templates.ts",
38+
"types": "./lib/types/templates.d.ts",
39+
"import": "./lib/templates.js"
3540
}
3641
},
3742
"scripts": {
3843
"build": "vite build --config ../../vite.sdk-components.config.ts",
3944
"build:args": "NODE_OPTIONS=--conditions=webstudio generate-arg-types './src/*.tsx !./src/*.stories.tsx !./src/*.ws.ts !./src/*.test.{ts,tsx}' -e asChild -e modal -e defaultOpen -e defaultChecked && prettier --write \"**/*.props.ts\"",
40-
"build:tailwind": "tsx scripts/generate-tailwind-theme.ts && prettier --write src/theme/__generated__",
45+
"build:tailwind": "tsx --conditions=webstudio scripts/generate-tailwind-theme.ts && prettier --write src/theme/__generated__",
4146
"build:stories": "webstudio-sdk generate-stories && prettier --write \"src/__generated__/*.stories.tsx\"",
4247
"dts": "tsc --project tsconfig.dts.json",
4348
"typecheck": "tsc"
@@ -73,6 +78,7 @@
7378
"@webstudio-is/generate-arg-types": "workspace:*",
7479
"@webstudio-is/sdk-cli": "workspace:^",
7580
"@webstudio-is/sdk-components-react": "workspace:*",
81+
"@webstudio-is/template": "workspace:*",
7682
"@webstudio-is/tsconfig": "workspace:*",
7783
"react": "18.3.0-canary-14898b6a9-20240318",
7884
"react-dom": "18.3.0-canary-14898b6a9-20240318",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {
2+
css,
3+
PlaceholderValue,
4+
type TemplateMeta,
5+
} from "@webstudio-is/template";
6+
import { radix } from "./shared/proxy";
7+
import { fontSize, lineHeight, weights } from "./shared/theme";
8+
9+
export const meta: TemplateMeta = {
10+
category: "radix",
11+
description:
12+
"An accessible label to describe the purpose of an input. Match the “For” property on the label with the “ID” of the input to connect them.",
13+
order: 102,
14+
template: (
15+
<radix.Label
16+
// text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70
17+
// We are not supporting peer like styles yet
18+
ws:style={css`
19+
font-size: ${fontSize.sm};
20+
line-height: ${lineHeight.none};
21+
font-weight: ${weights.medium};
22+
`}
23+
>
24+
{new PlaceholderValue("Form Label")}
25+
</radix.Label>
26+
),
27+
};

packages/sdk-components-react-radix/src/label.ws.ts

-19
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,16 @@ import {
77
} from "@webstudio-is/react-sdk";
88
import { label } from "@webstudio-is/sdk/normalize.css";
99
import { props } from "./__generated__/label.props";
10-
import * as tc from "./theme/tailwind-classes";
1110

1211
const presetStyle = {
1312
label,
1413
} satisfies PresetStyle<"label">;
1514

1615
export const meta: WsComponentMeta = {
17-
category: "radix",
18-
order: 102,
1916
type: "container",
2017
icon: LabelIcon,
2118
presetStyle,
2219
states: defaultStates,
23-
description:
24-
"An accessible label to describe the purpose of an input. Match the “For” property on the label with the “ID” of the input to connect them.",
25-
template: [
26-
{
27-
type: "instance",
28-
component: "Label",
29-
styles: [
30-
// text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70
31-
tc.text("sm"),
32-
tc.font("medium"),
33-
tc.leading("none"),
34-
// We are not supporting peer like styles yet
35-
].flat(),
36-
children: [{ type: "text", value: "Form Label", placeholder: true }],
37-
},
38-
],
3920
};
4021

4122
export const propsMeta: WsComponentPropsMeta = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createProxy } from "@webstudio-is/template";
2+
3+
export const radix = createProxy("@webstudio-is/sdk-components-react-radix:");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
export const fontSize = {
2+
xs: "0.75rem",
3+
sm: "0.875rem",
4+
base: "1rem",
5+
lg: "1.125rem",
6+
xl: "1.25rem",
7+
"2xl": "1.5rem",
8+
"3xl": "1.875rem",
9+
"4xl": "2.25rem",
10+
"5xl": "3rem",
11+
"6xl": "3.75rem",
12+
"7xl": "4.5rem",
13+
"8xl": "6rem",
14+
"9xl": "8rem",
15+
} as const;
16+
17+
export const fontSizeLineHeight = {
18+
xs: "1rem",
19+
sm: "1.25rem",
20+
base: "1.5rem",
21+
lg: "1.75rem",
22+
xl: "1.75rem",
23+
"2xl": "2rem",
24+
"3xl": "2.25rem",
25+
"4xl": "2.5rem",
26+
"5xl": "1",
27+
"6xl": "1",
28+
"7xl": "1",
29+
"8xl": "1",
30+
"9xl": "1",
31+
} as const;
32+
33+
export const lineHeight = {
34+
"3": "0.75rem",
35+
"4": "1rem",
36+
"5": "1.25rem",
37+
"6": "1.5rem",
38+
"7": "1.75rem",
39+
"8": "2rem",
40+
"9": "2.25rem",
41+
"10": "2.5rem",
42+
none: "1",
43+
tight: "1.25",
44+
snug: "1.375",
45+
normal: "1.5",
46+
relaxed: "1.625",
47+
loose: "2",
48+
} as const;
49+
50+
export const weights = {
51+
thin: "100",
52+
extralight: "200",
53+
light: "300",
54+
normal: "400",
55+
medium: "500",
56+
semibold: "600",
57+
bold: "700",
58+
extrabold: "800",
59+
black: "900",
60+
} as const;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { meta as Label } from "./label.template";

packages/template/src/css.test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { expect, test } from "vitest";
2+
import { css } from "./css";
3+
4+
test("parse css", () => {
5+
expect(css`
6+
color: red;
7+
`).toEqual([
8+
{
9+
property: "color",
10+
value: { type: "keyword", value: "red" },
11+
},
12+
]);
13+
});
14+
15+
test("support interpolations in local styles", () => {
16+
expect(css`
17+
color: ${"red"};
18+
`).toEqual([
19+
{
20+
property: "color",
21+
value: { type: "keyword", value: "red" },
22+
},
23+
]);
24+
});

packages/template/src/css.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ export type TemplateStyleDecl = {
77
value: StyleValue;
88
};
99

10-
export const css = (strings: TemplateStringsArray): TemplateStyleDecl[] => {
11-
const cssString = `.styles{ ${strings.join()} }`;
10+
export const css = (
11+
strings: TemplateStringsArray,
12+
...values: string[]
13+
): TemplateStyleDecl[] => {
14+
const cssString = `.styles{ ${String.raw({ raw: strings }, ...values)} }`;
1215
const styles: TemplateStyleDecl[] = [];
1316
for (const { state, property, value } of parseCss(cssString)) {
1417
styles.push({ state, property, value });

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)