Skip to content

Styling ​

Form Kit controls draw with vyuh_cdx_ui and are themed through CdxConfig, the CDX ThemeExtension. The look of every field (text fields, dropdown triggers, pickers, switch rows, field labels and section captions) comes from one token set, CdxFieldStyle, with two presets.

Classic and refined ​

CdxConfig.classic() (default)CdxConfig.refined()
Field styleCdxFieldStyle()CdxFieldStyle.refined()
LabelFloating inside the outline, muted toneAbove the field, 14/20 w500, strong tone, 4 px gap
Field heightcontrolHeight (36 px)36 px, 12 px horizontal padding
RadiuscontrolBorderRadius (4 px)6 px
OutlineStrong (outline)Soft (outlineVariant)
Focus ring1 px1.5 px
TextTheme default16/20 value, 12/16 notes and captions
Type scaleYour TextTheme as givenCdxTypeScale.refined(): 16/20 body on a 4 px baseline
SpacingHand-picked valuesSteps of CdxSpacing
Switch rowsPlatform sizeFit into 24 px
Use forExisting apps; nothing changesDesigners, blueprints and dense data-entry forms

CdxConfig.classic() is the same as const CdxConfig(), token for token, so apps that never pass a config keep their look. The refined preset differs from classic in fieldStyle, typeScale and the spacing tokens; control height, icon size, shapes and colours are the same.

The refined type scale ​

CdxTypeScale.refined() resizes your TextTheme when createCdxTheme builds the theme; your font family, weights and colours stay. Every line height is a multiple of 4 px, so stacked text and controls keep a steady vertical rhythm.

StepSize / lineSlots
caption12 / 16labelSmall, notes, section captions
small14 / 20bodySmall, labelMedium, labelLarge, titleSmall, field labels
body16 / 20bodyMedium, titleMedium, field values
lead18 / 24bodyLarge, titleLarge
title20 / 24headlineSmall
heading24 / 28headlineMedium
headline28 / 32headlineLarge
display, hero, jumbo32/36, 40/44, 48/52displaySmall, displayMedium, displayLarge

The spacing scale ​

CdxSpacing is the set of distances layout gaps and paddings take: 4, 8, 12, 16, 24, 32 and 48 px. It grows by more the further up it goes, so the closer two things sit, the more closely they belong together.

SteppxUsed for
xs4a label and its field
sm8properties within one group
md12padding inside a card; a field's horizontal padding
lg16fields in a form, sections, container padding
xl, xxl, xxxl24, 32, 48groups of sections, page-level breaks
dart
import 'package:material_ui/material_ui.dart';
import 'package:vyuh_cdx_ui/vyuh_cdx_ui.dart';

// Existing apps: no change, classic look.
final classic = createCdxTheme(colorScheme: scheme, textTheme: textTheme);

// Form Kit apps: refined look, with token overrides on top.
final refined = createCdxTheme(
  colorScheme: scheme,
  textTheme: textTheme,
  config: const CdxConfig.refined(
    primary: Color(0xFF1F5FAF),
    fieldStyle: CdxFieldStyle.refined(height: 30),
  ),
);

// Mix: classic chrome, labels above only.
const labelsAbove = CdxConfig(
  fieldStyle: CdxFieldStyle(labelPlacement: CdxFieldLabelPlacement.above),
);

Read the active look inside a widget:

dart
final style = CdxConfig.of(context).fieldStyle;
if (style.height != null) {
  // fixed-height fields
}

CdxFieldStyle tokens ​

TokenTypeClassicRefined
labelPlacementCdxFieldLabelPlacement (floating, above)floatingabove
labelToneCdxFieldLabelTone (muted, strong)mutedstrong
labelStyleTextStyle?null12 px, w500
labelGapdouble66
borderRadiusBorderRadius?null (uses controlBorderRadius)6 px
outlineCdxFieldOutline (strong, soft)strongsoft
focusWidthdouble11.5
heightdouble?null (intrinsic)32
horizontalPaddingdouble?null10
textStyleTextStyle?null13 px
noteStyleTextStyle?null11 px
captionStyleTextStyle?null11 px, w600, 0.88 letter spacing
toggleHeightdouble?null20

Text tokens are partial styles layered over the matching TextTheme slot, so a brand's typography still comes through. null means "keep the Material or caller default". Both CdxConfig and CdxFieldStyle support copyWith, lerp and value equality, so overrides compose:

dart
final config = const CdxConfig.refined().copyWith(
  fieldStyle: const CdxFieldStyle.refined().copyWith(focusWidth: 2),
);

Supporting widgets ​

WidgetUse
CdxLabeledField(label:, child:, hasError:, active:, labelStyle:)Draws a label above a field and merges both into one accessibility node, so the field keeps its label as its accessible name. The label takes the primary colour while focus is inside and the error colour when hasError.
CdxSectionCaption(text)A group caption styled by the active captionStyle.
CdxFieldAffixButton(icon:, onPressed:, tooltip:)A prefix or suffix button inside a field. With a fixed field height it is a square of that height, so it cannot grow the field.
InputDecoration.withoutLabel()An extension that strips label / labelText from a decoration, for fields that draw their label above.

Not affected by the presets ​

The Material DropdownMenu focus ring (2 px), non-field radii (buttons, cards, dialogs, data tables) and CdxSlider look the same in both presets.

The rest of CdxConfig is documented with vyuh_cdx_ui.