august-design-system
Version:
A comprehensive React Native design system following Apple Human Interface Guidelines
1,516 lines (1,508 loc) • 31.8 kB
JavaScript
'use strict';
// src/design-system/tokens/colors.ts
var palette = {
// Gray scale - iOS system grays
gray: {
50: "#F2F2F7",
100: "#E5E5EA",
200: "#D1D1D6",
300: "#C7C7CC",
400: "#AEAEB2",
500: "#8E8E93",
600: "#636366",
700: "#48484A",
800: "#3A3A3C",
900: "#2C2C2E",
950: "#1C1C1E"
},
// System colors - iOS standard palette
// Light mode values
red: {
light: "#FF3B30",
dark: "#FF453A"
},
orange: {
light: "#FF9500",
dark: "#FF9F0A"
},
yellow: {
light: "#FFCC00",
dark: "#FFD60A"
},
green: {
light: "#34C759",
dark: "#30D158"
},
mint: {
light: "#00C7BE",
dark: "#63E6E2"
},
teal: {
light: "#30B0C7",
dark: "#40C8E0"
},
cyan: {
light: "#32ADE6",
dark: "#64D2FF"
},
blue: {
light: "#007AFF",
dark: "#0A84FF"
},
indigo: {
light: "#5856D6",
dark: "#5E5CE6"
},
purple: {
light: "#AF52DE",
dark: "#BF5AF2"
},
pink: {
light: "#FF2D55",
dark: "#FF375F"
},
brown: {
light: "#A2845E",
dark: "#AC8E68"
}
};
var lightColors = {
// Background colors - iOS grouped table view style layering
background: {
primary: "#FFFFFF",
secondary: "#F2F2F7",
tertiary: "#FFFFFF",
grouped: "#F2F2F7",
groupedSecondary: "#FFFFFF",
groupedTertiary: "#F2F2F7"
},
// Label colors - for text content
label: {
primary: "#000000",
// 100% black
secondary: "rgba(60, 60, 67, 0.6)",
// 60% opacity
tertiary: "rgba(60, 60, 67, 0.3)",
// 30% opacity
quaternary: "rgba(60, 60, 67, 0.18)"
// 18% opacity
},
// Fill colors - for thin and small shapes
fill: {
primary: "rgba(120, 120, 128, 0.2)",
secondary: "rgba(120, 120, 128, 0.16)",
tertiary: "rgba(118, 118, 128, 0.12)",
quaternary: "rgba(116, 116, 128, 0.08)"
},
// Separator colors
separator: {
opaque: "#C6C6C8",
nonOpaque: "rgba(60, 60, 67, 0.36)"
},
// System colors - Apple standard
system: {
red: palette.red.light,
orange: palette.orange.light,
yellow: palette.yellow.light,
green: palette.green.light,
mint: palette.mint.light,
teal: palette.teal.light,
cyan: palette.cyan.light,
blue: palette.blue.light,
indigo: palette.indigo.light,
purple: palette.purple.light,
pink: palette.pink.light,
brown: palette.brown.light,
gray: palette.gray[500],
gray2: palette.gray[400],
gray3: palette.gray[300],
gray4: palette.gray[200],
gray5: palette.gray[100],
gray6: palette.gray[50]
},
// Semantic colors - functional meaning
semantic: {
success: palette.green.light,
warning: palette.orange.light,
error: palette.red.light,
info: palette.blue.light
},
// Interactive colors
interactive: {
tint: palette.blue.light,
tintPressed: "#0062CC",
// Darkened blue for pressed state
tintDisabled: "rgba(0, 122, 255, 0.3)",
destructive: palette.red.light,
destructivePressed: "#CC2F26"
},
// Material/Blur backgrounds - approximated for non-blur fallback
material: {
thin: "rgba(255, 255, 255, 0.6)",
regular: "rgba(255, 255, 255, 0.72)",
thick: "rgba(255, 255, 255, 0.85)",
chrome: "rgba(247, 247, 247, 0.8)"
}
};
var darkColors = {
// Background colors - elevated surfaces in dark mode
background: {
primary: "#000000",
secondary: "#1C1C1E",
tertiary: "#2C2C2E",
grouped: "#000000",
groupedSecondary: "#1C1C1E",
groupedTertiary: "#2C2C2E"
},
// Label colors - inverted for dark mode
label: {
primary: "#FFFFFF",
secondary: "rgba(235, 235, 245, 0.6)",
tertiary: "rgba(235, 235, 245, 0.3)",
quaternary: "rgba(235, 235, 245, 0.18)"
},
// Fill colors - adjusted for dark backgrounds
fill: {
primary: "rgba(120, 120, 128, 0.36)",
secondary: "rgba(120, 120, 128, 0.32)",
tertiary: "rgba(118, 118, 128, 0.24)",
quaternary: "rgba(116, 116, 128, 0.18)"
},
// Separator colors
separator: {
opaque: "#38383A",
nonOpaque: "rgba(84, 84, 88, 0.6)"
},
// System colors - adjusted for dark mode (higher luminance)
system: {
red: palette.red.dark,
orange: palette.orange.dark,
yellow: palette.yellow.dark,
green: palette.green.dark,
mint: palette.mint.dark,
teal: palette.teal.dark,
cyan: palette.cyan.dark,
blue: palette.blue.dark,
indigo: palette.indigo.dark,
purple: palette.purple.dark,
pink: palette.pink.dark,
brown: palette.brown.dark,
gray: palette.gray[500],
gray2: palette.gray[600],
gray3: palette.gray[700],
gray4: palette.gray[800],
gray5: palette.gray[900],
gray6: palette.gray[950]
},
// Semantic colors - dark mode variants
semantic: {
success: palette.green.dark,
warning: palette.orange.dark,
error: palette.red.dark,
info: palette.blue.dark
},
// Interactive colors - adjusted for dark backgrounds
interactive: {
tint: palette.blue.dark,
tintPressed: "#409CFF",
// Lightened blue for pressed state in dark mode
tintDisabled: "rgba(10, 132, 255, 0.3)",
destructive: palette.red.dark,
destructivePressed: "#FF6961"
},
// Material/Blur backgrounds - dark mode variants
material: {
thin: "rgba(30, 30, 30, 0.6)",
regular: "rgba(30, 30, 30, 0.72)",
thick: "rgba(30, 30, 30, 0.85)",
chrome: "rgba(36, 36, 38, 0.8)"
}
};
function withAlpha(color, alpha) {
if (color.startsWith("rgba")) {
return color.replace(/[\d.]+\)$/, `${alpha})`);
}
if (color.startsWith("#")) {
const hex = color.replace("#", "");
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
return color;
}
function hasMinimumContrast(foreground, background, minimumRatio = 4.5) {
const isDarkBg = background === "#000000" || background.includes("1C1C1E") || background.includes("2C2C2E");
const isLightFg = foreground === "#FFFFFF" || foreground.includes("235, 235, 245");
return isDarkBg === isLightFg;
}
// src/design-system/tokens/typography.ts
var fontFamily = {
regular: "System",
medium: "System",
semibold: "System",
bold: "System",
heavy: "System",
monospace: "Menlo",
// Falls back to platform monospace
rounded: "System"
// SF Pro Rounded on iOS
};
var typography = {
// ==========================================================================
// DISPLAY STYLES
// Large, prominent text for titles and headers
// ==========================================================================
/**
* Large Title - Used for main screen titles in navigation bars.
* iOS: 34pt Regular
*/
largeTitle: {
fontFamily: fontFamily.regular,
fontSize: 34,
lineHeight: 41,
// 1.2x
letterSpacing: 0.37,
fontWeight: "400"
},
/**
* Title 1 - Primary content titles.
* iOS: 28pt Regular
*/
title1: {
fontFamily: fontFamily.regular,
fontSize: 28,
lineHeight: 34,
// 1.21x
letterSpacing: 0.36,
fontWeight: "400"
},
/**
* Title 2 - Secondary titles.
* iOS: 22pt Regular
*/
title2: {
fontFamily: fontFamily.regular,
fontSize: 22,
lineHeight: 28,
// 1.27x
letterSpacing: 0.35,
fontWeight: "400"
},
/**
* Title 3 - Tertiary titles.
* iOS: 20pt Regular
*/
title3: {
fontFamily: fontFamily.regular,
fontSize: 20,
lineHeight: 25,
// 1.25x
letterSpacing: 0.38,
fontWeight: "400"
},
// ==========================================================================
// HEADLINE STYLES
// For section headers and emphasized text
// ==========================================================================
/**
* Headline - Section headers, emphasized body text.
* iOS: 17pt Semibold
*/
headline: {
fontFamily: fontFamily.semibold,
fontSize: 17,
lineHeight: 22,
// 1.29x
letterSpacing: -0.41,
fontWeight: "600"
},
/**
* Subheadline - Subordinate section headers.
* iOS: 15pt Regular
*/
subheadline: {
fontFamily: fontFamily.regular,
fontSize: 15,
lineHeight: 20,
// 1.33x
letterSpacing: -0.24,
fontWeight: "400"
},
// ==========================================================================
// BODY STYLES
// Primary reading text
// ==========================================================================
/**
* Body - Primary reading text throughout the app.
* iOS: 17pt Regular
*/
body: {
fontFamily: fontFamily.regular,
fontSize: 17,
lineHeight: 22,
// 1.29x
letterSpacing: -0.41,
fontWeight: "400"
},
/**
* Callout - Secondary text that's slightly smaller than body.
* iOS: 16pt Regular
*/
callout: {
fontFamily: fontFamily.regular,
fontSize: 16,
lineHeight: 21,
// 1.31x
letterSpacing: -0.32,
fontWeight: "400"
},
// ==========================================================================
// SUPPORTING STYLES
// Smaller text for captions, footnotes, and labels
// ==========================================================================
/**
* Footnote - Smaller supporting text.
* iOS: 13pt Regular
*/
footnote: {
fontFamily: fontFamily.regular,
fontSize: 13,
lineHeight: 18,
// 1.38x
letterSpacing: -0.08,
fontWeight: "400"
},
/**
* Caption 1 - Primary caption style.
* iOS: 12pt Regular
*/
caption1: {
fontFamily: fontFamily.regular,
fontSize: 12,
lineHeight: 16,
// 1.33x
letterSpacing: 0,
fontWeight: "400"
},
/**
* Caption 2 - Secondary caption style (smallest).
* iOS: 11pt Regular
*/
caption2: {
fontFamily: fontFamily.regular,
fontSize: 11,
lineHeight: 13,
// 1.18x
letterSpacing: 0.07,
fontWeight: "400"
}
};
function withWeight(style, weight) {
return {
...style,
fontWeight: weight
};
}
function withSize(style, fontSize) {
const ratio = style.lineHeight / style.fontSize;
return {
...style,
fontSize,
lineHeight: Math.round(fontSize * ratio)
};
}
function emphasized(style) {
return withWeight(style, "600");
}
function bold(style) {
return withWeight(style, "700");
}
var typographyEmphasis = {
bodyEmphasis: emphasized(typography.body),
calloutEmphasis: emphasized(typography.callout),
footnoteEmphasis: emphasized(typography.footnote),
caption1Emphasis: emphasized(typography.caption1),
subheadlineEmphasis: emphasized(typography.subheadline)
};
// src/design-system/tokens/spacing.ts
var SPACING_UNIT = 4;
var spacing = {
// Base scale
none: 0,
xxs: 2,
xs: 4,
sm: 8,
md: 12,
lg: 16,
xl: 20,
xxl: 24,
xxxl: 32,
xxxxl: 40,
xxxxxl: 48,
// Semantic spacing - Inset (padding)
// Used for content padding inside containers
inset: {
none: 0,
xs: 4,
sm: 8,
md: 12,
lg: 16,
// Standard content inset
xl: 20
},
// Semantic spacing - Stack (vertical)
// Used for vertical spacing between elements
stack: {
none: 0,
xs: 4,
sm: 8,
// Tight grouping
md: 12,
lg: 16,
// Standard section spacing
xl: 24
// Large section spacing
},
// Semantic spacing - Inline (horizontal)
// Used for horizontal spacing between elements
inline: {
none: 0,
xs: 4,
sm: 8,
// Icon to text spacing
md: 12,
lg: 16,
// Standard element spacing
xl: 24
}
};
var layoutConstants = {
/**
* Standard horizontal margin for content.
* iOS typically uses 16pt margins.
*/
screenHorizontalPadding: 16,
/**
* Standard vertical margin for content.
*/
screenVerticalPadding: 16,
/**
* Navigation bar height (standard).
*/
navigationBarHeight: 44,
/**
* Navigation bar height (large title).
*/
navigationBarLargeTitleHeight: 96,
/**
* Tab bar height.
*/
tabBarHeight: 49,
/**
* Tab bar height with home indicator (iPhone X+).
*/
tabBarHeightWithHomeIndicator: 83,
/**
* Minimum touch target size (Apple HIG requirement).
* All interactive elements should be at least 44x44pt.
*/
minTouchTarget: 44,
/**
* Standard list item height.
*/
listItemHeight: 44,
/**
* Standard list item height (subtitle style).
*/
listItemSubtitleHeight: 64,
/**
* Standard search bar height.
*/
searchBarHeight: 36,
/**
* Standard toolbar height.
*/
toolbarHeight: 44,
/**
* Standard separator thickness.
*/
separatorThickness: 0.5,
/**
* Standard icon size in lists.
*/
listIconSize: 28,
/**
* Disclosure indicator width.
*/
disclosureIndicatorWidth: 8,
/**
* Standard button corner radius.
*/
buttonCornerRadius: 10,
/**
* Standard card corner radius.
*/
cardCornerRadius: 12,
/**
* Sheet corner radius.
*/
sheetCornerRadius: 16
};
function space(multiplier) {
return SPACING_UNIT * multiplier;
}
function insetAll(value) {
return {
padding: value
};
}
function insetSquish(horizontal, vertical) {
return {
paddingHorizontal: horizontal,
paddingVertical: vertical
};
}
function insetDirectional(top, right, bottom, left) {
return {
paddingTop: top,
paddingRight: right,
paddingBottom: bottom,
paddingLeft: left
};
}
// src/design-system/tokens/radius.ts
var radius = {
none: 0,
xs: 4,
sm: 8,
md: 12,
lg: 16,
xl: 20,
xxl: 24,
full: 9999
};
var semanticRadius = {
/**
* Button corner radius (matches iOS default).
*/
button: radius.sm,
/**
* Small button corner radius.
*/
buttonSmall: radius.xs,
/**
* Card corner radius.
*/
card: radius.md,
/**
* Input field corner radius.
*/
input: radius.sm,
/**
* Modal/Dialog corner radius.
*/
modal: radius.lg,
/**
* Bottom sheet corner radius.
*/
sheet: radius.xl,
/**
* Image thumbnail radius.
*/
thumbnail: radius.sm,
/**
* Avatar (circular) radius.
*/
avatar: radius.full,
/**
* Badge/Chip radius.
*/
badge: radius.full,
/**
* Pill button radius.
*/
pill: radius.full,
/**
* Tag/Label radius.
*/
tag: radius.xs,
/**
* Toast notification radius.
*/
toast: radius.md,
/**
* Tooltip radius.
*/
tooltip: radius.sm,
/**
* Popover radius.
*/
popover: radius.md,
/**
* Search bar radius.
*/
searchBar: radius.sm,
/**
* Segment control radius.
*/
segmentControl: radius.sm,
/**
* Slider track radius.
*/
slider: radius.full,
/**
* Progress bar radius.
*/
progressBar: radius.full
};
function circular(size) {
return size / 2;
}
function corners(topLeft, topRight, bottomRight, bottomLeft) {
return {
borderTopLeftRadius: topLeft,
borderTopRightRadius: topRight,
borderBottomRightRadius: bottomRight,
borderBottomLeftRadius: bottomLeft
};
}
function topRounded(value) {
return corners(value, value, 0, 0);
}
function bottomRounded(value) {
return corners(0, 0, value, value);
}
function leftRounded(value) {
return corners(value, 0, 0, value);
}
function rightRounded(value) {
return corners(0, value, value, 0);
}
// src/design-system/tokens/shadows.ts
var shadowColors = {
light: "rgba(0, 0, 0, 1)",
// Opacity controlled per shadow
dark: "rgba(0, 0, 0, 1)"
// Deeper shadows in dark mode
};
var lightShadows = {
/**
* No shadow.
*/
none: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0
},
/**
* Extra small shadow - subtle lift.
* Use for: Subtle hover states, pressed buttons.
*/
xs: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.04,
shadowRadius: 2,
elevation: 1
},
/**
* Small shadow - light elevation.
* Use for: Cards, list items, buttons.
*/
sm: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.08,
shadowRadius: 4,
elevation: 2
},
/**
* Medium shadow - standard elevation.
* Use for: Dropdown menus, popovers, floating action buttons.
*/
md: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.12,
shadowRadius: 8,
elevation: 4
},
/**
* Large shadow - prominent elevation.
* Use for: Modals, dialogs, navigation overlays.
*/
lg: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.15,
shadowRadius: 16,
elevation: 8
},
/**
* Extra large shadow - high elevation.
* Use for: Bottom sheets, side panels.
*/
xl: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 12 },
shadowOpacity: 0.18,
shadowRadius: 24,
elevation: 12
},
/**
* XXL shadow - maximum elevation.
* Use for: Full-screen overlays, critical modals.
*/
xxl: {
shadowColor: shadowColors.light,
shadowOffset: { width: 0, height: 16 },
shadowOpacity: 0.22,
shadowRadius: 32,
elevation: 16
}
};
var darkShadows = {
none: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0
},
xs: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.2,
shadowRadius: 2,
elevation: 1
},
sm: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 2
},
md: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 4
},
lg: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.35,
shadowRadius: 16,
elevation: 8
},
xl: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 12 },
shadowOpacity: 0.4,
shadowRadius: 24,
elevation: 12
},
xxl: {
shadowColor: shadowColors.dark,
shadowOffset: { width: 0, height: 16 },
shadowOpacity: 0.45,
shadowRadius: 32,
elevation: 16
}
};
var semanticShadows = {
/**
* Card shadow.
*/
card: lightShadows.sm,
/**
* Button shadow (when elevated).
*/
button: lightShadows.xs,
/**
* Pressed button shadow (reduced).
*/
buttonPressed: lightShadows.none,
/**
* Floating action button shadow.
*/
fab: lightShadows.md,
/**
* Dropdown/Popover shadow.
*/
dropdown: lightShadows.md,
/**
* Modal/Dialog shadow.
*/
modal: lightShadows.lg,
/**
* Bottom sheet shadow.
*/
sheet: lightShadows.xl,
/**
* Toast notification shadow.
*/
toast: lightShadows.md,
/**
* Navigation header shadow.
*/
header: lightShadows.xs,
/**
* Tab bar shadow.
*/
tabBar: lightShadows.xs
};
function createShadow(offsetY, opacity2, radius2, elevation, offsetX = 0, color = shadowColors.light) {
return {
shadowColor: color,
shadowOffset: { width: offsetX, height: offsetY },
shadowOpacity: opacity2,
shadowRadius: radius2,
elevation
};
}
function combineShadows(...shadows) {
if (shadows.length === 0) return lightShadows.none;
return shadows.reduce(
(prev, current) => current.elevation > prev.elevation ? current : prev
);
}
function scaleShadow(shadow, factor) {
return {
...shadow,
shadowOffset: {
width: shadow.shadowOffset.width * factor,
height: shadow.shadowOffset.height * factor
},
shadowRadius: shadow.shadowRadius * factor,
elevation: Math.round(shadow.elevation * factor)
};
}
// src/design-system/tokens/animation.ts
var duration = {
instant: 0,
fastest: 50,
faster: 100,
fast: 150,
normal: 250,
slow: 350,
slower: 500,
slowest: 700
};
var easing = {
/**
* Linear - constant speed (rarely used for UI).
*/
linear: [0, 0, 1, 1],
/**
* Ease In - slow start, fast end.
* Use for: Elements leaving the screen.
*/
easeIn: [0.42, 0, 1, 1],
/**
* Ease Out - fast start, slow end.
* Use for: Elements entering the screen.
* This is the most common easing for iOS-style animations.
*/
easeOut: [0, 0, 0.58, 1],
/**
* Ease In Out - slow start and end.
* Use for: Elements that start and end on screen.
*/
easeInOut: [0.42, 0, 0.58, 1],
/**
* Default spring - balanced, natural feel.
* iOS default animation spring characteristics.
* Use for: Most interactive animations.
*/
spring: {
damping: 15,
stiffness: 150,
mass: 1
},
/**
* Gentle spring - soft, slow settling.
* Use for: Subtle movements, floating elements.
*/
springGentle: {
damping: 20,
stiffness: 100,
mass: 1
},
/**
* Bouncy spring - energetic, playful feel.
* Use for: Emphasis, celebrations, playful interactions.
* Use sparingly to avoid overwhelming users.
*/
springBouncy: {
damping: 10,
stiffness: 200,
mass: 1
}
};
var animation = {
duration,
easing
};
var animationPresets = {
/**
* Button press feedback.
*/
buttonPress: {
duration: duration.faster,
easing: easing.easeOut
},
/**
* Button release feedback.
*/
buttonRelease: {
duration: duration.fast,
easing: easing.spring
},
/**
* Modal/Sheet appear.
*/
modalEnter: {
duration: duration.normal,
easing: easing.spring
},
/**
* Modal/Sheet dismiss.
*/
modalExit: {
duration: duration.fast,
easing: easing.easeIn
},
/**
* Page/Screen transition.
*/
pageTransition: {
duration: duration.slow,
easing: easing.easeInOut
},
/**
* Fade in content.
*/
fadeIn: {
duration: duration.normal,
easing: easing.easeOut
},
/**
* Fade out content.
*/
fadeOut: {
duration: duration.fast,
easing: easing.easeIn
},
/**
* Slide in from bottom.
*/
slideInUp: {
duration: duration.normal,
easing: easing.spring
},
/**
* Slide out to bottom.
*/
slideOutDown: {
duration: duration.fast,
easing: easing.easeIn
},
/**
* Scale up (appearing).
*/
scaleIn: {
duration: duration.normal,
easing: easing.springBouncy
},
/**
* Scale down (disappearing).
*/
scaleOut: {
duration: duration.fast,
easing: easing.easeIn
},
/**
* Expand/Collapse accordion.
*/
expand: {
duration: duration.normal,
easing: easing.easeInOut
},
/**
* Switch/Toggle animation.
*/
toggle: {
duration: duration.fast,
easing: easing.spring
},
/**
* Skeleton loading shimmer.
*/
skeleton: {
duration: duration.slowest,
easing: easing.linear
},
/**
* Toast notification appear.
*/
toastEnter: {
duration: duration.normal,
easing: easing.springBouncy
},
/**
* Toast notification dismiss.
*/
toastExit: {
duration: duration.fast,
easing: easing.easeIn
},
/**
* Haptic feedback timing.
*/
haptic: {
duration: duration.instant,
easing: easing.linear
}
};
var reducedMotionPresets = {
/**
* Replaces spring/bouncy animations with simple fade.
*/
default: {
duration: duration.fast,
easing: easing.easeOut
},
/**
* Replaces sliding animations with fade.
*/
slide: {
duration: duration.faster,
easing: easing.easeOut
},
/**
* Replaces scale animations with fade.
*/
scale: {
duration: duration.faster,
easing: easing.easeOut
},
/**
* Instant change (no animation).
*/
instant: {
duration: duration.instant,
easing: easing.linear
}
};
function withDelay(baseDelay, index = 0, staggerAmount = 50) {
return baseDelay + index * staggerAmount;
}
function stagger(index, staggerAmount = 50, maxDelay = 500) {
return Math.min(index * staggerAmount, maxDelay);
}
// src/design-system/tokens/sizes.ts
var sizes = {
// Touch targets - Apple HIG minimum 44pt
touchTarget: {
/**
* Minimum touch target size (44pt).
* Required by Apple HIG for all interactive elements.
*/
minimum: 44,
/**
* Comfortable touch target (48pt).
* Recommended for frequently used actions.
*/
comfortable: 48,
/**
* Spacious touch target (56pt).
* For primary actions and accessibility.
*/
spacious: 56
},
// Icon sizes
icon: {
/**
* Extra small icon (12pt).
* Use for: Inline badges, tiny indicators.
*/
xs: 12,
/**
* Small icon (16pt).
* Use for: Inline text icons, compact UI.
*/
sm: 16,
/**
* Medium icon (20pt).
* Use for: Standard inline icons.
*/
md: 20,
/**
* Large icon (24pt).
* Use for: Navigation icons, tab bar icons.
*/
lg: 24,
/**
* Extra large icon (32pt).
* Use for: Featured icons, prominent actions.
*/
xl: 32,
/**
* XXL icon (40pt).
* Use for: Illustrations, large feature icons.
*/
xxl: 40
},
// Avatar sizes
avatar: {
/**
* Extra small avatar (24pt).
* Use for: Inline mentions, compact lists.
*/
xs: 24,
/**
* Small avatar (32pt).
* Use for: Comments, messaging.
*/
sm: 32,
/**
* Medium avatar (40pt).
* Use for: Standard list items.
*/
md: 40,
/**
* Large avatar (56pt).
* Use for: Profile cards, detailed lists.
*/
lg: 56,
/**
* Extra large avatar (72pt).
* Use for: Profile headers.
*/
xl: 72,
/**
* XXL avatar (96pt).
* Use for: Profile pages, settings.
*/
xxl: 96
},
// Button heights
button: {
/**
* Small button (32pt).
* Use for: Compact UI, inline actions.
* Note: May not meet touch target minimum.
*/
sm: 32,
/**
* Medium button (44pt) - DEFAULT.
* Use for: Standard buttons.
* Meets Apple HIG minimum touch target.
*/
md: 44,
/**
* Large button (50pt).
* Use for: Primary actions, CTAs.
*/
lg: 50,
/**
* Extra large button (56pt).
* Use for: Hero actions, onboarding.
*/
xl: 56
},
// Input heights
input: {
/**
* Small input (36pt).
* Use for: Compact forms, filters.
*/
sm: 36,
/**
* Medium input (44pt) - DEFAULT.
* Use for: Standard form inputs.
* Meets Apple HIG minimum touch target.
*/
md: 44,
/**
* Large input (52pt).
* Use for: Search bars, prominent inputs.
*/
lg: 52
}
};
var zIndex = {
/**
* Base level - standard content.
*/
base: 0,
/**
* Dropdown level - menus, selects.
*/
dropdown: 1e3,
/**
* Sticky level - headers, navigation.
*/
sticky: 1100,
/**
* Overlay level - background overlays.
*/
overlay: 1200,
/**
* Modal level - dialogs, sheets.
*/
modal: 1300,
/**
* Popover level - tooltips, popovers.
*/
popover: 1400,
/**
* Tooltip level - floating hints.
*/
tooltip: 1500,
/**
* Toast level - notifications (highest).
*/
toast: 1600
};
var breakpoints = {
/**
* Extra small - small phones.
*/
xs: 0,
/**
* Small - standard phones (iPhone SE+).
* iPhone SE: 375pt width.
*/
sm: 375,
/**
* Medium - large phones (iPhone Pro Max).
* iPhone Pro Max: 428pt width.
*/
md: 428,
/**
* Large - small tablets (iPad Mini).
* iPad Mini portrait: 744pt width.
*/
lg: 744,
/**
* Extra large - large tablets (iPad Pro).
* iPad Pro portrait: 1024pt width.
*/
xl: 1024
};
var opacity = {
/**
* Fully transparent.
*/
transparent: 0,
/**
* Disabled state opacity.
* iOS uses 0.3-0.4 for disabled elements.
*/
disabled: 0.38,
/**
* Medium opacity - overlays, secondary elements.
*/
medium: 0.6,
/**
* High opacity - emphasized content.
*/
high: 0.87,
/**
* Fully opaque.
*/
opaque: 1
};
var componentSizes = {
/**
* Navigation bar heights.
*/
navigationBar: {
standard: 44,
large: 96,
largeExpanded: 140
},
/**
* Tab bar heights.
*/
tabBar: {
standard: 49,
withHomeIndicator: 83
},
/**
* Search bar dimensions.
*/
searchBar: {
height: 36,
iconSize: 18
},
/**
* Toolbar dimensions.
*/
toolbar: {
height: 44,
iconSize: 24
},
/**
* Segmented control.
*/
segmentedControl: {
height: 32,
minSegmentWidth: 60
},
/**
* Switch/Toggle.
*/
switch: {
width: 51,
height: 31,
thumbSize: 27
},
/**
* Slider.
*/
slider: {
trackHeight: 4,
thumbSize: 28
},
/**
* Progress bar.
*/
progressBar: {
height: 4,
heightLarge: 8
},
/**
* Badge.
*/
badge: {
minWidth: 20,
height: 20,
dotSize: 8
},
/**
* Chip/Tag.
*/
chip: {
height: 32,
heightSmall: 24
},
/**
* List item.
*/
listItem: {
standard: 44,
subtitle: 64,
large: 88
},
/**
* Card.
*/
card: {
minHeight: 80,
imageAspectRatio: 16 / 9
},
/**
* Modal.
*/
modal: {
maxWidth: 540,
minHeight: 200
},
/**
* Sheet.
*/
sheet: {
handleWidth: 36,
handleHeight: 5,
snapPoints: {
collapsed: 0.25,
half: 0.5,
expanded: 0.9
}
},
/**
* Toast.
*/
toast: {
minHeight: 48,
maxWidth: 400
}
};
function meetsMinimumTouchTarget(size) {
return size >= sizes.touchTarget.minimum;
}
function ensureMinimumTouchTarget(size) {
return Math.max(size, sizes.touchTarget.minimum);
}
function getIconSizeForContext(context) {
switch (context) {
case "inline":
return sizes.icon.sm;
case "navigation":
return sizes.icon.lg;
case "tabBar":
return sizes.icon.lg;
case "feature":
return sizes.icon.xl;
default:
return sizes.icon.md;
}
}
exports.SPACING_UNIT = SPACING_UNIT;
exports.animation = animation;
exports.animationPresets = animationPresets;
exports.bold = bold;
exports.bottomRounded = bottomRounded;
exports.breakpoints = breakpoints;
exports.circular = circular;
exports.combineShadows = combineShadows;
exports.componentSizes = componentSizes;
exports.corners = corners;
exports.createShadow = createShadow;
exports.darkColors = darkColors;
exports.darkShadows = darkShadows;
exports.duration = duration;
exports.easing = easing;
exports.emphasized = emphasized;
exports.ensureMinimumTouchTarget = ensureMinimumTouchTarget;
exports.fontFamily = fontFamily;
exports.getIconSizeForContext = getIconSizeForContext;
exports.hasMinimumContrast = hasMinimumContrast;
exports.insetAll = insetAll;
exports.insetDirectional = insetDirectional;
exports.insetSquish = insetSquish;
exports.layoutConstants = layoutConstants;
exports.leftRounded = leftRounded;
exports.lightColors = lightColors;
exports.lightShadows = lightShadows;
exports.meetsMinimumTouchTarget = meetsMinimumTouchTarget;
exports.opacity = opacity;
exports.radius = radius;
exports.reducedMotionPresets = reducedMotionPresets;
exports.rightRounded = rightRounded;
exports.scaleShadow = scaleShadow;
exports.semanticRadius = semanticRadius;
exports.semanticShadows = semanticShadows;
exports.shadowColors = shadowColors;
exports.sizes = sizes;
exports.space = space;
exports.spacing = spacing;
exports.stagger = stagger;
exports.topRounded = topRounded;
exports.typography = typography;
exports.typographyEmphasis = typographyEmphasis;
exports.withAlpha = withAlpha;
exports.withDelay = withDelay;
exports.withSize = withSize;
exports.withWeight = withWeight;
exports.zIndex = zIndex;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map