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, 12 px / w500, strong tone
Field heightIntrinsic32 px, 10 px horizontal padding
RadiuscontrolBorderRadius (4 px)6 px
OutlineStrong (outline)Soft (outlineVariant)
Focus ring1 px1.5 px
TextTheme default13 px value, 11 px notes and captions
Switch rowsPlatform sizeFit into 20 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 only in fieldStyle; every shape and colour token is the same.

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.isCompact) {
  // 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.

See CDX UI theming for the rest of CdxConfig.