mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-09 14:03:33 +09:00
Migrate preset styles to array of declarations (#1531)
Before preset styles used `{ tag: { property: value } }` format. Now we
are switching to `{ tag: [{ state,property,value }] }` to support
specifying states in preset styles.
Same format will be used for embed template styles.
Here switched only format. States in preset styles not supported in
builder yet.
This commit is contained in:
1 parent
776ed3bedb
commit
2017153253
31 files changed
+561
-512
No files matched your search
@@ -168,7 +168,6 @@ test("compute inherited styles", () => {
|
||||
["2", "div"],
|
||||
["3", "div"],
|
||||
]),
|
||||
|
||||
cascadedBreakpointIds,
|
||||
selectedBreakpointId
|
||||
)
|
||||
|
||||
@@ -187,10 +187,9 @@ export const getCascadedInfo = (
|
||||
return cascadedStyle;
|
||||
};
|
||||
|
||||
export const getPresetStyle = (
|
||||
export const getInstanceComponent = (
|
||||
instances: Instances,
|
||||
instanceId: undefined | Instance["id"],
|
||||
tagName: HtmlTags
|
||||
instanceId: undefined | Instance["id"]
|
||||
) => {
|
||||
if (instanceId === undefined) {
|
||||
return;
|
||||
@@ -199,10 +198,22 @@ export const getPresetStyle = (
|
||||
if (instance === undefined) {
|
||||
return;
|
||||
}
|
||||
if (tagName === undefined) {
|
||||
return instance.component;
|
||||
};
|
||||
|
||||
export const getPresetStyleRule = (component: string, tagName: HtmlTags) => {
|
||||
const meta = getComponentMeta(component);
|
||||
const presetStyles = meta?.presetStyle?.[tagName];
|
||||
if (presetStyles === undefined) {
|
||||
return;
|
||||
}
|
||||
return getComponentMeta(instance.component)?.presetStyle?.[tagName];
|
||||
const presetStyle: Style = {};
|
||||
for (const styleDecl of presetStyles) {
|
||||
if (styleDecl.state === undefined) {
|
||||
presetStyle[styleDecl.property] = styleDecl.value;
|
||||
}
|
||||
}
|
||||
return presetStyle;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -236,16 +247,20 @@ export const getInheritedInfo = (
|
||||
|
||||
const tagName = selectedInstanceIntanceToTag.get(instanceId);
|
||||
|
||||
const component = getInstanceComponent(instances, instanceId);
|
||||
const presetStyle =
|
||||
tagName !== undefined
|
||||
? getPresetStyle(instances, ancestorInstance.id, tagName)
|
||||
tagName !== undefined && component !== undefined
|
||||
? getComponentMeta(component)?.presetStyle?.[tagName]
|
||||
: undefined;
|
||||
if (presetStyle) {
|
||||
for (const [styleProperty, styleValue] of Object.entries(presetStyle)) {
|
||||
if (inheritableProperties.has(styleProperty)) {
|
||||
inheritedStyle[styleProperty as StyleProperty] = {
|
||||
for (const styleDecl of presetStyle) {
|
||||
if (
|
||||
styleDecl.state === undefined &&
|
||||
inheritableProperties.has(styleDecl.property)
|
||||
) {
|
||||
inheritedStyle[styleDecl.property] = {
|
||||
instanceId: ancestorInstance.id,
|
||||
value: styleValue,
|
||||
value: styleDecl.value,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -256,6 +271,7 @@ export const getInheritedInfo = (
|
||||
for (const styleDecl of ancestorInstanceStyles) {
|
||||
if (
|
||||
styleDecl.breakpointId === breakpointId &&
|
||||
styleDecl.state === undefined &&
|
||||
inheritableProperties.has(styleDecl.property)
|
||||
) {
|
||||
inheritedStyle[styleDecl.property] = {
|
||||
@@ -405,10 +421,11 @@ export const useStyleInfo = () => {
|
||||
return;
|
||||
}
|
||||
const tagName = selectedInstanceIntanceToTag?.get(selectedInstanceId);
|
||||
|
||||
return tagName !== undefined
|
||||
? getPresetStyle(instances, selectedInstanceSelector?.[0], tagName)
|
||||
: undefined;
|
||||
const component = getInstanceComponent(instances, selectedInstanceId);
|
||||
if (tagName === undefined || component === undefined) {
|
||||
return;
|
||||
}
|
||||
return getPresetStyleRule(component, tagName);
|
||||
}, [instances, selectedInstanceSelector, selectedInstanceIntanceToTag]);
|
||||
|
||||
const styleInfoData = useMemo(() => {
|
||||
@@ -481,15 +498,16 @@ export const useInstanceStyleData = (
|
||||
const selectedBreakpointId = selectedBreakpoint?.id;
|
||||
|
||||
const presetStyle = useMemo(() => {
|
||||
const selectedInstanceId = instanceSelector?.[0];
|
||||
if (selectedInstanceId === undefined) {
|
||||
const instanceId = instanceSelector?.[0];
|
||||
if (instanceId === undefined) {
|
||||
return;
|
||||
}
|
||||
const tagName = selectedInstanceIntanceToTag?.get(selectedInstanceId);
|
||||
|
||||
return tagName !== undefined
|
||||
? getPresetStyle(instances, instanceSelector?.[0], tagName)
|
||||
: undefined;
|
||||
const tagName = selectedInstanceIntanceToTag?.get(instanceId);
|
||||
const component = getInstanceComponent(instances, instanceId);
|
||||
if (tagName === undefined || component === undefined) {
|
||||
return;
|
||||
}
|
||||
return getPresetStyleRule(component, tagName);
|
||||
}, [instances, instanceSelector, selectedInstanceIntanceToTag]);
|
||||
|
||||
const cascadedBreakpointIds = useMemo(
|
||||
|
||||
@@ -2,7 +2,8 @@ import { collapsedAttribute, idAttribute } from "@webstudio-is/react-sdk";
|
||||
import {
|
||||
getCascadedBreakpointIds,
|
||||
getCascadedInfo,
|
||||
getPresetStyle,
|
||||
getInstanceComponent,
|
||||
getPresetStyleRule,
|
||||
} from "~/builder/features/style-panel/shared/style-info";
|
||||
import {
|
||||
breakpointsStore,
|
||||
@@ -63,9 +64,10 @@ const getInstanceSize = (instanceId: string, tagName: HtmlTags | undefined) => {
|
||||
selectedBreakpointId
|
||||
);
|
||||
|
||||
const component = getInstanceComponent(instances, instanceId);
|
||||
const presetStyle =
|
||||
tagName !== undefined
|
||||
? getPresetStyle(instances, instanceId, tagName)
|
||||
tagName !== undefined && component !== undefined
|
||||
? getPresetStyleRule(component, tagName)
|
||||
: undefined;
|
||||
|
||||
const cascadedStyle = getCascadedInfo(stylesByInstanceId, instanceId, [
|
||||
@@ -228,7 +230,7 @@ export const setDataCollapsed = (instanceId: string, syncExec = false) => {
|
||||
* In that case we just check the subtree of parent/common ancestor of changed elements to find collapsed elements
|
||||
**/
|
||||
export const subscribeCollapsedToPubSub = () =>
|
||||
subscribe("sendStoreChanges", ({ source, changes }) => {
|
||||
subscribe("sendStoreChanges", ({ changes }) => {
|
||||
for (const change of changes) {
|
||||
if (change.namespace === "styleSourceSelections") {
|
||||
for (const patch of change.patches) {
|
||||
|
||||
@@ -5,13 +5,13 @@ import { useStore } from "@nanostores/react";
|
||||
import type { Assets } from "@webstudio-is/asset-uploader";
|
||||
import {
|
||||
collapsedAttribute,
|
||||
componentAttribute,
|
||||
getComponentMeta,
|
||||
getComponentNames,
|
||||
idAttribute,
|
||||
addGlobalRules,
|
||||
createImageValueTransformer,
|
||||
getParams,
|
||||
getPresetStyleRules,
|
||||
} from "@webstudio-is/react-sdk";
|
||||
import type { Instance, StyleDecl } from "@webstudio-is/project-build";
|
||||
import {
|
||||
@@ -137,15 +137,12 @@ export const GlobalStyles = () => {
|
||||
for (const component of getComponentNames()) {
|
||||
const meta = getComponentMeta(component);
|
||||
const presetStyle = meta?.presetStyle;
|
||||
if (presetStyle !== undefined) {
|
||||
for (const [tag, style] of Object.entries(presetStyle)) {
|
||||
presetStylesEngine.addStyleRule(
|
||||
`${tag}:where([${componentAttribute}=${component}])`,
|
||||
{
|
||||
style,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (presetStyle === undefined) {
|
||||
continue;
|
||||
}
|
||||
const rules = getPresetStyleRules(component, presetStyle);
|
||||
for (const [selector, style] of rules) {
|
||||
presetStylesEngine.addStyleRule(selector, { style });
|
||||
}
|
||||
}
|
||||
presetStylesEngine.render();
|
||||
|
||||
@@ -1,72 +1,62 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { BlockquoteIcon } from "@webstudio-is/icons";
|
||||
import type { defaultTag } from "./blockquote";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/blockquote.props";
|
||||
|
||||
const presetStyle = {
|
||||
blockquote: {
|
||||
marginTop: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
blockquote: [
|
||||
{
|
||||
property: "marginTop",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginRight: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginRight",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginBottom: {
|
||||
type: "unit",
|
||||
value: 10,
|
||||
unit: "px",
|
||||
{
|
||||
property: "marginBottom",
|
||||
value: { type: "unit", value: 10, unit: "px" },
|
||||
},
|
||||
marginLeft: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginLeft",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
|
||||
paddingTop: {
|
||||
type: "unit",
|
||||
value: 10,
|
||||
unit: "px",
|
||||
{
|
||||
property: "paddingTop",
|
||||
value: { type: "unit", value: 10, unit: "px" },
|
||||
},
|
||||
paddingBottom: {
|
||||
type: "unit",
|
||||
value: 10,
|
||||
unit: "px",
|
||||
{
|
||||
property: "paddingBottom",
|
||||
value: { type: "unit", value: 10, unit: "px" },
|
||||
},
|
||||
paddingLeft: {
|
||||
type: "unit",
|
||||
value: 20,
|
||||
unit: "px",
|
||||
{
|
||||
property: "paddingLeft",
|
||||
value: { type: "unit", value: 20, unit: "px" },
|
||||
},
|
||||
paddingRight: {
|
||||
type: "unit",
|
||||
value: 20,
|
||||
unit: "px",
|
||||
{
|
||||
property: "paddingRight",
|
||||
value: { type: "unit", value: 20, unit: "px" },
|
||||
},
|
||||
|
||||
borderLeftWidth: {
|
||||
type: "unit",
|
||||
value: 5,
|
||||
unit: "px",
|
||||
{
|
||||
property: "borderLeftWidth",
|
||||
value: { type: "unit", value: 5, unit: "px" },
|
||||
},
|
||||
borderLeftStyle: {
|
||||
type: "keyword",
|
||||
value: "solid",
|
||||
{
|
||||
property: "borderLeftStyle",
|
||||
value: { type: "keyword", value: "solid" },
|
||||
},
|
||||
|
||||
borderLeftColor: {
|
||||
type: "rgb",
|
||||
r: 226,
|
||||
g: 226,
|
||||
b: 226,
|
||||
alpha: 1,
|
||||
{
|
||||
property: "borderLeftColor",
|
||||
value: { type: "rgb", r: 226, g: 226, b: 226, alpha: 1 },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "typography",
|
||||
|
||||
@@ -1,38 +1,35 @@
|
||||
import { BodyIcon } from "@webstudio-is/icons";
|
||||
import { body } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/body.props";
|
||||
import type { defaultTag } from "./body";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
|
||||
const presetStyle = {
|
||||
body: {
|
||||
body: [
|
||||
...body,
|
||||
|
||||
minHeight: {
|
||||
type: "unit",
|
||||
unit: "%",
|
||||
value: 100,
|
||||
{
|
||||
property: "minHeight",
|
||||
value: { type: "unit", unit: "%", value: 100 },
|
||||
},
|
||||
|
||||
fontFamily: {
|
||||
type: "keyword",
|
||||
value: "Arial",
|
||||
{
|
||||
property: "fontFamily",
|
||||
value: { type: "keyword", value: "Arial" },
|
||||
},
|
||||
|
||||
fontSize: {
|
||||
type: "unit",
|
||||
unit: "px",
|
||||
value: 14,
|
||||
{
|
||||
property: "fontSize",
|
||||
value: { type: "unit", unit: "px", value: 14 },
|
||||
},
|
||||
|
||||
lineHeight: {
|
||||
type: "unit",
|
||||
unit: "number",
|
||||
value: 1.5,
|
||||
{
|
||||
property: "lineHeight",
|
||||
value: { type: "unit", unit: "number", value: 1.5 },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
type: "container",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { BoldIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/bold.props";
|
||||
import { b } from "../css/normalize";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import type { defaultTag } from "./bold";
|
||||
|
||||
const presetStyle = {
|
||||
b,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
type: "rich-text-child",
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { BoxIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/box.props";
|
||||
import type { Box } from "./box";
|
||||
import type { ComponentProps } from "react";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import {
|
||||
div,
|
||||
address,
|
||||
@@ -30,7 +33,7 @@ const presetStyle = {
|
||||
main,
|
||||
nav,
|
||||
section,
|
||||
} as const satisfies Record<BoxTags, Style>;
|
||||
} satisfies PresetStyle<BoxTags>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "general",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { ButtonElementIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import { props } from "./__generated__/button.props";
|
||||
import { button } from "../css/normalize";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/button.props";
|
||||
import type { defaultTag } from "./button";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
|
||||
const presetStyle = {
|
||||
button,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "forms",
|
||||
|
||||
@@ -1,44 +1,38 @@
|
||||
import { CodeIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { type defaultTag, displayVarNamespace } from "./code";
|
||||
import { props } from "./__generated__/code.props";
|
||||
import type { Style, StyleValue } from "@webstudio-is/css-data";
|
||||
import { code } from "../css/normalize";
|
||||
|
||||
const display: StyleValue = {
|
||||
type: "var",
|
||||
value: displayVarNamespace,
|
||||
fallbacks: [
|
||||
const presetStyle = {
|
||||
code: [
|
||||
...code,
|
||||
{
|
||||
type: "keyword",
|
||||
value: "inline-block",
|
||||
property: "display",
|
||||
value: {
|
||||
type: "var",
|
||||
value: displayVarNamespace,
|
||||
fallbacks: [{ type: "keyword", value: "inline-block" }],
|
||||
},
|
||||
},
|
||||
{
|
||||
property: "paddingLeft",
|
||||
value: { type: "unit", value: 0.2, unit: "em" },
|
||||
},
|
||||
{
|
||||
property: "paddingRight",
|
||||
value: { type: "unit", value: 0.2, unit: "em" },
|
||||
},
|
||||
{
|
||||
property: "backgroundColor",
|
||||
value: { type: "rgb", r: 238, g: 238, b: 238, alpha: 1 },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const presetStyle = {
|
||||
code: {
|
||||
...code,
|
||||
display,
|
||||
paddingLeft: {
|
||||
type: "unit",
|
||||
value: 0.2,
|
||||
unit: "em",
|
||||
},
|
||||
paddingRight: {
|
||||
type: "unit",
|
||||
value: 0.2,
|
||||
unit: "em",
|
||||
},
|
||||
backgroundColor: {
|
||||
type: "rgb",
|
||||
r: 238,
|
||||
g: 238,
|
||||
b: 238,
|
||||
alpha: 1,
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "general",
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { z } from "zod";
|
||||
import type { FunctionComponent } from "react";
|
||||
import type { IconProps } from "@webstudio-is/icons";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { PropMeta } from "@webstudio-is/generate-arg-types";
|
||||
import type { htmlTags as HtmlTags } from "html-tags";
|
||||
import { WsEmbedTemplate } from "../embed-template";
|
||||
import { EmbedTemplateStyleDecl, WsEmbedTemplate } from "../embed-template";
|
||||
|
||||
type PresetStyle = Partial<Record<HtmlTags, Style>>;
|
||||
export type PresetStyle<Tag extends HtmlTags = HtmlTags> = Partial<
|
||||
Record<Tag, EmbedTemplateStyleDecl[]>
|
||||
>;
|
||||
|
||||
// props are separated from the rest of the meta
|
||||
// so they can be exported separately and potentially tree-shaken
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { FormIcon } from "@webstudio-is/icons";
|
||||
import { form } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./form";
|
||||
import { props } from "./__generated__/form.props";
|
||||
|
||||
const presetStyle = {
|
||||
form: {
|
||||
form: [
|
||||
...form,
|
||||
minHeight: {
|
||||
type: "unit",
|
||||
unit: "px",
|
||||
value: 20,
|
||||
{
|
||||
property: "minHeight",
|
||||
value: { type: "unit", unit: "px", value: 20 },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "forms",
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { HeadingIcon } from "@webstudio-is/icons";
|
||||
import type { ComponentProps } from "react";
|
||||
import { h1, h2, h3, h4, h5, h6 } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { Heading } from "./heading";
|
||||
import { props } from "./__generated__/heading.props";
|
||||
|
||||
@@ -15,7 +18,7 @@ const presetStyle = {
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
} as const satisfies Record<HeadingTags, Style>;
|
||||
} satisfies PresetStyle<HeadingTags>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "typography",
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { ImageIcon } from "@webstudio-is/icons";
|
||||
import { img } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./image";
|
||||
import { props } from "./__generated__/image.props";
|
||||
|
||||
const presetStyle = {
|
||||
img: {
|
||||
img: [
|
||||
...img,
|
||||
|
||||
// Otherwise on new image insert onto canvas it can overfit screen size multiple times
|
||||
maxWidth: {
|
||||
type: "unit",
|
||||
unit: "%",
|
||||
value: 100,
|
||||
{
|
||||
property: "maxWidth",
|
||||
value: { type: "unit", unit: "%", value: 100 },
|
||||
},
|
||||
// inline | inline-block is not suitable because without line-height: 0 on the parent you get unsuitable spaces/margins
|
||||
// see https://stackoverflow.com/questions/24771194/is-the-margin-of-inline-block-4px-is-static-for-all-browsers
|
||||
display: {
|
||||
type: "keyword",
|
||||
value: "block",
|
||||
{
|
||||
property: "display",
|
||||
value: { type: "keyword", value: "block" },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "media",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { FormTextFieldIcon } from "@webstudio-is/icons";
|
||||
import { input } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./input";
|
||||
import { props } from "./__generated__/input.props";
|
||||
|
||||
const presetStyle = {
|
||||
input,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "forms",
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { TextItalicIcon } from "@webstudio-is/icons";
|
||||
import type { defaultTag } from "./italic";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/italic.props";
|
||||
import { i } from "../css/normalize";
|
||||
|
||||
const presetStyle = {
|
||||
i: {
|
||||
i: [
|
||||
...i,
|
||||
fontStyle: {
|
||||
type: "keyword",
|
||||
value: "italic",
|
||||
{
|
||||
property: "fontStyle",
|
||||
value: { type: "keyword", value: "italic" },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
type: "rich-text-child",
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { BoxLinkIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/link-block.props";
|
||||
import { meta as linkMeta, propsMeta as linkPropsMeta } from "./link.ws";
|
||||
import type { defaultTag } from "./link-block";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { a } from "../css/normalize";
|
||||
|
||||
const presetStyle = {
|
||||
a: {
|
||||
a: [
|
||||
...a,
|
||||
display: {
|
||||
type: "keyword",
|
||||
value: "inline-block",
|
||||
{
|
||||
property: "display",
|
||||
value: { type: "keyword", value: "inline-block" },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "general",
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { LinkIcon } from "@webstudio-is/icons";
|
||||
import { a } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./link";
|
||||
import { props } from "./__generated__/link.props";
|
||||
|
||||
const presetStyle = {
|
||||
a: {
|
||||
a: [
|
||||
...a,
|
||||
minHeight: {
|
||||
type: "unit",
|
||||
unit: "em",
|
||||
value: 1,
|
||||
{
|
||||
property: "minHeight",
|
||||
value: { type: "unit", unit: "em", value: 1 },
|
||||
},
|
||||
display: {
|
||||
type: "keyword",
|
||||
value: "inline-block",
|
||||
{
|
||||
property: "display",
|
||||
value: { type: "keyword", value: "inline-block" },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "general",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { ListItemIcon } from "@webstudio-is/icons";
|
||||
import { li } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./list-item";
|
||||
import { props } from "./__generated__/list-item.props";
|
||||
|
||||
const presetStyle = {
|
||||
li,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "typography",
|
||||
|
||||
@@ -1,42 +1,45 @@
|
||||
import { ListIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/list.props";
|
||||
import type { ListTag } from "./list";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { ol, ul } from "../css/normalize";
|
||||
|
||||
const presetStyle = {
|
||||
ol: {
|
||||
ol: [
|
||||
...ol,
|
||||
marginTop: {
|
||||
type: "keyword",
|
||||
value: "0",
|
||||
{
|
||||
property: "marginTop",
|
||||
value: { type: "keyword", value: "0" },
|
||||
},
|
||||
marginBottom: {
|
||||
type: "keyword",
|
||||
value: "10px",
|
||||
{
|
||||
property: "marginBottom",
|
||||
value: { type: "keyword", value: "10px" },
|
||||
},
|
||||
paddingLeft: {
|
||||
type: "keyword",
|
||||
value: "40px",
|
||||
{
|
||||
property: "paddingLeft",
|
||||
value: { type: "keyword", value: "40px" },
|
||||
},
|
||||
},
|
||||
ul: {
|
||||
],
|
||||
ul: [
|
||||
...ul,
|
||||
marginTop: {
|
||||
type: "keyword",
|
||||
value: "0",
|
||||
{
|
||||
property: "marginTop",
|
||||
value: { type: "keyword", value: "0" },
|
||||
},
|
||||
marginBottom: {
|
||||
type: "keyword",
|
||||
value: "10px",
|
||||
{
|
||||
property: "marginBottom",
|
||||
value: { type: "keyword", value: "10px" },
|
||||
},
|
||||
paddingLeft: {
|
||||
type: "keyword",
|
||||
value: "40px",
|
||||
{
|
||||
property: "paddingLeft",
|
||||
value: { type: "keyword", value: "40px" },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<ListTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<ListTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "typography",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { TextAlignLeftIcon } from "@webstudio-is/icons";
|
||||
import { p } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./paragraph";
|
||||
import { props } from "./__generated__/paragraph.props";
|
||||
|
||||
const presetStyle = {
|
||||
p,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "typography",
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
import { DashIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/separator.props";
|
||||
import type { defaultTag } from "./separator";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { hr } from "../css/normalize";
|
||||
|
||||
const presetStyle = {
|
||||
hr: {
|
||||
hr: [
|
||||
...hr,
|
||||
|
||||
height: {
|
||||
type: "keyword",
|
||||
value: "1px",
|
||||
{
|
||||
property: "height",
|
||||
value: { type: "keyword", value: "1px" },
|
||||
},
|
||||
|
||||
backgroundColor: {
|
||||
type: "keyword",
|
||||
value: "gray",
|
||||
{
|
||||
property: "backgroundColor",
|
||||
value: { type: "keyword", value: "gray" },
|
||||
},
|
||||
|
||||
borderTopStyle: {
|
||||
type: "keyword",
|
||||
value: "none",
|
||||
{
|
||||
property: "borderTopStyle",
|
||||
value: { type: "keyword", value: "none" },
|
||||
},
|
||||
borderRightStyle: {
|
||||
type: "keyword",
|
||||
value: "none",
|
||||
{
|
||||
property: "borderRightStyle",
|
||||
value: { type: "keyword", value: "none" },
|
||||
},
|
||||
borderLeftStyle: {
|
||||
type: "keyword",
|
||||
value: "none",
|
||||
{
|
||||
property: "borderLeftStyle",
|
||||
value: { type: "keyword", value: "none" },
|
||||
},
|
||||
borderBottomStyle: {
|
||||
type: "keyword",
|
||||
value: "none",
|
||||
{
|
||||
property: "borderBottomStyle",
|
||||
value: { type: "keyword", value: "none" },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "general",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { PaintBrushIcon } from "@webstudio-is/icons";
|
||||
import { span } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./span";
|
||||
import { props } from "./__generated__/span.props";
|
||||
|
||||
const presetStyle = {
|
||||
span,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
type: "rich-text-child",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { SubscriptIcon } from "@webstudio-is/icons";
|
||||
import { sub } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./subscript";
|
||||
import { props } from "./__generated__/subscript.props";
|
||||
|
||||
const presetStyle = {
|
||||
sub,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
type: "rich-text-child",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { SuperscriptIcon } from "@webstudio-is/icons";
|
||||
import { sup } from "../css/normalize";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import type { defaultTag } from "./superscript";
|
||||
import { props } from "./__generated__/superscript.props";
|
||||
|
||||
const presetStyle = {
|
||||
sup,
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
type: "rich-text-child",
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { TextBlockIcon } from "@webstudio-is/icons";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "./component-meta";
|
||||
import type {
|
||||
PresetStyle,
|
||||
WsComponentMeta,
|
||||
WsComponentPropsMeta,
|
||||
} from "./component-meta";
|
||||
import { props } from "./__generated__/text-block.props";
|
||||
import type { defaultTag } from "./text-block";
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import { div } from "../css/normalize";
|
||||
|
||||
const presetStyle = {
|
||||
div: {
|
||||
div: [
|
||||
...div,
|
||||
|
||||
minHeight: {
|
||||
type: "unit",
|
||||
unit: "em",
|
||||
value: 1,
|
||||
{
|
||||
property: "minHeight",
|
||||
value: { type: "unit", unit: "em", value: 1 },
|
||||
},
|
||||
},
|
||||
} as const satisfies Record<typeof defaultTag, Style>;
|
||||
],
|
||||
} satisfies PresetStyle<typeof defaultTag>;
|
||||
|
||||
export const meta: WsComponentMeta = {
|
||||
category: "typography",
|
||||
|
||||
@@ -3,9 +3,9 @@ import type { Asset, Assets } from "@webstudio-is/asset-uploader";
|
||||
import type { Build } from "@webstudio-is/project-build";
|
||||
import { getComponentNames } from "../components/components-utils";
|
||||
import { getComponentMeta } from "../components";
|
||||
import { componentAttribute, idAttribute } from "../tree";
|
||||
import { idAttribute } from "../tree";
|
||||
import { addGlobalRules } from "./global-rules";
|
||||
import { getStyleRules } from "./style-rules";
|
||||
import { getPresetStyleRules, getStyleRules } from "./style-rules";
|
||||
|
||||
type Data = {
|
||||
assets: Asset[];
|
||||
@@ -64,15 +64,12 @@ export const generateCssText = (data: Data, options: CssOptions) => {
|
||||
for (const component of getComponentNames()) {
|
||||
const meta = getComponentMeta(component);
|
||||
const presetStyle = meta?.presetStyle;
|
||||
if (presetStyle !== undefined) {
|
||||
for (const [tag, style] of Object.entries(presetStyle)) {
|
||||
engine.addStyleRule(
|
||||
`${tag}:where([${componentAttribute}=${component}])`,
|
||||
{
|
||||
style,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (presetStyle === undefined) {
|
||||
continue;
|
||||
}
|
||||
const rules = getPresetStyleRules(component, presetStyle);
|
||||
for (const [selector, style] of rules) {
|
||||
engine.addStyleRule(selector, { style });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,18 +15,17 @@
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
||||
*/
|
||||
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
|
||||
// webstudio custom opinionated presets
|
||||
import { borders } from "./presets";
|
||||
import type { EmbedTemplateStyleDecl } from "../embed-template";
|
||||
|
||||
/**
|
||||
Use a better box model (opinionated).
|
||||
*/
|
||||
const boxSizing = {
|
||||
type: "keyword",
|
||||
value: "border-box",
|
||||
} as const;
|
||||
property: "boxSizing",
|
||||
value: { type: "keyword", value: "border-box" },
|
||||
} satisfies EmbedTemplateStyleDecl;
|
||||
|
||||
/**
|
||||
* We dont support rules like this now, implement boxSizing for each used element
|
||||
@@ -36,10 +35,7 @@ const boxSizing = {
|
||||
* box-sizing: border-box;
|
||||
}
|
||||
*/
|
||||
const baseStyle = {
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
const baseStyle = [boxSizing, ...borders] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
export const div = baseStyle;
|
||||
export const address = baseStyle;
|
||||
@@ -78,83 +74,78 @@ export const span = baseStyle;
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size (opinionated).
|
||||
*/
|
||||
export const html = {
|
||||
export const html = [
|
||||
/* 1 */
|
||||
lineHeight: {
|
||||
type: "unit",
|
||||
value: 1.15,
|
||||
unit: "number",
|
||||
{
|
||||
property: "lineHeight",
|
||||
value: { type: "unit", value: 1.15, unit: "number" },
|
||||
},
|
||||
|
||||
/* 2 */
|
||||
textSizeAdjust: {
|
||||
type: "unit",
|
||||
value: 100,
|
||||
unit: "%",
|
||||
{
|
||||
property: "textSizeAdjust",
|
||||
value: { type: "unit", value: 100, unit: "%" },
|
||||
},
|
||||
|
||||
/* 3 */
|
||||
tabSize: {
|
||||
type: "unit",
|
||||
value: 4,
|
||||
unit: "number",
|
||||
{
|
||||
property: "tabSize",
|
||||
value: { type: "unit", value: 4, unit: "number" },
|
||||
},
|
||||
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/**
|
||||
1. Remove the margin in all browsers.
|
||||
2. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
|
||||
*/
|
||||
export const body = {
|
||||
export const body = [
|
||||
/* 1 */
|
||||
marginTop: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginTop",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginRight: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginRight",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginBottom: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginBottom",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginLeft: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginLeft",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
/* 2 */
|
||||
fontFamily: {
|
||||
type: "keyword",
|
||||
value: `system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'`,
|
||||
{
|
||||
property: "fontFamily",
|
||||
value: {
|
||||
type: "keyword",
|
||||
value: `system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'`,
|
||||
},
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/**
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
*/
|
||||
export const hr = {
|
||||
export const hr = [
|
||||
/* 1 */
|
||||
height: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "height",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
/* 2 */
|
||||
color: { type: "keyword", value: "inherit" },
|
||||
{
|
||||
property: "color",
|
||||
value: { type: "keyword", value: "inherit" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/**
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
@@ -169,35 +160,37 @@ abbr[title] {
|
||||
/**
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
export const b = {
|
||||
fontWeight: {
|
||||
type: "keyword",
|
||||
value: "bolder",
|
||||
export const b = [
|
||||
{
|
||||
property: "fontWeight",
|
||||
value: { type: "keyword", value: "bolder" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
export const strong = b;
|
||||
|
||||
/**
|
||||
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
|
||||
2. Correct the odd 'em' font sizing in all browsers.
|
||||
*/
|
||||
export const code = {
|
||||
export const code = [
|
||||
/* 1 */
|
||||
fontFamily: {
|
||||
type: "keyword",
|
||||
value: `ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace`,
|
||||
{
|
||||
property: "fontFamily",
|
||||
value: {
|
||||
type: "keyword",
|
||||
value: `ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace`,
|
||||
},
|
||||
},
|
||||
/* 2 */
|
||||
fontSize: {
|
||||
type: "unit",
|
||||
value: 1,
|
||||
unit: "em",
|
||||
{
|
||||
property: "fontSize",
|
||||
value: { type: "unit", value: 1, unit: "em" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
export const kbd = code;
|
||||
export const samp = code;
|
||||
@@ -207,60 +200,55 @@ export const pre = code;
|
||||
Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
export const small = {
|
||||
fontSize: {
|
||||
type: "unit",
|
||||
value: 80,
|
||||
unit: "%",
|
||||
export const small = [
|
||||
{
|
||||
property: "fontSize",
|
||||
value: { type: "unit", value: 80, unit: "%" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/**
|
||||
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
|
||||
*/
|
||||
|
||||
const subSupBase = {
|
||||
fontSize: {
|
||||
type: "unit",
|
||||
value: 75,
|
||||
unit: "%",
|
||||
const subSupBase = [
|
||||
{
|
||||
property: "fontSize",
|
||||
value: { type: "unit", value: 75, unit: "%" },
|
||||
},
|
||||
lineHeight: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "lineHeight",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
position: {
|
||||
type: "keyword",
|
||||
value: "relative",
|
||||
{
|
||||
property: "position",
|
||||
value: { type: "keyword", value: "relative" },
|
||||
},
|
||||
verticalAlign: {
|
||||
type: "keyword",
|
||||
value: "baseline",
|
||||
{
|
||||
property: "verticalAlign",
|
||||
value: { type: "keyword", value: "baseline" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
export const sub = {
|
||||
export const sub = [
|
||||
...subSupBase,
|
||||
bottom: {
|
||||
type: "unit",
|
||||
value: -0.25,
|
||||
unit: "em",
|
||||
{
|
||||
property: "bottom",
|
||||
value: { type: "unit", value: -0.25, unit: "em" },
|
||||
},
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
export const sup = {
|
||||
export const sup = [
|
||||
...subSupBase,
|
||||
top: {
|
||||
type: "unit",
|
||||
value: -0.5,
|
||||
unit: "em",
|
||||
{
|
||||
property: "top",
|
||||
value: { type: "unit", value: -0.5, unit: "em" },
|
||||
},
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/*
|
||||
Tabular data
|
||||
@@ -272,33 +260,32 @@ Tabular data
|
||||
2. Correct table border color inheritance in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
*/
|
||||
|
||||
export const table = {
|
||||
export const table = [
|
||||
/* 1 */
|
||||
textIndent: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "textIndent",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
...borders,
|
||||
/* 2 */
|
||||
borderTopColor: {
|
||||
type: "keyword",
|
||||
value: "inherit",
|
||||
{
|
||||
property: "borderTopColor",
|
||||
value: { type: "keyword", value: "inherit" },
|
||||
},
|
||||
borderRightColor: {
|
||||
type: "keyword",
|
||||
value: "inherit",
|
||||
{
|
||||
property: "borderRightColor",
|
||||
value: { type: "keyword", value: "inherit" },
|
||||
},
|
||||
borderBottomColor: {
|
||||
type: "keyword",
|
||||
value: "inherit",
|
||||
{
|
||||
property: "borderBottomColor",
|
||||
value: { type: "keyword", value: "inherit" },
|
||||
},
|
||||
borderLeftColor: {
|
||||
type: "keyword",
|
||||
value: "inherit",
|
||||
{
|
||||
property: "borderLeftColor",
|
||||
value: { type: "keyword", value: "inherit" },
|
||||
},
|
||||
boxSizing,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/*
|
||||
Forms
|
||||
@@ -310,46 +297,40 @@ Forms
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
const buttonBase = {
|
||||
const buttonBase = [
|
||||
/* 1 */
|
||||
fontFamily: {
|
||||
type: "keyword",
|
||||
value: "inherit",
|
||||
{
|
||||
property: "fontFamily",
|
||||
value: { type: "keyword", value: "inherit" },
|
||||
},
|
||||
fontSize: {
|
||||
type: "unit",
|
||||
value: 100,
|
||||
unit: "%",
|
||||
{
|
||||
property: "fontSize",
|
||||
value: { type: "unit", value: 100, unit: "%" },
|
||||
},
|
||||
lineHeight: {
|
||||
type: "unit",
|
||||
value: 1.15,
|
||||
unit: "number",
|
||||
{
|
||||
property: "lineHeight",
|
||||
value: { type: "unit", value: 1.15, unit: "number" },
|
||||
},
|
||||
/* 2 */
|
||||
marginTop: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginTop",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginRight: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginRight",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginBottom: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginBottom",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
marginLeft: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "marginLeft",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
export const input = buttonBase;
|
||||
export const optgroup = buttonBase;
|
||||
@@ -358,13 +339,13 @@ export const textarea = buttonBase;
|
||||
/**
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
export const button = {
|
||||
export const button = [
|
||||
...buttonBase,
|
||||
textTransform: {
|
||||
type: "keyword",
|
||||
value: "none",
|
||||
{
|
||||
property: "textTransform",
|
||||
value: { type: "keyword", value: "none" },
|
||||
},
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
export const select = button;
|
||||
|
||||
@@ -417,43 +398,39 @@ See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d4
|
||||
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
|
||||
*/
|
||||
|
||||
export const legend = {
|
||||
paddingTop: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
export const legend = [
|
||||
{
|
||||
property: "paddingTop",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
paddingRight: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "paddingRight",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
paddingBottom: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "paddingBottom",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
paddingLeft: {
|
||||
type: "unit",
|
||||
value: 0,
|
||||
unit: "number",
|
||||
{
|
||||
property: "paddingLeft",
|
||||
value: { type: "unit", value: 0, unit: "number" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/**
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
|
||||
export const progress = {
|
||||
verticalAlign: {
|
||||
type: "keyword",
|
||||
value: "baseline",
|
||||
export const progress = [
|
||||
{
|
||||
property: "verticalAlign",
|
||||
value: { type: "keyword", value: "baseline" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
|
||||
/**
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
@@ -509,11 +486,11 @@ Interactive
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
|
||||
export const summary = {
|
||||
display: {
|
||||
type: "keyword",
|
||||
value: "list-item",
|
||||
export const summary = [
|
||||
{
|
||||
property: "display",
|
||||
value: { type: "keyword", value: "list-item" },
|
||||
},
|
||||
boxSizing,
|
||||
...borders,
|
||||
} as const satisfies Style;
|
||||
] satisfies EmbedTemplateStyleDecl[];
|
||||
@@ -1,42 +1,37 @@
|
||||
import type { Style } from "@webstudio-is/css-data";
|
||||
import type { EmbedTemplateStyleDecl } from "../embed-template";
|
||||
|
||||
export const borders = {
|
||||
borderTopColor: {
|
||||
type: "keyword",
|
||||
value: "currentColor",
|
||||
export const borders: EmbedTemplateStyleDecl[] = [
|
||||
{
|
||||
property: "borderTopColor",
|
||||
value: { type: "keyword", value: "currentColor" },
|
||||
},
|
||||
borderRightColor: {
|
||||
type: "keyword",
|
||||
value: "currentColor",
|
||||
{
|
||||
property: "borderRightColor",
|
||||
value: { type: "keyword", value: "currentColor" },
|
||||
},
|
||||
borderBottomColor: {
|
||||
type: "keyword",
|
||||
value: "currentColor",
|
||||
{
|
||||
property: "borderBottomColor",
|
||||
value: { type: "keyword", value: "currentColor" },
|
||||
},
|
||||
borderLeftColor: {
|
||||
type: "keyword",
|
||||
value: "currentColor",
|
||||
{
|
||||
property: "borderLeftColor",
|
||||
value: { type: "keyword", value: "currentColor" },
|
||||
},
|
||||
|
||||
borderTopWidth: {
|
||||
type: "unit",
|
||||
value: 1,
|
||||
unit: "px",
|
||||
{
|
||||
property: "borderTopWidth",
|
||||
value: { type: "unit", value: 1, unit: "px" },
|
||||
},
|
||||
|
||||
borderRightWidth: {
|
||||
type: "unit",
|
||||
value: 1,
|
||||
unit: "px",
|
||||
{
|
||||
property: "borderRightWidth",
|
||||
value: { type: "unit", value: 1, unit: "px" },
|
||||
},
|
||||
borderBottomWidth: {
|
||||
type: "unit",
|
||||
value: 1,
|
||||
unit: "px",
|
||||
{
|
||||
property: "borderBottomWidth",
|
||||
value: { type: "unit", value: 1, unit: "px" },
|
||||
},
|
||||
borderLeftWidth: {
|
||||
type: "unit",
|
||||
value: 1,
|
||||
unit: "px",
|
||||
{
|
||||
property: "borderLeftWidth",
|
||||
value: { type: "unit", value: 1, unit: "px" },
|
||||
},
|
||||
} as const satisfies Style;
|
||||
];
|
||||
@@ -6,6 +6,8 @@ import type {
|
||||
StyleSource,
|
||||
StyleSourceSelections,
|
||||
} from "@webstudio-is/project-build";
|
||||
import type { PresetStyle } from "../components/component-meta";
|
||||
import { componentAttribute } from "../tree";
|
||||
|
||||
type StyleRule = {
|
||||
instanceId: string;
|
||||
@@ -75,3 +77,25 @@ export const getStyleRules = (
|
||||
|
||||
return styleRules;
|
||||
};
|
||||
|
||||
export const getPresetStyleRules = (
|
||||
component: string,
|
||||
presetStyle: PresetStyle
|
||||
) => {
|
||||
// group style declarations by selector to render as separate rules
|
||||
const presetStyleRules = new Map<string, Style>();
|
||||
for (const [tag, styles] of Object.entries(presetStyle)) {
|
||||
for (const styleDecl of styles) {
|
||||
const selector = `${tag}:where([${componentAttribute}=${component}])${
|
||||
styleDecl.state ?? ""
|
||||
}`;
|
||||
let rule = presetStyleRules.get(selector);
|
||||
if (rule === undefined) {
|
||||
rule = {};
|
||||
presetStyleRules.set(selector, rule);
|
||||
}
|
||||
rule[styleDecl.property] = styleDecl.value;
|
||||
}
|
||||
}
|
||||
return presetStyleRules;
|
||||
};
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
type InstancesList,
|
||||
PropsList,
|
||||
} from "@webstudio-is/project-build";
|
||||
import { StyleValue, type StyleProperty } from "@webstudio-is/css-data";
|
||||
|
||||
const EmbedTemplateText = z.object({
|
||||
type: z.literal("text"),
|
||||
@@ -38,10 +39,19 @@ const EmbedTemplateProp = z.union([
|
||||
|
||||
type EmbedTemplateProp = z.infer<typeof EmbedTemplateProp>;
|
||||
|
||||
export const EmbedTemplateStyleDecl = z.object({
|
||||
state: z.optional(z.string()),
|
||||
property: z.string() as z.ZodType<StyleProperty>,
|
||||
value: StyleValue,
|
||||
});
|
||||
|
||||
export type EmbedTemplateStyleDecl = z.infer<typeof EmbedTemplateStyleDecl>;
|
||||
|
||||
type EmbedTemplateInstance = {
|
||||
type: "instance";
|
||||
component: string;
|
||||
props?: EmbedTemplateProp[];
|
||||
styles?: EmbedTemplateStyleDecl[];
|
||||
children: Array<EmbedTemplateInstance | EmbedTemplateText>;
|
||||
};
|
||||
|
||||
@@ -49,6 +59,7 @@ const EmbedTemplateInstance: z.ZodType<EmbedTemplateInstance> = z.object({
|
||||
type: z.literal("instance"),
|
||||
component: z.string(),
|
||||
props: z.optional(z.array(EmbedTemplateProp)),
|
||||
styles: z.optional(z.array(EmbedTemplateStyleDecl)),
|
||||
children: z.lazy(() => WsEmbedTemplate),
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user