Skip to content

Commit 879cc68

Browse files
committed
feat: use html elements for typography
Html elements can completely replace legacy typography components. Here replace component templates with element templates as part of sdk.
1 parent 88c467c commit 879cc68

File tree

22 files changed

+148
-121
lines changed

22 files changed

+148
-121
lines changed

apps/builder/app/builder/features/components/components.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type Meta = {
5555
label: string;
5656
description: undefined | string;
5757
icon?: string;
58+
firstInstance: { component: string; tag?: string };
5859
};
5960

6061
const $metas = computed(
@@ -87,6 +88,7 @@ const $metas = computed(
8788
order: componentMeta.order,
8889
label: getInstanceLabel({ component: name }, componentMeta),
8990
description: componentMeta.description,
91+
firstInstance: { component: name },
9092
});
9193
}
9294
for (const [name, templateMeta] of templates) {
@@ -103,6 +105,7 @@ const $metas = computed(
103105
continue;
104106
}
105107

108+
availableComponents.add(name);
106109
metas.push({
107110
name,
108111
category: templateMeta.category ?? "hidden",
@@ -113,6 +116,7 @@ const $metas = computed(
113116
getInstanceLabel({ component: name }, templateMeta),
114117
description: templateMeta.description,
115118
icon: templateMeta.icon,
119+
firstInstance: templateMeta.template.instances[0],
116120
});
117121
}
118122
const metasByCategory = mapGroupBy(metas, (meta) => meta.category);
@@ -339,7 +343,7 @@ export const ComponentsPanel = ({
339343
icon={
340344
<InstanceIcon
341345
size="auto"
342-
instance={{ component: meta.name }}
346+
instance={meta.firstInstance}
343347
// for cases like Sheet template
344348
icon={meta.icon}
345349
/>

apps/builder/app/builder/features/settings-panel/controls/tag-control.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ export const TagControl = ({ meta, prop }: ControlProps<"tag">) => {
7979
>
8080
{options.length > 10 ? (
8181
<Combobox<string>
82-
defaultHighlightedIndex={0}
8382
getItems={() => options}
83+
itemToString={(item) => item ?? options[0]}
84+
value={value ?? computedTag}
85+
selectedItem={computedTag}
86+
onChange={(value) => setValue(value ?? undefined)}
8487
onItemSelect={(item) => {
8588
updateTag(item);
8689
setValue(undefined);
8790
}}
88-
itemToString={(item) => item ?? options[0]}
89-
value={value ?? computedTag}
90-
onChange={(value) => setValue(value ?? undefined)}
9191
getDescription={(item) => (
9292
<Box css={{ width: theme.spacing[28] }}>
9393
{elementsByTag[item ?? ""]?.description}

apps/builder/app/builder/features/settings-panel/controls/text-content.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import { useId, useMemo } from "react";
1+
import { useMemo } from "react";
22
import { useStore } from "@nanostores/react";
33
import { computed } from "nanostores";
4-
import { Flex, rawTheme, Text, TextArea } from "@webstudio-is/design-system";
4+
import {
5+
DialogClose,
6+
DialogMaximize,
7+
DialogTitle,
8+
DialogTitleActions,
9+
Flex,
10+
rawTheme,
11+
Text,
12+
} from "@webstudio-is/design-system";
513
import type { Instance } from "@webstudio-is/sdk";
614
import { AlertIcon } from "@webstudio-is/icons";
715
import { $instances } from "~/shared/nano-states";
@@ -10,6 +18,7 @@ import {
1018
BindingPopover,
1119
} from "~/builder/shared/binding-popover";
1220
import { updateWebstudioData } from "~/shared/instance-utils";
21+
import { CodeEditor } from "~/builder/shared/code-editor";
1322
import {
1423
type ControlProps,
1524
useLocalValue,
@@ -55,7 +64,6 @@ export const TextContent = ({
5564
updateChildren(instanceId, "text", value);
5665
}
5766
});
58-
const id = useId();
5967

6068
const { scope, aliases } = useStore($selectedInstanceScope);
6169
let expression: undefined | string;
@@ -107,15 +115,24 @@ export const TextContent = ({
107115
}
108116
>
109117
<BindingControl>
110-
<TextArea
111-
id={id}
112-
disabled={overwritable === false}
113-
autoGrow
118+
<CodeEditor
119+
title={
120+
<DialogTitle
121+
suffix={
122+
<DialogTitleActions>
123+
<DialogMaximize />
124+
<DialogClose />
125+
</DialogTitleActions>
126+
}
127+
>
128+
<Text variant="labelsTitleCase">Text Content</Text>
129+
</DialogTitle>
130+
}
131+
size="small"
132+
readOnly={overwritable === false}
114133
value={localValue.value}
115-
rows={1}
116134
onChange={localValue.set}
117-
onBlur={localValue.save}
118-
onSubmit={localValue.save}
135+
onChangeComplete={localValue.save}
119136
/>
120137
{expression !== undefined && (
121138
<BindingPopover

apps/builder/app/builder/shared/code-editor-base.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,17 @@ const editorContentStyle = css({
8181
boxSizing: "border-box",
8282
color: theme.colors.foregroundMain,
8383
borderRadius: theme.borderRadius[4],
84-
border: `1px solid ${theme.colors.borderMain}`,
84+
border: `1px solid transparent`,
8585
background: theme.colors.backgroundControls,
8686
paddingTop: 4,
8787
paddingBottom: 2,
8888
paddingRight: theme.spacing[2],
8989
paddingLeft: theme.spacing[3],
9090
// required to support copying selected text
9191
userSelect: "text",
92+
"&:hover": {
93+
borderColor: theme.colors.borderMain,
94+
},
9295
"&:focus-within": {
9396
borderColor: theme.colors.borderFocus,
9497
},

apps/builder/app/builder/shared/code-editor.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const wrapperStyle = css({
4343
variants: {
4444
size: {
4545
default: getMinMaxHeightVars({ minHeight: "160px", maxHeight: "320px" }),
46-
keyframe: getMinMaxHeightVars({ minHeight: "60px", maxHeight: "120px" }),
46+
small: getMinMaxHeightVars({ minHeight: "16px", maxHeight: "120px" }),
4747
},
4848
},
4949
defaultVariants: {
@@ -120,7 +120,7 @@ export const CodeEditor = forwardRef<
120120
Omit<ComponentProps<typeof EditorContent>, "extensions"> & {
121121
lang?: "html" | "markdown" | "css-properties";
122122
title?: ReactNode;
123-
size?: "default" | "keyframe";
123+
size?: "default" | "small";
124124
}
125125
>(({ lang, title, size, ...editorContentProps }, ref) => {
126126
const extensions = useMemo(() => {

apps/builder/app/builder/shared/instance-label.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
BodyIcon,
66
BoldIcon,
77
BoxIcon,
8+
BracesIcon,
89
ButtonElementIcon,
910
CalendarIcon,
1011
FormIcon,
@@ -42,6 +43,7 @@ const htmlIcons: Record<string, undefined | string> = {
4243
h6: HeadingIcon,
4344
p: TextAlignLeftIcon,
4445
blockquote: BlockquoteIcon,
46+
code: BracesIcon,
4547
ul: ListIcon,
4648
ol: ListIcon,
4749
li: ListItemIcon,

apps/builder/app/shared/content-model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ export const richTextPlaceholders: Map<undefined | string, string> = new Map([
422422
["h6", "Heading 6"],
423423
["p", "Paragraph"],
424424
["blockquote", "Blockquote"],
425+
["code", "Code Text"],
425426
["li", "List item"],
426427
["a", "Link"],
427428
["span", ""],

packages/html-data/bin/aria.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { aria } from "aria-query";
22
import { mkdir, writeFile } from "node:fs/promises";
33
import {
4+
coreMetas,
45
createScope,
56
elementComponent,
67
Prop,
@@ -152,12 +153,12 @@ await writeFile(
152153
generateWebstudioComponent({
153154
name: "Page",
154155
scope: createScope(),
156+
metas: new Map(Object.entries(coreMetas)),
155157
instances,
156158
props,
157159
dataSources: new Map(),
158160
rootInstanceId: instance.id,
159161
classesMap: new Map(),
160162
parameters: [],
161-
metas: new Map(),
162163
}) + "export { Page }"
163164
);

packages/html-data/bin/attributes.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { mkdir, writeFile } from "node:fs/promises";
22
import {
3+
coreMetas,
34
createScope,
45
elementComponent,
56
type Instance,
@@ -54,6 +55,9 @@ const overrides: Record<
5455
target: { required: true },
5556
download: { type: "boolean", required: true },
5657
},
58+
blockquote: {
59+
cite: { required: true },
60+
},
5761
form: {
5862
action: { required: true },
5963
method: { required: true },
@@ -263,13 +267,13 @@ await writeFile(
263267
generateWebstudioComponent({
264268
name: "Page",
265269
scope: createScope(),
270+
metas: new Map(Object.entries(coreMetas)),
266271
instances,
267272
props,
268273
dataSources: new Map(),
269274
rootInstanceId: body.id,
270275
classesMap: new Map(),
271276
parameters: [],
272-
metas: new Map(),
273277
}) + "export { Page }"
274278
);
275279

packages/html-data/src/__generated__/attributes.ts

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)