Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ export const FontFamilyControl = () => {
return toValue(value, (value) => value).replace(/"/g, "");
}, [value]);

if (value.type !== "fontFamily") {
return;
}

return (
<Flex>
<Combobox<Item>
Expand All @@ -73,7 +69,7 @@ export const FontFamilyControl = () => {
title="Fonts"
content={
<FontsManager
value={value}
value={value.type === "fontFamily" ? value : undefined}
onChange={(newValue = itemValue) => {
setValue({ type: "fontFamily", value: [newValue] });
}}
Expand Down
2 changes: 2 additions & 0 deletions apps/builder/app/builder/features/workspace/workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const workspaceStyle = css({
const canvasContainerStyle = css({
position: "absolute",
transformOrigin: "0 0",
// We had a case where some Windows 10 + Chrome 129 users couldn't scroll iframe canvas.
willChange: "transform",
});

const useMeasureWorkspace = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const useLogic = ({ onChange, value }: FontsManagerProps) => {
);

const currentIndex = useMemo(() => {
return groupedItems.findIndex((item) => item.label === value.value[0]);
return groupedItems.findIndex((item) => item.label === value?.value[0]);
}, [groupedItems, value]);

const handleChangeCurrent = (nextCurrentIndex: number) => {
Expand Down Expand Up @@ -104,7 +104,7 @@ const useLogic = ({ onChange, value }: FontsManagerProps) => {
};

type FontsManagerProps = {
value: FontFamilyValue;
value?: FontFamilyValue;
onChange: (value?: string) => void;
};

Expand Down
26 changes: 26 additions & 0 deletions apps/builder/app/shared/style-object-model.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,32 @@ test("fallback cascaded value to inherited computed value", () => {
).toEqual({ type: "keyword", value: "currentColor" });
});

test("work with unknown or invalid properties", () => {
const model = createModel({
css: `
bodyLocal {
unknown-property: [object Object];
}
`,
jsx: <$.Body ws:id="body" class="bodyLocal"></$.Body>,
});
const instanceSelector = ["body"];
expect(
getComputedStyleDecl({
model,
instanceSelector,
property: "unknownProperty",
}).usedValue
).toEqual({ type: "unparsed", value: "[object Object]" });
expect(
getComputedStyleDecl({
model,
instanceSelector,
property: "undefinedProperty",
}).usedValue
).toEqual({ type: "invalid", value: "" });
});

describe("selected style", () => {
test("access selected style source value within cascade", () => {
const model = createModel({
Expand Down
7 changes: 6 additions & 1 deletion apps/builder/app/shared/style-object-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ const customPropertyData = {
initial: guaranteedInvalidValue,
};

const invalidPropertyData = {
inherited: false,
initial: invalidValue,
};

export type ComputedStyleDecl = {
property: string;
source: StyleValueSource;
Expand Down Expand Up @@ -269,7 +274,7 @@ export const getComputedStyleDecl = ({
const isCustomProperty = property.startsWith("--");
const propertyData = isCustomProperty
? customPropertyData
: properties[property as keyof typeof properties];
: (properties[property as keyof typeof properties] ?? invalidPropertyData);
const inherited = propertyData.inherited;
const initialValue: StyleValue = propertyData.initial;
let computedValue: StyleValue = initialValue;
Expand Down
31 changes: 29 additions & 2 deletions packages/css-engine/src/core/to-value.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe("Convert WS CSS Values to native CSS strings", () => {
expect(value).toBe("var(--namespace, normal, 10px)");
});

test("fontFamily stack", () => {
test("fontFamily is known stack name", () => {
expect(
toValue({
type: "fontFamily",
Expand All @@ -57,7 +57,16 @@ describe("Convert WS CSS Values to native CSS strings", () => {
);
});

test("fontFamily unknown", () => {
test("fontFamily is a custom stack", () => {
expect(
toValue({
type: "fontFamily",
value: ["DejaVu Sans Mono", "monospace"],
})
).toBe('"DejaVu Sans Mono", monospace');
});

test("fontFamily is unknown family name", () => {
expect(
toValue({
type: "fontFamily",
Expand All @@ -66,6 +75,24 @@ describe("Convert WS CSS Values to native CSS strings", () => {
).toBe("something-random, sans-serif");
});

test("fontFamily is empty", () => {
expect(
toValue({
type: "fontFamily",
value: [],
})
).toBe("sans-serif");
});

test("fontFamily has duplicates", () => {
expect(
toValue({
type: "fontFamily",
value: ["a", "a", "b"],
})
).toBe("a, b");
});

test("Transform font family value to override default fallback", () => {
const value = toValue(
{
Expand Down
32 changes: 21 additions & 11 deletions packages/css-engine/src/core/to-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,28 @@ import type { StyleValue } from "../schema";
export type TransformValue = (styleValue: StyleValue) => undefined | StyleValue;

const fallbackTransform: TransformValue = (styleValue) => {
if (styleValue.type === "fontFamily") {
const fonts = SYSTEM_FONTS.get(styleValue.value[0])?.stack ?? [
styleValue.value[0],
DEFAULT_FONT_FALLBACK,
];
const value = Array.from(new Set(fonts));

return {
type: "fontFamily",
value,
};
if (styleValue.type !== "fontFamily") {
return;
}

// By default we assume its a custom font stack.
let { value } = styleValue;

// Shouldn't be possible, but just in case.
if (value.length === 0) {
value = [DEFAULT_FONT_FALLBACK];
}

// User provided a single name. It could be a specific font name or a stack name.
if (value.length === 1) {
const stack = SYSTEM_FONTS.get(value[0])?.stack;
value = stack ?? [value[0], DEFAULT_FONT_FALLBACK];
}

return {
type: "fontFamily",
value: Array.from(new Set(value)),
};
};

// Use JSON.stringify to escape double quotes and backslashes in strings as it automatically replaces " with \" and \ with \\.
Expand Down
2 changes: 2 additions & 0 deletions packages/design-system/src/components/scroll-area.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const ScrollAreaRoot = styled(Root, {
boxSizing: "border-box",
overflow: "hidden",
display: "grid",
// We had a case where some Windows 10 + Chrome 129 users couldn't scroll style panel.
willChange: "transform",
});

const ScrollAreaThumb = styled(Thumb, {
Expand Down
Loading