UNPKG

@johnmusans/arcadia-ui-style-engine

Version:

Shared style system logic and types for Arcadia UI components

295 lines (266 loc) 9.09 kB
import { z } from "zod"; import { registryBackgroundPatterns } from "@arcadia-ui/registry-definition/registry-bg-patterns"; import { iconLibraries } from "@arcadia-ui/registry-definition/registry-icons"; import { registryTextures } from "@arcadia-ui/registry-definition/registry-textures"; // --------------------------------- Definitions ----------------------------------- // // Icons export const iconLibrarySchema = z.enum(iconLibraries.map((lib) => lib.name)); export const iconsDefinitionSchema = z.object({ library: iconLibrarySchema, strokeWidth: z.number().min(0.5).max(3), }); // Colors export const colorScaleSchema = z.object({ name: z.string().min(1), colorKeys: z .array( z.object({ id: z.number(), color: z.string(), }), ) .min(1), ratios: z.array(z.number().min(0)), smooth: z.boolean(), overrides: z.record(z.string(), z.string()), }); export const modeDefinitionSchema = z.object({ lightness: z.number().min(0).max(100), saturation: z.number().min(0).max(100), contrast: z.number().min(0).max(500), scales: z .object({ neutral: colorScaleSchema, accent: colorScaleSchema, success: colorScaleSchema, warning: colorScaleSchema, danger: colorScaleSchema, info: colorScaleSchema, }) .and(z.record(z.string(), colorScaleSchema)), }); export const colorTokenSchema = z.object({ id: z.string(), name: z.string(), value: z.string(), }); export const colorTokensSchema = z.array(colorTokenSchema); // layout export const radiusSchema = z.number().min(0).max(2); export const spacingSchema = z.number().min(0.1).max(0.35); // typography export const fontsSchema = z.object({ heading: z.string().min(2), body: z.string().min(2), }); export const letterSpacingSchema = z.number().min(-0.05).max(0.1); // effects export const backgroundPatternSchema = z.enum([ "none", ...registryBackgroundPatterns.map((bgPattern) => bgPattern.slug), ]); export const textureSchema = z.enum([ "none", ...registryTextures.map((texture) => texture.slug), ]); export const shadowPresetSchema = z.enum(["default"]); export const shadowsSchema = z.union([ shadowPresetSchema, z.object({ color: z.string(), opacity: z.number().min(0).max(1), blurRadius: z.number().min(0).max(100), offsetX: z.number().min(0).max(100), offsetY: z.number().min(0).max(100), spread: z.number().min(0).max(100), }), ]); export const activeModesSchema = z .array(z.enum(["light", "dark"]).and(z.string())) .refine((modes) => modes.length > 0, { message: "At least one mode must be defined", }); // theme export const themeDefinitionSchema = z.object({ colors: z.object({ activeModes: activeModesSchema, modes: z.object({ light: modeDefinitionSchema, dark: modeDefinitionSchema, }), tokens: colorTokensSchema, }), radius: radiusSchema, spacing: spacingSchema, fonts: fontsSchema, letterSpacing: letterSpacingSchema, backgroundPattern: backgroundPatternSchema, texture: textureSchema, shadows: shadowsSchema, }); // Variants export const variantsDefinitionSchema = z.object({ alert: z.enum(["basic", "notch", "notch-2"]), buttons: z.enum(["basic", "brutalist", "outline", "ripple"]), loader: z.enum(["ring"]), "focus-style": z.enum(["basic"]), inputs: z.enum(["basic"]), pickers: z.enum(["basic"]), selection: z.enum(["basic"]), calendars: z.enum(["basic"]), "list-box-and-menu": z.enum(["basic"]), overlays: z.enum(["basic"]), checkboxes: z.enum(["basic"]), radios: z.enum(["basic"]), switch: z.enum(["basic"]), slider: z.enum(["basic"]), "badge-and-tag-group": z.enum(["basic"]), tooltip: z.enum(["basic"]), }); export const styleDefinitionSchema = z.object({ theme: themeDefinitionSchema, icons: iconsDefinitionSchema, variants: variantsDefinitionSchema, }); // --------------------------------- Minimized definitions ----------------------------------- // export const minimizedColorTokensSchema = colorTokensSchema.optional(); export const minimizedColorScaleSchema = z.object({ name: z.string().min(1).optional(), colorKeys: z.array(z.string()).min(1).optional(), ratios: z.array(z.number().min(0)).optional(), smooth: z.boolean().optional(), overrides: z.record(z.string(), z.string()).optional(), }); export const minimizedModeDefinitionSchema = z.object({ lightness: z.number().min(0).max(100).optional(), saturation: z.number().min(0).max(100).optional(), contrast: z.number().min(0).max(500).optional(), scales: z .object({ neutral: minimizedColorScaleSchema.optional(), accent: minimizedColorScaleSchema.optional(), success: minimizedColorScaleSchema.optional(), warning: minimizedColorScaleSchema.optional(), danger: minimizedColorScaleSchema.optional(), info: minimizedColorScaleSchema.optional(), }) .and(z.record(z.string(), minimizedColorScaleSchema)) .optional(), }); export const minimizedThemeDefinitionSchema = z.object({ colors: z.object({ activeModes: activeModesSchema.optional(), modes: z .object({ light: minimizedModeDefinitionSchema.optional(), dark: minimizedModeDefinitionSchema.optional(), }) .optional(), tokens: colorTokensSchema.optional(), }), radius: radiusSchema.optional(), spacing: spacingSchema.optional(), fonts: fontsSchema.partial().optional(), letterSpacing: letterSpacingSchema.optional(), backgroundPattern: backgroundPatternSchema.optional(), texture: textureSchema.optional(), shadows: shadowsSchema.optional(), }); export const minimizedVariantsDefinitionSchema = variantsDefinitionSchema.partial(); export const minimizedIconsDefinitionSchema = iconsDefinitionSchema .partial() .optional(); export const minimizedStyleDefinitionSchema = z.object({ theme: minimizedThemeDefinitionSchema, icons: minimizedIconsDefinitionSchema.optional().nullable(), variants: minimizedVariantsDefinitionSchema.optional().nullable(), }); // --------------------------------- Processed ----------------------------------- // export const CssSchema = z.record( z.string(), z.union([ z.string(), z.record( z.string(), z.union([z.string(), z.record(z.string(), z.string())]), ), ]), ); // Theme will include all the cssVars and css need for colors, radius, spacing, fonts, backgroundPattern, texture and shadows. export const themeSchema = z.object({ css: CssSchema.optional(), cssVars: z.object({ light: z.record(z.string(), z.string()), dark: z.record(z.string(), z.string()).optional(), theme: z.record(z.string(), z.string()), }), }); export const variantsSchema = z.object({ // components alert: z.enum(["basic", "notch", "notch-2"]), avatar: z.enum(["basic"]), badge: z.enum(["basic"]), breadcrumbs: z.enum(["basic"]), button: z.enum(["basic", "outline", "brutalist", "ripple"]), "button-group": z.enum(["basic"]), calendar: z.enum(["basic", "cal"]), card: z.enum(["basic"]), checkbox: z.enum(["basic"]), "checkbox-group": z.enum(["basic"]), "color-area": z.enum(["basic"]), "color-field": z.enum(["basic"]), "color-picker": z.enum(["basic"]), "color-slider": z.enum(["basic"]), "color-swatch": z.enum(["basic"]), "color-swatch-picker": z.enum(["basic"]), "color-thumb": z.enum(["basic"]), combobox: z.enum(["basic"]), command: z.enum(["basic"]), "date-field": z.enum(["basic"]), "date-input": z.enum(["basic"]), "date-picker": z.enum(["basic"]), "date-range-picker": z.enum(["basic"]), dialog: z.enum(["basic"]), drawer: z.enum(["basic"]), "drop-zone": z.enum(["basic"]), field: z.enum(["basic"]), "file-trigger": z.enum(["basic"]), form: z.enum(["basic", "react-hook-form"]), input: z.enum(["basic"]), kbd: z.enum(["basic"]), "list-box": z.enum(["basic"]), loader: z.enum(["dots", "line", "ring", "tailspin", "wave"]), menu: z.enum(["basic"]), modal: z.enum(["basic", "blur"]), "number-field": z.enum(["basic"]), overlay: z.enum(["basic"]), popover: z.enum(["basic"]), "progress-bar": z.enum(["basic"]), "radio-group": z.enum(["basic"]), ripple: z.enum(["basic"]), "search-field": z.enum(["basic"]), select: z.enum(["basic"]), separator: z.enum(["basic"]), skeleton: z.enum(["basic"]), slider: z.enum(["basic"]), switch: z.enum(["basic"]), table: z.enum(["basic"]), tabs: z.enum(["basic", "motion"]), "tag-group": z.enum(["basic"]), text: z.enum(["basic"]), "text-area": z.enum(["basic"]), "text-field": z.enum(["basic"]), "time-field": z.enum(["basic"]), "toggle-button": z.enum(["basic"]), "toggle-button-group": z.enum(["basic"]), tooltip: z.enum(["basic", "motion"]), toast: z.enum(["basic"]), // lib "focus-style": z.enum(["basic"]), }); export const styleSchema = z.object({ theme: themeSchema, // used in {styleName}/theme icons: iconsDefinitionSchema, // used in {styleName}/base and {styleName}/{componentName} variants: variantsSchema, // used in {styleName}/{componentName} });