august-design-system
Version:
A comprehensive React Native design system following Apple Human Interface Guidelines
1,438 lines (1,425 loc) • 31.2 kB
JavaScript
'use strict';
var React = require('react');
var reactNative = require('react-native');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
// 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)"
}
};
// 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 emphasized(style) {
return withWeight(style, "600");
}
({
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 = {
// 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
}
};
// src/design-system/tokens/radius.ts
var radius = {
none: 0,
xs: 4,
sm: 8,
md: 12,
lg: 16,
xl: 20,
xxl: 24,
full: 9999
};
({
/**
* 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
});
// 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
}
};
({
/**
* 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
});
// 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
};
({
/**
* 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
}
});
({
/**
* 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
}
});
// 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
};
// src/design-system/theme/defaultTheme.ts
var lightTheme = {
name: "August Light",
mode: "light",
colors: lightColors,
typography,
fontFamily,
spacing,
radius,
shadows: lightShadows,
animation,
sizes,
zIndex,
breakpoints,
opacity
};
var darkTheme = {
name: "August Dark",
mode: "dark",
colors: darkColors,
typography,
fontFamily,
spacing,
radius,
shadows: darkShadows,
animation,
sizes,
zIndex,
breakpoints,
opacity
};
var defaultThemeConfig = {
light: lightTheme,
dark: darkTheme
};
function getTheme(mode) {
return mode === "dark" ? darkTheme : lightTheme;
}
// src/design-system/theme/createTheme.ts
function isPlainObject(value) {
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
}
function deepMerge(target, source) {
if (!isPlainObject(target) || !isPlainObject(source)) {
return source ?? target;
}
const output = { ...target };
const sourceObj = source;
const targetObj = target;
for (const key in sourceObj) {
if (Object.prototype.hasOwnProperty.call(sourceObj, key)) {
const sourceValue = sourceObj[key];
const targetValue = targetObj[key];
if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
output[key] = deepMerge(targetValue, sourceValue);
} else if (sourceValue !== void 0) {
output[key] = sourceValue;
}
}
}
return output;
}
function createLightTheme(name, extension = {}) {
const baseTheme = { ...lightTheme, name };
return deepMerge(baseTheme, extension);
}
function createDarkTheme(name, extension = {}) {
const baseTheme = { ...darkTheme, name };
return deepMerge(baseTheme, extension);
}
function createTheme(config) {
return {
light: createLightTheme(`${config.name} Light`, config.light),
dark: createDarkTheme(`${config.name} Dark`, config.dark)
};
}
function createBrandColors(primary, options = {}) {
return {
colors: {
interactive: {
tint: primary,
tintPressed: options.primaryPressed ?? primary,
tintDisabled: options.primaryDisabled ?? `${primary}4D`
// 30% opacity
}
}
};
}
function createCustomTypography(fontFamilies) {
return {
fontFamily: {
regular: fontFamilies.regular ?? "System",
medium: fontFamilies.medium ?? "System",
semibold: fontFamilies.semibold ?? "System",
bold: fontFamilies.bold ?? "System",
heavy: "System",
monospace: "Menlo",
rounded: "System"
}
};
}
function mergeExtensions(...extensions) {
return extensions.reduce(
(acc, ext) => deepMerge(acc, ext),
{}
);
}
function isValidTheme(theme) {
if (!isPlainObject(theme)) return false;
const requiredKeys = [
"name",
"mode",
"colors",
"typography",
"fontFamily",
"spacing",
"radius",
"shadows",
"animation",
"sizes",
"zIndex",
"breakpoints",
"opacity"
];
return requiredKeys.every((key) => key in theme);
}
function getTokenValue(theme, path) {
const keys = path.split(".");
let current = theme;
for (const key of keys) {
if (!isPlainObject(current) || !(key in current)) {
return void 0;
}
current = current[key];
}
return current;
}
var defaultContextValue = {
theme: lightTheme,
colorMode: "light",
colorModePreference: "system",
toggleColorMode: () => {
console.warn("ThemeProvider not found in component tree");
},
setColorMode: () => {
console.warn("ThemeProvider not found in component tree");
},
isDark: false,
isLight: true
};
var ThemeContext = React.createContext(defaultContextValue);
function ThemeProvider({
children,
defaultColorMode = "system",
theme: customTheme,
storageKey = "august-color-mode"
}) {
const systemColorScheme = reactNative.useColorScheme();
const [colorModePreference, setColorModePreference] = React.useState(defaultColorMode);
const colorMode = React.useMemo(() => {
if (colorModePreference === "system") {
return systemColorScheme === "dark" ? "dark" : "light";
}
return colorModePreference;
}, [colorModePreference, systemColorScheme]);
const themes = React.useMemo(() => {
if (customTheme) {
return {
light: createLightTheme(
customTheme.name ? `${customTheme.name} Light` : "Custom Light",
customTheme.light
),
dark: createDarkTheme(
customTheme.name ? `${customTheme.name} Dark` : "Custom Dark",
customTheme.dark
)
};
}
return {
light: lightTheme,
dark: darkTheme
};
}, [customTheme]);
const currentTheme = React.useMemo(() => {
return colorMode === "dark" ? themes.dark : themes.light;
}, [colorMode, themes]);
const toggleColorMode = React.useCallback(() => {
setColorModePreference((prev) => {
if (prev === "system") {
return colorMode === "dark" ? "light" : "dark";
}
return prev === "dark" ? "light" : "dark";
});
}, [colorMode]);
const setColorMode = React.useCallback((mode) => {
setColorModePreference(mode);
}, []);
const contextValue = React.useMemo(
() => ({
theme: currentTheme,
colorMode,
colorModePreference,
toggleColorMode,
setColorMode,
isDark: colorMode === "dark",
isLight: colorMode === "light"
}),
[
currentTheme,
colorMode,
colorModePreference,
toggleColorMode,
setColorMode
]
);
return /* @__PURE__ */ React__default.default.createElement(ThemeContext.Provider, { value: contextValue }, children);
}
function useTheme() {
const context = React.useContext(ThemeContext);
if (context === defaultContextValue) {
console.warn(
"useTheme must be used within a ThemeProvider. Falling back to default light theme."
);
}
return context;
}
function useThemeTokens() {
const { theme } = useTheme();
return theme;
}
function useColorMode() {
const { colorMode } = useTheme();
return colorMode;
}
function useIsDarkMode() {
const { isDark } = useTheme();
return isDark;
}
function useToken(selector) {
const { theme } = useTheme();
return React.useMemo(() => selector(theme), [theme, selector]);
}
function useColors() {
const { theme } = useTheme();
return theme.colors;
}
function useSpacing() {
const { theme } = useTheme();
return theme.spacing;
}
function useTypography() {
const { theme } = useTheme();
return theme.typography;
}
exports.ThemeContext = ThemeContext;
exports.ThemeProvider = ThemeProvider;
exports.createBrandColors = createBrandColors;
exports.createCustomTypography = createCustomTypography;
exports.createDarkTheme = createDarkTheme;
exports.createLightTheme = createLightTheme;
exports.createTheme = createTheme;
exports.darkTheme = darkTheme;
exports.defaultThemeConfig = defaultThemeConfig;
exports.getTheme = getTheme;
exports.getTokenValue = getTokenValue;
exports.isValidTheme = isValidTheme;
exports.lightTheme = lightTheme;
exports.mergeExtensions = mergeExtensions;
exports.useColorMode = useColorMode;
exports.useColors = useColors;
exports.useIsDarkMode = useIsDarkMode;
exports.useSpacing = useSpacing;
exports.useTheme = useTheme;
exports.useThemeTokens = useThemeTokens;
exports.useToken = useToken;
exports.useTypography = useTypography;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map