Skip to content

Commit 729aa86

Browse files
committed
fix(ui): align form labels and grouped surfaces
1 parent f7fc1d0 commit 729aa86

23 files changed

Lines changed: 103 additions & 27 deletions

File tree

‎design-system/apps/design-lab/src/pages/PatternsPage.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {
3535
type TokenOverrides,
3636
} from "@openbitfun/ui";
3737
import { useI18n, type MessageKey } from "../i18n";
38-
import { NestedMenuPattern, ProviderConfigurationPattern, SceneToolbarPattern } from "./ReferencePatterns";
38+
import { FormTypographyPattern, NestedMenuPattern, ProviderConfigurationPattern, SceneToolbarPattern } from "./ReferencePatterns";
3939

4040
interface PatternsPageProps {
4141
colorScheme: ColorScheme;
@@ -116,6 +116,8 @@ export function PatternsPage({ colorScheme, contrast, density, tokenOverrides }:
116116
</Card>
117117
</PatternSection>
118118

119+
<FormTypographyPattern />
120+
119121
<PatternSection description={t("patterns.navigation.description")} index="02" title={t("patterns.navigation.title")}>
120122
<div className="pattern-navigation-stage" data-openbitfun-pattern="navigation-panel">
121123
<NavigationPanel

‎design-system/apps/design-lab/src/pages/ReferencePatterns.tsx‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Field,
99
FieldGroup,
1010
FieldRow,
11+
FormSection,
1112
Icon,
1213
IconButton,
1314
Input,
@@ -35,6 +36,26 @@ import {
3536
} from "@openbitfun/ui";
3637
import { useI18n } from "../i18n";
3738

39+
export function FormTypographyPattern() {
40+
const { t } = useI18n();
41+
return <Card appearance="subtle" padding="md" data-openbitfun-pattern="form-typography">
42+
<FormSection title={t("patterns.settings.title")} description={t("patterns.settings.description")}>
43+
<FieldGroup>
44+
<FieldRow>
45+
<Field label={t("patterns.settings.language")} description={t("patterns.settings.languageDescription")} orientation="horizontal" controlWidth="fill" labelWidth="md">
46+
<Input defaultValue="English / 简体中文 / 繁體中文" />
47+
</Field>
48+
</FieldRow>
49+
<FieldRow>
50+
<Field label={t("patterns.provider.headers")} description={t("components.preview.fieldDescription")} orientation="vertical" controlWidth="fill">
51+
<Input defaultValue="X-OpenBitFun-Workspace-Display-Name-With-A-Long-Value" />
52+
</Field>
53+
</FieldRow>
54+
</FieldGroup>
55+
</FormSection>
56+
</Card>;
57+
}
58+
3859
export function ProviderConfigurationPattern() {
3960
const { t } = useI18n();
4061
const [open, setOpen] = useState(false);

‎design-system/packages/design-tokens/src/system.tokens.json‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@
169169
"letterSpacing": { "$value": "{letterSpacing.normal}" }
170170
}
171171
},
172+
"fieldHelper": {
173+
"$description": "Field helper leading: 16px at the default 11px type size, scaling with user typography.",
174+
"lineHeight": { "$type": "number", "$value": 1.4545454545454546 }
175+
},
176+
"formDescription": {
177+
"$description": "Form-section description leading: 16px at the default 13px type size, scaling with user typography.",
178+
"lineHeight": { "$type": "number", "$value": 1.2307692307692308 }
179+
},
172180
"support": {
173181
"fontFamily": { "$value": "{font.family.control}" },
174182
"fontSize": { "$value": "{font.size.meta}" },

‎design-system/packages/theme-openbitfun/README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ component token is absent, and keeps explicit component overrides intact.
6262

6363
- `color.surface.scene`, `panel`, and `raised` own primary content and elevated planes.
6464
- `color.surface.chrome` owns persistent application structure such as navigation and window-control regions.
65-
- `color.surface.tertiary` is an opaque low-emphasis fill for persistent grouped content such as cards and field groups.
65+
- `color.surface.tertiary` is an opaque low-emphasis fill for persistent containers such as cards.
66+
- `color.field.groupBackground` owns grouped form surfaces: light mode uses a 3% black tint so the underlying surface remains visible; dark and high-contrast modes retain their tertiary fill. Opaque tertiary containers and transient `surface.subtle` feedback cannot express this form-specific contract. Imported appearances inherit an explicitly supplied legacy tertiary color unless they supply the new field token.
6667
- `color.surface.subtle` is a translucent local tint for transient feedback and small inset details. It must not define a persistent application plane.
6768
- `color.selection.surface` owns persistent neutral selection. Hover and pressed colors remain action feedback and are not substitutes for selection.
6869
- `color.codeChange.added` (`#1aa73e`) and `color.codeChange.removed` (`#ec221f`) also anchor success and danger emphasis. Warning emphasis uses `#ff8c00`; information uses the existing creative-action blue (`#2e7eff`). These clear hues share light tints instead of separate per-component palettes.

‎design-system/packages/theme-openbitfun/src/dark.tokens.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
}
176176
},
177177
"field": {
178+
"groupBackground": { "$description": "Grouped form tint; independent of opaque tertiary containers and transient subtle feedback.", "$type": "color", "$value": "{color.surface.tertiary}" },
178179
"borderActive": { "$type": "color", "$value": "{color.field.borderFocus}" },
179180
"placeholder": { "$type": "color", "$value": "{color.content.muted}" },
180181
"background": { "$type": "color", "$value": "{ref.color.neutral.900}" },

‎design-system/packages/theme-openbitfun/src/high-contrast-dark.tokens.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
}
5252
},
5353
"field": {
54+
"groupBackground": { "$description": "Grouped form tint; independent of opaque tertiary containers and transient subtle feedback.", "$type": "color", "$value": "{color.surface.tertiary}" },
5455
"borderActive": { "$type": "color", "$value": "{color.field.borderFocus}" },
5556
"placeholder": { "$type": "color", "$value": "{color.content.muted}" },
5657
"border": { "$type": "color", "$value": "{ref.color.gray.250}" },

‎design-system/packages/theme-openbitfun/src/high-contrast-light.tokens.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
}
5252
},
5353
"field": {
54+
"groupBackground": { "$description": "Grouped form tint; independent of opaque tertiary containers and transient subtle feedback.", "$type": "color", "$value": "{color.surface.tertiary}" },
5455
"borderActive": { "$type": "color", "$value": "{color.field.borderFocus}" },
5556
"placeholder": { "$type": "color", "$value": "{color.content.muted}" },
5657
"border": { "$type": "color", "$value": "{ref.color.gray.650}" },

‎design-system/packages/theme-openbitfun/src/light.tokens.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
}
176176
},
177177
"field": {
178+
"groupBackground": { "$description": "Grouped form tint; independent of opaque tertiary containers and transient subtle feedback.", "$type": "color", "$value": "rgba(0, 0, 0, 0.03)" },
178179
"borderActive": { "$description": "Input and SearchField editing border, distinct from the stronger generic focus indicator used by other controls.", "$type": "color", "$value": "{color.field.borderHover}" },
179180
"placeholder": { "$description": "Empty field hints and decorative adornments; distinct from general secondary prose.", "$type": "color", "$value": "rgba(0, 0, 0, 0.40)" },
180181
"background": { "$type": "color", "$value": "{ref.color.neutral.0}" },

‎design-system/packages/ui/README.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,11 @@ Tool-specific data shaping, localization, host actions, stores, and heavy
397397
renderers remain in the consuming product and enter through semantic props,
398398
callbacks, and slots. Bespoke product workflows remain product-owned rather
399399
than being forced into a standard package view.
400+
401+
Field labels follow their orientation: horizontal labels use the 13px semibold
402+
label role, while vertical labels use the 11px regular meta role. Field helpers
403+
use secondary content with 16px leading at the default 11px font size;
404+
FormSection descriptions use primary content with 16px leading at 13px. Both
405+
leading roles scale with user typography. FieldGroup uses the form group tint,
406+
retaining its existing row padding, dividers, and radius. The Patterns form
407+
specimen shows both orientations and long values over a tinted container.

‎design-system/packages/ui/src/components/Field/Field.meta.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const fieldMeta = {
2323
tokens: [
2424
"color.content.requiredIndicator",
2525
"color.content.primary",
26-
"color.content.muted",
26+
"color.content.secondary",
2727
"color.status.danger.content",
2828
"layout.field.rootGap",
2929
"layout.field.horizontalGap",
@@ -35,7 +35,9 @@ export const fieldMeta = {
3535
"layout.field.labelGap",
3636
"layout.field.labelActionGap",
3737
"layout.field.controlGap",
38-
"type.label.md.fontSize",
38+
"type.label.selected.fontSize",
39+
"type.meta.fontSize",
40+
"type.fieldHelper.lineHeight",
3941
"type.support.fontSize",
4042
],
4143
} as const satisfies ComponentMeta;

0 commit comments

Comments
 (0)