diff --git a/apps/builder/app/builder/features/style-panel/style-source-section.tsx b/apps/builder/app/builder/features/style-panel/style-source-section.tsx
index 28b4ef735a95..2fb316ab389f 100644
--- a/apps/builder/app/builder/features/style-panel/style-source-section.tsx
+++ b/apps/builder/app/builder/features/style-panel/style-source-section.tsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useStore } from "@nanostores/react";
import { nanoid } from "nanoid";
import { computed, type WritableAtom } from "nanostores";
+import { pseudoClassesByTag } from "@webstudio-is/html-data";
import {
type Instance,
type StyleSource,
@@ -41,6 +42,8 @@ import { removeByMutable } from "~/shared/array-utils";
import { cloneStyles } from "~/shared/tree-utils";
import { serverSyncStore } from "~/shared/sync";
import { $selectedInstance } from "~/shared/awareness";
+import { $instanceTags } from "./shared/model";
+import { humanizeString } from "~/shared/string-utils";
const selectStyleSource = (
styleSourceId: StyleSource["id"],
@@ -325,12 +328,26 @@ const clearStyles = (styleSourceId: StyleSource["id"]) => {
};
const $componentStates = computed(
- [$selectedInstance, $registeredComponentMetas],
- (selectedInstance, registeredComponentMetas) => {
+ [$selectedInstance, $registeredComponentMetas, $instanceTags],
+ (selectedInstance, registeredComponentMetas, instanceTags) => {
if (selectedInstance === undefined) {
return;
}
- return registeredComponentMetas.get(selectedInstance.component)?.states;
+ const tag = instanceTags.get(selectedInstance.id);
+ const tagStates = [
+ ...pseudoClassesByTag["*"],
+ ...(pseudoClassesByTag[tag ?? ""] ?? []),
+ ].map((state) => ({
+ category: "states" as const,
+ label: humanizeString(state),
+ selector: state,
+ }));
+ const meta = registeredComponentMetas.get(selectedInstance.component);
+ const componentStates = (meta?.states ?? []).map((item) => ({
+ category: "component-states" as const,
+ ...item,
+ }));
+ return [...tagStates, ...componentStates];
}
);
diff --git a/apps/builder/app/builder/features/style-panel/style-source/style-source-control.tsx b/apps/builder/app/builder/features/style-panel/style-source/style-source-control.tsx
index 9b7a39fbb32c..0ffe08314d14 100644
--- a/apps/builder/app/builder/features/style-panel/style-source/style-source-control.tsx
+++ b/apps/builder/app/builder/features/style-panel/style-source/style-source-control.tsx
@@ -98,7 +98,7 @@ const Menu = (props: MenuProps) => {
event.preventDefault()}
- css={{ maxWidth: theme.spacing[24] }}
+ css={{ maxWidth: theme.spacing[26] }}
>
{props.children}
diff --git a/apps/builder/app/builder/features/style-panel/style-source/style-source-input.tsx b/apps/builder/app/builder/features/style-panel/style-source/style-source-input.tsx
index 20134d9ff242..7aaca676d4cb 100644
--- a/apps/builder/app/builder/features/style-panel/style-source/style-source-input.tsx
+++ b/apps/builder/app/builder/features/style-panel/style-source/style-source-input.tsx
@@ -50,7 +50,6 @@ import {
useCallback,
} from "react";
import { mergeRefs } from "@react-aria/utils";
-import { type ComponentState, stateCategories } from "@webstudio-is/sdk";
import {
type ItemSource,
type StyleSourceError,
@@ -268,6 +267,17 @@ const TextFieldBase: ForwardRefRenderFunction<
const TextField = forwardRef(TextFieldBase);
TextField.displayName = "TextField";
+type ComponentState = {
+ category: "states" | "component-states";
+ selector: string;
+ label: string;
+};
+
+const categories = [
+ "states",
+ "component-states",
+] satisfies ComponentState["category"][];
+
type StyleSourceInputProps- = {
$styleSourceInputElement: WritableAtom;
error?: StyleSourceError;
@@ -417,9 +427,9 @@ const renderMenuItems = (props: {
)}
- {stateCategories.map((currentCategory) => {
+ {categories.map((currentCategory) => {
const categoryStates = props.states.filter(
- ({ category }) => (category ?? "states") === currentCategory
+ ({ category }) => category === currentCategory
);
// prevent rendering empty category
if (categoryStates.length === 0) {
diff --git a/packages/html-data/src/index.ts b/packages/html-data/src/index.ts
index 04e2535ca47c..abd0c7bb3832 100644
--- a/packages/html-data/src/index.ts
+++ b/packages/html-data/src/index.ts
@@ -1,3 +1,4 @@
export * from "./__generated__/elements";
export * from "./__generated__/attributes";
export * from "./__generated__/aria";
+export * from "./pseudo-classes";
diff --git a/packages/html-data/src/pseudo-classes.ts b/packages/html-data/src/pseudo-classes.ts
new file mode 100644
index 000000000000..d1f1d3d48629
--- /dev/null
+++ b/packages/html-data/src/pseudo-classes.ts
@@ -0,0 +1,70 @@
+// https://drafts.csswg.org/selectors
+
+const location = [
+ // ':link',
+ ":visited",
+ // ':any-link',
+ // ':local-link',
+ // ':target',
+ // ':target-within',
+];
+
+const userAction = [":hover", ":focus-visible", ":focus-within", ":active"];
+
+const ability = [
+ // ":enabled",
+ ":disabled",
+];
+
+const validity = [
+ // ":valid",
+ ":invalid",
+ // ":user-valid",
+ ":user-invalid",
+];
+
+const required = [
+ ":required",
+ // ":optional"
+];
+
+export const pseudoClassesByTag: Record = {
+ "*": userAction,
+ a: [...location],
+ area: [...location],
+ button: [...ability],
+ label: [],
+ input: [
+ ":placeholder-shown",
+ // @todo temporary until proper pseudo elements support is added
+ "::placeholder",
+ ...ability,
+ ...validity,
+ ...required,
+ ":checked",
+ // ":indeterminate",
+ // :in-range
+ // :out-of-range
+ // ":open",
+ ],
+ textarea: [
+ ":placeholder-shown",
+ // @todo temporary until proper pseudo elements support is added
+ "::placeholder",
+ ...ability,
+ ...validity,
+ ...required,
+ ],
+ select: [
+ ...ability,
+ ...validity,
+ ...required,
+ // ":open"
+ ],
+ optgroup: [...ability],
+ option: [...ability, ":checked"],
+ fieldset: [...ability, ...validity],
+ progress: [":indeterminate"],
+ details: [":open"],
+ dialog: [":open"],
+};
diff --git a/packages/sdk-components-react-radix/src/accordion.ws.ts b/packages/sdk-components-react-radix/src/accordion.ws.ts
index 9699bb47cb94..2795935ac1f9 100644
--- a/packages/sdk-components-react-radix/src/accordion.ws.ts
+++ b/packages/sdk-components-react-radix/src/accordion.ws.ts
@@ -5,7 +5,7 @@ import {
TriggerIcon,
ContentIcon,
} from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { div, h3, button } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import { buttonReset } from "./shared/preset-styles";
@@ -74,14 +74,7 @@ export const metaAccordionTrigger: WsComponentMeta = {
category: "none",
children: ["instance", "rich-text"],
},
- states: [
- ...defaultStates,
- {
- category: "component-states",
- label: "Open",
- selector: "[data-state=open]",
- },
- ],
+ states: [{ label: "Open", selector: "[data-state=open]" }],
presetStyle: {
button: [button, buttonReset].flat(),
},
diff --git a/packages/sdk-components-react-radix/src/checkbox.ws.ts b/packages/sdk-components-react-radix/src/checkbox.ws.ts
index 73d1a34c62e9..2b6da74027f5 100644
--- a/packages/sdk-components-react-radix/src/checkbox.ws.ts
+++ b/packages/sdk-components-react-radix/src/checkbox.ws.ts
@@ -1,5 +1,5 @@
import { CheckboxCheckedIcon, TriggerIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { button, span } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import { buttonReset } from "./shared/preset-styles";
@@ -16,17 +16,8 @@ export const metaCheckbox: WsComponentMeta = {
descendants: [radix.CheckboxIndicator],
},
states: [
- ...defaultStates,
- {
- label: "Checked",
- selector: "[data-state=checked]",
- category: "component-states",
- },
- {
- label: "Unchecked",
- selector: "[data-state=unchecked]",
- category: "component-states",
- },
+ { label: "Checked", selector: "[data-state=checked]" },
+ { label: "Unchecked", selector: "[data-state=unchecked]" },
],
presetStyle: {
button: [button, buttonReset].flat(),
@@ -41,7 +32,6 @@ export const metaCheckboxIndicator: WsComponentMeta = {
category: "none",
children: ["instance", "rich-text"],
},
- states: defaultStates,
presetStyle: {
span,
},
diff --git a/packages/sdk-components-react-radix/src/dialog.ws.ts b/packages/sdk-components-react-radix/src/dialog.ws.ts
index 45579ea22d3d..ed71518c1f35 100644
--- a/packages/sdk-components-react-radix/src/dialog.ws.ts
+++ b/packages/sdk-components-react-radix/src/dialog.ws.ts
@@ -7,7 +7,7 @@ import {
TextIcon,
ButtonElementIcon,
} from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { div, button, h2, p } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import {
@@ -84,7 +84,6 @@ export const metaDialogClose: WsComponentMeta = {
category: "none",
children: ["instance", "rich-text"],
},
- states: defaultStates,
presetStyle: {
button: [buttonReset, button].flat(),
},
diff --git a/packages/sdk-components-react-radix/src/label.ws.ts b/packages/sdk-components-react-radix/src/label.ws.ts
index f16a81f81ca6..e2b60af24616 100644
--- a/packages/sdk-components-react-radix/src/label.ws.ts
+++ b/packages/sdk-components-react-radix/src/label.ws.ts
@@ -1,14 +1,11 @@
import { LabelIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { label } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/label.props";
export const meta: WsComponentMeta = {
icon: LabelIcon,
- states: defaultStates,
- presetStyle: {
- label,
- },
+ presetStyle: { label },
initialProps: ["id", "class", "for"],
props,
};
diff --git a/packages/sdk-components-react-radix/src/popover.ws.ts b/packages/sdk-components-react-radix/src/popover.ws.ts
index a76dfd12c87e..69c490ae7bab 100644
--- a/packages/sdk-components-react-radix/src/popover.ws.ts
+++ b/packages/sdk-components-react-radix/src/popover.ws.ts
@@ -4,7 +4,7 @@ import {
ContentIcon,
ButtonElementIcon,
} from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { button, div } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import {
@@ -57,7 +57,6 @@ export const metaPopoverClose: WsComponentMeta = {
category: "none",
children: ["instance", "rich-text"],
},
- states: defaultStates,
presetStyle: {
button: [buttonReset, button].flat(),
},
diff --git a/packages/sdk-components-react-radix/src/radio-group.ws.ts b/packages/sdk-components-react-radix/src/radio-group.ws.ts
index 7182bedc0c9e..ca81dd45802e 100644
--- a/packages/sdk-components-react-radix/src/radio-group.ws.ts
+++ b/packages/sdk-components-react-radix/src/radio-group.ws.ts
@@ -1,5 +1,5 @@
import { ItemIcon, RadioGroupIcon, TriggerIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { button, div, span } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import { buttonReset } from "./shared/preset-styles";
@@ -17,17 +17,8 @@ export const metaRadioGroup: WsComponentMeta = {
descendants: [radix.RadioGroupItem],
},
states: [
- ...defaultStates,
- {
- label: "Checked",
- selector: "[data-state=checked]",
- category: "component-states",
- },
- {
- label: "Unchecked",
- selector: "[data-state=unchecked]",
- category: "component-states",
- },
+ { label: "Checked", selector: "[data-state=checked]" },
+ { label: "Unchecked", selector: "[data-state=unchecked]" },
],
presetStyle: {
div,
@@ -43,7 +34,6 @@ export const metaRadioGroupItem: WsComponentMeta = {
children: ["instance"],
descendants: [radix.RadioGroupIndicator],
},
- states: defaultStates,
presetStyle: {
button: [button, buttonReset].flat(),
},
@@ -57,7 +47,6 @@ export const metaRadioGroupIndicator: WsComponentMeta = {
category: "none",
children: ["instance"],
},
- states: defaultStates,
presetStyle: {
span,
},
diff --git a/packages/sdk-components-react-radix/src/switch.ws.ts b/packages/sdk-components-react-radix/src/switch.ws.ts
index 615736ed8afc..da4cc43e5dee 100644
--- a/packages/sdk-components-react-radix/src/switch.ws.ts
+++ b/packages/sdk-components-react-radix/src/switch.ws.ts
@@ -1,5 +1,5 @@
import { SwitchIcon, TriggerIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { button, span } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import { buttonReset } from "./shared/preset-styles";
@@ -13,17 +13,8 @@ export const metaSwitch: WsComponentMeta = {
descendants: [radix.SwitchThumb],
},
states: [
- ...defaultStates,
- {
- label: "Checked",
- selector: "[data-state=checked]",
- category: "component-states",
- },
- {
- label: "Unchecked",
- selector: "[data-state=unchecked]",
- category: "component-states",
- },
+ { label: "Checked", selector: "[data-state=checked]" },
+ { label: "Unchecked", selector: "[data-state=unchecked]" },
],
presetStyle: {
button: [button, buttonReset].flat(),
@@ -39,17 +30,8 @@ export const metaSwitchThumb: WsComponentMeta = {
children: ["instance"],
},
states: [
- ...defaultStates,
- {
- label: "Checked",
- selector: "[data-state=checked]",
- category: "component-states",
- },
- {
- label: "Unchecked",
- selector: "[data-state=unchecked]",
- category: "component-states",
- },
+ { label: "Checked", selector: "[data-state=checked]" },
+ { label: "Unchecked", selector: "[data-state=unchecked]" },
],
presetStyle: {
span,
diff --git a/packages/sdk-components-react-radix/src/tabs.ws.ts b/packages/sdk-components-react-radix/src/tabs.ws.ts
index 0c211d441fd2..a35962114145 100644
--- a/packages/sdk-components-react-radix/src/tabs.ws.ts
+++ b/packages/sdk-components-react-radix/src/tabs.ws.ts
@@ -4,7 +4,7 @@ import {
TabsIcon,
TriggerIcon,
} from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { button, div } from "@webstudio-is/sdk/normalize.css";
import { radix } from "./shared/meta";
import { buttonReset } from "./shared/preset-styles";
@@ -45,14 +45,7 @@ export const metaTabsTrigger: WsComponentMeta = {
category: "none",
children: ["instance", "rich-text"],
},
- states: [
- ...defaultStates,
- {
- category: "component-states",
- label: "Active",
- selector: "[data-state=active]",
- },
- ],
+ states: [{ label: "Active", selector: "[data-state=active]" }],
presetStyle: {
button: [button, buttonReset].flat(),
},
diff --git a/packages/sdk-components-react/src/blockquote.ws.ts b/packages/sdk-components-react/src/blockquote.ws.ts
index ae83691bef06..9b5f4939cf28 100644
--- a/packages/sdk-components-react/src/blockquote.ws.ts
+++ b/packages/sdk-components-react/src/blockquote.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import type { defaultTag } from "./blockquote";
import { props } from "./__generated__/blockquote.props";
@@ -58,7 +54,6 @@ const presetStyle = {
} satisfies PresetStyle;
export const meta: WsComponentMeta = {
- states: defaultStates,
presetStyle,
initialProps: ["id", "class", "cite"],
props,
diff --git a/packages/sdk-components-react/src/body.ws.ts b/packages/sdk-components-react/src/body.ws.ts
index c8b16b20e5d2..f1117c651edd 100644
--- a/packages/sdk-components-react/src/body.ws.ts
+++ b/packages/sdk-components-react/src/body.ws.ts
@@ -1,29 +1,9 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { body } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/body.props";
-import type { defaultTag } from "./body";
-
-const presetStyle = {
- body: [
- ...body,
- {
- property: "-webkit-font-smoothing",
- value: { type: "keyword", value: "antialiased" },
- },
- {
- property: "-moz-osx-font-smoothing",
- value: { type: "keyword", value: "grayscale" },
- },
- ],
-} satisfies PresetStyle;
export const meta: WsComponentMeta = {
- states: defaultStates,
- presetStyle,
+ presetStyle: { body },
initialProps: ["id", "class"],
props,
};
diff --git a/packages/sdk-components-react/src/bold.ws.ts b/packages/sdk-components-react/src/bold.ws.ts
index 0fb6717162f9..f6717e748bdf 100644
--- a/packages/sdk-components-react/src/bold.ws.ts
+++ b/packages/sdk-components-react/src/bold.ws.ts
@@ -1,10 +1,9 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { b } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/bold.props";
export const meta: WsComponentMeta = {
label: "Bold Text",
- states: defaultStates,
presetStyle: { b },
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/box.ws.ts b/packages/sdk-components-react/src/box.ws.ts
index 918cd406de3e..e5c98e639151 100644
--- a/packages/sdk-components-react/src/box.ws.ts
+++ b/packages/sdk-components-react/src/box.ws.ts
@@ -1,4 +1,4 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import {
div,
address,
@@ -17,7 +17,6 @@ export const meta: WsComponentMeta = {
category: "general",
description:
"A container for content. By default this is a Div, but the tag can be changed in settings.",
- states: defaultStates,
presetStyle: {
div,
address,
diff --git a/packages/sdk-components-react/src/button.ws.ts b/packages/sdk-components-react/src/button.ws.ts
index 8b44d3d5e83a..66f94f96f445 100644
--- a/packages/sdk-components-react/src/button.ws.ts
+++ b/packages/sdk-components-react/src/button.ws.ts
@@ -1,23 +1,9 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { button } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/button.props";
-import type { defaultTag } from "./button";
-
-const presetStyle = {
- button,
-} satisfies PresetStyle;
export const meta: WsComponentMeta = {
- presetStyle,
- states: [
- ...defaultStates,
- { selector: ":disabled", label: "Disabled" },
- { selector: ":enabled", label: "Enabled" },
- ],
+ presetStyle: { button },
initialProps: ["id", "class", "type", "aria-label"],
props,
};
diff --git a/packages/sdk-components-react/src/checkbox.ws.ts b/packages/sdk-components-react/src/checkbox.ws.ts
index 32dbdf3d0149..8287a50ba61c 100644
--- a/packages/sdk-components-react/src/checkbox.ws.ts
+++ b/packages/sdk-components-react/src/checkbox.ws.ts
@@ -1,9 +1,5 @@
import { CheckboxCheckedIcon } from "@webstudio-is/icons/svg";
-import {
- type WsComponentMeta,
- type PresetStyle,
- defaultStates,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta, PresetStyle } from "@webstudio-is/sdk";
import { checkbox } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./checkbox";
import { props } from "./__generated__/checkbox.props";
@@ -21,16 +17,6 @@ const presetStyle = {
export const meta: WsComponentMeta = {
icon: CheckboxCheckedIcon,
presetStyle,
- states: [
- ...defaultStates,
- { selector: ":checked", label: "Checked" },
- { selector: ":required", label: "Required" },
- { selector: ":optional", label: "Optional" },
- { selector: ":disabled", label: "Disabled" },
- { selector: ":enabled", label: "Enabled" },
- { selector: ":read-only", label: "Read Only" },
- { selector: ":read-write", label: "Read Write" },
- ],
initialProps: ["id", "class", "name", "value", "required", "checked"],
props,
};
diff --git a/packages/sdk-components-react/src/code-text.ws.ts b/packages/sdk-components-react/src/code-text.ws.ts
index 9221be12e72d..b492f6d05123 100644
--- a/packages/sdk-components-react/src/code-text.ws.ts
+++ b/packages/sdk-components-react/src/code-text.ws.ts
@@ -1,9 +1,5 @@
import { BracesIcon } from "@webstudio-is/icons/svg";
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { code } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./code-text";
import { props } from "./__generated__/code-text.props";
@@ -44,7 +40,6 @@ export const meta: WsComponentMeta = {
category: "instance",
children: [],
},
- states: defaultStates,
presetStyle,
initialProps: ["id", "class", "lang", "code"],
props: {
diff --git a/packages/sdk-components-react/src/form.ws.ts b/packages/sdk-components-react/src/form.ws.ts
index 0b78c2d982a4..d156e2ebf628 100644
--- a/packages/sdk-components-react/src/form.ws.ts
+++ b/packages/sdk-components-react/src/form.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { form } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./form";
import { props } from "./__generated__/form.props";
@@ -18,7 +14,6 @@ export const meta: WsComponentMeta = {
category: "forms",
label: "Form",
description: "Create filters, surveys, searches and more.",
- states: defaultStates,
presetStyle,
order: 0,
initialProps: ["id", "class", "action"],
diff --git a/packages/sdk-components-react/src/heading.ws.ts b/packages/sdk-components-react/src/heading.ws.ts
index 7f5ea714d35a..d7c52e5eaf93 100644
--- a/packages/sdk-components-react/src/heading.ws.ts
+++ b/packages/sdk-components-react/src/heading.ws.ts
@@ -1,9 +1,8 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { h1, h2, h3, h4, h5, h6 } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/heading.props";
export const meta: WsComponentMeta = {
- states: defaultStates,
presetStyle: {
h1,
h2,
diff --git a/packages/sdk-components-react/src/image.ws.ts b/packages/sdk-components-react/src/image.ws.ts
index 9a1d3665a0a1..4da1c2164f9c 100644
--- a/packages/sdk-components-react/src/image.ws.ts
+++ b/packages/sdk-components-react/src/image.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { img } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./image";
import { props } from "./__generated__/image.props";
@@ -36,7 +32,6 @@ export const meta: WsComponentMeta = {
category: "media",
description:
"Add an image asset to the page. Webstudio automatically converts images to WebP or AVIF format and makes them responsive for best performance.",
- states: defaultStates,
presetStyle,
order: 0,
initialProps: [
diff --git a/packages/sdk-components-react/src/input.ws.ts b/packages/sdk-components-react/src/input.ws.ts
index d71fb9d01204..3581a03f8833 100644
--- a/packages/sdk-components-react/src/input.ws.ts
+++ b/packages/sdk-components-react/src/input.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { input } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./input";
import { props } from "./__generated__/input.props";
@@ -24,19 +20,6 @@ export const meta: WsComponentMeta = {
"A single-line text input for collecting string data from your users.",
presetStyle,
order: 3,
- states: [
- ...defaultStates,
- { selector: "::placeholder", label: "Placeholder" },
- { selector: ":valid", label: "Valid" },
- { selector: ":invalid", label: "Invalid" },
- { selector: ":required", label: "Required" },
- { selector: ":optional", label: "Optional" },
- // Additional states will go into submenu
- //{ selector: ":disabled", label: "Disabled" },
- //{ selector: ":enabled", label: "Enabled" },
- //{ selector: ":read-only", label: "Read Only" },
- //{ selector: ":read-write", label: "Read Write" },
- ],
initialProps: [
"id",
"class",
diff --git a/packages/sdk-components-react/src/italic.ws.ts b/packages/sdk-components-react/src/italic.ws.ts
index b9074c286685..9da086ef39ab 100644
--- a/packages/sdk-components-react/src/italic.ws.ts
+++ b/packages/sdk-components-react/src/italic.ws.ts
@@ -1,26 +1,10 @@
-import type { defaultTag } from "./italic";
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { i } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/italic.props";
-const presetStyle = {
- i: [
- ...i,
- {
- property: "font-style",
- value: { type: "keyword", value: "italic" },
- },
- ],
-} satisfies PresetStyle;
-
export const meta: WsComponentMeta = {
label: "Italic Text",
- states: defaultStates,
- presetStyle,
+ presetStyle: { i },
initialProps: ["id", "class"],
props,
};
diff --git a/packages/sdk-components-react/src/label.ws.ts b/packages/sdk-components-react/src/label.ws.ts
index cba9e5577517..a9e1f4c25456 100644
--- a/packages/sdk-components-react/src/label.ws.ts
+++ b/packages/sdk-components-react/src/label.ws.ts
@@ -1,8 +1,4 @@
-import {
- type WsComponentMeta,
- type PresetStyle,
- defaultStates,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta, PresetStyle } from "@webstudio-is/sdk";
import { label } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/label.props";
import type { defaultTag } from "./label";
@@ -16,7 +12,6 @@ const presetStyle = {
export const meta: WsComponentMeta = {
label: "Input Label",
- states: defaultStates,
presetStyle,
initialProps: ["id", "class", "for"],
props,
diff --git a/packages/sdk-components-react/src/link.ws.ts b/packages/sdk-components-react/src/link.ws.ts
index 20b2a1b3d563..0de9f2b5ab0d 100644
--- a/packages/sdk-components-react/src/link.ws.ts
+++ b/packages/sdk-components-react/src/link.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { a } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./link";
import { props } from "./__generated__/link.props";
@@ -19,18 +15,7 @@ const presetStyle = {
export const meta: WsComponentMeta = {
presetStyle,
- states: [
- ...defaultStates,
- {
- selector: ":visited",
- label: "Visited",
- },
- {
- category: "component-states",
- selector: "[aria-current=page]",
- label: "Current page",
- },
- ],
+ states: [{ label: "Current page", selector: "[aria-current=page]" }],
initialProps: ["id", "class", "href", "target", "prefetch", "download"],
props: {
...props,
diff --git a/packages/sdk-components-react/src/list-item.ws.ts b/packages/sdk-components-react/src/list-item.ws.ts
index 198e8727cfde..6c7248a6aef2 100644
--- a/packages/sdk-components-react/src/list-item.ws.ts
+++ b/packages/sdk-components-react/src/list-item.ws.ts
@@ -1,9 +1,8 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { li } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/list-item.props";
export const meta: WsComponentMeta = {
- states: defaultStates,
presetStyle: { li },
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/list.ws.ts b/packages/sdk-components-react/src/list.ws.ts
index 53388a9fe1f9..6a685d94397b 100644
--- a/packages/sdk-components-react/src/list.ws.ts
+++ b/packages/sdk-components-react/src/list.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { ol, ul } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/list.props";
import type { ListTag } from "./list";
@@ -41,7 +37,6 @@ const presetStyle = {
} satisfies PresetStyle;
export const meta: WsComponentMeta = {
- states: defaultStates,
presetStyle,
initialProps: ["id", "class", "ordered", "start", "reversed"],
props,
diff --git a/packages/sdk-components-react/src/paragraph.ws.ts b/packages/sdk-components-react/src/paragraph.ws.ts
index ef8514aa3b20..0aa2c38e5ad1 100644
--- a/packages/sdk-components-react/src/paragraph.ws.ts
+++ b/packages/sdk-components-react/src/paragraph.ws.ts
@@ -1,9 +1,8 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { p } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/paragraph.props";
export const meta: WsComponentMeta = {
- states: defaultStates,
presetStyle: { p },
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/radio-button.ws.ts b/packages/sdk-components-react/src/radio-button.ws.ts
index a026b36b2584..8ae3c8483ced 100644
--- a/packages/sdk-components-react/src/radio-button.ws.ts
+++ b/packages/sdk-components-react/src/radio-button.ws.ts
@@ -1,9 +1,5 @@
import { RadioCheckedIcon } from "@webstudio-is/icons/svg";
-import {
- type WsComponentMeta,
- type PresetStyle,
- defaultStates,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta, PresetStyle } from "@webstudio-is/sdk";
import type { defaultTag } from "./radio-button";
import { radio } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/radio-button.props";
@@ -22,17 +18,6 @@ export const meta: WsComponentMeta = {
label: "Radio",
icon: RadioCheckedIcon,
presetStyle,
- states: [
- ...defaultStates,
- { selector: ":checked", label: "Checked" },
- { selector: ":required", label: "Required" },
- { selector: ":optional", label: "Optional" },
- // Additional states will go into submenu
- //{ selector: ":disabled", label: "Disabled" },
- //{ selector: ":enabled", label: "Enabled" },
- //{ selector: ":read-only", label: "Read Only" },
- //{ selector: ":read-write", label: "Read Write" },
- ],
initialProps: ["id", "class", "name", "value", "required", "checked"],
props,
};
diff --git a/packages/sdk-components-react/src/select.ws.ts b/packages/sdk-components-react/src/select.ws.ts
index b5ebf1312071..76e1ab177e43 100644
--- a/packages/sdk-components-react/src/select.ws.ts
+++ b/packages/sdk-components-react/src/select.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { select } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./select";
import { props } from "./__generated__/select.props";
@@ -19,14 +15,6 @@ const presetStyle = {
export const meta: WsComponentMeta = {
presetStyle,
- states: [
- ...defaultStates,
- { selector: "::placeholder", label: "Placeholder" },
- { selector: ":valid", label: "Valid" },
- { selector: ":invalid", label: "Invalid" },
- { selector: ":required", label: "Required" },
- { selector: ":optional", label: "Optional" },
- ],
initialProps: [
"id",
"class",
diff --git a/packages/sdk-components-react/src/separator.ws.ts b/packages/sdk-components-react/src/separator.ws.ts
index 6e7d8aeccab7..008ef8d70f19 100644
--- a/packages/sdk-components-react/src/separator.ws.ts
+++ b/packages/sdk-components-react/src/separator.ws.ts
@@ -1,8 +1,4 @@
-import {
- defaultStates,
- type PresetStyle,
- type WsComponentMeta,
-} from "@webstudio-is/sdk";
+import type { PresetStyle, WsComponentMeta } from "@webstudio-is/sdk";
import { hr } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/separator.props";
import type { defaultTag } from "./separator";
@@ -38,7 +34,6 @@ const presetStyle = {
} satisfies PresetStyle;
export const meta: WsComponentMeta = {
- states: defaultStates,
presetStyle,
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/span.ws.ts b/packages/sdk-components-react/src/span.ws.ts
index fbdd0ad2584c..c435dcb0da02 100644
--- a/packages/sdk-components-react/src/span.ws.ts
+++ b/packages/sdk-components-react/src/span.ws.ts
@@ -1,12 +1,11 @@
import { PaintBrushIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { span } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/span.props";
export const meta: WsComponentMeta = {
label: "Text",
icon: PaintBrushIcon,
- states: defaultStates,
presetStyle: { span },
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/subscript.ws.ts b/packages/sdk-components-react/src/subscript.ws.ts
index 72bae98fa767..b6eae30941f4 100644
--- a/packages/sdk-components-react/src/subscript.ws.ts
+++ b/packages/sdk-components-react/src/subscript.ws.ts
@@ -1,10 +1,9 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { sub } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/subscript.props";
export const meta: WsComponentMeta = {
label: "Subscript Text",
- states: defaultStates,
presetStyle: { sub },
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/superscript.ws.ts b/packages/sdk-components-react/src/superscript.ws.ts
index 4bcee0a23541..c62538989373 100644
--- a/packages/sdk-components-react/src/superscript.ws.ts
+++ b/packages/sdk-components-react/src/superscript.ws.ts
@@ -1,10 +1,9 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { sup } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/superscript.props";
export const meta: WsComponentMeta = {
label: "Superscript Text",
- states: defaultStates,
presetStyle: { sup },
initialProps: ["id", "class"],
props,
diff --git a/packages/sdk-components-react/src/text.ws.ts b/packages/sdk-components-react/src/text.ws.ts
index 1e5427781886..342bc0454bdc 100644
--- a/packages/sdk-components-react/src/text.ws.ts
+++ b/packages/sdk-components-react/src/text.ws.ts
@@ -1,11 +1,10 @@
import { TextIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { div } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/text.props";
export const meta: WsComponentMeta = {
icon: TextIcon,
- states: defaultStates,
presetStyle: {
div: [
...div,
diff --git a/packages/sdk-components-react/src/textarea.ws.ts b/packages/sdk-components-react/src/textarea.ws.ts
index 19ce31de8351..7dd4d4cac0b4 100644
--- a/packages/sdk-components-react/src/textarea.ws.ts
+++ b/packages/sdk-components-react/src/textarea.ws.ts
@@ -1,8 +1,4 @@
-import {
- type WsComponentMeta,
- type PresetStyle,
- defaultStates,
-} from "@webstudio-is/sdk";
+import type { WsComponentMeta, PresetStyle } from "@webstudio-is/sdk";
import { textarea } from "@webstudio-is/sdk/normalize.css";
import type { defaultTag } from "./textarea";
import { props } from "./__generated__/textarea.props";
@@ -30,19 +26,6 @@ export const meta: WsComponentMeta = {
category: "instance",
children: [],
},
- states: [
- ...defaultStates,
- { selector: "::placeholder", label: "Placeholder" },
- { selector: ":valid", label: "Valid" },
- { selector: ":invalid", label: "Invalid" },
- { selector: ":required", label: "Required" },
- { selector: ":optional", label: "Optional" },
- // Additional states will go into submenu
- //{ selector: ":disabled", label: "Disabled" },
- //{ selector: ":enabled", label: "Enabled" },
- //{ selector: ":read-only", label: "Read Only" },
- //{ selector: ":read-write", label: "Read Write" },
- ],
initialProps: [
"id",
"class",
diff --git a/packages/sdk-components-react/src/time.ws.ts b/packages/sdk-components-react/src/time.ws.ts
index 3a7ca160ab11..081b6ad514a0 100644
--- a/packages/sdk-components-react/src/time.ws.ts
+++ b/packages/sdk-components-react/src/time.ws.ts
@@ -1,4 +1,4 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { time } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/time.props";
@@ -10,7 +10,6 @@ export const meta: WsComponentMeta = {
category: "instance",
children: [],
},
- states: defaultStates,
presetStyle: {
time,
},
diff --git a/packages/sdk-components-react/src/vimeo-play-button.ws.ts b/packages/sdk-components-react/src/vimeo-play-button.ws.ts
index 0647f58cd9c1..093b5dc59ca1 100644
--- a/packages/sdk-components-react/src/vimeo-play-button.ws.ts
+++ b/packages/sdk-components-react/src/vimeo-play-button.ws.ts
@@ -1,4 +1,4 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { ButtonElementIcon } from "@webstudio-is/icons/svg";
import { button } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/vimeo-play-button.props";
@@ -7,7 +7,6 @@ export const meta: WsComponentMeta = {
category: "hidden",
label: "Play Button",
icon: ButtonElementIcon,
- states: defaultStates,
contentModel: {
category: "none",
children: ["instance"],
diff --git a/packages/sdk-components-react/src/vimeo-spinner.ws.ts b/packages/sdk-components-react/src/vimeo-spinner.ws.ts
index f91d67b93cc9..340969725e4d 100644
--- a/packages/sdk-components-react/src/vimeo-spinner.ws.ts
+++ b/packages/sdk-components-react/src/vimeo-spinner.ws.ts
@@ -1,11 +1,10 @@
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { div } from "@webstudio-is/sdk/normalize.css";
import { BoxIcon } from "@webstudio-is/icons/svg";
import { props } from "./__generated__/vimeo-spinner.props";
export const meta: WsComponentMeta = {
icon: BoxIcon,
- states: defaultStates,
category: "hidden",
label: "Spinner",
contentModel: {
diff --git a/packages/sdk-components-react/src/vimeo.ws.ts b/packages/sdk-components-react/src/vimeo.ws.ts
index 8bc257a8e976..ff304fc7bd28 100644
--- a/packages/sdk-components-react/src/vimeo.ws.ts
+++ b/packages/sdk-components-react/src/vimeo.ws.ts
@@ -1,6 +1,6 @@
import type { ComponentProps } from "react";
import { VimeoIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { div } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/vimeo.props";
import type { Vimeo } from "./vimeo";
@@ -27,7 +27,6 @@ const initialProps: Array> = [
export const meta: WsComponentMeta = {
icon: VimeoIcon,
- states: defaultStates,
contentModel: {
category: "instance",
children: ["instance"],
diff --git a/packages/sdk-components-react/src/youtube.ws.ts b/packages/sdk-components-react/src/youtube.ws.ts
index 3eb03b2c25a6..ece717201b4b 100644
--- a/packages/sdk-components-react/src/youtube.ws.ts
+++ b/packages/sdk-components-react/src/youtube.ws.ts
@@ -1,6 +1,6 @@
import type { ComponentProps } from "react";
import { YoutubeIcon } from "@webstudio-is/icons/svg";
-import { defaultStates, type WsComponentMeta } from "@webstudio-is/sdk";
+import type { WsComponentMeta } from "@webstudio-is/sdk";
import { div } from "@webstudio-is/sdk/normalize.css";
import { props } from "./__generated__/youtube.props";
import type { YouTube } from "./youtube";
@@ -37,7 +37,6 @@ const initialProps: Array> = [
export const meta: WsComponentMeta = {
icon: YoutubeIcon,
- states: defaultStates,
contentModel: {
category: "instance",
children: ["instance"],
diff --git a/packages/sdk/src/__generated__/normalize.css.ts b/packages/sdk/src/__generated__/normalize.css.ts
index eef4c853a3d8..9a354d1a28c0 100644
--- a/packages/sdk/src/__generated__/normalize.css.ts
+++ b/packages/sdk/src/__generated__/normalize.css.ts
@@ -128,6 +128,14 @@ export const body: StyleDecl[] = [
property: "border-left-width",
value: { type: "unit", unit: "px", value: 1 },
},
+ {
+ property: "-webkit-font-smoothing",
+ value: { type: "keyword", value: "antialiased" },
+ },
+ {
+ property: "-moz-osx-font-smoothing",
+ value: { type: "keyword", value: "grayscale" },
+ },
];
export const hr: StyleDecl[] = [
diff --git a/packages/sdk/src/normalize.css b/packages/sdk/src/normalize.css
index 3311d7f4a3fd..96185b8198dd 100644
--- a/packages/sdk/src/normalize.css
+++ b/packages/sdk/src/normalize.css
@@ -92,6 +92,8 @@ body {
/* webstudio custom opinionated presets */
box-sizing: border-box;
border-width: 1px;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
/**
diff --git a/packages/sdk/src/schema/component-meta.ts b/packages/sdk/src/schema/component-meta.ts
index f249f7a49bc0..411d1dcd037b 100644
--- a/packages/sdk/src/schema/component-meta.ts
+++ b/packages/sdk/src/schema/component-meta.ts
@@ -35,24 +35,13 @@ export const componentCategories = [
"internal",
] as const;
-export const stateCategories = ["states", "component-states"] as const;
-
export const ComponentState = z.object({
- category: z.enum(stateCategories).optional(),
selector: z.string(),
label: z.string(),
});
export type ComponentState = z.infer;
-export const defaultStates: ComponentState[] = [
- { selector: ":hover", label: "Hover" },
- { selector: ":active", label: "Active" },
- { selector: ":focus", label: "Focus" },
- { selector: ":focus-visible", label: "Focus Visible" },
- { selector: ":focus-within", label: "Focus Within" },
-];
-
/**
* rich-text - can be edited as rich text
* instance - other instances accepted