UNPKG

@jonmatum/react-mfe-shell

Version:

Production-ready React micro frontend shell with atomic design system, shared components, and utilities for building scalable MFE applications

1,861 lines (1,851 loc) 169 kB
"use client" "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { AVATAR_SIZES: () => AVATAR_SIZES, Avatar: () => Avatar_default, BADGE_SIZES: () => BADGE_SIZES, BADGE_VARIANTS: () => BADGE_VARIANTS, BUTTON_SIZES: () => BUTTON_SIZES, BUTTON_VARIANTS: () => BUTTON_VARIANTS, Badge: () => Badge_default, Button: () => Button_default, Card: () => Card_default, Checkbox: () => Checkbox_default, Code: () => Code_default, DARK_MODE_MEDIA_QUERY: () => DARK_MODE_MEDIA_QUERY, Divider: () => Divider_default, FEATURE_CHIP_SIZES: () => FEATURE_CHIP_SIZES, FEATURE_CHIP_VARIANTS: () => FEATURE_CHIP_VARIANTS, FORM_FIELD_SIZES: () => FORM_FIELD_SIZES, FORM_FIELD_VARIANTS: () => FORM_FIELD_VARIANTS, FeatureChip: () => FeatureChip_default, FileUpload: () => FileUpload_default, FormField: () => FormField_default, Heading: () => Heading_default, ICON_SIZES: () => ICON_SIZES, INPUT_SIZES: () => INPUT_SIZES, INPUT_VARIANTS: () => INPUT_VARIANTS, Icon: () => Icon_default, Input: () => Input_default, LABEL_SIZES: () => LABEL_SIZES, LINE_CLAMP_OPTIONS: () => LINE_CLAMP_OPTIONS, Label: () => Label_default, LoadingSpinner: () => LoadingSpinner_default, Modal: () => Modal_default, Paragraph: () => Paragraph_default, Radio: () => Radio_default, SearchBox: () => SearchBox_default, Select: () => Select_default, SettingsProvider: () => SettingsProvider, Switch: () => Switch_default, SwitchField: () => SwitchField_default, TEXT_ALIGNMENTS: () => TEXT_ALIGNMENTS, TEXT_DECORATIONS: () => TEXT_DECORATIONS, TEXT_OVERFLOW: () => TEXT_OVERFLOW, TEXT_SIZES: () => TEXT_SIZES, TEXT_TRANSFORMS: () => TEXT_TRANSFORMS, TEXT_VARIANTS: () => TEXT_VARIANTS, TEXT_WEIGHTS: () => TEXT_WEIGHTS, TEXT_WHITESPACE: () => TEXT_WHITESPACE, THEME_CLASS_NAMES: () => THEME_CLASS_NAMES, THEME_MODES: () => THEME_MODES, THEME_STORAGE_KEY: () => THEME_STORAGE_KEY, TYPOGRAPHY_BREAKPOINTS: () => TYPOGRAPHY_BREAKPOINTS, Text: () => Text_default, Textarea: () => Textarea_default, TypographyProvider: () => TypographyProvider, alignmentClasses: () => alignmentClasses, animationDuration: () => animationDuration, animationTimingFunction: () => animationTimingFunction, applyThemeCustomProperties: () => applyThemeCustomProperties, applyThemeToDOM: () => applyThemeToDOM, baseColors: () => baseColors, borderRadius: () => borderRadius, boxShadow: () => boxShadow, breakpoints: () => breakpoints, clamp: () => clamp, classNames: () => classNames, clearThemePreference: () => clearThemePreference, colors: () => colors, componentSizes: () => componentSizes, createSystemThemeListener: () => createSystemThemeListener, createThemeConfig: () => createThemeConfig, debounce: () => debounce, decorationClasses: () => decorationClasses, deepMerge: () => deepMerge, dropShadow: () => dropShadow, fontFamily: () => fontFamily, fontSize: () => fontSize, fontWeight: () => fontWeight, formatNumber: () => formatNumber, generateHeadingClasses: () => generateHeadingClasses, generateId: () => generateId, generateResponsiveClasses: () => generateResponsiveClasses, generateThemeCustomProperties: () => generateThemeCustomProperties, generateTypographyClasses: () => generateTypographyClasses, getCurrentThemeFromDOM: () => getCurrentThemeFromDOM, getFieldErrorProps: () => getFieldErrorProps, getFormFieldAccessibility: () => getFormFieldAccessibility, getOppositeTheme: () => getOppositeTheme, getSemanticElement: () => getSemanticElement, getSystemTheme: () => getSystemTheme, getThemeColor: () => getThemeColor, getVariantConfig: () => getVariantConfig, initializeTheme: () => initializeTheme, isBrowser: () => isBrowser, isDarkTheme: () => isDarkTheme, isLightTheme: () => isLightTheme, isValidThemeMode: () => isValidThemeMode, leadingClasses: () => leadingClasses, letterSpacing: () => letterSpacing, lineClampClasses: () => lineClampClasses, loadThemePreference: () => loadThemePreference, overflowClasses: () => overflowClasses, prefersReducedMotion: () => prefersReducedMotion, resolveTheme: () => resolveTheme, saveThemePreference: () => saveThemePreference, semanticColors: () => semanticColors, setupThemeManagement: () => setupThemeManagement, shadows: () => shadows, sizeClasses: () => sizeClasses, spacing: () => spacing, storage: () => storage, theme: () => theme, themeColors: () => themeColors, throttle: () => throttle, tokens: () => tokens_default, trackingClasses: () => trackingClasses, transformClasses: () => transformClasses, transitions: () => transitions, truncate: () => truncate, typography: () => typography, typographyScales: () => typographyScales, typographyVariants: () => typographyVariants, useFormField: () => useFormField, useFormFieldId: () => useFormFieldId, useScaledTypography: () => useScaledTypography, useSettings: () => useSettings, useTypography: () => useTypography, validateField: () => validateField, validateTypographyProps: () => validateTypographyProps, validationPatterns: () => validationPatterns, weightClasses: () => weightClasses, whitespaceClasses: () => whitespaceClasses, zIndex: () => zIndex }); module.exports = __toCommonJS(index_exports); // src/utils/tokens.ts var baseColors = { // Neutral colors white: "#ffffff", black: "#000000", // Gray scale (optimized for accessibility) gray: { 50: "#f9fafb", 100: "#f3f4f6", 200: "#e5e7eb", 300: "#d1d5db", 400: "#9ca3af", 500: "#6b7280", 600: "#4b5563", 700: "#374151", 800: "#1f2937", 900: "#111827", 950: "#030712" }, // Primary brand colors blue: { 50: "#eff6ff", 100: "#dbeafe", 200: "#bfdbfe", 300: "#93c5fd", 400: "#60a5fa", 500: "#3b82f6", 600: "#2563eb", 700: "#1d4ed8", 800: "#1e40af", 900: "#1e3a8a", 950: "#172554" }, // Success colors green: { 50: "#f0fdf4", 100: "#dcfce7", 200: "#bbf7d0", 300: "#86efac", 400: "#4ade80", 500: "#22c55e", 600: "#16a34a", 700: "#15803d", 800: "#166534", 900: "#14532d", 950: "#052e16" }, // Warning colors yellow: { 50: "#fefce8", 100: "#fef3c7", 200: "#fde68a", 300: "#fcd34d", 400: "#fbbf24", 500: "#f59e0b", 600: "#d97706", 700: "#b45309", 800: "#92400e", 900: "#78350f", 950: "#451a03" }, // Error colors red: { 50: "#fef2f2", 100: "#fee2e2", 200: "#fecaca", 300: "#fca5a5", 400: "#f87171", 500: "#ef4444", 600: "#dc2626", 700: "#b91c1c", 800: "#991b1b", 900: "#7f1d1d", 950: "#450a0a" }, // Info colors cyan: { 50: "#ecfeff", 100: "#cffafe", 200: "#a5f3fc", 300: "#67e8f9", 400: "#22d3ee", 500: "#06b6d4", 600: "#0891b2", 700: "#0e7490", 800: "#155e75", 900: "#164e63", 950: "#083344" } }; var semanticColors = { primary: baseColors.blue, secondary: baseColors.gray, success: baseColors.green, warning: baseColors.yellow, error: baseColors.red, info: baseColors.cyan }; var themeColors = { light: { // Background colors background: { primary: baseColors.white, secondary: baseColors.gray[50], tertiary: baseColors.gray[100] }, // Surface colors (cards, modals, etc.) surface: { primary: baseColors.white, secondary: baseColors.gray[50], tertiary: baseColors.gray[100], elevated: baseColors.white }, // Text colors text: { primary: baseColors.gray[900], secondary: baseColors.gray[600], tertiary: baseColors.gray[500], inverse: baseColors.white, disabled: baseColors.gray[400] }, // Border colors border: { primary: baseColors.gray[200], secondary: baseColors.gray[300], tertiary: baseColors.gray[400], focus: semanticColors.primary[500] }, // Interactive colors interactive: { primary: semanticColors.primary[600], "primary-hover": semanticColors.primary[700], "primary-active": semanticColors.primary[800], secondary: baseColors.gray[100], "secondary-hover": baseColors.gray[200], "secondary-active": baseColors.gray[300] }, // Status colors status: { success: semanticColors.success[600], warning: semanticColors.warning[600], error: semanticColors.error[600], info: semanticColors.info[600] } }, dark: { // Background colors background: { primary: baseColors.gray[900], secondary: baseColors.gray[800], tertiary: baseColors.gray[700] }, // Surface colors surface: { primary: baseColors.gray[800], secondary: baseColors.gray[700], tertiary: baseColors.gray[600], elevated: baseColors.gray[700] }, // Text colors text: { primary: baseColors.gray[100], secondary: baseColors.gray[300], tertiary: baseColors.gray[400], inverse: baseColors.gray[900], disabled: baseColors.gray[500] }, // Border colors border: { primary: baseColors.gray[700], secondary: baseColors.gray[600], tertiary: baseColors.gray[500], focus: semanticColors.primary[400] }, // Interactive colors interactive: { primary: semanticColors.primary[500], "primary-hover": semanticColors.primary[400], "primary-active": semanticColors.primary[300], secondary: baseColors.gray[700], "secondary-hover": baseColors.gray[600], "secondary-active": baseColors.gray[500] }, // Status colors status: { success: semanticColors.success[500], warning: semanticColors.warning[500], error: semanticColors.error[500], info: semanticColors.info[500] } } }; var fontFamily = { sans: [ "Inter", "-apple-system", "BlinkMacSystemFont", '"Segoe UI"', "Roboto", '"Helvetica Neue"', "Arial", "sans-serif" ], mono: [ '"JetBrains Mono"', "Menlo", "Monaco", "Consolas", '"Liberation Mono"', '"Courier New"', "monospace" ] }; var fontSize = { xs: ["0.75rem", { lineHeight: "1rem" }], // 12px sm: ["0.875rem", { lineHeight: "1.25rem" }], // 14px base: ["1rem", { lineHeight: "1.5rem" }], // 16px lg: ["1.125rem", { lineHeight: "1.75rem" }], // 18px xl: ["1.25rem", { lineHeight: "1.75rem" }], // 20px "2xl": ["1.5rem", { lineHeight: "2rem" }], // 24px "3xl": ["1.875rem", { lineHeight: "2.25rem" }], // 30px "4xl": ["2.25rem", { lineHeight: "2.5rem" }], // 36px "5xl": ["3rem", { lineHeight: "1" }], // 48px "6xl": ["3.75rem", { lineHeight: "1" }], // 60px "7xl": ["4.5rem", { lineHeight: "1" }], // 72px "8xl": ["6rem", { lineHeight: "1" }], // 96px "9xl": ["8rem", { lineHeight: "1" }] // 128px }; var fontWeight = { thin: "100", extralight: "200", light: "300", normal: "400", medium: "500", semibold: "600", bold: "700", extrabold: "800", black: "900" }; var letterSpacing = { tighter: "-0.05em", tight: "-0.025em", normal: "0em", wide: "0.025em", wider: "0.05em", widest: "0.1em" }; var spacing = { 0: "0px", px: "1px", 0.5: "0.125rem", // 2px 1: "0.25rem", // 4px 1.5: "0.375rem", // 6px 2: "0.5rem", // 8px 2.5: "0.625rem", // 10px 3: "0.75rem", // 12px 3.5: "0.875rem", // 14px 4: "1rem", // 16px 5: "1.25rem", // 20px 6: "1.5rem", // 24px 7: "1.75rem", // 28px 8: "2rem", // 32px 9: "2.25rem", // 36px 10: "2.5rem", // 40px 11: "2.75rem", // 44px 12: "3rem", // 48px 14: "3.5rem", // 56px 16: "4rem", // 64px 20: "5rem", // 80px 24: "6rem", // 96px 28: "7rem", // 112px 32: "8rem", // 128px 36: "9rem", // 144px 40: "10rem", // 160px 44: "11rem", // 176px 48: "12rem", // 192px 52: "13rem", // 208px 56: "14rem", // 224px 60: "15rem", // 240px 64: "16rem", // 256px 72: "18rem", // 288px 80: "20rem", // 320px 96: "24rem" // 384px }; var boxShadow = { none: "none", sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)", base: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)", xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)", "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)", inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)" }; var dropShadow = { none: "none", sm: "0 1px 1px rgb(0 0 0 / 0.05)", base: "0 1px 2px rgb(0 0 0 / 0.1)", md: "0 4px 3px rgb(0 0 0 / 0.07)", lg: "0 10px 8px rgb(0 0 0 / 0.04)", xl: "0 20px 13px rgb(0 0 0 / 0.03)", "2xl": "0 25px 25px rgb(0 0 0 / 0.15)" }; var borderRadius = { none: "0px", sm: "0.125rem", // 2px base: "0.25rem", // 4px md: "0.375rem", // 6px lg: "0.5rem", // 8px xl: "0.75rem", // 12px "2xl": "1rem", // 16px "3xl": "1.5rem", // 24px full: "9999px" }; var breakpoints = { xs: "475px", sm: "640px", md: "768px", lg: "1024px", xl: "1280px", "2xl": "1536px" }; var animationDuration = { 75: "75ms", 100: "100ms", 150: "150ms", 200: "200ms", 300: "300ms", 500: "500ms", 700: "700ms", 1e3: "1000ms" }; var animationTimingFunction = { linear: "linear", in: "cubic-bezier(0.4, 0, 1, 1)", out: "cubic-bezier(0, 0, 0.2, 1)", "in-out": "cubic-bezier(0.4, 0, 0.2, 1)" }; var zIndex = { auto: "auto", 0: "0", 10: "10", 20: "20", 30: "30", 40: "40", 50: "50", dropdown: "1000", sticky: "1020", fixed: "1030", modal: "1040", popover: "1050", tooltip: "1060", toast: "1070" }; var componentSizes = { xs: { height: spacing[6], padding: `${spacing[1]} ${spacing[2]}`, fontSize: fontSize.xs[0] }, sm: { height: spacing[8], padding: `${spacing[1.5]} ${spacing[3]}`, fontSize: fontSize.sm[0] }, md: { height: spacing[10], padding: `${spacing[2]} ${spacing[4]}`, fontSize: fontSize.base[0] }, lg: { height: spacing[12], padding: `${spacing[2.5]} ${spacing[6]}`, fontSize: fontSize.lg[0] }, xl: { height: spacing[14], padding: `${spacing[3]} ${spacing[8]}`, fontSize: fontSize.xl[0] } }; var tokens = { colors: { base: baseColors, semantic: semanticColors, theme: themeColors }, typography: { fontFamily, fontSize, fontWeight, letterSpacing }, spacing, shadows: { box: boxShadow, drop: dropShadow }, borderRadius, breakpoints, animation: { duration: animationDuration, timingFunction: animationTimingFunction }, zIndex, components: { sizes: componentSizes } }; var colors = baseColors; var typography = { fontFamily, fontSize, fontWeight, letterSpacing }; var shadows = boxShadow; var transitions = animationTimingFunction; var tokens_default = tokens; // src/utils/theme.ts var THEME_MODES = ["light", "dark", "system"]; var THEME_STORAGE_KEY = "mfe-shell-theme"; var THEME_CLASS_NAMES = { light: "", dark: "dark" }; var DARK_MODE_MEDIA_QUERY = "(prefers-color-scheme: dark)"; function getSystemTheme() { if (typeof window === "undefined") { return "light"; } try { const mediaQuery = window.matchMedia(DARK_MODE_MEDIA_QUERY); return mediaQuery.matches ? "dark" : "light"; } catch { return "light"; } } function resolveTheme(mode) { switch (mode) { case "light": return "light"; case "dark": return "dark"; case "system": return getSystemTheme(); default: return "light"; } } function saveThemePreference(mode) { try { localStorage.setItem(THEME_STORAGE_KEY, mode); } catch (error) { console.warn("Failed to save theme preference:", error); } } function loadThemePreference() { try { const stored = localStorage.getItem(THEME_STORAGE_KEY); if (stored && THEME_MODES.includes(stored)) { return stored; } } catch (error) { console.warn("Failed to load theme preference:", error); } return "system"; } function clearThemePreference() { try { localStorage.removeItem(THEME_STORAGE_KEY); } catch (error) { console.warn("Failed to clear theme preference:", error); } } function applyThemeToDOM(mode) { if (typeof document === "undefined") { return; } const resolvedTheme = resolveTheme(mode); const { classList } = document.documentElement; classList.remove("light", "dark"); if (resolvedTheme === "dark") { classList.add("dark"); } document.documentElement.setAttribute("data-theme", resolvedTheme); } function getCurrentThemeFromDOM() { if (typeof document === "undefined") { return "light"; } return document.documentElement.classList.contains("dark") ? "dark" : "light"; } function generateThemeCustomProperties(theme2) { return { // Background colors "--color-background-primary": theme2.background.primary, "--color-background-secondary": theme2.background.secondary, "--color-background-tertiary": theme2.background.tertiary, // Surface colors "--color-surface-primary": theme2.surface.primary, "--color-surface-secondary": theme2.surface.secondary, "--color-surface-tertiary": theme2.surface.tertiary, "--color-surface-elevated": theme2.surface.elevated || theme2.surface.primary, // Text colors "--color-text-primary": theme2.text.primary, "--color-text-secondary": theme2.text.secondary, "--color-text-tertiary": theme2.text.tertiary, "--color-text-inverse": theme2.text.inverse, "--color-text-disabled": theme2.text.disabled, // Border colors "--color-border-primary": theme2.border.primary, "--color-border-secondary": theme2.border.secondary, "--color-border-tertiary": theme2.border.tertiary, "--color-border-focus": theme2.border.focus, // Interactive colors "--color-interactive-primary": theme2.interactive.primary, "--color-interactive-primary-hover": theme2.interactive["primary-hover"], "--color-interactive-primary-active": theme2.interactive["primary-active"], "--color-interactive-secondary": theme2.interactive.secondary, "--color-interactive-secondary-hover": theme2.interactive["secondary-hover"], "--color-interactive-secondary-active": theme2.interactive["secondary-active"], // Status colors "--color-status-success": theme2.status.success, "--color-status-warning": theme2.status.warning, "--color-status-error": theme2.status.error, "--color-status-info": theme2.status.info }; } function applyThemeCustomProperties(theme2) { if (typeof document === "undefined") { return; } const properties = generateThemeCustomProperties(theme2); const { style } = document.documentElement; Object.entries(properties).forEach(([property, value]) => { style.setProperty(property, value); }); } function createSystemThemeListener(callback) { if (typeof window === "undefined") { return null; } try { const mediaQuery = window.matchMedia(DARK_MODE_MEDIA_QUERY); const listener = (event) => { callback(event.matches); }; if (mediaQuery.addEventListener) { mediaQuery.addEventListener("change", listener); return () => { mediaQuery.removeEventListener("change", listener); }; } else if (mediaQuery.addListener) { mediaQuery.addListener(listener); return () => { mediaQuery.removeListener(listener); }; } } catch (error) { console.warn("Failed to create system theme listener:", error); } return null; } function createThemeConfig(mode) { const resolvedTheme = resolveTheme(mode); const colors2 = themeColors[resolvedTheme]; return { mode, colors: colors2 }; } function isValidThemeMode(mode) { return THEME_MODES.includes(mode); } function getOppositeTheme(theme2) { return theme2 === "light" ? "dark" : "light"; } function isDarkTheme(mode) { return resolveTheme(mode) === "dark"; } function isLightTheme(mode) { return resolveTheme(mode) === "light"; } function getThemeColor(colorPath, mode = "system") { const resolvedTheme = resolveTheme(mode); const colors2 = themeColors[resolvedTheme]; const pathParts = colorPath.split("."); let value = colors2; for (const part of pathParts) { if (value && typeof value === "object" && part in value) { value = value[part]; } else { return ""; } } return typeof value === "string" ? value : ""; } function initializeTheme() { const preferredMode = loadThemePreference(); applyThemeToDOM(preferredMode); const resolvedTheme = resolveTheme(preferredMode); applyThemeCustomProperties(themeColors[resolvedTheme]); return preferredMode; } function setupThemeManagement(onThemeChange) { const currentMode = initializeTheme(); const cleanup = createSystemThemeListener((isDark) => { const storedMode = loadThemePreference(); if (storedMode === "system") { const newTheme = isDark ? "dark" : "light"; applyThemeToDOM("system"); applyThemeCustomProperties(themeColors[newTheme]); onThemeChange?.("system", newTheme); } }); const setTheme = (mode) => { saveThemePreference(mode); applyThemeToDOM(mode); const resolvedTheme = resolveTheme(mode); applyThemeCustomProperties(themeColors[resolvedTheme]); onThemeChange?.(mode, resolvedTheme); }; return { currentMode, setTheme, cleanup: cleanup || (() => { }) }; } // src/utils/form.ts var import_react = require("react"); var validateField = (value, rules) => { if (!rules) return void 0; if (rules.required) { const isEmpty = value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0; if (isEmpty) { return typeof rules.required === "string" ? rules.required : "This field is required"; } } if (!value && !rules.required) return void 0; if (typeof value === "string") { if (rules.minLength) { const minLength = typeof rules.minLength === "number" ? rules.minLength : rules.minLength.value; const message = typeof rules.minLength === "object" ? rules.minLength.message : `Must be at least ${minLength} characters`; if (value.length < minLength) return message; } if (rules.maxLength) { const maxLength = typeof rules.maxLength === "number" ? rules.maxLength : rules.maxLength.value; const message = typeof rules.maxLength === "object" ? rules.maxLength.message : `Must be no more than ${maxLength} characters`; if (value.length > maxLength) return message; } if (rules.pattern) { const pattern = rules.pattern instanceof RegExp ? rules.pattern : rules.pattern.value; const message = rules.pattern instanceof RegExp ? "Invalid format" : rules.pattern.message; if (!pattern.test(value)) return message; } } if (rules.custom) { return rules.custom(value); } return void 0; }; var useFormField = ({ initialValue = "", validation, validateOnChange = false, validateOnBlur = true } = {}) => { const [state, setState] = (0, import_react.useState)({ value: initialValue, error: void 0, touched: false, dirty: false }); const validate = (0, import_react.useCallback)( (value) => { return validateField(value, validation); }, [validation] ); const setValue = (0, import_react.useCallback)( (newValue) => { setState((prev) => { const error = validateOnChange ? validate(newValue) : prev.error; return { ...prev, value: newValue, dirty: newValue !== initialValue, error }; }); }, [initialValue, validate, validateOnChange] ); const setTouched = (0, import_react.useCallback)(() => { setState((prev) => { if (prev.touched) return prev; const error = validateOnBlur ? validate(prev.value) : prev.error; return { ...prev, touched: true, error }; }); }, [validate, validateOnBlur]); const setError = (0, import_react.useCallback)((error) => { setState((prev) => ({ ...prev, error })); }, []); const reset = (0, import_react.useCallback)(() => { setState({ value: initialValue, error: void 0, touched: false, dirty: false }); }, [initialValue]); const validateNow = (0, import_react.useCallback)(() => { const error = validate(state.value); setState((prev) => ({ ...prev, error, touched: true })); return !error; }, [validate, state.value]); return { ...state, setValue, setTouched, setError, reset, validate: validateNow, isValid: !state.error }; }; var validationPatterns = { email: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "Please enter a valid email address" }, phone: { value: /^[+]?[1-9][\d]{0,15}$/, message: "Please enter a valid phone number" }, url: { value: /^https?:\/\/.+/, message: "Please enter a valid URL" }, alphanumeric: { value: /^[a-zA-Z0-9]+$/, message: "Only letters and numbers are allowed" }, noSpecialChars: { value: /^[a-zA-Z0-9\s]+$/, message: "Special characters are not allowed" } }; var useFormFieldId = (prefix = "field") => { return (0, import_react.useId)() || `${prefix}-${Math.random().toString(36).substr(2, 9)}`; }; var getFieldErrorProps = (error, fieldId) => ({ "aria-invalid": error ? "true" : "false", "aria-describedby": error && fieldId ? `${fieldId}-error` : void 0 }); var getFormFieldAccessibility = (fieldId, error, description, required) => { const describedBy = []; if (description) describedBy.push(`${fieldId}-description`); if (error) describedBy.push(`${fieldId}-error`); return { id: fieldId, "aria-invalid": error ? "true" : "false", "aria-describedby": describedBy.length > 0 ? describedBy.join(" ") : void 0, "aria-required": required ? "true" : void 0 }; }; // src/utils/index.ts function classNames(...classes) { if (classes.length === 0) return ""; if (classes.length === 1) return classes[0] || ""; return classes.filter(Boolean).join(" "); } var storage = { get: (key, defaultValue) => { try { const item = localStorage.getItem(key); return item ? JSON.parse(item) : defaultValue; } catch { return defaultValue; } }, set: (key, value) => { try { localStorage.setItem(key, JSON.stringify(value)); } catch { } }, remove: (key) => { try { localStorage.removeItem(key); } catch { } }, clear: () => { try { localStorage.clear(); } catch { } } }; var systemThemeCache = null; var mediaQueryListener = null; var theme = { /** * Gets the system theme preference with caching */ getSystemTheme: () => { if (typeof window === "undefined") return "light"; if (systemThemeCache === null) { const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); systemThemeCache = mediaQuery.matches ? "dark" : "light"; if (!mediaQueryListener && mediaQuery.addEventListener) { mediaQueryListener = (e) => { systemThemeCache = e.matches ? "dark" : "light"; }; mediaQuery.addEventListener("change", mediaQueryListener); } } return systemThemeCache; }, /** * Applies theme to document with performance optimization */ applyTheme: (themeName) => { if (typeof document === "undefined") return; const actualTheme = themeName === "system" ? theme.getSystemTheme() : themeName; const { classList } = document.documentElement; if (classList && classList.contains) { const currentTheme = classList.contains("dark") ? "dark" : "light"; if (currentTheme !== actualTheme) { classList.remove("light", "dark"); classList.add(actualTheme); } } else { classList.remove("light", "dark"); classList.add(actualTheme); } }, /** * Clear theme cache (useful for testing) */ clearCache: () => { systemThemeCache = null; if (mediaQueryListener && typeof window !== "undefined") { const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); if (mediaQuery.removeEventListener) { mediaQuery.removeEventListener("change", mediaQueryListener); } mediaQueryListener = null; } } }; var debounceTimers = /* @__PURE__ */ new WeakMap(); function debounce(func, wait) { return (...args) => { const existingTimer = debounceTimers.get(func); if (existingTimer) { clearTimeout(existingTimer); } const timer = setTimeout(() => { debounceTimers.delete(func); func(...args); }, wait); debounceTimers.set(func, timer); }; } var throttleTimers = /* @__PURE__ */ new WeakMap(); function throttle(func, limit) { return (...args) => { const now = Date.now(); const throttleData = throttleTimers.get(func) || { timer: null, lastRun: 0 }; if (now - throttleData.lastRun >= limit) { func(...args); throttleData.lastRun = now; } else if (!throttleData.timer) { throttleData.timer = setTimeout( () => { func(...args); throttleData.lastRun = Date.now(); throttleData.timer = null; }, limit - (now - throttleData.lastRun) ); } throttleTimers.set(func, throttleData); }; } var idCounter = 0; function generateId(prefix = "id") { return `${prefix}-${++idCounter}-${Math.random().toString(36).substr(2, 9)}`; } var numberFormatters = /* @__PURE__ */ new Map(); function formatNumber(num, locale = "en-US") { if (!numberFormatters.has(locale)) { numberFormatters.set(locale, new Intl.NumberFormat(locale)); } return numberFormatters.get(locale).format(num); } function truncate(text, maxLength) { if (text.length <= maxLength) return text; return text.slice(0, maxLength - 3) + "..."; } function deepMerge(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); deepMerge( target[key], source[key] ); } else { Object.assign(target, { [key]: source[key] }); } } } return deepMerge(target, ...sources); } function isObject(item) { return item !== null && typeof item === "object" && !Array.isArray(item); } function clamp(value, min, max) { return Math.min(Math.max(value, min), max); } var isBrowser = typeof window !== "undefined"; function prefersReducedMotion() { if (!isBrowser) return false; return window.matchMedia("(prefers-reduced-motion: reduce)").matches; } // src/utils/typography.ts var typographyVariants = { // Content variants body: { defaultSize: "base", defaultWeight: "normal", defaultColor: "text-primary", semanticElement: "p", description: "Standard body text for content" }, "body-large": { defaultSize: "lg", defaultWeight: "normal", defaultColor: "text-primary", semanticElement: "p", description: "Larger body text for emphasis" }, "body-small": { defaultSize: "sm", defaultWeight: "normal", defaultColor: "text-primary", semanticElement: "p", description: "Smaller body text for secondary content" }, caption: { defaultSize: "sm", defaultWeight: "normal", defaultColor: "text-secondary", semanticElement: "span", description: "Captions and secondary information" }, overline: { defaultSize: "xs", defaultWeight: "medium", defaultColor: "text-secondary", semanticElement: "span", description: "Overline text with uppercase styling" }, label: { defaultSize: "sm", defaultWeight: "medium", defaultColor: "text-primary", semanticElement: "label", description: "Form labels and UI labels" }, helper: { defaultSize: "xs", defaultWeight: "normal", defaultColor: "text-secondary", semanticElement: "span", description: "Helper text and descriptions" }, // Display variants display: { defaultSize: "6xl", defaultWeight: "bold", defaultColor: "text-primary", semanticElement: "h1", description: "Large display text for hero sections" }, headline: { defaultSize: "4xl", defaultWeight: "bold", defaultColor: "text-primary", semanticElement: "h1", description: "Headlines and page titles" }, title: { defaultSize: "2xl", defaultWeight: "semibold", defaultColor: "text-primary", semanticElement: "h2", description: "Section titles and headings" }, subtitle: { defaultSize: "lg", defaultWeight: "medium", defaultColor: "text-secondary", semanticElement: "h3", description: "Subtitles and subheadings" }, // Specialized variants code: { defaultSize: "sm", defaultWeight: "normal", defaultColor: "text-primary", semanticElement: "code", description: "Inline code and monospace text" }, kbd: { defaultSize: "xs", defaultWeight: "medium", defaultColor: "text-primary", semanticElement: "kbd", description: "Keyboard shortcuts and keys" }, quote: { defaultSize: "lg", defaultWeight: "normal", defaultColor: "text-secondary", semanticElement: "blockquote", description: "Quotes and testimonials" }, lead: { defaultSize: "xl", defaultWeight: "normal", defaultColor: "text-primary", semanticElement: "p", description: "Lead paragraphs and introductions" }, muted: { defaultSize: "base", defaultWeight: "normal", defaultColor: "text-tertiary", semanticElement: "span", description: "Muted text with reduced emphasis" } }; var sizeClasses = { xs: "text-xs", sm: "text-sm", base: "text-base", lg: "text-lg", xl: "text-xl", "2xl": "text-2xl", "3xl": "text-3xl", "4xl": "text-4xl", "5xl": "text-5xl", "6xl": "text-6xl", "7xl": "text-7xl", "8xl": "text-8xl", "9xl": "text-9xl" }; var weightClasses = { thin: "font-thin", extralight: "font-extralight", light: "font-light", normal: "font-normal", medium: "font-medium", semibold: "font-semibold", bold: "font-bold", extrabold: "font-extrabold", black: "font-black" }; var alignmentClasses = { left: "text-left", center: "text-center", right: "text-right", justify: "text-justify", start: "text-start", end: "text-end" }; var transformClasses = { none: "", uppercase: "uppercase", lowercase: "lowercase", capitalize: "capitalize" }; var decorationClasses = { none: "no-underline", underline: "underline", overline: "overline", "line-through": "line-through" }; var whitespaceClasses = { normal: "whitespace-normal", nowrap: "whitespace-nowrap", pre: "whitespace-pre", "pre-line": "whitespace-pre-line", "pre-wrap": "whitespace-pre-wrap", "break-spaces": "whitespace-break-spaces" }; var overflowClasses = { visible: "overflow-visible", hidden: "overflow-hidden", clip: "text-clip", ellipsis: "text-ellipsis" }; var leadingClasses = { none: "leading-none", tight: "leading-tight", snug: "leading-snug", normal: "leading-normal", relaxed: "leading-relaxed", loose: "leading-loose" }; var trackingClasses = { tighter: "tracking-tighter", tight: "tracking-tight", normal: "tracking-normal", wide: "tracking-wide", wider: "tracking-wider", widest: "tracking-widest" }; var lineClampClasses = { 1: "line-clamp-1", 2: "line-clamp-2", 3: "line-clamp-3", 4: "line-clamp-4", 5: "line-clamp-5", 6: "line-clamp-6" }; function generateResponsiveClasses(value, classMap) { if (typeof value === "string" || typeof value === "number") { const className = classMap[value]; return className ? [className] : []; } if (typeof value === "object" && value !== null) { const classes = []; if ("base" in value && value.base) { const className = classMap[value.base]; if (className) classes.push(className); } Object.entries(value).forEach(([breakpoint, val]) => { if (breakpoint !== "base" && val) { const className = classMap[val]; if (className) { const responsiveClass = breakpoint === "xs" ? className : `${breakpoint}:${className}`; classes.push(responsiveClass); } } }); return classes; } return []; } var typographyScales = { default: { name: "Default Scale", sizes: { xs: { fontSize: "0.75rem", lineHeight: "1rem" }, sm: { fontSize: "0.875rem", lineHeight: "1.25rem" }, base: { fontSize: "1rem", lineHeight: "1.5rem" }, lg: { fontSize: "1.125rem", lineHeight: "1.75rem" }, xl: { fontSize: "1.25rem", lineHeight: "1.75rem" }, "2xl": { fontSize: "1.5rem", lineHeight: "2rem" }, "3xl": { fontSize: "1.875rem", lineHeight: "2.25rem" }, "4xl": { fontSize: "2.25rem", lineHeight: "2.5rem" }, "5xl": { fontSize: "3rem", lineHeight: "1" }, "6xl": { fontSize: "3.75rem", lineHeight: "1" }, "7xl": { fontSize: "4.5rem", lineHeight: "1" }, "8xl": { fontSize: "6rem", lineHeight: "1" }, "9xl": { fontSize: "8rem", lineHeight: "1" } }, weights: { thin: "100", extralight: "200", light: "300", normal: "400", medium: "500", semibold: "600", bold: "700", extrabold: "800", black: "900" } }, compact: { name: "Compact Scale", sizes: { xs: { fontSize: "0.625rem", lineHeight: "0.875rem" }, sm: { fontSize: "0.75rem", lineHeight: "1rem" }, base: { fontSize: "0.875rem", lineHeight: "1.25rem" }, lg: { fontSize: "1rem", lineHeight: "1.5rem" }, xl: { fontSize: "1.125rem", lineHeight: "1.5rem" }, "2xl": { fontSize: "1.25rem", lineHeight: "1.75rem" }, "3xl": { fontSize: "1.5rem", lineHeight: "2rem" }, "4xl": { fontSize: "1.875rem", lineHeight: "2.25rem" }, "5xl": { fontSize: "2.25rem", lineHeight: "2.5rem" }, "6xl": { fontSize: "3rem", lineHeight: "1" }, "7xl": { fontSize: "3.75rem", lineHeight: "1" }, "8xl": { fontSize: "4.5rem", lineHeight: "1" }, "9xl": { fontSize: "6rem", lineHeight: "1" } }, weights: { thin: "100", extralight: "200", light: "300", normal: "400", medium: "500", semibold: "600", bold: "700", extrabold: "800", black: "900" } }, generous: { name: "Generous Scale", sizes: { xs: { fontSize: "0.875rem", lineHeight: "1.25rem" }, sm: { fontSize: "1rem", lineHeight: "1.5rem" }, base: { fontSize: "1.125rem", lineHeight: "1.75rem" }, lg: { fontSize: "1.25rem", lineHeight: "1.875rem" }, xl: { fontSize: "1.5rem", lineHeight: "2rem" }, "2xl": { fontSize: "1.875rem", lineHeight: "2.25rem" }, "3xl": { fontSize: "2.25rem", lineHeight: "2.5rem" }, "4xl": { fontSize: "3rem", lineHeight: "1.2" }, "5xl": { fontSize: "3.75rem", lineHeight: "1.1" }, "6xl": { fontSize: "4.5rem", lineHeight: "1" }, "7xl": { fontSize: "6rem", lineHeight: "1" }, "8xl": { fontSize: "8rem", lineHeight: "1" }, "9xl": { fontSize: "10rem", lineHeight: "1" } }, weights: { thin: "100", extralight: "200", light: "300", normal: "400", medium: "500", semibold: "600", bold: "700", extrabold: "800", black: "900" } } }; function getVariantConfig(variant) { const config = typographyVariants[variant]; if (!config && process.env.NODE_ENV === "development") { console.warn( `Invalid typography variant: ${variant}. Falling back to 'body' variant.` ); return typographyVariants.body; } return config || typographyVariants.body; } function getSemanticElement(variant, as) { if (as) return as; const variantConfig = typographyVariants[variant]; if (!variantConfig) return "span"; const semanticElement = variantConfig.semanticElement; return semanticElement || "span"; } function generateTypographyClasses({ variant = "body", size, weight, align, transform, decoration, whitespace, overflow, leading, tracking, lineClamp, truncate: truncate2, color, gradient, selectable }) { const variantConfig = getVariantConfig(variant); const classes = []; if (variant === "overline") { classes.push("uppercase", "tracking-wide"); } if (variant === "code") { classes.push("font-mono"); } if (variant === "kbd") { classes.push( "font-mono", "px-1.5", "py-0.5", "text-xs", "bg-surface-secondary", "border", "border-border-primary", "rounded" ); } if (variant === "quote") { classes.push("italic", "border-l-4", "border-border-primary", "pl-4"); } if (size) { classes.push(...generateResponsiveClasses(size, sizeClasses)); } else { classes.push(sizeClasses[variantConfig.defaultSize]); } if (weight) { classes.push(...generateResponsiveClasses(weight, weightClasses)); } else { classes.push(weightClasses[variantConfig.defaultWeight]); } if (align) { classes.push(...generateResponsiveClasses(align, alignmentClasses)); } if (transform && transform !== "none") { classes.push(transformClasses[transform]); } if (decoration && decoration !== "none") { classes.push(decorationClasses[decoration]); } if (whitespace && whitespace !== "normal") { classes.push(whitespaceClasses[whitespace]); } if (overflow && overflow !== "visible") { classes.push(overflowClasses[overflow]); } if (leading && leading !== "normal") { classes.push(leadingClasses[leading]); } if (tracking && tracking !== "normal") { classes.push(trackingClasses[tracking]); } if (lineClamp) { classes.push(lineClampClasses[lineClamp]); } if (truncate2) { classes.push("truncate"); } if (color && (color.startsWith("text-") || color.startsWith("bg-"))) { classes.push(color); } else { classes.push(variantConfig.defaultColor); } if (gradient) { classes.push("bg-gradient-to-r", "bg-clip-text", "text-transparent"); } if (selectable === false) { classes.push("select-none"); } else if (selectable === true) { classes.push("select-text"); } return classNames(...classes); } function generateHeadingClasses(level) { const headingMap = { 1: { defaultSize: "4xl", defaultWeight: "bold" }, 2: { defaultSize: "3xl", defaultWeight: "bold" }, 3: { defaultSize: "2xl", defaultWeight: "semibold" }, 4: { defaultSize: "xl", defaultWeight: "semibold" }, 5: { defaultSize: "lg", defaultWeight: "medium" }, 6: { defaultSize: "base", defaultWeight: "medium" } }; return headingMap[level]; } function validateTypographyProps(props) { const errors = []; if (props.variant && typeof props.variant === "string" && !(props.variant in typographyVariants)) { errors.push(`Invalid variant: ${props.variant}`); } if (props.size && typeof props.size === "string" && !(props.size in sizeClasses)) { errors.push(`Invalid size: ${props.size}`); } if (props.weight && typeof props.weight === "string" && !(props.weight in weightClasses)) { errors.push(`Invalid weight: ${props.weight}`); } return errors; } // src/types/form.ts var FORM_FIELD_SIZES = ["sm", "md", "lg"]; var FORM_FIELD_VARIANTS = ["default", "error", "success"]; // src/types/index.ts var BUTTON_VARIANTS = [ "primary", "secondary", "ghost", "danger", "success", "warning" ]; var BUTTON_SIZES = ["xs", "sm", "md", "lg", "xl"]; var INPUT_VARIANTS = ["default", "error", "success"]; var INPUT_SIZES = ["sm", "md", "lg"]; var LABEL_SIZES = ["sm", "md", "lg"]; var ICON_SIZES = ["xs", "sm", "md", "lg", "xl", "2xl"]; var BADGE_VARIANTS = [ "default", "primary", "secondary", "success", "warning", "danger" ]; var BADGE_SIZES = ["sm", "md", "lg"]; var FEATURE_CHIP_VARIANTS = [ "default", "primary", "secondary", "success", "warning", "danger" ]; var FEATURE_CHIP_SIZES = ["sm", "md", "lg"]; var AVATAR_SIZES = ["xs", "sm", "md", "lg", "xl", "2xl"]; var TEXT_VARIANTS = [ // Content variants "body", "body-large", "body-small", "caption", "overline", "label", "helper", // Display variants "display", "headline", "title", "subtitle", // Specialized variants "code", "kbd", "quote", "lead", "muted" ]; var TEXT_SIZES = [ "xs", // 12px "sm", // 14px "base", // 16px (renamed from 'md' for clarity) "lg", // 18px "xl", // 20px "2xl", // 24px "3xl", // 30px "4xl", // 36px "5xl", // 48px "6xl", // 60px "7xl", // 72px "8xl", // 96px "9xl" // 128px ]; var TEXT_WEIGHTS = [ "thin", // 100 "extralight", // 200 "light", // 300 "normal", // 400 "medium", // 500 "semibold", // 600 "bold", // 700 "extrabold", // 800 "black" // 900 ]; var TEXT_ALIGNMENTS = [ "left", "center", "right", "justify", "start", "end" ]; var TEXT_TRANSFORMS = [ "none", "uppercase", "lowercase", "capitalize" ]; var TEXT_DECORATIONS = [ "none", "underline", "overline", "line-through" ]; var TEXT_WHITESPACE = [ "normal", "nowrap", "pre", "pre-line", "pre-wrap", "break-spaces" ]; var TEXT_OVERFLOW = ["visible", "hidden", "clip", "ellipsis"]; var LINE_CLAMP_OPTIONS = [1, 2, 3, 4, 5, 6]; var TYPOGRAPHY_BREAKPOINTS = [ "xs", "sm", "md", "lg", "xl", "2xl" ]; // src/contexts/SettingsContext.tsx var import_react2 = require("react"); var import_jsx_runtime = require("react/jsx-runtime"); var defaultSettings = { theme: "system", layout: "stacked", containerWidth: "boxed" }; var SettingsContext = (0, import_react2.createContext)( void 0 ); var SettingsProvider = ({ children, initialSettings = {}, storageKey = "mfe-settings" }) => { const [settings, setSettings] = (0, import_react2.useState)(() => { const savedSettings = storage.get(storageKey, {}); return { ...defaultSettings, ...initialSettings, ...savedSettings }; }); (0, import_react2.useEffect)(() => { theme.applyTheme(settings.theme); }, [settings.theme]); (0, import_react2.useEffect)(() => { if (settings.theme !== "system") return; const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const handleChange = () => { theme.applyTheme("system"); }; mediaQuery.addEventListener("change", handleChange); return () => mediaQuery.removeEventListener("change", handleChange); }, [settings.theme]); const updateSettings = (newSettings) => { setSettings((prev) => { const updated = { ...prev, ...newSettings }; storage.set(storageKey, updated); return updated; }); }; const resetSettings = () => { const reset = { ...defaultSettings, ...initialSettings }; setSettings(reset); storage.set(storageKey, reset); }; const value = { settings, updateSettings, resetSettings }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingsContext.Provider, { value, children }); }; var useSettings = () => { const context = (0, import_react2.useContext)(SettingsContext); if (context === void 0) { throw new Error("useSettings must be used within a SettingsProvider"); } return context; }; // src/contexts/TypographyContext.tsx var import_react3 = require("react"); var import_jsx_runtime2 = require("react/jsx-runtime"); var TypographyContext = (0, import_react3.createContext)(null); function TypographyProvider({ children, baseSize = "base", baseWeight = "normal", baseColor = "text-text-primary", scale = 1, lineHeight = 1.5 }) { const contextValue = (0, import_react3.useMemo)( () => ({ baseSize, baseWeight, baseColor, scale, lineHeight }), [baseSize, baseWeight, baseColor, scale, lineHeight] ); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TypographyContext.Provider, { value: contextValue, children }); } function useTypography() { const context = (0, import_react3.useContext)(TypographyContext); if (!context) { return { baseSize: "base", baseWeight: "normal", baseColor: "text-text-primary", scale: 1, lineHeight: 1.5 }; } retu