Design Tokens
SwiftDS uses a centralised token system defined in DSTokens.swift. All components consume these tokens — never hardcoded values — ensuring visual consistency and maintainability across the entire codebase.
Colors
Palette based on Zinc (neutrals), Indigo (primary), Pink (accent), and semantic colours. All values are accessible in dark mode via adaptive logic built into every component.
Primary
DSColor.primary
#6366F1
Electric indigo — primary action colour
DSColor.primaryHover
#4F46E5
Primary hover state
DSColor.primaryMuted
#EEF2FF
Light tinted background
Secondary
DSColor.secondary
#64748B
Cool slate — neutral elements
DSColor.secondaryMuted
#F1F5F9
Filled card background
Accent
DSColor.accent
#EC4899
Vibrant pink — highlights
Background
DSColor.background
#FAFAFA
Screen background (light)
DSColor.backgroundDark
#09090B
Screen background (dark)
Surface
DSColor.surface
#FFFFFF
Cards and sheets (light)
DSColor.surfaceDark
#18181B
Cards and sheets (dark)
Semantic
DSColor.success
#22C55E
Confirmation and success
DSColor.warning
#F59E0B
Attention and warning
DSColor.error
#EF4444
Error and destructive actions
DSColor.info
#3B82F6
Neutral information
Text
DSColor.foreground
#09090B
Primary text (light)
DSColor.foregroundDark
#FAFAFA
Primary text (dark)
DSColor.muted
#71717A
Secondary text
DSColor.subtle
#A1A1AA
Tertiary text / placeholder
Border
DSColor.border
#E4E4E7
Default border (light)
DSColor.borderDark
#3F3F46
Default border (dark)
// Uso nos componentes
.foregroundStyle(scheme == .dark ? DSColor.foregroundDark : DSColor.foreground)
.background(scheme == .dark ? DSColor.surfaceDark : DSColor.surface)
// Cor adaptativa helper
let adaptive = DSColor.adaptive(
light: DSColor.surface,
dark: DSColor.surfaceDark
)
Text("Hello").background(adaptive.resolve(in: colorScheme))Spacing
Spacing scale in multiples of 4pt, following the same logic as Apple's HIG and Material Design.
VStack(spacing: DSSpacing.md) { // 16pt entre linhas
HStack(spacing: DSSpacing.sm) { // 8pt entre colunas
Image(systemName: "star")
Text("Favorito")
}
.padding(.horizontal, DSSpacing.lg) // 24pt lateral
}
.padding(DSSpacing.xl) // 32pt externoBorder Radius
DSRadius.small
6pt
Badges, Tags, Checkboxes
DSRadius.medium
10pt
Inputs, Buttons (.md)
DSRadius.large
16pt
Cards, Modals, Sheets
DSRadius.xl
24pt
BottomSheet handle, large containers
DSRadius.pill
9999pt
SearchBar, pill Badges, Avatars
Shadows
DSShadow.none
No shadow
Usage: Elements on an elevated surface
DSShadow.sm
rgba(0,0,0,0.06) r:4 y:2
Usage: Resting cards, focused inputs
DSShadow.md
rgba(0,0,0,0.08) r:8 y:4
Usage: Hovered cards, dropdowns
DSShadow.lg
rgba(0,0,0,0.10) r:16 y:8
Usage: Toasts, popovers
DSShadow.xl
rgba(0,0,0,0.14) r:32 y:16
Usage: Modals, command palette
DSShadow.primary
primary(0.30) r:16 y:8
Usage: Highlighted primary button
DSShadow.glow
primary(0.50) r:24 y:0
Usage: Hero elements with glow effect
// Aplicado via extension em View
myView.dsShadow(.md)
myView.dsShadow(.primary)
// Sombra customizada
myView.dsShadow(DSShadow(
color: DSColor.accent.opacity(0.3),
radius: 20,
x: 0,
y: 10
))Animations
All animation tokens use spring physics or easing curves — never fixed linear durations. This ensures a natural feel across all devices and frame rates.
DSAnimation.interactive
spring(response: 0.3, damping: 0.7)
Buttons, toggles, checkboxes
DSAnimation.smooth
spring(response: 0.45, damping: 0.8)
Modals, sheets, overlays
DSAnimation.gentle
spring(response: 0.6, damping: 0.85)
List insertions, layout changes
DSAnimation.fade
easeOut(duration: 0.2)
Opacity and fade effects
DSAnimation.pulse
easeInOut(1.0).repeatForever()
Skeleton loaders, ping indicators
// Botão com spring interativo
Button(action: action) { label }
.scaleEffect(isPressed ? 0.96 : 1.0)
.animation(DSAnimation.interactive, value: isPressed)
// Modal com entrada suave
if isPresented {
ModalView()
.transition(.scale(scale: 0.94).combined(with: .opacity))
.animation(DSAnimation.smooth, value: isPresented)
}
// Skeleton pulse infinito
.opacity(opacity)
.onAppear {
withAnimation(DSAnimation.pulse) { opacity = 0.9 }
}Typography
The system uses DSText with DSTextStyle for consistency. Internally it uses Apple's .system(size:weight:) without custom fonts, ensuring full accessibility and Dynamic Type support.
DSText("Título da Seção", style: .headline)
DSText("Descrição detalhada do item.", style: .body)
DSText("12 min atrás", style: .caption)
// Customização pontual (evite quando possível)
Text("Valor especial")
.font(.system(size: 15, weight: .semibold, design: .monospaced))
.foregroundStyle(DSColor.primary)