@shohojdhara/atomix 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/atomix.css +77 -0
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +77 -0
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/charts.js.map +1 -1
  6. package/dist/core.d.ts +2 -2
  7. package/dist/core.js.map +1 -1
  8. package/dist/forms.js.map +1 -1
  9. package/dist/heavy.js.map +1 -1
  10. package/dist/index.d.ts +578 -515
  11. package/dist/index.esm.js +3157 -2626
  12. package/dist/index.esm.js.map +1 -1
  13. package/dist/index.js +10496 -9973
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.min.js +1 -1
  16. package/dist/index.min.js.map +1 -1
  17. package/dist/theme.d.ts +237 -420
  18. package/dist/theme.js +1629 -1701
  19. package/dist/theme.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/components/DataTable/DataTable.stories.tsx +238 -0
  22. package/src/components/DataTable/DataTable.test.tsx +450 -0
  23. package/src/components/DataTable/DataTable.tsx +384 -61
  24. package/src/components/DatePicker/DatePicker.tsx +29 -38
  25. package/src/components/Upload/Upload.tsx +539 -40
  26. package/src/lib/composables/useDataTable.ts +355 -15
  27. package/src/lib/composables/useDatePicker.ts +19 -0
  28. package/src/lib/constants/components.ts +10 -0
  29. package/src/lib/theme/adapters/cssVariableMapper.ts +29 -14
  30. package/src/lib/theme/adapters/index.ts +1 -4
  31. package/src/lib/theme/config/configLoader.ts +53 -35
  32. package/src/lib/theme/core/composeTheme.ts +22 -30
  33. package/src/lib/theme/core/createTheme.ts +49 -26
  34. package/src/lib/theme/core/index.ts +0 -1
  35. package/src/lib/theme/generators/generateCSSNested.ts +4 -3
  36. package/src/lib/theme/generators/generateCSSVariables.ts +24 -16
  37. package/src/lib/theme/index.ts +10 -17
  38. package/src/lib/theme/runtime/ThemeApplicator.ts +6 -109
  39. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +3 -3
  40. package/src/lib/theme/runtime/ThemeProvider.tsx +186 -44
  41. package/src/lib/theme/runtime/useTheme.ts +1 -1
  42. package/src/lib/theme/runtime/useThemeTokens.ts +7 -16
  43. package/src/lib/theme/test/testTheme.ts +2 -1
  44. package/src/lib/theme/types.ts +14 -14
  45. package/src/lib/theme/utils/componentTheming.ts +35 -27
  46. package/src/lib/theme/utils/domUtils.ts +57 -15
  47. package/src/lib/theme/utils/injectCSS.ts +0 -1
  48. package/src/lib/theme/utils/themeHelpers.ts +1 -39
  49. package/src/lib/theme/utils/themeUtils.ts +1 -170
  50. package/src/lib/types/components.ts +145 -0
  51. package/src/lib/utils/dataTableExport.ts +143 -0
  52. package/src/styles/06-components/_components.data-table.scss +95 -0
  53. package/src/lib/hooks/useThemeTokens.ts +0 -105
package/dist/theme.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { loadAtomixConfig } from "../lib/config/loader";
2
+
1
3
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
4
 
3
5
  import { createContext, useRef, useEffect, useCallback, useMemo, useState, useContext, Component } from "react";
@@ -319,6 +321,14 @@ import { createContext, useRef, useEffect, useCallback, useMemo, useState, useCo
319
321
  };
320
322
  }
321
323
 
324
+ const tokens = Object.freeze( Object.defineProperty({
325
+ __proto__: null,
326
+ createTokens: createTokens,
327
+ defaultTokens: defaultTokens
328
+ }, Symbol.toStringTag, {
329
+ value: "Module"
330
+ }));
331
+
322
332
  /**
323
333
  * CSS Variable Generator
324
334
  *
@@ -375,1386 +385,1046 @@ import { createContext, useRef, useEffect, useCallback, useMemo, useState, useCo
375
385
  });
376
386
  }
377
387
 
378
- var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
388
+ /**
389
+ * Theme System Error Handling
390
+ *
391
+ * Centralized error handling for the Atomix theme system.
392
+ * Provides custom error classes and logging utilities.
393
+ */
394
+ /**
395
+ * Theme error codes
396
+ */ var ThemeErrorCode, LogLevel;
379
397
 
380
- function getDefaultExportFromCjs(x) {
381
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
382
- }
398
+ !function(ThemeErrorCode) {
399
+ /** Theme not found in registry */
400
+ ThemeErrorCode.THEME_NOT_FOUND = "THEME_NOT_FOUND",
401
+ /** Theme failed to load */
402
+ ThemeErrorCode.THEME_LOAD_FAILED = "THEME_LOAD_FAILED",
403
+ /** Theme validation failed */
404
+ ThemeErrorCode.THEME_VALIDATION_FAILED = "THEME_VALIDATION_FAILED",
405
+ /** Configuration loading failed */
406
+ ThemeErrorCode.CONFIG_LOAD_FAILED = "CONFIG_LOAD_FAILED",
407
+ /** Configuration validation failed */
408
+ ThemeErrorCode.CONFIG_VALIDATION_FAILED = "CONFIG_VALIDATION_FAILED",
409
+ /** Circular dependency detected */
410
+ ThemeErrorCode.CIRCULAR_DEPENDENCY = "CIRCULAR_DEPENDENCY",
411
+ /** Missing dependency */
412
+ ThemeErrorCode.MISSING_DEPENDENCY = "MISSING_DEPENDENCY",
413
+ /** Storage operation failed */
414
+ ThemeErrorCode.STORAGE_ERROR = "STORAGE_ERROR",
415
+ /** Invalid theme name */
416
+ ThemeErrorCode.INVALID_THEME_NAME = "INVALID_THEME_NAME",
417
+ /** CSS injection failed */
418
+ ThemeErrorCode.CSS_INJECTION_FAILED = "CSS_INJECTION_FAILED",
419
+ /** Unknown error */
420
+ ThemeErrorCode.UNKNOWN_ERROR = "UNKNOWN_ERROR";
421
+ }(ThemeErrorCode || (ThemeErrorCode = {}));
383
422
 
384
- var fails$9 = function(exec) {
385
- try {
386
- return !!exec();
387
- } catch (error) {
388
- return !0;
423
+ /**
424
+ * Custom error class for theme-related errors
425
+ */
426
+ class ThemeError extends Error {
427
+ constructor(message, code = ThemeErrorCode.UNKNOWN_ERROR, context) {
428
+ super(message), this.name = "ThemeError", this.code = code, this.context = context,
429
+ this.timestamp = Date.now(),
430
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
431
+ Error.captureStackTrace && Error.captureStackTrace(this, ThemeError);
389
432
  }
390
- }, functionBindNative = !fails$9((function() {
391
- // eslint-disable-next-line es/no-function-prototype-bind -- safe
392
- var test = function() {/* empty */}.bind();
393
- // eslint-disable-next-line no-prototype-builtins -- safe
394
- return "function" != typeof test || test.hasOwnProperty("prototype");
395
- })), NATIVE_BIND$3 = functionBindNative, FunctionPrototype$1 = Function.prototype, call$5 = FunctionPrototype$1.call, uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$1.bind.bind(call$5, call$5), functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function(fn) {
396
- return function() {
397
- return call$5.apply(fn, arguments);
398
- };
399
- }, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
400
- return it && it.Math === Math && it;
401
- }, globalThis_1 =
402
- // eslint-disable-next-line es/no-global-this -- safe
403
- check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
404
- // eslint-disable-next-line no-restricted-globals -- safe
405
- check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
406
- // eslint-disable-next-line no-new-func -- fallback
407
- function() {
408
- return this;
409
- }() || Function("return this")(), NATIVE_BIND$2 = functionBindNative, FunctionPrototype = Function.prototype, apply$1 = FunctionPrototype.apply, call$4 = FunctionPrototype.call, functionApply = "object" == typeof Reflect && Reflect.apply || (NATIVE_BIND$2 ? call$4.bind(apply$1) : function() {
410
- return call$4.apply(apply$1, arguments);
411
- }), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
412
- return stringSlice(toString$3(it), 8, -1);
413
- }, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
414
- // Nashorn bug:
415
- // https://github.com/zloirock/core-js/issues/1128
416
- // https://github.com/zloirock/core-js/issues/1130
417
- if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
418
- }, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
419
- return "function" == typeof argument || argument === documentAll;
420
- } : function(argument) {
421
- return "function" == typeof argument;
422
- }, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$9((function() {
423
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
424
- return 7 !== Object.defineProperty({}, 1, {
425
- get: function() {
426
- return 7;
427
- }
428
- })[1];
429
- })), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
430
- return call$3.apply(call$3, arguments);
431
- }, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
432
- 1: 2
433
- }, 1);
434
-
435
- // `Object.prototype.propertyIsEnumerable` method implementation
436
- // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
437
- objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
438
- var descriptor = getOwnPropertyDescriptor$1(this, V);
439
- return !!descriptor && descriptor.enumerable;
440
- } : $propertyIsEnumerable;
441
-
442
- var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
443
- return {
444
- enumerable: !(1 & bitmap),
445
- configurable: !(2 & bitmap),
446
- writable: !(4 & bitmap),
447
- value: value
448
- };
449
- }, fails$6 = fails$9, classof$4 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$6((function() {
450
- // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
451
- // eslint-disable-next-line no-prototype-builtins -- safe
452
- return !$Object$3("z").propertyIsEnumerable(0);
453
- })) ? function(it) {
454
- return "String" === classof$4(it) ? split(it, "") : $Object$3(it);
455
- } : $Object$3, isNullOrUndefined$2 = function(it) {
456
- return null == it;
457
- }, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$7 = TypeError, requireObjectCoercible$3 = function(it) {
458
- if (isNullOrUndefined$1(it)) throw new $TypeError$7("Can't call method on " + it);
459
- return it;
460
- }, IndexedObject$1 = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
461
- return IndexedObject$1(requireObjectCoercible$2(it));
462
- }, isCallable$7 = isCallable$8, isObject$6 = function(it) {
463
- return "object" == typeof it ? null !== it : isCallable$7(it);
464
- }, path$3 = {}, path$2 = path$3, globalThis$b = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
465
- return isCallable$6(variable) ? variable : void 0;
466
- }, navigator$1 = globalThis_1.navigator, userAgent$2 = navigator$1 && navigator$1.userAgent, environmentUserAgent = userAgent$2 ? String(userAgent$2) : "", globalThis$9 = globalThis_1, userAgent$1 = environmentUserAgent, process$1 = globalThis$9.process, Deno$1 = globalThis$9.Deno, versions = process$1 && process$1.versions || Deno$1 && Deno$1.version, v8 = versions && versions.v8;
433
+ /**
434
+ * Convert error to JSON for logging
435
+ */ toJSON() {
436
+ return {
437
+ name: this.name,
438
+ message: this.message,
439
+ code: this.code,
440
+ context: this.context,
441
+ timestamp: this.timestamp,
442
+ stack: this.stack
443
+ };
444
+ }
445
+ }
467
446
 
468
- v8 && (
469
- // in old Chrome, versions of V8 isn't V8 = Chrome / 10
470
- // but their correct versions are not interesting for us
471
- version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
472
- // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
473
- // so check `userAgent` even if `.v8` exists, but 0
474
- !version && userAgent$1 && (!(match = userAgent$1.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent$1.match(/Chrome\/(\d+)/)) && (version = +match[1]);
447
+ /**
448
+ * Log level
449
+ */ !function(LogLevel) {
450
+ LogLevel[LogLevel.ERROR = 0] = "ERROR", LogLevel[LogLevel.WARN = 1] = "WARN", LogLevel[LogLevel.INFO = 2] = "INFO",
451
+ LogLevel[LogLevel.DEBUG = 3] = "DEBUG";
452
+ }(LogLevel || (LogLevel = {}));
475
453
 
476
- var environmentV8Version = version, V8_VERSION = environmentV8Version, fails$5 = fails$9, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$5((function() {
477
- var symbol = Symbol("symbol detection");
478
- // Chrome 38 Symbol has incorrect toString conversion
479
- // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
480
- // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
481
- // of course, fail.
482
- return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
483
- // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
484
- !Symbol.sham && V8_VERSION && V8_VERSION < 41;
485
- })), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$2 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
486
- return "symbol" == typeof it;
487
- } : function(it) {
488
- var $Symbol = function(namespace, method) {
489
- return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$b[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$b[namespace] && globalThis$b[namespace][method];
490
- }("Symbol");
491
- return isCallable$5($Symbol) && isPrototypeOf$2($Symbol.prototype, $Object$2(it));
492
- }, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$6 = TypeError, aCallable$3 = function(argument) {
493
- if (isCallable$4(argument)) return argument;
494
- throw new $TypeError$6(function(argument) {
495
- try {
496
- return $String$2(argument);
497
- } catch (error) {
498
- return "Object";
499
- }
500
- }(argument) + " is not a function");
501
- }, aCallable$2 = aCallable$3, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$5 = isObject$6, $TypeError$5 = TypeError, sharedStore = {
502
- exports: {}
503
- }, globalThis$7 = globalThis_1, defineProperty = Object.defineProperty, globalThis$6 = globalThis_1, store$1 = sharedStore.exports = globalThis$6["__core-js_shared__"] || function(key, value) {
504
- try {
505
- defineProperty(globalThis$7, key, {
506
- value: value,
507
- configurable: !0,
508
- writable: !0
509
- });
510
- } catch (error) {
511
- globalThis$7[key] = value;
454
+ /**
455
+ * Theme Logger
456
+ *
457
+ * Centralized logging for the theme system.
458
+ * Replaces console statements with structured logging.
459
+ */
460
+ class ThemeLogger {
461
+ constructor(config = {}) {
462
+ this.config = {
463
+ level: config.level ?? ("undefined" != typeof process && "production" === process.env?.NODE_ENV ? LogLevel.WARN : LogLevel.INFO),
464
+ enableConsole: config.enableConsole ?? !0,
465
+ onError: config.onError,
466
+ onWarn: config.onWarn,
467
+ onInfo: config.onInfo,
468
+ onDebug: config.onDebug
469
+ };
512
470
  }
513
- return value;
514
- }("__core-js_shared__", {});
471
+ /**
472
+ * Log an error
473
+ */ error(message, error, context) {
474
+ if (this.config.level < LogLevel.ERROR) return;
475
+ const errorObj = error instanceof Error ? error : new Error(message), themeError = error instanceof ThemeError ? error : new ThemeError(message, ThemeErrorCode.UNKNOWN_ERROR, context);
476
+ this.config.enableConsole && console.error(`[ThemeError] ${message}`, {
477
+ error: errorObj,
478
+ context: {
479
+ ...context,
480
+ ...themeError.context
481
+ },
482
+ code: themeError.code
483
+ }), this.config.onError?.(themeError, context);
484
+ }
485
+ /**
486
+ * Log a warning
487
+ */ warn(message, context) {
488
+ this.config.level < LogLevel.WARN || (this.config.enableConsole && console.warn(`[ThemeWarning] ${message}`, context || {}),
489
+ this.config.onWarn?.(message, context));
490
+ }
491
+ /**
492
+ * Log an info message
493
+ */ info(message, context) {
494
+ this.config.level < LogLevel.INFO || (this.config.enableConsole && console.info(`[ThemeInfo] ${message}`, context || {}),
495
+ this.config.onInfo?.(message, context));
496
+ }
497
+ /**
498
+ * Log a debug message
499
+ */ debug(message, context) {
500
+ this.config.level < LogLevel.DEBUG || (this.config.enableConsole, this.config.onDebug?.(message, context));
501
+ }
502
+ }
515
503
 
516
- /* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
517
- version: "3.43.0",
518
- mode: "pure",
519
- copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
520
- license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
521
- source: "https://github.com/zloirock/core-js"
522
- });
504
+ /**
505
+ * Default logger instance
506
+ */ let defaultLogger = null;
523
507
 
524
- var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, toObject$2 = function(argument) {
525
- return $Object$1(requireObjectCoercible$1(argument));
526
- }, toObject$1 = toObject$2, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
527
- return hasOwnProperty(toObject$1(it), key);
528
- }, uncurryThis$3 = functionUncurryThis, id = 0, postfix = Math.random(), toString$2 = uncurryThis$3(1.1.toString), hasOwn$2 = hasOwnProperty_1, NATIVE_SYMBOL = symbolConstructorDetection, USE_SYMBOL_AS_UID = useSymbolAsUid, Symbol$1 = globalThis_1.Symbol, WellKnownSymbolsStore = store[key = "wks"] || (store[key] = value || {}), createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1.for || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || function(key) {
529
- return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
530
- }, wellKnownSymbol$5 = function(name) {
531
- return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
532
- WellKnownSymbolsStore[name];
533
- }, call$1 = functionCall, isObject$4 = isObject$6, isSymbol$1 = isSymbol$2, $TypeError$4 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
534
- if (!isObject$4(input) || isSymbol$1(input)) return input;
535
- var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$2(func));
536
- if (exoticToPrim) {
537
- if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
538
- !isObject$4(result) || isSymbol$1(result)) return result;
539
- throw new $TypeError$4("Can't convert object to primitive value");
540
- }
541
- return void 0 === pref && (pref = "number"), function(input, pref) {
542
- var fn, val;
543
- if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$5(val = call$2(fn, input))) return val;
544
- if (isCallable$3(fn = input.valueOf) && !isObject$5(val = call$2(fn, input))) return val;
545
- if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$5(val = call$2(fn, input))) return val;
546
- throw new $TypeError$5("Can't convert object to primitive value");
547
- }(input, pref);
548
- }, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
549
- var key = toPrimitive(argument, "string");
550
- return isSymbol(key) ? key : key + "";
551
- }, isObject$3 = isObject$6, document$1 = globalThis_1.document, EXISTS = isObject$3(document$1) && isObject$3(document$1.createElement), ie8DomDefine = !descriptors && !fails$9((function() {
552
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
553
- return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
554
- get: function() {
555
- return 7;
556
- }
557
- }).a;
558
- var it;
559
- })), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toIndexedObject$1 = toIndexedObject$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
560
-
561
- // `Object.getOwnPropertyDescriptor` method
562
- // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
563
- objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
564
- if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
565
- return $getOwnPropertyDescriptor$1(O, P);
566
- } catch (error) {/* empty */}
567
- if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
568
- };
569
-
570
- var fails$3 = fails$9, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
571
- var value = data[normalize(feature)];
572
- return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$3(detection) : !!detection);
573
- }, normalize = isForced$1.normalize = function(string) {
574
- return String(string).replace(replacement, ".").toLowerCase();
575
- }, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable$1 = aCallable$3, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$9((function() {
576
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
577
- return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
578
- value: 42,
579
- writable: !1
580
- }).prototype;
581
- })), isObject$2 = isObject$6, $String$1 = String, $TypeError$3 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
582
- if (isObject$2(argument)) return argument;
583
- throw new $TypeError$3($String$1(argument) + " is not an object");
584
- }, toPropertyKey = toPropertyKey$2, $TypeError$2 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
508
+ /**
509
+ * Get or create default logger
510
+ */ function getLogger() {
511
+ return defaultLogger || (defaultLogger = new ThemeLogger), defaultLogger;
512
+ }
585
513
 
586
- // `Object.defineProperty` method
587
- // https://tc39.es/ecma262/#sec-object.defineproperty
588
- objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
589
- if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
590
- var current = $getOwnPropertyDescriptor(O, P);
591
- current && current.writable && (O[P] = Attributes.value, Attributes = {
592
- configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
593
- enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
594
- writable: !1
514
+ /**
515
+ * Core Theme Functions
516
+ *
517
+ * Simplified theme system using DesignTokens only.
518
+ * Config-first approach: loads from atomix.config.ts when no input is provided.
519
+ */
520
+ /**
521
+ * Create theme CSS from DesignTokens
522
+ *
523
+ * **Config-First Approach**: If no input is provided, loads from `atomix.config.ts`.
524
+ *
525
+ * @param input - DesignTokens (partial) or undefined (loads from config)
526
+ * @param options - CSS generation options (prefix is automatically read from config if not provided)
527
+ * @returns CSS string with custom properties
528
+ * @throws Error if config loading fails when no input is provided
529
+ *
530
+ * @example
531
+ * ```typescript
532
+ * // Loads from atomix.config.ts
533
+ * const css = createTheme();
534
+ *
535
+ * // Using DesignTokens
536
+ * const css = createTheme({
537
+ * 'primary': '#7c3aed',
538
+ * 'spacing-4': '1rem',
539
+ * });
540
+ *
541
+ * // With custom options
542
+ * const css = createTheme(undefined, { prefix: 'myapp', selector: ':root' });
543
+ * ```
544
+ */ function createTheme(input, options) {
545
+ // Validate options if provided
546
+ if (options?.prefix) {
547
+ const prefixPattern = /^[a-z][a-z0-9-]*$/;
548
+ if (!prefixPattern.test(options.prefix)) throw new ThemeError(`Invalid CSS variable prefix: "${options.prefix}". Prefix must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens (e.g., "atomix", "my-app").`, ThemeErrorCode.THEME_VALIDATION_FAILED, {
549
+ prefix: options.prefix,
550
+ pattern: prefixPattern.toString()
595
551
  });
596
552
  }
597
- return $defineProperty(O, P, Attributes);
598
- } : $defineProperty : function(O, P, Attributes) {
599
- if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
600
- return $defineProperty(O, P, Attributes);
601
- } catch (error) {/* empty */}
602
- if ("get" in Attributes || "set" in Attributes) throw new $TypeError$2("Accessors not supported");
603
- return "value" in Attributes && (O[P] = Attributes.value), O;
604
- };
605
-
606
- var definePropertyModule = objectDefineProperty, createPropertyDescriptor = createPropertyDescriptor$2, createNonEnumerableProperty$1 = descriptors ? function(object, key, value) {
607
- return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
608
- } : function(object, key, value) {
609
- return object[key] = value, object;
610
- }, globalThis$3 = globalThis_1, apply = functionApply, uncurryThis$1 = functionUncurryThisClause, isCallable$1 = isCallable$8, getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f, isForced = isForced_1, path$1 = path$3, bind = function(fn, that) {
611
- return aCallable$1(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
612
- return fn.apply(that, arguments);
613
- };
614
- }, createNonEnumerableProperty = createNonEnumerableProperty$1, hasOwn = hasOwnProperty_1, wrapConstructor = function(NativeConstructor) {
615
- var Wrapper = function(a, b, c) {
616
- if (this instanceof Wrapper) {
617
- switch (arguments.length) {
618
- case 0:
619
- return new NativeConstructor;
620
-
621
- case 1:
622
- return new NativeConstructor(a);
623
-
624
- case 2:
625
- return new NativeConstructor(a, b);
553
+ // Validate selector if provided
554
+ if (options?.selector && ("string" != typeof options.selector || 0 === options.selector.trim().length)) throw new ThemeError(`Invalid CSS selector: "${options.selector}". Selector must be a non-empty string (e.g., ":root", ".my-theme").`, ThemeErrorCode.THEME_VALIDATION_FAILED, {
555
+ selector: options.selector
556
+ });
557
+ // Determine tokens based on input
558
+ let tokens;
559
+ if (input) {
560
+ // Validate input tokens structure
561
+ if ("object" != typeof input || null === input || Array.isArray(input)) throw new ThemeError(`Invalid tokens input. Expected an object with DesignTokens, but received: ${typeof input}.`, ThemeErrorCode.THEME_VALIDATION_FAILED, {
562
+ inputType: typeof input
563
+ });
564
+ // Use DesignTokens directly
565
+ tokens = input;
566
+ }
567
+ // Merge with defaults and generate CSS
568
+ else {
569
+ // Check if we're in a browser environment
570
+ if ("undefined" != typeof window) throw new ThemeError("No input provided and config loading is not available in browser environment. Please provide tokens explicitly or use Node.js/SSR environment.", ThemeErrorCode.CONFIG_LOAD_FAILED, {
571
+ environment: "browser"
572
+ });
573
+ // Load from config when no input provided
574
+ let loadThemeFromConfigSync, loadAtomixConfig;
575
+ try {
576
+ const configLoaderModule = require("../config/configLoader"), loaderModule = require("../../config/loader");
577
+ // Get prefix from config if needed
578
+ if (loadThemeFromConfigSync = configLoaderModule.loadThemeFromConfigSync, loadAtomixConfig = loaderModule.loadAtomixConfig,
579
+ tokens = loadThemeFromConfigSync(), !options?.prefix) try {
580
+ const config = loadAtomixConfig({
581
+ configPath: "atomix.config.ts",
582
+ required: !1
583
+ });
584
+ options = {
585
+ ...options,
586
+ prefix: config?.prefix || "atomix"
587
+ };
588
+ } catch (error) {
589
+ // If config loading fails, use default prefix
590
+ options = {
591
+ ...options,
592
+ prefix: "atomix"
593
+ };
626
594
  }
627
- return new NativeConstructor(a, b, c);
595
+ } catch (error) {
596
+ throw new ThemeError("No input provided and config loading is not available in this environment. Please provide tokens explicitly.", ThemeErrorCode.CONFIG_LOAD_FAILED, {
597
+ error: error instanceof Error ? error.message : String(error)
598
+ });
628
599
  }
629
- return apply(NativeConstructor, this, arguments);
630
- };
631
- return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
632
- }, _export = function(options, source) {
633
- var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor, TARGET = options.target, GLOBAL = options.global, STATIC = options.stat, PROTO = options.proto, nativeSource = GLOBAL ? globalThis$3 : STATIC ? globalThis$3[TARGET] : globalThis$3[TARGET] && globalThis$3[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
634
- for (key in source)
635
- // contains in native
636
- USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
637
- targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
638
- // export native or implementation
639
- sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
640
- // bind methods to global for calling from export context
641
- resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$3) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
642
- // add a flag to not completely full polyfills
643
- (options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
644
- createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
645
- // export virtual prototype methods
646
- createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
647
- // export real prototype methods
648
- options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
649
- }, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
650
- var n = +x;
651
- return (n > 0 ? floor : ceil)(n);
652
- }, toIntegerOrInfinity$2 = function(argument) {
653
- var number = +argument;
654
- // eslint-disable-next-line no-self-compare -- NaN check
655
- return number != number || 0 === number ? 0 : trunc(number);
656
- }, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, max = Math.max, min$1 = Math.min, toIntegerOrInfinity = toIntegerOrInfinity$2, min = Math.min, lengthOfArrayLike$2 = function(obj) {
657
- return argument = obj.length, (len = toIntegerOrInfinity(argument)) > 0 ? min(len, 9007199254740991) : 0;
658
- var argument, len;
659
- }, toIndexedObject = toIndexedObject$2, lengthOfArrayLike$1 = lengthOfArrayLike$2, createMethod$1 = function(IS_INCLUDES) {
660
- return function($this, el, fromIndex) {
661
- var O = toIndexedObject($this), length = lengthOfArrayLike$1(O);
662
- if (0 === length) return !IS_INCLUDES && -1;
663
- var value, index = function(index, length) {
664
- var integer = toIntegerOrInfinity$1(index);
665
- return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
666
- }(fromIndex, length);
667
- // Array#includes uses SameValueZero equality algorithm
668
- // eslint-disable-next-line no-self-compare -- NaN check
669
- if (IS_INCLUDES && el != el) {
670
- for (;length > index; )
671
- // eslint-disable-next-line no-self-compare -- NaN check
672
- if ((value = O[index++]) != value) return !0;
673
- // Array#indexOf ignores holes, Array#includes - not
674
- } else for (;length > index; index++) if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
675
- return !IS_INCLUDES && -1;
676
- };
677
- }, $includes = [ createMethod$1(!0), createMethod$1(!1) ][0];
678
-
679
- // `Array.prototype.includes` method
680
- // https://tc39.es/ecma262/#sec-array.prototype.includes
681
- _export({
682
- target: "Array",
683
- proto: !0,
684
- forced: fails$9((function() {
685
- // eslint-disable-next-line es/no-array-prototype-includes -- detection
686
- return !Array(1).includes();
687
- }))
688
- }, {
689
- includes: function(el /* , fromIndex = 0 */) {
690
- return $includes(this, el, arguments.length > 1 ? arguments[1] : void 0);
691
600
  }
692
- });
601
+ const allTokens = createTokens(tokens), prefix = options?.prefix ?? "atomix";
602
+ // Get prefix from options or use default
603
+ return generateCSSVariables$1(allTokens, {
604
+ ...options,
605
+ prefix: prefix
606
+ });
607
+ }
693
608
 
694
- var globalThis$2 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$3 = function(CONSTRUCTOR, METHOD) {
695
- var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
696
- if (pureMethod) return pureMethod;
697
- var NativeConstructor = globalThis$2[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
698
- return NativePrototype && NativePrototype[METHOD];
699
- }, includes$4 = getBuiltInPrototypeMethod$3("Array", "includes"), isObject$1 = isObject$6, classof$3 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError$1 = TypeError, test = {};
609
+ /**
610
+ * Theme Composition Utilities
611
+ *
612
+ * Simplified utilities for composing and merging DesignTokens.
613
+ */
614
+ // ============================================================================
615
+ // Deep Merge Utility
616
+ // ============================================================================
617
+ /**
618
+ * Check if value is an object
619
+ */ function isObject$6(item) {
620
+ return item && "object" == typeof item && !Array.isArray(item) && "function" != typeof item;
621
+ }
700
622
 
701
- test[wellKnownSymbol$5("toStringTag")] = "z";
623
+ /**
624
+ * Deep merge multiple objects
625
+ * Later objects override earlier ones
626
+ */ function deepMerge(...objects) {
627
+ if (0 === objects.length) return {};
628
+ if (1 === objects.length) return objects[0];
629
+ const [target, ...sources] = objects, result = {
630
+ ...target
631
+ };
632
+ for (const source of sources) if (source) for (const key in source) {
633
+ if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
634
+ const targetValue = result[key], sourceValue = source[key];
635
+ isObject$6(targetValue) && isObject$6(sourceValue) ?
636
+ // Recursively merge objects
637
+ result[key] = deepMerge(targetValue, sourceValue) :
638
+ // Override with source value
639
+ result[key] = sourceValue;
640
+ }
641
+ return result;
642
+ }
702
643
 
703
- var TO_STRING_TAG_SUPPORT = "[object z]" === String(test), isCallable = isCallable$8, classofRaw = classofRaw$2, TO_STRING_TAG = wellKnownSymbol$5("toStringTag"), $Object = Object, CORRECT_ARGUMENTS = "Arguments" === classofRaw(function() {
704
- return arguments;
705
- }()), classof$1 = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {
706
- var O, tag, result;
707
- return void 0 === it ? "Undefined" : null === it ? "Null" : "string" == typeof (tag = function(it, key) {
708
- try {
709
- return it[key];
710
- } catch (error) {/* empty */}
711
- }(O = $Object(it), TO_STRING_TAG)) ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : "Object" === (result = classofRaw(O)) && isCallable(O.callee) ? "Arguments" : result;
712
- }, $String = String, MATCH = wellKnownSymbol$5("match"), $$1 = _export, notARegExp = function(it) {
713
- if (function(it) {
714
- var isRegExp;
715
- return isObject$1(it) && (void 0 !== (isRegExp = it[MATCH$1]) ? !!isRegExp : "RegExp" === classof$3(it));
716
- }(it)) throw new $TypeError$1("The method doesn't accept regular expressions");
717
- return it;
718
- }, requireObjectCoercible = requireObjectCoercible$3, toString = function(argument) {
719
- if ("Symbol" === classof$1(argument)) throw new TypeError("Cannot convert a Symbol value to a string");
720
- return $String(argument);
721
- }, stringIndexOf = functionUncurryThis("".indexOf);
722
-
723
- // `String.prototype.includes` method
724
- // https://tc39.es/ecma262/#sec-string.prototype.includes
725
- $$1({
726
- target: "String",
727
- proto: !0,
728
- forced: !function(METHOD_NAME) {
729
- var regexp = /./;
730
- try {
731
- "/./"[METHOD_NAME](regexp);
732
- } catch (error1) {
733
- try {
734
- return regexp[MATCH] = !1, "/./"[METHOD_NAME](regexp);
735
- } catch (error2) {/* empty */}
736
- }
737
- return !1;
738
- }("includes")
739
- }, {
740
- includes: function(searchString /* , position = 0 */) {
741
- return !!~stringIndexOf(toString(requireObjectCoercible(this)), toString(notARegExp(searchString)), arguments.length > 1 ? arguments[1] : void 0);
742
- }
743
- });
744
-
745
- var includes$3 = getBuiltInPrototypeMethod$3("String", "includes"), isPrototypeOf$1 = objectIsPrototypeOf, arrayMethod = includes$4, stringMethod = includes$3, ArrayPrototype$1 = Array.prototype, StringPrototype = String.prototype;
746
-
747
- const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
748
- var own = it.includes;
749
- return it === ArrayPrototype$1 || isPrototypeOf$1(ArrayPrototype$1, it) && own === ArrayPrototype$1.includes ? arrayMethod : "string" == typeof it || it === StringPrototype || isPrototypeOf$1(StringPrototype, it) && own === StringPrototype.includes ? stringMethod : own;
750
- }));
644
+ /**
645
+ * Merge multiple DesignTokens objects into a single DesignTokens object
646
+ *
647
+ * @param tokens - DesignTokens objects to merge
648
+ * @returns Merged DesignTokens object
649
+ *
650
+ * @example
651
+ * ```typescript
652
+ * const baseTokens = { 'primary': '#000', 'spacing-4': '1rem' };
653
+ * const customTokens = { 'secondary': '#fff', 'spacing-4': '1.5rem' };
654
+ * const merged = mergeTheme(baseTokens, customTokens);
655
+ * // Returns: { 'primary': '#000', 'secondary': '#fff', 'spacing-4': '1.5rem' }
656
+ * ```
657
+ */ function mergeTheme(...tokens) {
658
+ return deepMerge({}, ...tokens);
659
+ }
751
660
 
752
661
  /**
753
- * Theme Utilities
662
+ * Extend DesignTokens with additional tokens
754
663
  *
755
- * Helper utilities for working with themes, including color manipulation,
756
- * spacing helpers, and theme value accessors.
757
- */
758
- // ============================================================================
759
- // Color Manipulation Utilities
760
- // ============================================================================
664
+ * @param baseTokens - Base DesignTokens to extend
665
+ * @param extension - Additional DesignTokens to merge
666
+ * @returns Extended DesignTokens object
667
+ *
668
+ * @example
669
+ * ```typescript
670
+ * const base = { 'primary': '#000' };
671
+ * const extended = extendTheme(base, { 'secondary': '#fff' });
672
+ * // Returns: { 'primary': '#000', 'secondary': '#fff' }
673
+ * ```
674
+ */ function extendTheme(baseTokens, extension) {
675
+ return mergeTheme(baseTokens, extension);
676
+ }
677
+
761
678
  /**
762
- * Convert hex color to RGB object
763
- */ function hexToRgb(hex) {
764
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
765
- return result ? {
766
- r: parseInt(result[1], 16),
767
- g: parseInt(result[2], 16),
768
- b: parseInt(result[3], 16)
769
- } : null;
679
+ * Create a new theme registry
680
+ */ function createThemeRegistry() {
681
+ return {};
770
682
  }
771
683
 
772
684
  /**
773
- * Convert RGB to hex color
774
- */ function rgbToHex(r, g, b) {
775
- const toHex = val => Math.round(Math.max(0, Math.min(255, val))).toString(16).padStart(2, "0");
776
- return `#${toHex(r ?? 0)}${toHex(g ?? 0)}${toHex(b ?? 0)}`;
685
+ * Register a theme
686
+ * @param registry - Theme registry object
687
+ * @param id - Theme identifier
688
+ * @param metadata - Theme metadata
689
+ */ function registerTheme(registry, id, metadata) {
690
+ registry[id] = metadata;
777
691
  }
778
692
 
779
693
  /**
780
- * Calculate relative luminance of a color
781
- * Used for determining contrast ratios
782
- */ function getLuminance(color) {
783
- const rgb = hexToRgb(color);
784
- if (!rgb) return 0;
785
- const {r: r, g: g, b: b} = rgb, [rs, gs, bs] = [ r ?? 0, g ?? 0, b ?? 0 ].map((c => {
786
- const val = c / 255;
787
- return val <= .03928 ? val / 12.92 : Math.pow((val + .055) / 1.055, 2.4);
788
- }));
789
- return .2126 * (rs ?? 0) + .7152 * (gs ?? 0) + .0722 * (bs ?? 0);
694
+ * Unregister a theme
695
+ * @param registry - Theme registry object
696
+ * @param id - Theme identifier
697
+ */ function unregisterTheme(registry, id) {
698
+ const exists = id in registry;
699
+ return delete registry[id], exists;
790
700
  }
791
701
 
792
702
  /**
793
- * Calculate contrast ratio between two colors
794
- */ function getContrastRatio(foreground, background) {
795
- const lumA = getLuminance(foreground), lumB = getLuminance(background);
796
- return (Math.max(lumA, lumB) + .05) / (Math.min(lumA, lumB) + .05);
703
+ * Check if a theme is registered
704
+ * @param registry - Theme registry object
705
+ * @param id - Theme identifier
706
+ */ function hasTheme(registry, id) {
707
+ return id in registry;
797
708
  }
798
709
 
799
710
  /**
800
- * Get appropriate contrast text color (black or white) for a background color
801
- */ function getContrastText(background, threshold = 3) {
802
- const contrastWithWhite = getContrastRatio("#FFFFFF", background), contrastWithBlack = getContrastRatio("#000000", background);
803
- return contrastWithWhite >= threshold ? "#FFFFFF" : contrastWithBlack >= threshold ? "#000000" : contrastWithWhite > contrastWithBlack ? "#FFFFFF" : "#000000";
711
+ * Get theme metadata
712
+ * @param registry - Theme registry object
713
+ * @param id - Theme identifier
714
+ */ function getTheme(registry, id) {
715
+ return registry[id];
804
716
  }
805
717
 
806
718
  /**
807
- * Lighten a color by a given amount
808
- *
809
- * @param color - Hex color string
810
- * @param amount - Amount to lighten (0-1), default 0.2
811
- * @returns Lightened hex color
812
- */ function lighten(color, amount = .2) {
813
- const rgb = hexToRgb(color);
814
- if (!rgb) return color;
815
- const {r: r, g: g, b: b} = rgb, lightenValue = val => Math.min(255, Math.round(val + (255 - val) * amount));
816
- return rgbToHex(lightenValue(r), lightenValue(g), lightenValue(b));
719
+ * Get all registered theme metadata
720
+ * @param registry - Theme registry object
721
+ */ function getAllThemes(registry) {
722
+ return Object.values(registry);
817
723
  }
818
724
 
819
725
  /**
820
- * Darken a color by a given amount
821
- *
822
- * @param color - Hex color string
823
- * @param amount - Amount to darken (0-1), default 0.2
824
- * @returns Darkened hex color
825
- */ function darken(color, amount = .2) {
826
- const rgb = hexToRgb(color);
827
- if (!rgb) return color;
828
- const {r: r, g: g, b: b} = rgb, darkenValue = val => Math.max(0, Math.round(val * (1 - amount)));
829
- return rgbToHex(darkenValue(r), darkenValue(g), darkenValue(b));
726
+ * Get all registered theme IDs
727
+ * @param registry - Theme registry object
728
+ */ function getThemeIds(registry) {
729
+ return Object.keys(registry);
830
730
  }
831
731
 
832
732
  /**
833
- * Add alpha (opacity) to a color
834
- *
835
- * @param color - Hex color string
836
- * @param opacity - Opacity value (0-1)
837
- * @returns RGBA color string
838
- */ function alpha(color, opacity) {
839
- const rgb = hexToRgb(color);
840
- if (!rgb) return color;
841
- const {r: r, g: g, b: b} = rgb;
842
- return `rgba(${r}, ${g}, ${b}, ${Math.max(0, Math.min(1, opacity))})`;
733
+ * Clear all registered themes
734
+ * @param registry - Theme registry object
735
+ */ function clearThemes(registry) {
736
+ Object.keys(registry).forEach((key => delete registry[key]));
843
737
  }
844
738
 
845
739
  /**
846
- * Emphasize a color (lighten if dark, darken if light)
740
+ * Get the number of registered themes
741
+ * @param registry - Theme registry object
742
+ */ function getThemeCount(registry) {
743
+ return Object.keys(registry).length;
744
+ }
745
+
746
+ /**
747
+ * Core Theme Engine
847
748
  *
848
- * @param color - Hex color string
849
- * @param coefficient - Amount to emphasize (0-1), default 0.15
850
- * @returns Emphasized hex color
851
- */
749
+ * Core theme creation, composition, and registry functionality
750
+ */ const index = Object.freeze( Object.defineProperty({
751
+ __proto__: null,
752
+ clearThemes: clearThemes,
753
+ createTheme: createTheme,
754
+ createThemeRegistry: createThemeRegistry,
755
+ deepMerge: deepMerge,
756
+ extendTheme: extendTheme,
757
+ getAllThemes: getAllThemes,
758
+ getTheme: getTheme,
759
+ getThemeCount: getThemeCount,
760
+ getThemeIds: getThemeIds,
761
+ hasTheme: hasTheme,
762
+ mergeTheme: mergeTheme,
763
+ registerTheme: registerTheme,
764
+ unregisterTheme: unregisterTheme
765
+ }, Symbol.toStringTag, {
766
+ value: "Module"
767
+ }));
768
+
852
769
  /**
853
- * Theme Adapter
770
+ * CSS Injection Utilities
854
771
  *
855
- * Converts between Theme objects and DesignTokens.
772
+ * Inject CSS into HTML head via <style> element.
856
773
  */
857
774
  /**
858
- * Convert Theme object to DesignTokens
775
+ * Check if running in browser environment
776
+ */ function isBrowser$1() {
777
+ return "undefined" != typeof document;
778
+ }
779
+
780
+ /**
781
+ * Inject CSS into HTML head via <style> element
859
782
  *
860
- * Extracts values from a Theme object and converts them to flat DesignTokens format.
783
+ * Creates or updates a style element in the document head.
784
+ * If an element with the same ID exists, it will be updated.
861
785
  *
862
- * @param theme - Theme object to convert
863
- * @returns Partial DesignTokens object
786
+ * @param css - CSS string to inject
787
+ * @param id - Style element ID (default: 'atomix-theme')
864
788
  *
865
789
  * @example
866
790
  * ```typescript
867
- * const theme = createTheme({ palette: { primary: { main: '#7c3aed' } } });
868
- * const tokens = themeToDesignTokens(theme);
869
- * // Returns: { 'primary': '#7c3aed', ... }
791
+ * const css = ':root { --atomix-color-primary: #7AFFD7; }';
792
+ * injectCSS(css);
793
+ *
794
+ * // With custom ID
795
+ * injectCSS(css, 'my-custom-theme');
870
796
  * ```
871
- */
872
- function themeToDesignTokens(theme) {
873
- const tokens = {};
874
- // Convert palette colors
875
- if (theme.palette) {
876
- // Primary colors
877
- if (theme.palette.primary && (tokens.primary = theme.palette.primary.main, theme.palette.primary.light && (tokens["primary-3"] = theme.palette.primary.light),
878
- theme.palette.primary.dark && (tokens["primary-9"] = theme.palette.primary.dark),
879
- theme.palette.primary.main)) {
880
- const rgb = hexToRgb(theme.palette.primary.main);
881
- rgb && (tokens["primary-rgb"] = `${rgb.r}, ${rgb.g}, ${rgb.b}`);
882
- }
883
- // Secondary colors
884
- if (theme.palette.secondary) {
885
- tokens.secondary = theme.palette.secondary.main, theme.palette.secondary.light && (tokens["gray-1"] = theme.palette.secondary.light),
886
- theme.palette.secondary.dark && (tokens["gray-3"] = theme.palette.secondary.dark);
887
- const rgb = hexToRgb(theme.palette.secondary.main);
888
- rgb && (tokens["secondary-rgb"] = `${rgb.r}, ${rgb.g}, ${rgb.b}`);
889
- }
890
- // Error colors
891
- if (theme.palette.error) {
892
- tokens.error = theme.palette.error.main, tokens["red-6"] = theme.palette.error.main,
893
- theme.palette.error.light && (tokens["red-4"] = theme.palette.error.light), theme.palette.error.dark && (tokens["red-9"] = theme.palette.error.dark);
894
- const rgb = hexToRgb(theme.palette.error.main);
895
- rgb && (tokens["error-rgb"] = `${rgb.r}, ${rgb.g}, ${rgb.b}`);
896
- }
897
- // Success colors
898
- if (theme.palette.success) {
899
- tokens.success = theme.palette.success.main, tokens["green-6"] = theme.palette.success.main,
900
- theme.palette.success.light && (tokens["green-4"] = theme.palette.success.light),
901
- theme.palette.success.dark && (tokens["green-9"] = theme.palette.success.dark);
902
- const rgb = hexToRgb(theme.palette.success.main);
903
- rgb && (tokens["success-rgb"] = `${rgb.r}, ${rgb.g}, ${rgb.b}`);
904
- }
905
- // Warning colors
906
- if (theme.palette.warning) {
907
- tokens.warning = theme.palette.warning.main, tokens["yellow-6"] = theme.palette.warning.main,
908
- theme.palette.warning.light && (tokens["yellow-4"] = theme.palette.warning.light),
909
- theme.palette.warning.dark && (tokens["yellow-9"] = theme.palette.warning.dark);
910
- const rgb = hexToRgb(theme.palette.warning.main);
911
- rgb && (tokens["warning-rgb"] = `${rgb.r}, ${rgb.g}, ${rgb.b}`);
912
- }
913
- // Info colors
914
- if (theme.palette.info) {
915
- tokens.info = theme.palette.info.main, tokens["blue-6"] = theme.palette.info.main,
916
- theme.palette.info.light && (tokens["blue-4"] = theme.palette.info.light), theme.palette.info.dark && (tokens["blue-9"] = theme.palette.info.dark);
917
- const rgb = hexToRgb(theme.palette.info.main);
918
- rgb && (tokens["info-rgb"] = `${rgb.r}, ${rgb.g}, ${rgb.b}`);
919
- }
920
- // Background colors
921
- theme.palette.background && (tokens["body-bg"] = theme.palette.background.default,
922
- tokens["primary-bg-subtle"] = theme.palette.background.default, tokens["secondary-bg-subtle"] = theme.palette.background.paper,
923
- tokens["tertiary-bg-subtle"] = theme.palette.background.subtle),
924
- // Text colors
925
- theme.palette.text && (tokens["body-color"] = theme.palette.text.primary, tokens["heading-color"] = theme.palette.text.primary,
926
- tokens["primary-text-emphasis"] = theme.palette.text.primary, tokens["secondary-text-emphasis"] = theme.palette.text.secondary,
927
- tokens["disabled-text-emphasis"] = theme.palette.text.disabled);
928
- }
929
- // Convert typography
930
- // Convert spacing (if available as object)
931
- if (theme.typography && (tokens["body-font-family"] = theme.typography.fontFamily,
932
- tokens["font-sans-serif"] = theme.typography.fontFamily, tokens["body-font-size"] = `${theme.typography.fontSize}px`,
933
- tokens["body-font-weight"] = String(theme.typography.fontWeightRegular),
934
- // Font weights
935
- tokens["font-weight-light"] = String(theme.typography.fontWeightLight), tokens["font-weight-normal"] = String(theme.typography.fontWeightRegular),
936
- tokens["font-weight-medium"] = String(theme.typography.fontWeightMedium), tokens["font-weight-semibold"] = String(theme.typography.fontWeightSemiBold),
937
- tokens["font-weight-bold"] = String(theme.typography.fontWeightBold),
938
- // Line heights
939
- theme.typography.h1?.lineHeight && (tokens["line-height-base"] = String(theme.typography.h1.lineHeight))),
940
- theme.spacing && "object" == typeof theme.spacing && !("__isSpacingFunction" in theme.spacing)) {
941
- const spacing = theme.spacing;
942
- Object.entries(spacing).forEach((([key, value]) => {
943
- tokens[`spacing-${key}`] = String(value);
944
- }));
945
- }
946
- // Convert border radius
947
- return theme.borderRadius && Object.entries(theme.borderRadius).forEach((([key, value]) => {
948
- tokens["sm" === key ? "border-radius-sm" : "md" === key ? "border-radius" : "lg" === key ? "border-radius-lg" : "xl" === key ? "border-radius-xl" : "xxl" === key ? "border-radius-xxl" : `border-radius-${key}`] = String(value);
949
- })),
950
- // Convert shadows
951
- theme.shadows && Object.entries(theme.shadows).forEach((([key, value]) => {
952
- tokens["xs" === key ? "box-shadow-xs" : "sm" === key ? "box-shadow-sm" : "md" === key ? "box-shadow" : "lg" === key ? "box-shadow-lg" : "xl" === key ? "box-shadow-xl" : `box-shadow-${key}`] = String(value);
953
- })),
954
- // Convert z-index
955
- theme.zIndex && Object.entries(theme.zIndex).forEach((([key, value]) => {
956
- tokens[`z-${key}`] = String(value);
957
- })),
958
- // Convert transitions
959
- theme.transitions && (theme.transitions.duration && Object.entries(theme.transitions.duration).forEach((([key, value]) => {
960
- tokens[`transition-duration-${key}`] = String(value);
961
- })), theme.transitions.easing && Object.entries(theme.transitions.easing).forEach((([key, value]) => {
962
- tokens[`easing-${key}`] = String(value);
963
- }))),
964
- // Convert breakpoints
965
- theme.breakpoints?.values && Object.entries(theme.breakpoints.values).forEach((([key, value]) => {
966
- tokens[`breakpoint-${key}`] = String(value);
967
- })),
968
- // Merge any existing cssVars from theme
969
- theme.cssVars && Object.entries(theme.cssVars).forEach((([key, value]) => {
970
- // Remove --atomix- prefix if present
971
- const cleanKey = key.replace(/^--atomix-/, "").replace(/^--/, "");
972
- tokens[cleanKey] = String(value);
973
- })), tokens;
797
+ */ function injectCSS$1(css, id = "atomix-theme") {
798
+ if (!isBrowser$1()) return;
799
+ let styleElement = document.getElementById(id);
800
+ styleElement || (styleElement = document.createElement("style"), styleElement.id = id,
801
+ styleElement.setAttribute("data-atomix-theme", "true"), document.head.appendChild(styleElement)),
802
+ styleElement.textContent = css;
974
803
  }
975
804
 
976
805
  /**
977
- * Convert DesignTokens to Theme-compatible CSS variables
806
+ * Remove injected CSS from DOM
978
807
  *
979
- * @param tokens - DesignTokens object
980
- * @returns CSS variables object compatible with Theme.cssVars
981
- */ function designTokensToCSSVars(tokens) {
982
- const cssVars = {};
983
- return Object.entries(tokens).forEach((([key, value]) => {
984
- void 0 !== value && (cssVars[`--atomix-${key}`] = String(value));
985
- })), cssVars;
986
- }
987
-
988
- /**
989
- * Create DesignTokens from Theme with defaults
808
+ * Removes the style element with the given ID from the document head.
990
809
  *
991
- * Converts a Theme to DesignTokens and merges with default tokens.
810
+ * @param id - Style element ID to remove (default: 'atomix-theme')
992
811
  *
993
- * @param theme - Theme object to convert
994
- * @returns Complete DesignTokens object
995
- */ function createDesignTokensFromTheme(theme) {
996
- return createTokens(themeToDesignTokens(theme));
812
+ * @example
813
+ * ```typescript
814
+ * removeCSS(); // Removes default 'atomix-theme'
815
+ * removeCSS('my-custom-theme'); // Removes custom ID
816
+ * ```
817
+ */ function removeCSS(id = "atomix-theme") {
818
+ if (!isBrowser$1()) return;
819
+ const styleElement = document.getElementById(id);
820
+ styleElement && styleElement.remove();
997
821
  }
998
822
 
999
823
  /**
1000
- * Create a minimal Theme object from DesignTokens
824
+ * Check if CSS is already injected
1001
825
  *
1002
- * @param tokens - DesignTokens to convert
1003
- * @returns Minimal Theme object with cssVars populated
1004
- */ function designTokensToTheme(tokens) {
1005
- return {
1006
- name: "Design Tokens Theme",
1007
- cssVars: designTokensToCSSVars(tokens),
1008
- __isJSTheme: !0
1009
- };
826
+ * @param id - Style element ID to check (default: 'atomix-theme')
827
+ * @returns True if style element exists
828
+ */ function isCSSInjected(id = "atomix-theme") {
829
+ return !!isBrowser$1() && null !== document.getElementById(id);
1010
830
  }
1011
831
 
1012
832
  /**
1013
- * Core Theme Functions
833
+ * CSS File Utilities
1014
834
  *
1015
- * Simplified theme system that handles both DesignTokens and Theme objects.
1016
- * Config-first approach: loads from atomix.config.ts when no input is provided.
1017
- * Config file is required for automatic loading.
835
+ * Save CSS to file system (Node.js only).
1018
836
  */
1019
837
  /**
1020
- * Create theme CSS from tokens or Theme object
838
+ * Save CSS to file
1021
839
  *
1022
- * **Config-First Approach**: If no input is provided, loads from `atomix.config.ts`.
1023
- * Config file is required for automatic loading.
840
+ * Writes CSS string to a file. Only works in Node.js environment.
1024
841
  *
1025
- * @param input - DesignTokens (partial), Theme object, or undefined (loads from config)
1026
- * @param options - CSS generation options (prefix is automatically read from config if not provided)
1027
- * @returns CSS string with custom properties
1028
- * @throws Error if config loading fails when no input is provided
842
+ * @param css - CSS string to save
843
+ * @param filePath - Output file path
844
+ * @throws Error if called in browser environment
1029
845
  *
1030
846
  * @example
1031
847
  * ```typescript
1032
- * // Loads from atomix.config.ts (config file required)
1033
- * const css = createTheme();
1034
- *
1035
- * // Using DesignTokens
1036
- * const css = createTheme({
1037
- * 'primary': '#7c3aed',
1038
- * 'spacing-4': '1rem',
1039
- * });
1040
- *
1041
- * // Using Theme object
1042
- * const theme = createThemeObject({ palette: { primary: { main: '#7c3aed' } } });
1043
- * const css = createTheme(theme);
1044
- *
1045
- * // With custom options
1046
- * const css = createTheme(undefined, { prefix: 'myapp', selector: ':root' });
848
+ * const css = ':root { --atomix-color-primary: #7AFFD7; }';
849
+ * await saveCSSFile(css, './themes/custom.css');
1047
850
  * ```
1048
- */ function createTheme(input, options) {
1049
- // Determine tokens based on input
1050
- let tokens;
1051
- if (input)
1052
- // Use DesignTokens directly
1053
- tokens =
1054
- // Helper functions to simplify main function
1055
- function(input) {
1056
- return !0 === input?.__isJSTheme || input?.palette && input?.typography;
1057
- }(input) ? themeToDesignTokens(input) : input;
1058
- // Merge with defaults and generate CSS
1059
- else {
1060
- // Check if we're in a browser environment
1061
- if ("undefined" != typeof window) throw new Error("createTheme: No input provided and config loading is not available in browser environment. Please provide tokens explicitly or use Node.js/SSR environment.");
1062
- // Load from config when no input provided
1063
- // Using dynamic import in a way that's more compatible with bundlers
1064
- let loadThemeFromConfigSync, loadAtomixConfig;
1065
- try {
1066
- // Use dynamic require but only in Node.js environments
1067
- // This approach allows bundlers to properly handle external dependencies
1068
- const configLoaderModule = require("../config/configLoader"), loaderModule = require("../../config/loader");
1069
- // Get prefix from config if needed
1070
- if (loadThemeFromConfigSync = configLoaderModule.loadThemeFromConfigSync, loadAtomixConfig = loaderModule.loadAtomixConfig,
1071
- tokens = loadThemeFromConfigSync(), !options?.prefix) try {
1072
- const config = loadAtomixConfig({
1073
- configPath: "atomix.config.ts",
1074
- required: !1
1075
- });
1076
- options = {
1077
- ...options,
1078
- prefix: config?.prefix || "atomix"
1079
- };
1080
- } catch (error) {
1081
- // If config loading fails, use default prefix
1082
- options = {
1083
- ...options,
1084
- prefix: "atomix"
1085
- };
1086
- }
1087
- } catch (error) {
1088
- throw new Error("createTheme: No input provided and config loading is not available in this environment. Please provide tokens explicitly.");
1089
- }
1090
- }
1091
- const allTokens = createTokens(tokens), prefix = options?.prefix ?? "atomix";
1092
- // Get prefix from options or use default
1093
- return generateCSSVariables$1(allTokens, {
1094
- ...options,
1095
- prefix: prefix
1096
- });
1097
- }
851
+ */ var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
1098
852
 
1099
- var aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike = lengthOfArrayLike$2, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
1100
- return function(that, callbackfn, argumentsLength, memo) {
1101
- var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
1102
- if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
1103
- var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
1104
- if (argumentsLength < 2) for (;;) {
1105
- if (index in self) {
1106
- memo = self[index], index += i;
1107
- break;
1108
- }
1109
- if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
1110
- }
1111
- for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
1112
- return memo;
1113
- };
1114
- }, arrayReduce = {
1115
- // `Array.prototype.reduce` method
1116
- // https://tc39.es/ecma262/#sec-array.prototype.reduce
1117
- left: createMethod(!1),
1118
- // `Array.prototype.reduceRight` method
1119
- // https://tc39.es/ecma262/#sec-array.prototype.reduceright
1120
- right: createMethod(!0)
1121
- }, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
1122
- return userAgent.slice(0, string.length) === string;
1123
- }, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$1.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$1.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$1.process) ? "NODE" : globalThis$1.window && globalThis$1.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
853
+ function getDefaultExportFromCjs(x) {
854
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
855
+ }
1124
856
 
1125
- // `Array.prototype.reduce` method
1126
- // https://tc39.es/ecma262/#sec-array.prototype.reduce
1127
- _export({
1128
- target: "Array",
1129
- proto: !0,
1130
- forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
1131
- var method = [][METHOD_NAME];
1132
- return !!method && fails((function() {
1133
- // eslint-disable-next-line no-useless-call -- required for testing
1134
- method.call(null, argument || function() {
1135
- return 1;
1136
- }, 1);
1137
- }));
1138
- }("reduce")
1139
- }, {
1140
- reduce: function(callbackfn /* , initialValue */) {
1141
- var length = arguments.length;
1142
- return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
857
+ var fails$9 = function(exec) {
858
+ try {
859
+ return !!exec();
860
+ } catch (error) {
861
+ return !0;
1143
862
  }
1144
- });
863
+ }, functionBindNative = !fails$9((function() {
864
+ // eslint-disable-next-line es/no-function-prototype-bind -- safe
865
+ var test = function() {/* empty */}.bind();
866
+ // eslint-disable-next-line no-prototype-builtins -- safe
867
+ return "function" != typeof test || test.hasOwnProperty("prototype");
868
+ })), NATIVE_BIND$3 = functionBindNative, FunctionPrototype$1 = Function.prototype, call$5 = FunctionPrototype$1.call, uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$1.bind.bind(call$5, call$5), functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function(fn) {
869
+ return function() {
870
+ return call$5.apply(fn, arguments);
871
+ };
872
+ }, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
873
+ return it && it.Math === Math && it;
874
+ }, globalThis_1 =
875
+ // eslint-disable-next-line es/no-global-this -- safe
876
+ check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
877
+ // eslint-disable-next-line no-restricted-globals -- safe
878
+ check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
879
+ // eslint-disable-next-line no-new-func -- fallback
880
+ function() {
881
+ return this;
882
+ }() || Function("return this")(), NATIVE_BIND$2 = functionBindNative, FunctionPrototype = Function.prototype, apply$1 = FunctionPrototype.apply, call$4 = FunctionPrototype.call, functionApply = "object" == typeof Reflect && Reflect.apply || (NATIVE_BIND$2 ? call$4.bind(apply$1) : function() {
883
+ return call$4.apply(apply$1, arguments);
884
+ }), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
885
+ return stringSlice(toString$3(it), 8, -1);
886
+ }, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
887
+ // Nashorn bug:
888
+ // https://github.com/zloirock/core-js/issues/1128
889
+ // https://github.com/zloirock/core-js/issues/1130
890
+ if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
891
+ }, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
892
+ return "function" == typeof argument || argument === documentAll;
893
+ } : function(argument) {
894
+ return "function" == typeof argument;
895
+ }, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$9((function() {
896
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
897
+ return 7 !== Object.defineProperty({}, 1, {
898
+ get: function() {
899
+ return 7;
900
+ }
901
+ })[1];
902
+ })), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
903
+ return call$3.apply(call$3, arguments);
904
+ }, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
905
+ 1: 2
906
+ }, 1);
1145
907
 
1146
- var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
908
+ // `Object.prototype.propertyIsEnumerable` method implementation
909
+ // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
910
+ objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
911
+ var descriptor = getOwnPropertyDescriptor$1(this, V);
912
+ return !!descriptor && descriptor.enumerable;
913
+ } : $propertyIsEnumerable;
1147
914
 
1148
- const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
1149
- var own = it.reduce;
1150
- return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
1151
- }));
915
+ var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
916
+ return {
917
+ enumerable: !(1 & bitmap),
918
+ configurable: !(2 & bitmap),
919
+ writable: !(4 & bitmap),
920
+ value: value
921
+ };
922
+ }, fails$6 = fails$9, classof$4 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$6((function() {
923
+ // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
924
+ // eslint-disable-next-line no-prototype-builtins -- safe
925
+ return !$Object$3("z").propertyIsEnumerable(0);
926
+ })) ? function(it) {
927
+ return "String" === classof$4(it) ? split(it, "") : $Object$3(it);
928
+ } : $Object$3, isNullOrUndefined$2 = function(it) {
929
+ return null == it;
930
+ }, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$7 = TypeError, requireObjectCoercible$3 = function(it) {
931
+ if (isNullOrUndefined$1(it)) throw new $TypeError$7("Can't call method on " + it);
932
+ return it;
933
+ }, IndexedObject$1 = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
934
+ return IndexedObject$1(requireObjectCoercible$2(it));
935
+ }, isCallable$7 = isCallable$8, isObject$5 = function(it) {
936
+ return "object" == typeof it ? null !== it : isCallable$7(it);
937
+ }, path$3 = {}, path$2 = path$3, globalThis$b = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
938
+ return isCallable$6(variable) ? variable : void 0;
939
+ }, navigator$1 = globalThis_1.navigator, userAgent$2 = navigator$1 && navigator$1.userAgent, environmentUserAgent = userAgent$2 ? String(userAgent$2) : "", globalThis$9 = globalThis_1, userAgent$1 = environmentUserAgent, process$1 = globalThis$9.process, Deno$1 = globalThis$9.Deno, versions = process$1 && process$1.versions || Deno$1 && Deno$1.version, v8 = versions && versions.v8;
1152
940
 
1153
- /**
1154
- * Theme Composition Utilities
1155
- *
1156
- * Simplified utilities for composing, merging, and extending themes.
1157
- */
1158
- // ============================================================================
1159
- // Deep Merge Utility
1160
- // ============================================================================
1161
- /**
1162
- * Check if value is an object
1163
- */ function isObject(item) {
1164
- return item && "object" == typeof item && !Array.isArray(item) && "function" != typeof item;
1165
- }
941
+ v8 && (
942
+ // in old Chrome, versions of V8 isn't V8 = Chrome / 10
943
+ // but their correct versions are not interesting for us
944
+ version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
945
+ // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
946
+ // so check `userAgent` even if `.v8` exists, but 0
947
+ !version && userAgent$1 && (!(match = userAgent$1.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent$1.match(/Chrome\/(\d+)/)) && (version = +match[1]);
1166
948
 
1167
- /**
1168
- * Deep merge multiple objects
1169
- * Later objects override earlier ones
1170
- */ function deepMerge(...objects) {
1171
- if (0 === objects.length) return {};
1172
- if (1 === objects.length) return objects[0];
1173
- const [target, ...sources] = objects, result = {
1174
- ...target
1175
- };
1176
- for (const source of sources) if (source) for (const key in source) {
1177
- if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
1178
- const targetValue = result[key], sourceValue = source[key];
1179
- isObject(targetValue) && isObject(sourceValue) ?
1180
- // Recursively merge objects
1181
- result[key] = deepMerge(targetValue, sourceValue) :
1182
- // Override with source value
1183
- result[key] = sourceValue;
949
+ var environmentV8Version = version, V8_VERSION = environmentV8Version, fails$5 = fails$9, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$5((function() {
950
+ var symbol = Symbol("symbol detection");
951
+ // Chrome 38 Symbol has incorrect toString conversion
952
+ // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
953
+ // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
954
+ // of course, fail.
955
+ return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
956
+ // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
957
+ !Symbol.sham && V8_VERSION && V8_VERSION < 41;
958
+ })), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$2 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
959
+ return "symbol" == typeof it;
960
+ } : function(it) {
961
+ var $Symbol = function(namespace, method) {
962
+ return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$b[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$b[namespace] && globalThis$b[namespace][method];
963
+ }("Symbol");
964
+ return isCallable$5($Symbol) && isPrototypeOf$2($Symbol.prototype, $Object$2(it));
965
+ }, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$6 = TypeError, aCallable$3 = function(argument) {
966
+ if (isCallable$4(argument)) return argument;
967
+ throw new $TypeError$6(function(argument) {
968
+ try {
969
+ return $String$2(argument);
970
+ } catch (error) {
971
+ return "Object";
972
+ }
973
+ }(argument) + " is not a function");
974
+ }, aCallable$2 = aCallable$3, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$5 = TypeError, sharedStore = {
975
+ exports: {}
976
+ }, globalThis$7 = globalThis_1, defineProperty = Object.defineProperty, globalThis$6 = globalThis_1, store$1 = sharedStore.exports = globalThis$6["__core-js_shared__"] || function(key, value) {
977
+ try {
978
+ defineProperty(globalThis$7, key, {
979
+ value: value,
980
+ configurable: !0,
981
+ writable: !0
982
+ });
983
+ } catch (error) {
984
+ globalThis$7[key] = value;
1184
985
  }
1185
- return result;
1186
- }
986
+ return value;
987
+ }("__core-js_shared__", {});
1187
988
 
1188
- // ============================================================================
1189
- // Theme Merging
1190
- // ============================================================================
1191
- /**
1192
- * Merge multiple theme options into a single theme options object
1193
- *
1194
- * @param themes - Theme options to merge
1195
- * @returns Merged theme options
1196
- *
1197
- * @example
1198
- * ```typescript
1199
- * const baseTheme = { palette: { primary: { main: '#000' } } };
1200
- * const customTheme = { palette: { secondary: { main: '#fff' } } };
1201
- * const merged = mergeTheme(baseTheme, customTheme);
1202
- * ```
1203
- */ function mergeTheme(...themes) {
1204
- return deepMerge({}, ...themes);
1205
- }
1206
-
1207
- /**
1208
- * Extend an existing theme with new options
1209
- *
1210
- * @param baseTheme - Base theme to extend (can be Theme or ThemeOptions)
1211
- * @param extension - Theme options to extend with
1212
- * @returns New theme with extended options
1213
- *
1214
- * @example
1215
- * ```typescript
1216
- * const base = createTheme({ palette: { primary: { main: '#000' } } });
1217
- * const extended = extendTheme(base, {
1218
- * palette: { secondary: { main: '#fff' } }
1219
- * });
1220
- * ```
1221
- */ function extendTheme(baseTheme, extension) {
1222
- return createThemeObject(mergeTheme(baseTheme.__isJSTheme ? {
1223
- ...baseTheme
1224
- } : baseTheme, extension));
1225
- }
989
+ /* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
990
+ version: "3.43.0",
991
+ mode: "pure",
992
+ copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
993
+ license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
994
+ source: "https://github.com/zloirock/core-js"
995
+ });
1226
996
 
1227
- // ============================================================================
1228
- // Default Theme Values
1229
- // ============================================================================
1230
- const DEFAULT_PALETTE = {
1231
- primary: {
1232
- main: "#7c3aed",
1233
- // Primary-6
1234
- light: "#d0b2f5",
1235
- // Primary-3
1236
- dark: "#3c1583",
1237
- // Primary-9
1238
- contrastText: "#ffffff"
1239
- },
1240
- secondary: {
1241
- main: "#f3f4f6",
1242
- // Gray-2
1243
- light: "#ffffff",
1244
- // Gray-1
1245
- dark: "#e5e7eb",
1246
- // Gray-3
1247
- contrastText: "#1f2937"
1248
- },
1249
- error: {
1250
- main: "#ef4444",
1251
- // Red-6
1252
- light: "#fca5a5",
1253
- // Red-4
1254
- dark: "#991b1b",
1255
- // Red-9
1256
- contrastText: "#ffffff"
1257
- },
1258
- warning: {
1259
- main: "#eab308",
1260
- // Yellow-6
1261
- light: "#fde047",
1262
- // Yellow-4
1263
- dark: "#854d0e",
1264
- // Yellow-9
1265
- contrastText: "#000000"
1266
- },
1267
- info: {
1268
- main: "#3b82f6",
1269
- // Blue-6
1270
- light: "#93c5fd",
1271
- // Blue-4
1272
- dark: "#1e40af",
1273
- // Blue-9
1274
- contrastText: "#ffffff"
1275
- },
1276
- success: {
1277
- main: "#22c55e",
1278
- // Green-6
1279
- light: "#86efac",
1280
- // Green-4
1281
- dark: "#166534",
1282
- // Green-9
1283
- contrastText: "#ffffff"
1284
- },
1285
- background: {
1286
- default: "#ffffff",
1287
- // Primary-bg
1288
- paper: "#f3f4f6",
1289
- // Secondary-bg
1290
- subtle: "#d1d5db"
1291
- },
1292
- text: {
1293
- primary: "#111827",
1294
- // Gray-10
1295
- secondary: "#374151",
1296
- // Gray-8
1297
- disabled: "#9ca3af"
1298
- }
1299
- }, DEFAULT_TYPOGRAPHY = {
1300
- fontFamily: '"Roboto", "Helvetica Neue", "Helvetica", "Arial", sans-serif',
1301
- fontSize: 16,
1302
- // 1rem
1303
- fontWeightLight: 300,
1304
- fontWeightRegular: 400,
1305
- fontWeightMedium: 500,
1306
- fontWeightSemiBold: 600,
1307
- fontWeightBold: 700,
1308
- fontWeightHeavy: 800,
1309
- fontWeightBlack: 900,
1310
- h1: {
1311
- fontSize: "2.5rem",
1312
- // 40px
1313
- fontWeight: 700,
1314
- lineHeight: 1.3,
1315
- letterSpacing: "-1px"
1316
- },
1317
- h2: {
1318
- fontSize: "2rem",
1319
- // 32px
1320
- fontWeight: 700,
1321
- lineHeight: 1.3,
1322
- letterSpacing: "-1px"
1323
- },
1324
- h3: {
1325
- fontSize: "1.5rem",
1326
- // 24px
1327
- fontWeight: 700,
1328
- lineHeight: 1.3,
1329
- letterSpacing: "-1px"
1330
- },
1331
- h4: {
1332
- fontSize: "1.25rem",
1333
- // 20px
1334
- fontWeight: 700,
1335
- lineHeight: 1.3,
1336
- letterSpacing: "-0.5px"
1337
- },
1338
- h5: {
1339
- fontSize: "1.125rem",
1340
- // 18px
1341
- fontWeight: 700,
1342
- lineHeight: 1.3,
1343
- letterSpacing: "-0.5px"
1344
- },
1345
- h6: {
1346
- fontSize: "1rem",
1347
- // 16px
1348
- fontWeight: 700,
1349
- lineHeight: 1.3,
1350
- letterSpacing: "-0.5px"
1351
- },
1352
- body1: {
1353
- fontSize: "1rem",
1354
- // 16px
1355
- fontWeight: 400,
1356
- lineHeight: 1.2
1357
- },
1358
- body2: {
1359
- fontSize: "0.875rem",
1360
- // 14px
1361
- fontWeight: 400,
1362
- lineHeight: 1.2
997
+ var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, toObject$2 = function(argument) {
998
+ return $Object$1(requireObjectCoercible$1(argument));
999
+ }, toObject$1 = toObject$2, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
1000
+ return hasOwnProperty(toObject$1(it), key);
1001
+ }, uncurryThis$3 = functionUncurryThis, id = 0, postfix = Math.random(), toString$2 = uncurryThis$3(1.1.toString), hasOwn$2 = hasOwnProperty_1, NATIVE_SYMBOL = symbolConstructorDetection, USE_SYMBOL_AS_UID = useSymbolAsUid, Symbol$1 = globalThis_1.Symbol, WellKnownSymbolsStore = store[key = "wks"] || (store[key] = value || {}), createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1.for || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || function(key) {
1002
+ return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
1003
+ }, wellKnownSymbol$5 = function(name) {
1004
+ return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
1005
+ WellKnownSymbolsStore[name];
1006
+ }, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$4 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
1007
+ if (!isObject$3(input) || isSymbol$1(input)) return input;
1008
+ var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$2(func));
1009
+ if (exoticToPrim) {
1010
+ if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
1011
+ !isObject$3(result) || isSymbol$1(result)) return result;
1012
+ throw new $TypeError$4("Can't convert object to primitive value");
1363
1013
  }
1364
- }, DEFAULT_SHADOWS = {
1365
- xs: "0px 1px 2px 0px rgba(45, 54, 67, 0.04), 0px 2px 4px 0px rgba(45, 54, 67, 0.08)",
1366
- sm: "0 2px 4px rgba(0, 0, 0, 0.075)",
1367
- md: "0 4px 8px rgba(0, 0, 0, 0.1)",
1368
- lg: "0 16px 48px rgba(0, 0, 0, 0.175)",
1369
- xl: "0px 16px 64px -8px rgba(45, 54, 67, 0.14)",
1370
- inset: "inset 0 1px 2px rgba(0, 0, 0, 0.075)"
1371
- }, DEFAULT_TRANSITIONS = {
1372
- duration: {
1373
- shortest: 150,
1374
- shorter: 200,
1375
- short: 250,
1376
- standard: 300,
1377
- complex: 375,
1378
- enteringScreen: 225,
1379
- leavingScreen: 195
1380
- },
1381
- easing: {
1382
- easeInOut: "cubic-bezier(0.4, 0, 0.2, 1)",
1383
- easeOut: "cubic-bezier(0.0, 0, 0.2, 1)",
1384
- easeIn: "cubic-bezier(0.4, 0, 1, 1)",
1385
- sharp: "cubic-bezier(0.4, 0, 0.6, 1)"
1014
+ return void 0 === pref && (pref = "number"), function(input, pref) {
1015
+ var fn, val;
1016
+ if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
1017
+ if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
1018
+ if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
1019
+ throw new $TypeError$5("Can't convert object to primitive value");
1020
+ }(input, pref);
1021
+ }, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
1022
+ var key = toPrimitive(argument, "string");
1023
+ return isSymbol(key) ? key : key + "";
1024
+ }, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$9((function() {
1025
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
1026
+ return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
1027
+ get: function() {
1028
+ return 7;
1029
+ }
1030
+ }).a;
1031
+ var it;
1032
+ })), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toIndexedObject$1 = toIndexedObject$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
1033
+
1034
+ // `Object.getOwnPropertyDescriptor` method
1035
+ // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
1036
+ objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
1037
+ if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
1038
+ return $getOwnPropertyDescriptor$1(O, P);
1039
+ } catch (error) {/* empty */}
1040
+ if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
1041
+ };
1042
+
1043
+ var fails$3 = fails$9, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
1044
+ var value = data[normalize(feature)];
1045
+ return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$3(detection) : !!detection);
1046
+ }, normalize = isForced$1.normalize = function(string) {
1047
+ return String(string).replace(replacement, ".").toLowerCase();
1048
+ }, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable$1 = aCallable$3, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$9((function() {
1049
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
1050
+ return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
1051
+ value: 42,
1052
+ writable: !1
1053
+ }).prototype;
1054
+ })), isObject$1 = isObject$5, $String$1 = String, $TypeError$3 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
1055
+ if (isObject$1(argument)) return argument;
1056
+ throw new $TypeError$3($String$1(argument) + " is not an object");
1057
+ }, toPropertyKey = toPropertyKey$2, $TypeError$2 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1058
+
1059
+ // `Object.defineProperty` method
1060
+ // https://tc39.es/ecma262/#sec-object.defineproperty
1061
+ objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
1062
+ if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
1063
+ var current = $getOwnPropertyDescriptor(O, P);
1064
+ current && current.writable && (O[P] = Attributes.value, Attributes = {
1065
+ configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
1066
+ enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
1067
+ writable: !1
1068
+ });
1386
1069
  }
1387
- }, DEFAULT_ZINDEX = {
1388
- mobileStepper: 1e3,
1389
- speedDial: 1050,
1390
- appBar: 1020,
1391
- drawer: 1070,
1392
- modal: 1040,
1393
- snackbar: 1080,
1394
- tooltip: 1060
1395
- }, DEFAULT_BORDER_RADIUS = {
1396
- base: "0.5rem",
1397
- // 8px (spacing-2)
1398
- sm: "0.25rem",
1399
- // 4px (spacing-1)
1400
- md: "0.25rem",
1401
- // 4px (spacing-1)
1402
- lg: "0.625rem",
1403
- // 10px (spacing-2.5)
1404
- xl: "0.75rem",
1405
- // 12px (spacing-3)
1406
- xxl: "1rem",
1407
- // 16px (spacing-4)
1408
- "3xl": "1.5rem",
1409
- // 24px (spacing-6)
1410
- "4xl": "2rem",
1411
- // 32px (spacing-8)
1412
- pill: "50rem"
1070
+ return $defineProperty(O, P, Attributes);
1071
+ } : $defineProperty : function(O, P, Attributes) {
1072
+ if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
1073
+ return $defineProperty(O, P, Attributes);
1074
+ } catch (error) {/* empty */}
1075
+ if ("get" in Attributes || "set" in Attributes) throw new $TypeError$2("Accessors not supported");
1076
+ return "value" in Attributes && (O[P] = Attributes.value), O;
1413
1077
  };
1414
1078
 
1415
- // ============================================================================
1416
- // Helper Functions
1417
- // ============================================================================
1418
- /**
1419
- * Create a complete palette color from partial configuration
1420
- */
1421
- function createPaletteColor(color) {
1422
- return "string" == typeof color ? {
1423
- main: color,
1424
- light: lighten(color),
1425
- dark: darken(color),
1426
- contrastText: getContrastText(color)
1427
- } : {
1428
- main: color.main || "#000000",
1429
- light: color.light || lighten(color.main || "#000000"),
1430
- dark: color.dark || darken(color.main || "#000000"),
1431
- contrastText: color.contrastText || getContrastText(color.main || "#000000")
1079
+ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = createPropertyDescriptor$2, createNonEnumerableProperty$1 = descriptors ? function(object, key, value) {
1080
+ return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
1081
+ } : function(object, key, value) {
1082
+ return object[key] = value, object;
1083
+ }, globalThis$3 = globalThis_1, apply = functionApply, uncurryThis$1 = functionUncurryThisClause, isCallable$1 = isCallable$8, getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f, isForced = isForced_1, path$1 = path$3, bind = function(fn, that) {
1084
+ return aCallable$1(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
1085
+ return fn.apply(that, arguments);
1086
+ };
1087
+ }, createNonEnumerableProperty = createNonEnumerableProperty$1, hasOwn = hasOwnProperty_1, wrapConstructor = function(NativeConstructor) {
1088
+ var Wrapper = function(a, b, c) {
1089
+ if (this instanceof Wrapper) {
1090
+ switch (arguments.length) {
1091
+ case 0:
1092
+ return new NativeConstructor;
1093
+
1094
+ case 1:
1095
+ return new NativeConstructor(a);
1096
+
1097
+ case 2:
1098
+ return new NativeConstructor(a, b);
1099
+ }
1100
+ return new NativeConstructor(a, b, c);
1101
+ }
1102
+ return apply(NativeConstructor, this, arguments);
1432
1103
  };
1433
- }
1104
+ return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
1105
+ }, _export = function(options, source) {
1106
+ var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor, TARGET = options.target, GLOBAL = options.global, STATIC = options.stat, PROTO = options.proto, nativeSource = GLOBAL ? globalThis$3 : STATIC ? globalThis$3[TARGET] : globalThis$3[TARGET] && globalThis$3[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
1107
+ for (key in source)
1108
+ // contains in native
1109
+ USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
1110
+ targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
1111
+ // export native or implementation
1112
+ sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
1113
+ // bind methods to global for calling from export context
1114
+ resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$3) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
1115
+ // add a flag to not completely full polyfills
1116
+ (options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
1117
+ createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
1118
+ // export virtual prototype methods
1119
+ createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
1120
+ // export real prototype methods
1121
+ options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
1122
+ }, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
1123
+ var n = +x;
1124
+ return (n > 0 ? floor : ceil)(n);
1125
+ }, toIntegerOrInfinity$2 = function(argument) {
1126
+ var number = +argument;
1127
+ // eslint-disable-next-line no-self-compare -- NaN check
1128
+ return number != number || 0 === number ? 0 : trunc(number);
1129
+ }, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, max = Math.max, min$1 = Math.min, toIntegerOrInfinity = toIntegerOrInfinity$2, min = Math.min, lengthOfArrayLike$2 = function(obj) {
1130
+ return argument = obj.length, (len = toIntegerOrInfinity(argument)) > 0 ? min(len, 9007199254740991) : 0;
1131
+ var argument, len;
1132
+ }, toIndexedObject = toIndexedObject$2, lengthOfArrayLike$1 = lengthOfArrayLike$2, createMethod$1 = function(IS_INCLUDES) {
1133
+ return function($this, el, fromIndex) {
1134
+ var O = toIndexedObject($this), length = lengthOfArrayLike$1(O);
1135
+ if (0 === length) return !IS_INCLUDES && -1;
1136
+ var value, index = function(index, length) {
1137
+ var integer = toIntegerOrInfinity$1(index);
1138
+ return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
1139
+ }(fromIndex, length);
1140
+ // Array#includes uses SameValueZero equality algorithm
1141
+ // eslint-disable-next-line no-self-compare -- NaN check
1142
+ if (IS_INCLUDES && el != el) {
1143
+ for (;length > index; )
1144
+ // eslint-disable-next-line no-self-compare -- NaN check
1145
+ if ((value = O[index++]) != value) return !0;
1146
+ // Array#indexOf ignores holes, Array#includes - not
1147
+ } else for (;length > index; index++) if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
1148
+ return !IS_INCLUDES && -1;
1149
+ };
1150
+ }, $includes = [ createMethod$1(!0), createMethod$1(!1) ][0];
1434
1151
 
1435
- /**
1436
- * Create breakpoints object
1437
- */
1438
- // ============================================================================
1439
- // Main createTheme Function
1440
- // ============================================================================
1441
- /**
1442
- * Create a theme object with computed values
1443
- *
1444
- * @param options - Theme configuration options
1445
- * @returns Complete theme object
1446
- */
1447
- function createThemeObject(...options) {
1448
- // Merge all options
1449
- const mergedOptions = _reduceInstanceProperty(options).call(options, ((acc, option) => deepMerge(acc, option)), {}), palette = {
1450
- primary: createPaletteColor(mergedOptions.palette?.primary || DEFAULT_PALETTE.primary),
1451
- secondary: createPaletteColor(mergedOptions.palette?.secondary || DEFAULT_PALETTE.secondary),
1452
- error: createPaletteColor(mergedOptions.palette?.error || DEFAULT_PALETTE.error),
1453
- warning: createPaletteColor(mergedOptions.palette?.warning || DEFAULT_PALETTE.warning),
1454
- info: createPaletteColor(mergedOptions.palette?.info || DEFAULT_PALETTE.info),
1455
- success: createPaletteColor(mergedOptions.palette?.success || DEFAULT_PALETTE.success),
1456
- // Handle light and dark colors if provided
1457
- ...mergedOptions.palette?.light && {
1458
- light: createPaletteColor(mergedOptions.palette.light)
1459
- },
1460
- ...mergedOptions.palette?.dark && {
1461
- dark: createPaletteColor(mergedOptions.palette.dark)
1462
- },
1463
- background: {
1464
- default: mergedOptions.palette?.background?.default || DEFAULT_PALETTE.background.default,
1465
- subtle: mergedOptions.palette?.background?.subtle || DEFAULT_PALETTE.background.subtle
1466
- },
1467
- text: {
1468
- primary: mergedOptions.palette?.text?.primary || DEFAULT_PALETTE.text.primary,
1469
- secondary: mergedOptions.palette?.text?.secondary || DEFAULT_PALETTE.text.secondary,
1470
- disabled: mergedOptions.palette?.text?.disabled || DEFAULT_PALETTE.text.disabled
1152
+ // `Array.prototype.includes` method
1153
+ // https://tc39.es/ecma262/#sec-array.prototype.includes
1154
+ _export({
1155
+ target: "Array",
1156
+ proto: !0,
1157
+ forced: fails$9((function() {
1158
+ // eslint-disable-next-line es/no-array-prototype-includes -- detection
1159
+ return !Array(1).includes();
1160
+ }))
1161
+ }, {
1162
+ includes: function(el /* , fromIndex = 0 */) {
1163
+ return $includes(this, el, arguments.length > 1 ? arguments[1] : void 0);
1164
+ }
1165
+ });
1166
+
1167
+ var globalThis$2 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$3 = function(CONSTRUCTOR, METHOD) {
1168
+ var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
1169
+ if (pureMethod) return pureMethod;
1170
+ var NativeConstructor = globalThis$2[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
1171
+ return NativePrototype && NativePrototype[METHOD];
1172
+ }, includes$4 = getBuiltInPrototypeMethod$3("Array", "includes"), isObject = isObject$5, classof$3 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError$1 = TypeError, test = {};
1173
+
1174
+ test[wellKnownSymbol$5("toStringTag")] = "z";
1175
+
1176
+ var TO_STRING_TAG_SUPPORT = "[object z]" === String(test), isCallable = isCallable$8, classofRaw = classofRaw$2, TO_STRING_TAG = wellKnownSymbol$5("toStringTag"), $Object = Object, CORRECT_ARGUMENTS = "Arguments" === classofRaw(function() {
1177
+ return arguments;
1178
+ }()), classof$1 = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {
1179
+ var O, tag, result;
1180
+ return void 0 === it ? "Undefined" : null === it ? "Null" : "string" == typeof (tag = function(it, key) {
1181
+ try {
1182
+ return it[key];
1183
+ } catch (error) {/* empty */}
1184
+ }(O = $Object(it), TO_STRING_TAG)) ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : "Object" === (result = classofRaw(O)) && isCallable(O.callee) ? "Arguments" : result;
1185
+ }, $String = String, MATCH = wellKnownSymbol$5("match"), $$1 = _export, notARegExp = function(it) {
1186
+ if (function(it) {
1187
+ var isRegExp;
1188
+ return isObject(it) && (void 0 !== (isRegExp = it[MATCH$1]) ? !!isRegExp : "RegExp" === classof$3(it));
1189
+ }(it)) throw new $TypeError$1("The method doesn't accept regular expressions");
1190
+ return it;
1191
+ }, requireObjectCoercible = requireObjectCoercible$3, toString = function(argument) {
1192
+ if ("Symbol" === classof$1(argument)) throw new TypeError("Cannot convert a Symbol value to a string");
1193
+ return $String(argument);
1194
+ }, stringIndexOf = functionUncurryThis("".indexOf);
1195
+
1196
+ // `String.prototype.includes` method
1197
+ // https://tc39.es/ecma262/#sec-string.prototype.includes
1198
+ $$1({
1199
+ target: "String",
1200
+ proto: !0,
1201
+ forced: !function(METHOD_NAME) {
1202
+ var regexp = /./;
1203
+ try {
1204
+ "/./"[METHOD_NAME](regexp);
1205
+ } catch (error1) {
1206
+ try {
1207
+ return regexp[MATCH] = !1, "/./"[METHOD_NAME](regexp);
1208
+ } catch (error2) {/* empty */}
1471
1209
  }
1472
- }, typography = deepMerge({
1473
- ...DEFAULT_TYPOGRAPHY
1474
- }, mergedOptions.typography || {}), spacing =
1475
- // ============================================================================
1476
- // Spacing Utilities
1477
- // ============================================================================
1478
- /**
1479
- * Create a spacing function from various input types
1480
- *
1481
- * @param spacingInput - Spacing configuration (number, array, or function), default 4
1482
- * @returns Spacing function
1483
- */
1484
- function(spacingInput = 4) {
1485
- // If it's already a function, return it
1486
- return "function" == typeof spacingInput ? spacingInput :
1487
- // If it's a number, create a function that multiplies by that number
1488
- "number" == typeof spacingInput ? (...values) => 0 === values.length ? "0px" : values.map((value => value * spacingInput + "px")).join(" ") :
1489
- // If it's an array, use it as a scale
1490
- Array.isArray(spacingInput) ? (...values) => 0 === values.length ? "0px" : values.map((value => `${spacingInput[value] || value}px`)).join(" ") : (...values) => 0 === values.length ? "0px" : values.map((value => 4 * value + "px")).join(" ");
1210
+ return !1;
1211
+ }("includes")
1212
+ }, {
1213
+ includes: function(searchString /* , position = 0 */) {
1214
+ return !!~stringIndexOf(toString(requireObjectCoercible(this)), toString(notARegExp(searchString)), arguments.length > 1 ? arguments[1] : void 0);
1491
1215
  }
1492
- /**
1493
- * Check if a theme is a JS theme (created with createTheme)
1494
- */ (mergedOptions.spacing), breakpoints = function(breakpointsInput) {
1495
- const values = {
1496
- xs: 0,
1497
- sm: 576,
1498
- md: 768,
1499
- lg: 992,
1500
- xl: 1200,
1501
- xxl: 1440,
1502
- ...breakpointsInput?.values
1503
- }, unit = breakpointsInput?.unit || "px";
1504
- return {
1505
- values: values,
1506
- unit: unit,
1507
- up: key => `@media (min-width:${"number" == typeof key ? key : values[key] ?? 0}${unit})`,
1508
- down: key => `@media (max-width:${("number" == typeof key ? key : values[key] ?? 0) - .05}${unit})`,
1509
- between: (start, end) => {
1510
- const startValue = "number" == typeof start ? start : values[start] ?? 0, endValue = "number" == typeof end ? end : values[end] ?? 0;
1511
- return `@media (min-width:${startValue}${unit}) and (max-width:${endValue - .05}${unit})`;
1512
- }
1513
- };
1514
- }(mergedOptions.breakpoints), shadows = deepMerge({
1515
- ...DEFAULT_SHADOWS
1516
- }, mergedOptions.shadows || {}), transitions = deepMerge({
1517
- ...DEFAULT_TRANSITIONS
1518
- }, mergedOptions.transitions || {}), zIndex = deepMerge({
1519
- ...DEFAULT_ZINDEX
1520
- }, mergedOptions.zIndex || {}), borderRadius = deepMerge({
1521
- ...DEFAULT_BORDER_RADIUS
1522
- }, mergedOptions.borderRadius || {});
1523
- // Create palette
1524
- return {
1525
- // Metadata
1526
- name: mergedOptions.name || "Custom Theme",
1527
- class: mergedOptions.class,
1528
- description: mergedOptions.description,
1529
- author: mergedOptions.author,
1530
- version: mergedOptions.version || "1.0.0",
1531
- tags: mergedOptions.tags,
1532
- supportsDarkMode: mergedOptions.supportsDarkMode,
1533
- status: mergedOptions.status || "experimental",
1534
- a11y: mergedOptions.a11y,
1535
- color: mergedOptions.color || palette.primary.main,
1536
- features: mergedOptions.features,
1537
- dependencies: mergedOptions.dependencies,
1538
- // Theme configuration
1539
- palette: palette,
1540
- typography: typography,
1541
- spacing: spacing,
1542
- breakpoints: breakpoints,
1543
- shadows: shadows,
1544
- transitions: transitions,
1545
- zIndex: zIndex,
1546
- borderRadius: borderRadius,
1547
- custom: mergedOptions.custom || {},
1548
- // Mark as JS theme
1549
- __isJSTheme: !0
1550
- };
1551
- }
1216
+ });
1552
1217
 
1553
- /**
1554
- * Create a new theme registry
1555
- */ function createThemeRegistry() {
1556
- return {};
1557
- }
1218
+ var includes$3 = getBuiltInPrototypeMethod$3("String", "includes"), isPrototypeOf$1 = objectIsPrototypeOf, arrayMethod = includes$4, stringMethod = includes$3, ArrayPrototype$1 = Array.prototype, StringPrototype = String.prototype;
1219
+
1220
+ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
1221
+ var own = it.includes;
1222
+ return it === ArrayPrototype$1 || isPrototypeOf$1(ArrayPrototype$1, it) && own === ArrayPrototype$1.includes ? arrayMethod : "string" == typeof it || it === StringPrototype || isPrototypeOf$1(StringPrototype, it) && own === StringPrototype.includes ? stringMethod : own;
1223
+ }));
1558
1224
 
1559
1225
  /**
1560
- * Register a theme
1561
- * @param registry - Theme registry object
1562
- * @param id - Theme identifier
1563
- * @param metadata - Theme metadata
1564
- */ function registerTheme(registry, id, metadata) {
1565
- registry[id] = metadata;
1566
- }
1567
-
1226
+ * Theme System Constants
1227
+ *
1228
+ * Centralized constants for the theme system to avoid magic numbers and strings.
1229
+ */
1568
1230
  /**
1569
- * Unregister a theme
1570
- * @param registry - Theme registry object
1571
- * @param id - Theme identifier
1572
- */ function unregisterTheme(registry, id) {
1573
- const exists = id in registry;
1574
- return delete registry[id], exists;
1575
- }
1231
+ * Default storage key for theme persistence
1232
+ */ "undefined" != typeof process && process.env;
1576
1233
 
1577
1234
  /**
1578
- * Check if a theme is registered
1579
- * @param registry - Theme registry object
1580
- * @param id - Theme identifier
1581
- */ function hasTheme(registry, id) {
1582
- return id in registry;
1583
- }
1235
+ * Check if code is running in a browser environment
1236
+ */
1237
+ const isBrowser = () => "undefined" != typeof window && "undefined" != typeof document, isServer = () => !isBrowser(), sanitizePath = path => path.replace(/[<>"']/g, "").replace(/\.\./g, "").replace(/\/+/g, "/").replace(/^\/+|\/+$/g, "") // Trim leading/trailing slashes
1238
+ , buildThemePath = (themeName, basePath = "/themes", useMinified = !1, cdnPath = null) => {
1239
+ // Validate theme name to prevent path injection
1240
+ if (!isValidThemeName(themeName)) throw new ThemeError(`Invalid theme name: "${themeName}". Theme names must be lowercase alphanumeric with hyphens (e.g., "my-theme").`, ThemeErrorCode.INVALID_THEME_NAME, {
1241
+ themeName: themeName,
1242
+ pattern: /^[a-z0-9]+(-[a-z0-9]+)*$/
1243
+ });
1244
+ const fileName = `${themeName}${useMinified ? ".min.css" : ".css"}`;
1245
+ return cdnPath ? `${sanitizePath(cdnPath)}/${fileName}` : `${sanitizePath(basePath)}/${fileName.replace(/^\//, "")}`;
1246
+ // Sanitize basePath to prevent path injection
1247
+ }, applyThemeAttributes = (dataAttribute, themeName) => {
1248
+ isServer() || (
1249
+ // Set data attribute on body (with null check)
1250
+ document.body && document.body.setAttribute(dataAttribute, themeName),
1251
+ // Also set on documentElement for broader compatibility
1252
+ document.documentElement.setAttribute(dataAttribute, themeName));
1253
+ }, isValidThemeName = themeName => !(!themeName || "string" != typeof themeName) && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(themeName), createLocalStorageAdapter = () => ({
1254
+ getItem: key => {
1255
+ if (isServer()) return null;
1256
+ try {
1257
+ return localStorage.getItem(key);
1258
+ } catch {
1259
+ return null;
1260
+ }
1261
+ },
1262
+ setItem: (key, value) => {
1263
+ if (!isServer()) try {
1264
+ localStorage.setItem(key, value);
1265
+ } catch {
1266
+ // Silently fail if localStorage is not available
1267
+ }
1268
+ },
1269
+ removeItem: key => {
1270
+ if (!isServer()) try {
1271
+ localStorage.removeItem(key);
1272
+ } catch {
1273
+ // Silently fail
1274
+ }
1275
+ },
1276
+ isAvailable: () => {
1277
+ if (isServer()) return !1;
1278
+ try {
1279
+ const test = "__atomix_storage_test__";
1280
+ return localStorage.setItem(test, test), localStorage.removeItem(test), !0;
1281
+ } catch {
1282
+ return !1;
1283
+ }
1284
+ }
1285
+ }), domUtils = Object.freeze( Object.defineProperty({
1286
+ __proto__: null,
1287
+ applyThemeAttributes: applyThemeAttributes,
1288
+ buildThemePath: buildThemePath,
1289
+ createLocalStorageAdapter: createLocalStorageAdapter,
1290
+ isBrowser: isBrowser,
1291
+ isServer: isServer,
1292
+ isValidThemeName: isValidThemeName,
1293
+ loadThemeCSS: (fullPath, linkId) => isServer() ? Promise.resolve() : new Promise(((resolve, reject) => {
1294
+ if (document.getElementById(linkId)) return void resolve();
1295
+ // Create link element
1296
+ const link = document.createElement("link");
1297
+ link.id = linkId, link.rel = "stylesheet", link.type = "text/css", link.href = fullPath,
1298
+ // Add data attribute for tracking
1299
+ link.setAttribute("data-atomix-theme", "true"),
1300
+ // Handle load success
1301
+ link.onload = () => {
1302
+ resolve();
1303
+ },
1304
+ // Handle load error
1305
+ link.onerror = () => {
1306
+ // Remove failed link element
1307
+ link.remove(), reject(new ThemeError(`Failed to load theme CSS from: ${fullPath}. Please check that the file exists and is accessible.`, ThemeErrorCode.THEME_LOAD_FAILED, {
1308
+ fullPath: fullPath,
1309
+ linkId: linkId
1310
+ }));
1311
+ },
1312
+ // Append to head
1313
+ document.head.appendChild(link);
1314
+ }))
1315
+ }, Symbol.toStringTag, {
1316
+ value: "Module"
1317
+ }));
1584
1318
 
1585
1319
  /**
1586
- * Get theme metadata
1587
- * @param registry - Theme registry object
1588
- * @param id - Theme identifier
1589
- */ function getTheme(registry, id) {
1590
- return registry[id];
1591
- }
1592
-
1320
+ * Check if code is running on the server (SSR)
1321
+ */
1593
1322
  /**
1594
- * Get all registered theme metadata
1595
- * @param registry - Theme registry object
1596
- */ function getAllThemes(registry) {
1597
- return Object.values(registry);
1598
- }
1599
-
1323
+ * Theme Utilities
1324
+ *
1325
+ * Helper utilities for working with themes, including color manipulation,
1326
+ * spacing helpers, and theme value accessors.
1327
+ */
1328
+ // ============================================================================
1329
+ // Color Manipulation Utilities
1330
+ // ============================================================================
1600
1331
  /**
1601
- * Get all registered theme IDs
1602
- * @param registry - Theme registry object
1603
- */ function getThemeIds(registry) {
1604
- return Object.keys(registry);
1332
+ * Convert hex color to RGB object
1333
+ */
1334
+ function hexToRgb(hex) {
1335
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1336
+ return result ? {
1337
+ r: parseInt(result[1], 16),
1338
+ g: parseInt(result[2], 16),
1339
+ b: parseInt(result[3], 16)
1340
+ } : null;
1605
1341
  }
1606
1342
 
1607
1343
  /**
1608
- * Clear all registered themes
1609
- * @param registry - Theme registry object
1610
- */ function clearThemes(registry) {
1611
- Object.keys(registry).forEach((key => delete registry[key]));
1344
+ * Convert RGB to hex color
1345
+ */ function rgbToHex(r, g, b) {
1346
+ const toHex = val => Math.round(Math.max(0, Math.min(255, val))).toString(16).padStart(2, "0");
1347
+ return `#${toHex(r ?? 0)}${toHex(g ?? 0)}${toHex(b ?? 0)}`;
1612
1348
  }
1613
1349
 
1614
1350
  /**
1615
- * Get the number of registered themes
1616
- * @param registry - Theme registry object
1617
- */ function getThemeCount(registry) {
1618
- return Object.keys(registry).length;
1351
+ * Calculate relative luminance of a color
1352
+ * Used for determining contrast ratios
1353
+ */ function getLuminance(color) {
1354
+ const rgb = hexToRgb(color);
1355
+ if (!rgb) return 0;
1356
+ const {r: r, g: g, b: b} = rgb, [rs, gs, bs] = [ r ?? 0, g ?? 0, b ?? 0 ].map((c => {
1357
+ const val = c / 255;
1358
+ return val <= .03928 ? val / 12.92 : Math.pow((val + .055) / 1.055, 2.4);
1359
+ }));
1360
+ return .2126 * (rs ?? 0) + .7152 * (gs ?? 0) + .0722 * (bs ?? 0);
1619
1361
  }
1620
1362
 
1621
1363
  /**
1622
- * CSS Injection Utilities
1623
- *
1624
- * Inject CSS into HTML head via <style> element.
1625
- */
1626
- /**
1627
- * Check if running in browser environment
1628
- */ function isBrowser$1() {
1629
- return "undefined" != typeof document;
1364
+ * Calculate contrast ratio between two colors
1365
+ */ function getContrastRatio(foreground, background) {
1366
+ const lumA = getLuminance(foreground), lumB = getLuminance(background);
1367
+ return (Math.max(lumA, lumB) + .05) / (Math.min(lumA, lumB) + .05);
1630
1368
  }
1631
1369
 
1632
1370
  /**
1633
- * Inject CSS into HTML head via <style> element
1634
- *
1635
- * Creates or updates a style element in the document head.
1636
- * If an element with the same ID exists, it will be updated.
1637
- *
1638
- * @param css - CSS string to inject
1639
- * @param id - Style element ID (default: 'atomix-theme')
1640
- *
1641
- * @example
1642
- * ```typescript
1643
- * const css = ':root { --atomix-color-primary: #7AFFD7; }';
1644
- * injectCSS(css);
1645
- *
1646
- * // With custom ID
1647
- * injectCSS(css, 'my-custom-theme');
1648
- * ```
1649
- */ function injectCSS$1(css, id = "atomix-theme") {
1650
- if (!isBrowser$1()) return void console.warn("injectCSS: Not in browser environment, CSS not injected");
1651
- let styleElement = document.getElementById(id);
1652
- styleElement || (styleElement = document.createElement("style"), styleElement.id = id,
1653
- styleElement.setAttribute("data-atomix-theme", "true"), document.head.appendChild(styleElement)),
1654
- styleElement.textContent = css;
1371
+ * Get appropriate contrast text color (black or white) for a background color
1372
+ */ function getContrastText(background, threshold = 3) {
1373
+ const contrastWithWhite = getContrastRatio("#FFFFFF", background), contrastWithBlack = getContrastRatio("#000000", background);
1374
+ return contrastWithWhite >= threshold ? "#FFFFFF" : contrastWithBlack >= threshold ? "#000000" : contrastWithWhite > contrastWithBlack ? "#FFFFFF" : "#000000";
1655
1375
  }
1656
1376
 
1657
1377
  /**
1658
- * Remove injected CSS from DOM
1659
- *
1660
- * Removes the style element with the given ID from the document head.
1661
- *
1662
- * @param id - Style element ID to remove (default: 'atomix-theme')
1378
+ * Lighten a color by a given amount
1663
1379
  *
1664
- * @example
1665
- * ```typescript
1666
- * removeCSS(); // Removes default 'atomix-theme'
1667
- * removeCSS('my-custom-theme'); // Removes custom ID
1668
- * ```
1669
- */ function removeCSS(id = "atomix-theme") {
1670
- if (!isBrowser$1()) return;
1671
- const styleElement = document.getElementById(id);
1672
- styleElement && styleElement.remove();
1380
+ * @param color - Hex color string
1381
+ * @param amount - Amount to lighten (0-1), default 0.2
1382
+ * @returns Lightened hex color
1383
+ */ function lighten(color, amount = .2) {
1384
+ const rgb = hexToRgb(color);
1385
+ if (!rgb) return color;
1386
+ const {r: r, g: g, b: b} = rgb, lightenValue = val => Math.min(255, Math.round(val + (255 - val) * amount));
1387
+ return rgbToHex(lightenValue(r), lightenValue(g), lightenValue(b));
1673
1388
  }
1674
1389
 
1675
1390
  /**
1676
- * Check if CSS is already injected
1391
+ * Darken a color by a given amount
1677
1392
  *
1678
- * @param id - Style element ID to check (default: 'atomix-theme')
1679
- * @returns True if style element exists
1680
- */ function isCSSInjected(id = "atomix-theme") {
1681
- return !!isBrowser$1() && null !== document.getElementById(id);
1393
+ * @param color - Hex color string
1394
+ * @param amount - Amount to darken (0-1), default 0.2
1395
+ * @returns Darkened hex color
1396
+ */ function darken(color, amount = .2) {
1397
+ const rgb = hexToRgb(color);
1398
+ if (!rgb) return color;
1399
+ const {r: r, g: g, b: b} = rgb, darkenValue = val => Math.max(0, Math.round(val * (1 - amount)));
1400
+ return rgbToHex(darkenValue(r), darkenValue(g), darkenValue(b));
1682
1401
  }
1683
1402
 
1684
1403
  /**
1685
- * CSS File Utilities
1686
- *
1687
- * Save CSS to file system (Node.js only).
1688
- */
1689
- /**
1690
- * Save CSS to file
1691
- *
1692
- * Writes CSS string to a file. Only works in Node.js environment.
1693
- *
1694
- * @param css - CSS string to save
1695
- * @param filePath - Output file path
1696
- * @throws Error if called in browser environment
1404
+ * Add alpha (opacity) to a color
1697
1405
  *
1698
- * @example
1699
- * ```typescript
1700
- * const css = ':root { --atomix-color-primary: #7AFFD7; }';
1701
- * await saveCSSFile(css, './themes/custom.css');
1702
- * ```
1703
- */ "undefined" != typeof process && process.env;
1704
-
1705
- /**
1706
- * Check if code is running in a browser environment
1707
- */
1708
- const isBrowser = () => "undefined" != typeof window && "undefined" != typeof document, isServer = () => !isBrowser(), buildThemePath = (themeName, basePath = "/themes", useMinified = !1, cdnPath = null) => {
1709
- // Validate theme name to prevent path injection
1710
- if (!isValidThemeName(themeName)) throw new Error(`Invalid theme name: "${themeName}". Theme names must be lowercase alphanumeric with hyphens.`);
1711
- const fileName = `${themeName}${useMinified ? ".min.css" : ".css"}`;
1712
- return cdnPath ? `${cdnPath.replace(/[<>"']/g, "")}/${fileName}` : `${basePath.replace(/\/$/, "").replace(/[<>"']/g, "")}/${fileName.replace(/^\//, "")}`;
1713
- // Ensure basePath doesn't end with slash and fileName doesn't start with slash
1714
- // Also sanitize basePath to prevent path injection
1715
- }, isValidThemeName = themeName => !(!themeName || "string" != typeof themeName) && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(themeName);
1406
+ * @param color - Hex color string
1407
+ * @param opacity - Opacity value (0-1)
1408
+ * @returns RGBA color string
1409
+ */ function alpha(color, opacity) {
1410
+ const rgb = hexToRgb(color);
1411
+ if (!rgb) return color;
1412
+ const {r: r, g: g, b: b} = rgb;
1413
+ return `rgba(${r}, ${g}, ${b}, ${Math.max(0, Math.min(1, opacity))})`;
1414
+ }
1716
1415
 
1717
1416
  /**
1718
- * Check if code is running on the server (SSR)
1719
- */
1720
- /**
1721
- * CSS Variable Generator
1722
- *
1723
- * Generates CSS custom properties from theme objects and injects them into the DOM.
1724
- *
1725
- * **Token Naming Alignment:**
1726
- * This generator produces CSS variables that match the SCSS token naming pattern exactly:
1727
- * - Colors: --atomix-primary, --atomix-primary-1 through --atomix-primary-10
1728
- * - Spacing: --atomix-spacing-1, --atomix-spacing-4, etc.
1729
- * - Typography: --atomix-font-size-base, --atomix-font-weight-normal, etc.
1730
- * - Shadows: --atomix-box-shadow, --atomix-box-shadow-sm, etc.
1731
- *
1732
- * All tokens follow the flat structure pattern used in SCSS (not nested like --atomix-palette-primary-main).
1733
- * This ensures compatibility between SCSS themes and JavaScript themes.
1417
+ * Emphasize a color (lighten if dark, darken if light)
1734
1418
  *
1735
- * @see src/styles/03-generic/_generic.root.scss for SCSS token definitions
1736
- */
1737
- /**
1738
- * Convert a nested object to flat CSS variable declarations
1419
+ * @param color - Hex color string
1420
+ * @param coefficient - Amount to emphasize (0-1), default 0.15
1421
+ * @returns Emphasized hex color
1739
1422
  */
1740
- function flattenObject(obj, prefix = "", result = {}) {
1741
- for (const key in obj) {
1742
- if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
1743
- const value = obj[key], newKey = prefix ? `${prefix}-${key}` : key;
1744
- if (value && "object" == typeof value && !Array.isArray(value)) {
1745
- // Skip special objects like functions
1746
- if ("function" == typeof value) continue;
1747
- // Recursively flatten nested objects
1748
- flattenObject(value, newKey, result);
1749
- } else "string" != typeof value && "number" != typeof value || (result[newKey.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()] = String(value));
1750
- }
1751
- return result;
1752
- }
1753
-
1754
1423
  /**
1755
1424
  * Generate a color scale from a base color (1-10 steps)
1756
1425
  * Creates lighter to darker variations
1757
- */ function generateColorScale(baseColor, prefix, colorName) {
1426
+ */
1427
+ function generateColorScale(baseColor, prefix, colorName) {
1758
1428
  const vars = {};
1759
1429
  if (!hexToRgb(baseColor)) return vars;
1760
1430
  // Generate 10-step scale
@@ -1818,7 +1488,16 @@ function generateCSSVariables(theme, options = {}) {
1818
1488
  // Text emphasis: emphasized version of the color for text (--atomix-primary-text-emphasis)
1819
1489
  vars[`${prefix}-${key}-text-emphasis`] = function(color, coefficient = .15) {
1820
1490
  return getLuminance(color) > .5 ? darken(color, coefficient) : lighten(color, coefficient);
1821
- }(color.main, .15),
1491
+ }
1492
+ // ============================================================================
1493
+ // Spacing Utilities
1494
+ // ============================================================================
1495
+ /**
1496
+ * Create a spacing function from various input types
1497
+ *
1498
+ * @param spacingInput - Spacing configuration (number, array, or function), default 4
1499
+ * @returns Spacing function
1500
+ */ (color.main, .15),
1822
1501
  // Background subtle: very light version for backgrounds (--atomix-primary-bg-subtle)
1823
1502
  vars[`${prefix}-${key}-bg-subtle`] = alpha(color.main, .1),
1824
1503
  // Border subtle: light version for borders (--atomix-primary-border-subtle)
@@ -2163,7 +1842,52 @@ function generateCSSVariables(theme, options = {}) {
2163
1842
  return vars[`${prefix}-focus-ring-width`] = "3px", vars[`${prefix}-focus-ring-offset`] = "2px",
2164
1843
  vars[`${prefix}-focus-ring-opacity`] = "0.25", vars;
2165
1844
  }(theme.palette, prefix)), theme.custom && Object.keys(theme.custom).length > 0) {
2166
- const customVars = flattenObject(theme.custom, `${prefix}-custom`);
1845
+ const customVars =
1846
+ /**
1847
+ * CSS Variable Generator
1848
+ *
1849
+ * Generates CSS custom properties from theme objects and injects them into the DOM.
1850
+ *
1851
+ * **Token Naming Alignment:**
1852
+ * This generator produces CSS variables that match the SCSS token naming pattern exactly:
1853
+ * - Colors: --atomix-primary, --atomix-primary-1 through --atomix-primary-10
1854
+ * - Spacing: --atomix-spacing-1, --atomix-spacing-4, etc.
1855
+ * - Typography: --atomix-font-size-base, --atomix-font-weight-normal, etc.
1856
+ * - Shadows: --atomix-box-shadow, --atomix-box-shadow-sm, etc.
1857
+ *
1858
+ * All tokens follow the flat structure pattern used in SCSS (not nested like --atomix-palette-primary-main).
1859
+ * This ensures compatibility between SCSS themes and JavaScript themes.
1860
+ *
1861
+ * @see src/styles/03-generic/_generic.root.scss for SCSS token definitions
1862
+ */
1863
+ /**
1864
+ * Convert a nested object to flat CSS variable declarations
1865
+ * Uses iterative approach for better performance with large objects
1866
+ */
1867
+ function(obj, prefix = "", result = {}) {
1868
+ // Use iterative approach with stack to avoid deep recursion
1869
+ const stack = [ {
1870
+ obj: obj,
1871
+ prefix: prefix
1872
+ } ];
1873
+ for (;stack.length > 0; ) {
1874
+ const {obj: currentObj, prefix: currentPrefix} = stack.pop();
1875
+ for (const key in currentObj) {
1876
+ if (!Object.prototype.hasOwnProperty.call(currentObj, key)) continue;
1877
+ const value = currentObj[key], newKey = currentPrefix ? `${currentPrefix}-${key}` : key;
1878
+ if (value && "object" == typeof value && !Array.isArray(value)) {
1879
+ // Skip special objects like functions
1880
+ if ("function" == typeof value) continue;
1881
+ // Add to stack for iterative processing
1882
+ stack.push({
1883
+ obj: value,
1884
+ prefix: newKey
1885
+ });
1886
+ } else "string" != typeof value && "number" != typeof value || (result[newKey.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()] = String(value));
1887
+ }
1888
+ }
1889
+ return result;
1890
+ }(theme.custom, `${prefix}-custom`);
2167
1891
  Object.assign(variables, customVars);
2168
1892
  }
2169
1893
  // Convert to CSS string
@@ -2234,6 +1958,7 @@ function generateClassName(block, element, modifiers) {
2234
1958
  * Component Theming Utilities
2235
1959
  *
2236
1960
  * Provides consistent patterns for applying theme values to components
1961
+ * using DesignTokens and CSS variables
2237
1962
  */
2238
1963
  /**
2239
1964
  * Get a theme value for a specific component using CSS variables
@@ -2247,33 +1972,28 @@ function generateClassName(block, element, modifiers) {
2247
1972
  }
2248
1973
 
2249
1974
  /**
2250
- * Generate component-specific CSS variables from theme
2251
- */ function generateComponentCSSVars(component, theme, variant, size) {
2252
- const vars = {}, prefixParts = [ "atomix", component ];
2253
- // This is a simplified implementation - in a real system you'd have more
2254
- // sophisticated logic to extract component-specific values from the theme
2255
- variant && prefixParts.push(variant), size && prefixParts.push(size);
1975
+ * Generate component-specific CSS variables from DesignTokens
1976
+ */ function generateComponentCSSVars(component, tokens, variant, size) {
1977
+ const vars = {};
1978
+ if (!tokens) return vars;
1979
+ const prefixParts = [ "atomix", component ];
1980
+ variant && prefixParts.push(variant), size && prefixParts.push(size);
2256
1981
  const prefix = prefixParts.join("-");
2257
- // Add common component properties
2258
- if (theme.palette && (vars[`--${prefix}-color`] = theme.palette.primary?.main || "#7c3aed",
2259
- vars[`--${prefix}-color-hover`] = theme.palette.primary?.dark || "#5b21b6", vars[`--${prefix}-color-active`] = theme.palette.primary?.main || "#7c3aed",
2260
- vars[`--${prefix}-color-disabled`] = theme.palette.text?.disabled || "#9ca3af"),
2261
- theme.typography && (vars[`--${prefix}-font-family`] = theme.typography.fontFamily || "Inter, sans-serif",
2262
- vars[`--${prefix}-font-size`] = theme.typography.fontSize ? `${theme.typography.fontSize}px` : "16px"),
2263
- theme.spacing) {
2264
- const spacing = "function" == typeof theme.spacing ? theme.spacing : val => 8 * val;
2265
- vars[`--${prefix}-spacing-unit`] = `${spacing(1)}px`, vars[`--${prefix}-spacing-sm`] = `${spacing(.5)}px`,
2266
- vars[`--${prefix}-spacing-md`] = `${spacing(1)}px`, vars[`--${prefix}-spacing-lg`] = `${spacing(2)}px`;
2267
- }
2268
- return vars;
1982
+ // Map common DesignTokens to component-specific CSS variables
1983
+ return tokens.primary && (vars[`--${prefix}-color`] = tokens.primary), tokens["primary-9"] && (vars[`--${prefix}-color-hover`] = tokens["primary-9"]),
1984
+ tokens["body-color"] && (vars[`--${prefix}-color-disabled`] = tokens["body-color"]),
1985
+ tokens["body-font-family"] && (vars[`--${prefix}-font-family`] = tokens["body-font-family"]),
1986
+ tokens["body-font-size"] && (vars[`--${prefix}-font-size`] = tokens["body-font-size"]),
1987
+ tokens["spacing-1"] && (vars[`--${prefix}-spacing-sm`] = tokens["spacing-1"]), tokens["spacing-2"] && (vars[`--${prefix}-spacing-md`] = tokens["spacing-2"]),
1988
+ tokens["spacing-4"] && (vars[`--${prefix}-spacing-lg`] = tokens["spacing-4"]), vars;
2269
1989
  }
2270
1990
 
2271
1991
  /**
2272
- * Apply consistent theme to component style object
2273
- */ function applyComponentTheme(component, style = {}, variant, size, theme) {
2274
- // If no theme provided, return original style
2275
- return theme ? {
2276
- ...generateComponentCSSVars(component, theme, variant, size),
1992
+ * Apply consistent theme to component style object using DesignTokens
1993
+ */ function applyComponentTheme(component, style = {}, variant, size, tokens) {
1994
+ // If no tokens provided, return original style
1995
+ return tokens ? {
1996
+ ...generateComponentCSSVars(component, tokens, variant, size),
2277
1997
  ...style
2278
1998
  } : style;
2279
1999
  // Generate component-specific CSS variables
@@ -2281,7 +2001,7 @@ function generateClassName(block, element, modifiers) {
2281
2001
 
2282
2002
  /**
2283
2003
  * Create a hook for consistent component theming
2284
- */ function useComponentTheme(component, variant, size, theme) {
2004
+ */ function useComponentTheme(component, variant, size, tokens) {
2285
2005
  return property => getComponentThemeValue(component, property, variant, size);
2286
2006
  }
2287
2007
 
@@ -2299,23 +2019,29 @@ function generateClassName(block, element, modifiers) {
2299
2019
  */ function loadThemeFromConfigSync(options) {
2300
2020
  // Check if we're in a browser environment
2301
2021
  if ("undefined" != typeof window) throw new Error("loadThemeFromConfigSync: Not available in browser environment. Config loading requires Node.js/SSR environment.");
2302
- // Use dynamic import to load the config loader
2303
- // This allows bundlers to handle external dependencies properly
2304
- let loadAtomixConfig;
2022
+ // Use static import - the function handles browser environment checks internally
2023
+ let config;
2305
2024
  try {
2306
- // eslint-disable-next-line @typescript-eslint/no-var-requires
2307
- const {loadAtomixConfig: loader} = require("../../config/loader");
2308
- loadAtomixConfig = loader;
2025
+ config = loadAtomixConfig({
2026
+ configPath: options?.configPath || "atomix.config.ts",
2027
+ required: !1 !== options?.required
2028
+ });
2309
2029
  } catch (error) {
2310
2030
  if (!1 !== options?.required) throw new Error("Config loader module not available");
2311
2031
  // Return empty tokens if config is not required
2312
2032
  return createTokens({});
2313
2033
  }
2314
- const config = loadAtomixConfig({
2315
- configPath: options?.configPath || "atomix.config.ts",
2316
- required: !1 !== options?.required
2317
- });
2318
- return config?.theme ? isThemeObject$1(config.theme) ? createDesignTokensFromTheme(config.theme) : createTokens(config.theme) : createTokens({});
2034
+ if (!config?.theme) return createTokens({});
2035
+ // Extract tokens from config.theme structure
2036
+ // config.theme can have: { extend?: ThemeTokens, tokens?: ThemeTokens, themes?: ... }
2037
+ // We need to extract the actual DesignTokens (flat structure)
2038
+ const themeConfig = config.theme;
2039
+ // Check if theme is directly a flat object (DesignTokens format)
2040
+ // This handles the case where config.theme might be passed as DesignTokens directly
2041
+ return createTokens(!themeConfig || "object" != typeof themeConfig || "extend" in themeConfig || "tokens" in themeConfig || "themes" in themeConfig ? {} : themeConfig);
2042
+ // If theme has nested structure (extend/tokens/themes), we can't directly use it
2043
+ // Return empty tokens - the theme system will use defaults
2044
+ // TODO: Add proper conversion from ThemeTokens to DesignTokens if needed
2319
2045
  }
2320
2046
 
2321
2047
  /**
@@ -2325,20 +2051,31 @@ function generateClassName(block, element, modifiers) {
2325
2051
  */ async function loadThemeFromConfig(options) {
2326
2052
  // Check if we're in a browser environment
2327
2053
  if ("undefined" != typeof window) throw new Error("loadThemeFromConfig: Not available in browser environment. Config loading requires Node.js/SSR environment.");
2328
- // Dynamic import for config loader
2329
- const {loadAtomixConfig: loadAtomixConfig} = await import("../lib/config/loader"), config = await loadAtomixConfig({
2330
- configPath: options?.configPath || "atomix.config.ts",
2331
- required: !1 !== options?.required
2332
- });
2333
- return config?.theme ? isThemeObject$1(config.theme) ? createDesignTokensFromTheme(config.theme) : createTokens(config.theme) : createTokens({});
2334
- }
2335
-
2336
- /**
2337
- * Check if the provided object is a Theme object
2338
- * @param theme - Object to check
2339
- * @returns True if the object is a Theme object, false otherwise
2340
- */ function isThemeObject$1(theme) {
2341
- return "object" == typeof theme && null !== theme;
2054
+ // Use static import with runtime check
2055
+ // The function will handle browser environment checks internally
2056
+ let config;
2057
+ try {
2058
+ // loadAtomixConfig is synchronous, not async
2059
+ config = loadAtomixConfig({
2060
+ configPath: options?.configPath || "atomix.config.ts",
2061
+ required: !1 !== options?.required
2062
+ });
2063
+ } catch (error) {
2064
+ if (!1 !== options?.required) throw new Error("Config loader module not available");
2065
+ // Return empty tokens if config is not required
2066
+ return createTokens({});
2067
+ }
2068
+ if (!config?.theme) return createTokens({});
2069
+ // Extract tokens from config.theme structure
2070
+ // config.theme can have: { extend?: ThemeTokens, tokens?: ThemeTokens, themes?: ... }
2071
+ // We need to extract the actual DesignTokens (flat structure)
2072
+ const themeConfig = config.theme;
2073
+ // Check if theme is directly a flat object (DesignTokens format)
2074
+ // This handles the case where config.theme might be passed as DesignTokens directly
2075
+ return createTokens(!themeConfig || "object" != typeof themeConfig || "extend" in themeConfig || "tokens" in themeConfig || "themes" in themeConfig ? {} : themeConfig);
2076
+ // If theme has nested structure (extend/tokens/themes), we can't directly use it
2077
+ // Return empty tokens - the theme system will use defaults
2078
+ // TODO: Add proper conversion from ThemeTokens to DesignTokens if needed
2342
2079
  }
2343
2080
 
2344
2081
  /**
@@ -2358,7 +2095,7 @@ ThemeContext.displayName = "ThemeContext";
2358
2095
  * React context provider for theme management with separated concerns.
2359
2096
  * Simplified version focusing on core functionality:
2360
2097
  * - String-based themes (CSS files)
2361
- * - JS Theme objects
2098
+ * - DesignTokens (dynamic themes)
2362
2099
  * - Persistence via localStorage
2363
2100
  *
2364
2101
  * Falls back to 'default' theme if no configuration is found.
@@ -2375,39 +2112,7 @@ const ThemeProvider = ({children: children, defaultTheme: defaultTheme, themes:
2375
2112
  onThemeChangeRef.current?.(theme);
2376
2113
  }), []), handleError = useCallback(((error, themeName) => {
2377
2114
  onErrorRef.current?.(error, themeName);
2378
- }), []), storageAdapter = useMemo((() => ({
2379
- getItem: key => {
2380
- if (isServer()) return null;
2381
- try {
2382
- return localStorage.getItem(key);
2383
- } catch {
2384
- return null;
2385
- }
2386
- },
2387
- setItem: (key, value) => {
2388
- if (!isServer()) try {
2389
- localStorage.setItem(key, value);
2390
- } catch {
2391
- // Silently fail if localStorage is not available
2392
- }
2393
- },
2394
- removeItem: key => {
2395
- if (!isServer()) try {
2396
- localStorage.removeItem(key);
2397
- } catch {
2398
- // Silently fail
2399
- }
2400
- },
2401
- isAvailable: () => {
2402
- if (isServer()) return !1;
2403
- try {
2404
- const test = "__atomix_storage_test__";
2405
- return localStorage.setItem(test, test), localStorage.removeItem(test), !0;
2406
- } catch {
2407
- return !1;
2408
- }
2409
- }
2410
- })), []), initialDefaultTheme = useMemo((() => {
2115
+ }), []), storageAdapter = useMemo((() => createLocalStorageAdapter()), []), initialDefaultTheme = useMemo((() => {
2411
2116
  // Check storage first
2412
2117
  if (enablePersistence && storageAdapter.isAvailable()) {
2413
2118
  const stored = storageAdapter.getItem(storageKey);
@@ -2424,72 +2129,126 @@ const ThemeProvider = ({children: children, defaultTheme: defaultTheme, themes:
2424
2129
  // For simplicity, we'll treat config tokens as a special theme name
2425
2130
  return "config-theme";
2426
2131
  } catch (error) {
2427
- console.warn("Failed to load theme from config, using default");
2132
+ // Failed to load theme from config, using default
2428
2133
  }
2429
2134
  // Default fallback
2430
2135
  return "default";
2431
- }), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = useState((() => initialDefaultTheme)), [activeTheme, setActiveTheme] = useState(null), [isLoading, setIsLoading] = useState(!1), [error, setError] = useState(null), loadedThemesRef = useRef(new Set), themePromisesRef = useRef({});
2136
+ }), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() => {
2137
+ // If defaultTheme is DesignTokens, store them
2138
+ if (defaultTheme && "string" != typeof defaultTheme) {
2139
+ const {createTokens: createTokens} = require("../tokens/tokens");
2140
+ return createTokens(defaultTheme);
2141
+ }
2142
+ return null;
2143
+ })), [isLoading, setIsLoading] = useState(!1), [error, setError] = useState(null), loadedThemesRef = useRef(new Set), themePromisesRef = useRef({}), abortControllerRef = useRef(null);
2144
+ // Handle initial DesignTokens defaultTheme
2145
+ useEffect((() => {
2146
+ defaultTheme && "string" != typeof defaultTheme && activeTokens && !isServer() && injectCSS$1(createTheme(defaultTheme), "theme-tokens-theme");
2147
+ }), [ defaultTheme, activeTokens ]), // Run when defaultTheme or activeTokens change
2432
2148
  // Apply initial theme attributes to document element
2433
2149
  useEffect((() => {
2434
- isServer() || ((dataAttribute, themeName) => {
2435
- isServer() || (
2436
- // Set data attribute on body
2437
- document.body.setAttribute(dataAttribute, themeName),
2438
- // Also set on documentElement for broader compatibility
2439
- document.documentElement.setAttribute(dataAttribute, themeName));
2440
- })(String(currentTheme), dataAttribute);
2150
+ isServer() || applyThemeAttributes(String(currentTheme), dataAttribute);
2441
2151
  }), [ currentTheme, dataAttribute ]),
2442
2152
  // Handle theme persistence
2443
2153
  useEffect((() => {
2444
2154
  enablePersistence && storageAdapter.isAvailable() && storageAdapter.setItem(storageKey, String(currentTheme));
2445
- }), [ currentTheme, storageKey, enablePersistence ]);
2155
+ }), [ currentTheme, storageKey, enablePersistence, storageAdapter ]),
2156
+ // Cleanup: Remove completed promises and abort controllers on unmount
2157
+ useEffect((() => () => {
2158
+ // Cancel any in-flight theme loads
2159
+ abortControllerRef.current && (abortControllerRef.current.abort(), abortControllerRef.current = null),
2160
+ Object.entries(themePromisesRef.current).forEach((([key, promise]) => {})),
2161
+ // Clear all on unmount
2162
+ themePromisesRef.current = {};
2163
+ }), []);
2446
2164
  // Function to set theme with proper type handling
2447
2165
  const setTheme = useCallback((async (theme, options) => {
2448
- setIsLoading(!0), setError(null);
2166
+ // Cancel previous theme load if in progress
2167
+ abortControllerRef.current && abortControllerRef.current.abort();
2168
+ // Create new AbortController for this theme load
2169
+ const abortController = new AbortController;
2170
+ abortControllerRef.current = abortController, setIsLoading(!0), setError(null);
2449
2171
  try {
2450
- let themeName, themeObj = null;
2172
+ let themeName;
2173
+ if ("string" != typeof theme) {
2174
+ // Check if aborted before processing
2175
+ if (abortController.signal.aborted) return;
2176
+ // For DesignTokens, create CSS and inject it
2177
+ const {createTheme: createTheme} = await Promise.resolve().then((() => index)), css = createTheme(theme), themeId = "tokens-theme";
2178
+ // Check if aborted after async operation
2179
+ if (abortController.signal.aborted) return;
2180
+ // Remove any previously loaded theme CSS
2181
+ removeCSS(`theme-${currentTheme}`),
2182
+ // Inject new theme CSS
2183
+ injectCSS$1(css, `theme-${themeId}`);
2184
+ // Store tokens for reference
2185
+ const {createTokens: createTokens} = await Promise.resolve().then((() => tokens)), fullTokens = createTokens(theme);
2186
+ // Check if aborted before state update
2187
+ if (abortController.signal.aborted) return;
2188
+ return setActiveTokens(fullTokens), setCurrentTheme(themeId), handleThemeChange(fullTokens),
2189
+ void setIsLoading(!1);
2190
+ }
2451
2191
  // If it's a string theme name, load the associated CSS
2452
- if ("string" == typeof theme ? themeName = theme :
2453
- // If it's a Theme object or DesignTokens, we need to process it
2454
- function(theme) {
2455
- return "object" == typeof theme && null !== theme && "__isJSTheme" in theme && !0 === theme.__isJSTheme;
2456
- }(theme) ? (themeObj = theme,
2457
- // For JS themes, we use a generic name
2458
- themeName = "js-theme", setActiveTheme(themeObj)) :
2459
- // For DesignTokens, we might create a theme from tokens
2460
- themeName = "tokens-theme", "string" == typeof theme && themes[theme]) {
2192
+ if (themeName = theme, "string" == typeof theme && themes[theme]) {
2461
2193
  // Check if theme is already loading
2462
- if (themePromisesRef.current[theme]) return await themePromisesRef.current[theme],
2463
- setCurrentTheme(theme), setActiveTheme(null), void handleThemeChange(theme);
2194
+ if (themePromisesRef.current[theme]) try {
2195
+ // Check if aborted
2196
+ if (await themePromisesRef.current[theme], abortController.signal.aborted) return;
2197
+ return setCurrentTheme(theme), setActiveTokens(null), handleThemeChange(theme),
2198
+ void setIsLoading(!1);
2199
+ } catch {
2200
+ // If previous load failed, continue with new load
2201
+ }
2464
2202
  // Load CSS theme
2465
2203
  const themeLoadPromise = new Promise((async (resolve, reject) => {
2466
2204
  try {
2205
+ // Check if aborted
2206
+ if (abortController.signal.aborted) return void resolve();
2467
2207
  if (!themes[theme]) throw new Error(`Theme metadata not found for theme: ${theme}`);
2468
2208
  {
2469
2209
  // Build CSS path using utility function
2470
2210
  const cssPath = buildThemePath(theme, basePath, useMinified, cdnPath);
2211
+ // Check if aborted
2212
+ if (abortController.signal.aborted) return void resolve();
2213
+ // Load CSS file (using loadThemeCSS from domUtils)
2214
+ const {loadThemeCSS: loadThemeCSS} = await Promise.resolve().then((() => domUtils));
2215
+ // Check if aborted after async operation
2216
+ if (await loadThemeCSS(cssPath, `theme-${theme}`), abortController.signal.aborted) return void resolve();
2471
2217
  // Remove any previously loaded theme CSS
2472
- removeCSS(`theme-${String(currentTheme)}`),
2473
- // Inject new theme CSS
2474
- await injectCSS$1(cssPath, `theme-${theme}`), loadedThemesRef.current.add(theme),
2475
- setCurrentTheme(theme), setActiveTheme(null), handleThemeChange(theme), resolve();
2218
+ removeCSS(`theme-${String(currentTheme)}`), loadedThemesRef.current.add(theme),
2219
+ setCurrentTheme(theme), setActiveTokens(null), handleThemeChange(theme), resolve();
2476
2220
  }
2477
2221
  } catch (err) {
2222
+ // Don't reject if aborted
2223
+ if (abortController.signal.aborted) return void resolve();
2478
2224
  const error = err instanceof Error ? err : new Error(String(err));
2479
2225
  setError(error), handleError(error, String(theme)), reject(error);
2480
2226
  }
2481
2227
  }));
2482
- themePromisesRef.current[theme] = themeLoadPromise, await themeLoadPromise;
2483
- } else themeObj ? (
2484
- // For JS themes, set them directly
2485
- setCurrentTheme(themeName), setActiveTheme(themeObj), handleThemeChange(themeObj)) : (
2486
- // For string theme that isn't in our themes record, just set the name
2487
- setCurrentTheme(themeName), setActiveTheme(null), handleThemeChange(themeName));
2228
+ themePromisesRef.current[theme] = themeLoadPromise;
2229
+ try {
2230
+ await themeLoadPromise;
2231
+ } catch {
2232
+ // Error already handled in promise
2233
+ }
2234
+ // Clean up completed promise after a delay to prevent memory leak
2235
+ setTimeout((() => {
2236
+ themePromisesRef.current[theme] === themeLoadPromise && delete themePromisesRef.current[theme];
2237
+ }), 1e3);
2238
+ } else {
2239
+ // Check if aborted
2240
+ if (abortController.signal.aborted) return;
2241
+ // For string theme that isn't in our themes record, just set the name
2242
+ setCurrentTheme(themeName), setActiveTokens(null), handleThemeChange(themeName);
2243
+ }
2488
2244
  } catch (err) {
2245
+ // Don't set error if aborted
2246
+ if (abortController.signal.aborted) return;
2489
2247
  const error = err instanceof Error ? err : new Error(String(err));
2490
2248
  setError(error), handleError(error, String(theme));
2491
2249
  } finally {
2492
- setIsLoading(!1);
2250
+ // Only update loading state if not aborted
2251
+ abortController.signal.aborted || setIsLoading(!1);
2493
2252
  }
2494
2253
  }), [ themes, currentTheme, handleThemeChange, handleError, basePath, useMinified, cdnPath ]), isThemeLoaded = useCallback((themeName => loadedThemesRef.current.has(themeName)), []), preloadTheme = useCallback((async themeName => {
2495
2254
  if (themes[themeName] && !isThemeLoaded(themeName)) {
@@ -2506,19 +2265,22 @@ const ThemeProvider = ({children: children, defaultTheme: defaultTheme, themes:
2506
2265
  setIsLoading(!1);
2507
2266
  }
2508
2267
  }
2509
- }), [ themes, isThemeLoaded, handleError, basePath, useMinified, cdnPath ]), themeManager = useMemo((() => ({})), []), contextValue = useMemo((() => ({
2510
- theme: "string" == typeof currentTheme ? currentTheme : "js-theme",
2511
- activeTheme: activeTheme,
2268
+ }), [ themes, isThemeLoaded, handleError, basePath, useMinified, cdnPath ]), themeManager = useMemo((() => ({})), []), availableThemes = useMemo((() => Object.entries(themes).map((([name, metadata]) => ({
2269
+ ...metadata,
2270
+ name: name
2271
+ })))), [ themes ]), contextValue = useMemo((() => ({
2272
+ theme: currentTheme,
2273
+ activeTokens: activeTokens,
2512
2274
  setTheme: setTheme,
2513
- availableThemes: Object.entries(themes).map((([name, metadata]) => ({
2514
- ...metadata
2515
- }))),
2275
+ availableThemes: availableThemes,
2516
2276
  isLoading: isLoading,
2517
2277
  error: error,
2518
2278
  isThemeLoaded: isThemeLoaded,
2519
2279
  preloadTheme: preloadTheme,
2520
2280
  themeManager: themeManager
2521
- })), [ currentTheme, activeTheme, setTheme, themes, isLoading, error, isThemeLoaded, preloadTheme, themeManager ]);
2281
+ })), [ currentTheme, activeTokens, setTheme, availableThemes,
2282
+ // Use memoized value
2283
+ isLoading, error, isThemeLoaded, preloadTheme, themeManager ]);
2522
2284
  // Check if theme is loaded
2523
2285
  return jsx(ThemeContext.Provider, {
2524
2286
  value: contextValue,
@@ -2556,227 +2318,97 @@ const ThemeProvider = ({children: children, defaultTheme: defaultTheme, themes:
2556
2318
  if (!context) throw new Error("useTheme must be used within a ThemeProvider");
2557
2319
  return {
2558
2320
  theme: context.theme,
2559
- activeTheme: context.activeTheme,
2321
+ activeTokens: context.activeTokens,
2560
2322
  setTheme: context.setTheme,
2561
2323
  availableThemes: context.availableThemes,
2562
2324
  isLoading: context.isLoading,
2563
- error: context.error,
2564
- isThemeLoaded: context.isThemeLoaded,
2565
- preloadTheme: context.preloadTheme
2566
- };
2567
- }
2568
-
2569
- function useThemeTokens() {
2570
- const {theme: theme, activeTheme: activeTheme} = useTheme(), getToken = useCallback(((tokenName, fallback) => {
2571
- if ("undefined" == typeof window) return fallback || "";
2572
- const cssVarName = `--atomix-${tokenName}`;
2573
- return getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim() || fallback || "";
2574
- }), []), getThemeValue = useCallback(((path, fallback) => {
2575
- var _context;
2576
- return activeTheme && _reduceInstanceProperty(_context = path.split(".")).call(_context, ((obj, key) => obj?.[key]), activeTheme) || fallback;
2577
- // Navigate through nested theme object using dot notation
2578
- }), [ activeTheme ]);
2579
- // Helper function to get CSS variable value
2580
- // Return unified API for accessing theme values
2581
- return {
2582
- theme: theme,
2583
- activeTheme: activeTheme,
2584
- getToken: getToken,
2585
- getThemeValue: getThemeValue,
2586
- // Commonly used tokens with fallbacks
2587
- colors: {
2588
- primary: getToken("primary", "#3b82f6"),
2589
- secondary: getToken("secondary", "#10b981"),
2590
- error: getToken("error", "#ef4444"),
2591
- success: getToken("success", "#22c55e"),
2592
- warning: getToken("warning", "#eab308"),
2593
- info: getToken("info", "#3b82f6"),
2594
- light: getToken("light", "#f9fafb"),
2595
- dark: getToken("dark", "#111827")
2596
- },
2597
- spacing: {
2598
- 1: getToken("spacing-1", "0.25rem"),
2599
- 2: getToken("spacing-2", "0.5rem"),
2600
- 3: getToken("spacing-3", "0.75rem"),
2601
- 4: getToken("spacing-4", "1rem"),
2602
- 5: getToken("spacing-5", "1.25rem"),
2603
- 6: getToken("spacing-6", "1.5rem"),
2604
- 8: getToken("spacing-8", "2rem"),
2605
- 10: getToken("spacing-10", "2.5rem"),
2606
- 12: getToken("spacing-12", "3rem"),
2607
- 16: getToken("spacing-16", "4rem"),
2608
- 20: getToken("spacing-20", "5rem")
2609
- },
2610
- borderRadius: {
2611
- sm: getToken("border-radius-sm", "0.25rem"),
2612
- md: getToken("border-radius-md", "0.5rem"),
2613
- lg: getToken("border-radius-lg", "0.75rem"),
2614
- xl: getToken("border-radius-xl", "1rem"),
2615
- full: getToken("border-radius-full", "9999px")
2616
- },
2617
- typography: {
2618
- fontFamily: {
2619
- sans: getToken("font-sans-serif", "Inter, system-ui, sans-serif"),
2620
- serif: getToken("font-serif", "Georgia, serif"),
2621
- mono: getToken("font-monospace", "Fira Code, monospace")
2622
- },
2623
- fontSize: {
2624
- xs: getToken("font-size-xs", "0.75rem"),
2625
- sm: getToken("font-size-sm", "0.875rem"),
2626
- md: getToken("font-size-md", "1rem"),
2627
- lg: getToken("font-size-lg", "1.125rem"),
2628
- xl: getToken("font-size-xl", "1.25rem"),
2629
- "2xl": getToken("font-size-2xl", "1.5rem"),
2630
- "3xl": getToken("font-size-3xl", "1.875rem"),
2631
- "4xl": getToken("font-size-4xl", "2.25rem")
2632
- },
2633
- fontWeight: {
2634
- light: getToken("font-weight-light", "300"),
2635
- normal: getToken("font-weight-normal", "400"),
2636
- medium: getToken("font-weight-medium", "500"),
2637
- semibold: getToken("font-weight-semibold", "600"),
2638
- bold: getToken("font-weight-bold", "700")
2639
- }
2640
- },
2641
- shadows: {
2642
- sm: getToken("box-shadow-sm", "0 1px 2px 0 rgba(0, 0, 0, 0.05)"),
2643
- md: getToken("box-shadow-md", "0 4px 6px -1px rgba(0, 0, 0, 0.1)"),
2644
- lg: getToken("box-shadow-lg", "0 10px 15px -3px rgba(0, 0, 0, 0.1)"),
2645
- xl: getToken("box-shadow-xl", "0 20px 25px -5px rgba(0, 0, 0, 0.1)"),
2646
- inset: getToken("box-shadow-inset", "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)")
2647
- },
2648
- transitions: {
2649
- fast: getToken("transition-fast", "150ms"),
2650
- base: getToken("transition-base", "200ms"),
2651
- slow: getToken("transition-slow", "300ms")
2652
- }
2653
- };
2654
- }
2655
-
2656
- /**
2657
- * Theme System Error Handling
2658
- *
2659
- * Centralized error handling for the Atomix theme system.
2660
- * Provides custom error classes and logging utilities.
2661
- */
2662
- /**
2663
- * Theme error codes
2664
- */ var ThemeErrorCode, LogLevel;
2665
-
2666
- !function(ThemeErrorCode) {
2667
- /** Theme not found in registry */
2668
- ThemeErrorCode.THEME_NOT_FOUND = "THEME_NOT_FOUND",
2669
- /** Theme failed to load */
2670
- ThemeErrorCode.THEME_LOAD_FAILED = "THEME_LOAD_FAILED",
2671
- /** Theme validation failed */
2672
- ThemeErrorCode.THEME_VALIDATION_FAILED = "THEME_VALIDATION_FAILED",
2673
- /** Configuration loading failed */
2674
- ThemeErrorCode.CONFIG_LOAD_FAILED = "CONFIG_LOAD_FAILED",
2675
- /** Configuration validation failed */
2676
- ThemeErrorCode.CONFIG_VALIDATION_FAILED = "CONFIG_VALIDATION_FAILED",
2677
- /** Circular dependency detected */
2678
- ThemeErrorCode.CIRCULAR_DEPENDENCY = "CIRCULAR_DEPENDENCY",
2679
- /** Missing dependency */
2680
- ThemeErrorCode.MISSING_DEPENDENCY = "MISSING_DEPENDENCY",
2681
- /** Storage operation failed */
2682
- ThemeErrorCode.STORAGE_ERROR = "STORAGE_ERROR",
2683
- /** Invalid theme name */
2684
- ThemeErrorCode.INVALID_THEME_NAME = "INVALID_THEME_NAME",
2685
- /** CSS injection failed */
2686
- ThemeErrorCode.CSS_INJECTION_FAILED = "CSS_INJECTION_FAILED",
2687
- /** Unknown error */
2688
- ThemeErrorCode.UNKNOWN_ERROR = "UNKNOWN_ERROR";
2689
- }(ThemeErrorCode || (ThemeErrorCode = {}));
2690
-
2691
- /**
2692
- * Custom error class for theme-related errors
2693
- */
2694
- class ThemeError extends Error {
2695
- constructor(message, code = ThemeErrorCode.UNKNOWN_ERROR, context) {
2696
- super(message), this.name = "ThemeError", this.code = code, this.context = context,
2697
- this.timestamp = Date.now(),
2698
- // Maintains proper stack trace for where our error was thrown (only available on V8)
2699
- Error.captureStackTrace && Error.captureStackTrace(this, ThemeError);
2700
- }
2701
- /**
2702
- * Convert error to JSON for logging
2703
- */ toJSON() {
2704
- return {
2705
- name: this.name,
2706
- message: this.message,
2707
- code: this.code,
2708
- context: this.context,
2709
- timestamp: this.timestamp,
2710
- stack: this.stack
2711
- };
2712
- }
2713
- }
2714
-
2715
- /**
2716
- * Log level
2717
- */ !function(LogLevel) {
2718
- LogLevel[LogLevel.ERROR = 0] = "ERROR", LogLevel[LogLevel.WARN = 1] = "WARN", LogLevel[LogLevel.INFO = 2] = "INFO",
2719
- LogLevel[LogLevel.DEBUG = 3] = "DEBUG";
2720
- }(LogLevel || (LogLevel = {}));
2721
-
2722
- /**
2723
- * Theme Logger
2724
- *
2725
- * Centralized logging for the theme system.
2726
- * Replaces console statements with structured logging.
2727
- */
2728
- class ThemeLogger {
2729
- constructor(config = {}) {
2730
- this.config = {
2731
- level: config.level ?? ("undefined" != typeof process && "production" === process.env?.NODE_ENV ? LogLevel.WARN : LogLevel.INFO),
2732
- enableConsole: config.enableConsole ?? !0,
2733
- onError: config.onError,
2734
- onWarn: config.onWarn,
2735
- onInfo: config.onInfo,
2736
- onDebug: config.onDebug
2737
- };
2738
- }
2739
- /**
2740
- * Log an error
2741
- */ error(message, error, context) {
2742
- if (this.config.level < LogLevel.ERROR) return;
2743
- const errorObj = error instanceof Error ? error : new Error(message), themeError = error instanceof ThemeError ? error : new ThemeError(message, ThemeErrorCode.UNKNOWN_ERROR, context);
2744
- this.config.enableConsole && console.error(`[ThemeError] ${message}`, {
2745
- error: errorObj,
2746
- context: {
2747
- ...context,
2748
- ...themeError.context
2749
- },
2750
- code: themeError.code
2751
- }), this.config.onError?.(themeError, context);
2752
- }
2753
- /**
2754
- * Log a warning
2755
- */ warn(message, context) {
2756
- this.config.level < LogLevel.WARN || (this.config.enableConsole && console.warn(`[ThemeWarning] ${message}`, context || {}),
2757
- this.config.onWarn?.(message, context));
2758
- }
2759
- /**
2760
- * Log an info message
2761
- */ info(message, context) {
2762
- this.config.level < LogLevel.INFO || (this.config.enableConsole && console.info(`[ThemeInfo] ${message}`, context || {}),
2763
- this.config.onInfo?.(message, context));
2764
- }
2765
- /**
2766
- * Log a debug message
2767
- */ debug(message, context) {
2768
- this.config.level < LogLevel.DEBUG || (this.config.enableConsole, this.config.onDebug?.(message, context));
2769
- }
2325
+ error: context.error,
2326
+ isThemeLoaded: context.isThemeLoaded,
2327
+ preloadTheme: context.preloadTheme
2328
+ };
2770
2329
  }
2771
2330
 
2772
- /**
2773
- * Default logger instance
2774
- */ let defaultLogger = null;
2775
-
2776
- /**
2777
- * Get or create default logger
2778
- */ function getLogger() {
2779
- return defaultLogger || (defaultLogger = new ThemeLogger), defaultLogger;
2331
+ function useThemeTokens() {
2332
+ const {theme: theme, activeTokens: activeTokens} = useTheme(), getToken = useCallback(((tokenName, fallback) => {
2333
+ if ("undefined" == typeof window) return fallback || "";
2334
+ const cssVarName = `--atomix-${tokenName}`;
2335
+ return getComputedStyle(document.documentElement).getPropertyValue(cssVarName).trim() || fallback || "";
2336
+ }), []);
2337
+ // Helper function to get CSS variable value
2338
+ // Return unified API for accessing theme values
2339
+ // Note: For SSR or direct token access, use activeTokens directly
2340
+ return {
2341
+ theme: theme,
2342
+ activeTokens: activeTokens,
2343
+ getToken: getToken,
2344
+ // Commonly used tokens with fallbacks
2345
+ colors: {
2346
+ primary: getToken("primary", "#3b82f6"),
2347
+ secondary: getToken("secondary", "#10b981"),
2348
+ error: getToken("error", "#ef4444"),
2349
+ success: getToken("success", "#22c55e"),
2350
+ warning: getToken("warning", "#eab308"),
2351
+ info: getToken("info", "#3b82f6"),
2352
+ light: getToken("light", "#f9fafb"),
2353
+ dark: getToken("dark", "#111827")
2354
+ },
2355
+ spacing: {
2356
+ 1: getToken("spacing-1", "0.25rem"),
2357
+ 2: getToken("spacing-2", "0.5rem"),
2358
+ 3: getToken("spacing-3", "0.75rem"),
2359
+ 4: getToken("spacing-4", "1rem"),
2360
+ 5: getToken("spacing-5", "1.25rem"),
2361
+ 6: getToken("spacing-6", "1.5rem"),
2362
+ 8: getToken("spacing-8", "2rem"),
2363
+ 10: getToken("spacing-10", "2.5rem"),
2364
+ 12: getToken("spacing-12", "3rem"),
2365
+ 16: getToken("spacing-16", "4rem"),
2366
+ 20: getToken("spacing-20", "5rem")
2367
+ },
2368
+ borderRadius: {
2369
+ sm: getToken("border-radius-sm", "0.25rem"),
2370
+ md: getToken("border-radius-md", "0.5rem"),
2371
+ lg: getToken("border-radius-lg", "0.75rem"),
2372
+ xl: getToken("border-radius-xl", "1rem"),
2373
+ full: getToken("border-radius-full", "9999px")
2374
+ },
2375
+ typography: {
2376
+ fontFamily: {
2377
+ sans: getToken("font-sans-serif", "Inter, system-ui, sans-serif"),
2378
+ serif: getToken("font-serif", "Georgia, serif"),
2379
+ mono: getToken("font-monospace", "Fira Code, monospace")
2380
+ },
2381
+ fontSize: {
2382
+ xs: getToken("font-size-xs", "0.75rem"),
2383
+ sm: getToken("font-size-sm", "0.875rem"),
2384
+ md: getToken("font-size-md", "1rem"),
2385
+ lg: getToken("font-size-lg", "1.125rem"),
2386
+ xl: getToken("font-size-xl", "1.25rem"),
2387
+ "2xl": getToken("font-size-2xl", "1.5rem"),
2388
+ "3xl": getToken("font-size-3xl", "1.875rem"),
2389
+ "4xl": getToken("font-size-4xl", "2.25rem")
2390
+ },
2391
+ fontWeight: {
2392
+ light: getToken("font-weight-light", "300"),
2393
+ normal: getToken("font-weight-normal", "400"),
2394
+ medium: getToken("font-weight-medium", "500"),
2395
+ semibold: getToken("font-weight-semibold", "600"),
2396
+ bold: getToken("font-weight-bold", "700")
2397
+ }
2398
+ },
2399
+ shadows: {
2400
+ sm: getToken("box-shadow-sm", "0 1px 2px 0 rgba(0, 0, 0, 0.05)"),
2401
+ md: getToken("box-shadow-md", "0 4px 6px -1px rgba(0, 0, 0, 0.1)"),
2402
+ lg: getToken("box-shadow-lg", "0 10px 15px -3px rgba(0, 0, 0, 0.1)"),
2403
+ xl: getToken("box-shadow-xl", "0 20px 25px -5px rgba(0, 0, 0, 0.1)"),
2404
+ inset: getToken("box-shadow-inset", "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)")
2405
+ },
2406
+ transitions: {
2407
+ fast: getToken("transition-fast", "150ms"),
2408
+ base: getToken("transition-base", "200ms"),
2409
+ slow: getToken("transition-slow", "300ms")
2410
+ }
2411
+ };
2780
2412
  }
2781
2413
 
2782
2414
  /**
@@ -2940,29 +2572,13 @@ class ThemeLogger {
2940
2572
  this.styleId = "atomix-theme-applicator", this.root = root;
2941
2573
  }
2942
2574
  /**
2943
- * Apply a complete theme configuration
2575
+ * Apply a complete theme configuration using DesignTokens
2944
2576
  *
2945
- * Uses the unified theme system to convert Theme to DesignTokens and inject CSS.
2577
+ * Uses the unified theme system to generate and inject CSS.
2946
2578
  * Automatically respects atomix.config.ts when using DesignTokens.
2947
- */ applyTheme(theme) {
2579
+ */ applyTheme(tokens) {
2948
2580
  // Clear previously applied variables
2949
2581
  this.clearAppliedVars(),
2950
- // Check if it's DesignTokens
2951
- this.isDesignTokens(theme) ?
2952
- // Direct DesignTokens - use unified theme system (with config support)
2953
- this.applyDesignTokens(theme) : injectCSS$1(createTheme(theme, {
2954
- selector: ":root",
2955
- prefix: "atomix"
2956
- }), this.styleId),
2957
- // Apply component overrides (only for Theme objects)
2958
- !this.isDesignTokens(theme) && theme.components && this.applyComponentOverrides(theme.components);
2959
- }
2960
- /**
2961
- * Apply DesignTokens using unified theme system
2962
- *
2963
- * Uses createTheme() which automatically loads from atomix.config.ts
2964
- * if no tokens are provided, ensuring config is always respected.
2965
- */ applyDesignTokens(tokens) {
2966
2582
  // Inject CSS into DOM
2967
2583
  injectCSS$1(createTheme(tokens, {
2968
2584
  selector: ":root",
@@ -2970,51 +2586,13 @@ class ThemeLogger {
2970
2586
  }), this.styleId);
2971
2587
  }
2972
2588
  /**
2973
- * Check if object is DesignTokens
2974
- */ isDesignTokens(obj) {
2975
- // DesignTokens is a flat object with string keys, no nested structures
2976
- return null !== obj && "object" == typeof obj && !("palette" in obj) && !("typography" in obj) && !("__isJSTheme" in obj);
2977
- }
2978
- /**
2979
- * Apply global CSS variables (for component overrides)
2589
+ * Apply global CSS variables
2980
2590
  */ applyGlobalCSSVars(vars) {
2981
2591
  Object.entries(vars).forEach((([key, value]) => {
2982
2592
  this.root.style.setProperty(key, String(value));
2983
2593
  }));
2984
2594
  }
2985
2595
  /**
2986
- * Apply component-level overrides
2987
- */ applyComponentOverrides(overrides) {
2988
- Object.entries(overrides).forEach((([componentName, override]) => {
2989
- override && this.applyComponentOverride(componentName, override);
2990
- }));
2991
- }
2992
- /**
2993
- * Apply override for a specific component
2994
- */ applyComponentOverride(componentName, override) {
2995
- const vars = {}, componentKey = componentName.toLowerCase();
2996
- // Apply component-level CSS variables
2997
- override.cssVars && Object.entries(override.cssVars).forEach((([key, value]) => {
2998
- // If key doesn't start with --, add component prefix
2999
- const varKey = key.startsWith("--") ? key : `--atomix-${componentKey}-${key}`;
3000
- vars[varKey] = value;
3001
- })),
3002
- // Apply part-specific CSS variables
3003
- override.parts && Object.entries(override.parts).forEach((([partName, partOverride]) => {
3004
- partOverride.cssVars && Object.entries(partOverride.cssVars).forEach((([key, value]) => {
3005
- const varKey = key.startsWith("--") ? key : `--atomix-${componentKey}-${partName}-${key}`;
3006
- vars[varKey] = value;
3007
- }));
3008
- })),
3009
- // Apply variant-specific CSS variables
3010
- override.variants && Object.entries(override.variants).forEach((([variantName, variantOverride]) => {
3011
- variantOverride.cssVars && Object.entries(variantOverride.cssVars).forEach((([key, value]) => {
3012
- const varKey = key.startsWith("--") ? key : `--atomix-${componentKey}-${variantName}-${key}`;
3013
- vars[varKey] = value;
3014
- }));
3015
- })), this.applyGlobalCSSVars(vars);
3016
- }
3017
- /**
3018
2596
  * Clear all applied CSS variables
3019
2597
  */ clearAppliedVars() {
3020
2598
  removeCSS(this.styleId);
@@ -3043,8 +2621,8 @@ class ThemeLogger {
3043
2621
 
3044
2622
  /**
3045
2623
  * Apply theme using global applicator
3046
- */ function applyTheme(theme) {
3047
- getThemeApplicator().applyTheme(theme);
2624
+ */ function applyTheme(tokens) {
2625
+ getThemeApplicator().applyTheme(tokens);
3048
2626
  }
3049
2627
 
3050
2628
  const VIEWPORT_PRESETS = {
@@ -4532,10 +4110,374 @@ class ThemeValidator {
4532
4110
  };
4533
4111
 
4534
4112
  /**
4535
- * Theme Comparator Component
4113
+ * Theme Comparator Component
4114
+ *
4115
+ * Compares two themes and highlights differences
4116
+ */ var aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike = lengthOfArrayLike$2, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
4117
+ return function(that, callbackfn, argumentsLength, memo) {
4118
+ var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
4119
+ if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
4120
+ var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
4121
+ if (argumentsLength < 2) for (;;) {
4122
+ if (index in self) {
4123
+ memo = self[index], index += i;
4124
+ break;
4125
+ }
4126
+ if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
4127
+ }
4128
+ for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
4129
+ return memo;
4130
+ };
4131
+ }, arrayReduce = {
4132
+ // `Array.prototype.reduce` method
4133
+ // https://tc39.es/ecma262/#sec-array.prototype.reduce
4134
+ left: createMethod(!1),
4135
+ // `Array.prototype.reduceRight` method
4136
+ // https://tc39.es/ecma262/#sec-array.prototype.reduceright
4137
+ right: createMethod(!0)
4138
+ }, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
4139
+ return userAgent.slice(0, string.length) === string;
4140
+ }, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$1.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$1.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$1.process) ? "NODE" : globalThis$1.window && globalThis$1.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
4141
+
4142
+ // `Array.prototype.reduce` method
4143
+ // https://tc39.es/ecma262/#sec-array.prototype.reduce
4144
+ _export({
4145
+ target: "Array",
4146
+ proto: !0,
4147
+ forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
4148
+ var method = [][METHOD_NAME];
4149
+ return !!method && fails((function() {
4150
+ // eslint-disable-next-line no-useless-call -- required for testing
4151
+ method.call(null, argument || function() {
4152
+ return 1;
4153
+ }, 1);
4154
+ }));
4155
+ }("reduce")
4156
+ }, {
4157
+ reduce: function(callbackfn /* , initialValue */) {
4158
+ var length = arguments.length;
4159
+ return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
4160
+ }
4161
+ });
4162
+
4163
+ var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
4164
+
4165
+ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
4166
+ var own = it.reduce;
4167
+ return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
4168
+ })), DEFAULT_PALETTE = {
4169
+ primary: {
4170
+ main: "#7c3aed",
4171
+ // Primary-6
4172
+ light: "#d0b2f5",
4173
+ // Primary-3
4174
+ dark: "#3c1583",
4175
+ // Primary-9
4176
+ contrastText: "#ffffff"
4177
+ },
4178
+ secondary: {
4179
+ main: "#f3f4f6",
4180
+ // Gray-2
4181
+ light: "#ffffff",
4182
+ // Gray-1
4183
+ dark: "#e5e7eb",
4184
+ // Gray-3
4185
+ contrastText: "#1f2937"
4186
+ },
4187
+ error: {
4188
+ main: "#ef4444",
4189
+ // Red-6
4190
+ light: "#fca5a5",
4191
+ // Red-4
4192
+ dark: "#991b1b",
4193
+ // Red-9
4194
+ contrastText: "#ffffff"
4195
+ },
4196
+ warning: {
4197
+ main: "#eab308",
4198
+ // Yellow-6
4199
+ light: "#fde047",
4200
+ // Yellow-4
4201
+ dark: "#854d0e",
4202
+ // Yellow-9
4203
+ contrastText: "#000000"
4204
+ },
4205
+ info: {
4206
+ main: "#3b82f6",
4207
+ // Blue-6
4208
+ light: "#93c5fd",
4209
+ // Blue-4
4210
+ dark: "#1e40af",
4211
+ // Blue-9
4212
+ contrastText: "#ffffff"
4213
+ },
4214
+ success: {
4215
+ main: "#22c55e",
4216
+ // Green-6
4217
+ light: "#86efac",
4218
+ // Green-4
4219
+ dark: "#166534",
4220
+ // Green-9
4221
+ contrastText: "#ffffff"
4222
+ },
4223
+ background: {
4224
+ default: "#ffffff",
4225
+ // Primary-bg
4226
+ paper: "#f3f4f6",
4227
+ // Secondary-bg
4228
+ subtle: "#d1d5db"
4229
+ },
4230
+ text: {
4231
+ primary: "#111827",
4232
+ // Gray-10
4233
+ secondary: "#374151",
4234
+ // Gray-8
4235
+ disabled: "#9ca3af"
4236
+ }
4237
+ }, DEFAULT_TYPOGRAPHY = {
4238
+ fontFamily: '"Roboto", "Helvetica Neue", "Helvetica", "Arial", sans-serif',
4239
+ fontSize: 16,
4240
+ // 1rem
4241
+ fontWeightLight: 300,
4242
+ fontWeightRegular: 400,
4243
+ fontWeightMedium: 500,
4244
+ fontWeightSemiBold: 600,
4245
+ fontWeightBold: 700,
4246
+ fontWeightHeavy: 800,
4247
+ fontWeightBlack: 900,
4248
+ h1: {
4249
+ fontSize: "2.5rem",
4250
+ // 40px
4251
+ fontWeight: 700,
4252
+ lineHeight: 1.3,
4253
+ letterSpacing: "-1px"
4254
+ },
4255
+ h2: {
4256
+ fontSize: "2rem",
4257
+ // 32px
4258
+ fontWeight: 700,
4259
+ lineHeight: 1.3,
4260
+ letterSpacing: "-1px"
4261
+ },
4262
+ h3: {
4263
+ fontSize: "1.5rem",
4264
+ // 24px
4265
+ fontWeight: 700,
4266
+ lineHeight: 1.3,
4267
+ letterSpacing: "-1px"
4268
+ },
4269
+ h4: {
4270
+ fontSize: "1.25rem",
4271
+ // 20px
4272
+ fontWeight: 700,
4273
+ lineHeight: 1.3,
4274
+ letterSpacing: "-0.5px"
4275
+ },
4276
+ h5: {
4277
+ fontSize: "1.125rem",
4278
+ // 18px
4279
+ fontWeight: 700,
4280
+ lineHeight: 1.3,
4281
+ letterSpacing: "-0.5px"
4282
+ },
4283
+ h6: {
4284
+ fontSize: "1rem",
4285
+ // 16px
4286
+ fontWeight: 700,
4287
+ lineHeight: 1.3,
4288
+ letterSpacing: "-0.5px"
4289
+ },
4290
+ body1: {
4291
+ fontSize: "1rem",
4292
+ // 16px
4293
+ fontWeight: 400,
4294
+ lineHeight: 1.2
4295
+ },
4296
+ body2: {
4297
+ fontSize: "0.875rem",
4298
+ // 14px
4299
+ fontWeight: 400,
4300
+ lineHeight: 1.2
4301
+ }
4302
+ }, DEFAULT_SHADOWS = {
4303
+ xs: "0px 1px 2px 0px rgba(45, 54, 67, 0.04), 0px 2px 4px 0px rgba(45, 54, 67, 0.08)",
4304
+ sm: "0 2px 4px rgba(0, 0, 0, 0.075)",
4305
+ md: "0 4px 8px rgba(0, 0, 0, 0.1)",
4306
+ lg: "0 16px 48px rgba(0, 0, 0, 0.175)",
4307
+ xl: "0px 16px 64px -8px rgba(45, 54, 67, 0.14)",
4308
+ inset: "inset 0 1px 2px rgba(0, 0, 0, 0.075)"
4309
+ }, DEFAULT_TRANSITIONS = {
4310
+ duration: {
4311
+ shortest: 150,
4312
+ shorter: 200,
4313
+ short: 250,
4314
+ standard: 300,
4315
+ complex: 375,
4316
+ enteringScreen: 225,
4317
+ leavingScreen: 195
4318
+ },
4319
+ easing: {
4320
+ easeInOut: "cubic-bezier(0.4, 0, 0.2, 1)",
4321
+ easeOut: "cubic-bezier(0.0, 0, 0.2, 1)",
4322
+ easeIn: "cubic-bezier(0.4, 0, 1, 1)",
4323
+ sharp: "cubic-bezier(0.4, 0, 0.6, 1)"
4324
+ }
4325
+ }, DEFAULT_ZINDEX = {
4326
+ mobileStepper: 1e3,
4327
+ speedDial: 1050,
4328
+ appBar: 1020,
4329
+ drawer: 1070,
4330
+ modal: 1040,
4331
+ snackbar: 1080,
4332
+ tooltip: 1060
4333
+ }, DEFAULT_BORDER_RADIUS = {
4334
+ base: "0.5rem",
4335
+ // 8px (spacing-2)
4336
+ sm: "0.25rem",
4337
+ // 4px (spacing-1)
4338
+ md: "0.25rem",
4339
+ // 4px (spacing-1)
4340
+ lg: "0.625rem",
4341
+ // 10px (spacing-2.5)
4342
+ xl: "0.75rem",
4343
+ // 12px (spacing-3)
4344
+ xxl: "1rem",
4345
+ // 16px (spacing-4)
4346
+ "3xl": "1.5rem",
4347
+ // 24px (spacing-6)
4348
+ "4xl": "2rem",
4349
+ // 32px (spacing-8)
4350
+ pill: "50rem"
4351
+ };
4352
+
4353
+ // ============================================================================
4354
+ // Default Theme Values
4355
+ // ============================================================================
4356
+ // ============================================================================
4357
+ // Helper Functions
4358
+ // ============================================================================
4359
+ /**
4360
+ * Create a complete palette color from partial configuration
4361
+ */
4362
+ function createPaletteColor(color) {
4363
+ return "string" == typeof color ? {
4364
+ main: color,
4365
+ light: lighten(color),
4366
+ dark: darken(color),
4367
+ contrastText: getContrastText(color)
4368
+ } : {
4369
+ main: color.main || "#000000",
4370
+ light: color.light || lighten(color.main || "#000000"),
4371
+ dark: color.dark || darken(color.main || "#000000"),
4372
+ contrastText: color.contrastText || getContrastText(color.main || "#000000")
4373
+ };
4374
+ }
4375
+
4376
+ /**
4377
+ * Create breakpoints object
4378
+ */
4379
+ // ============================================================================
4380
+ // Main createTheme Function
4381
+ // ============================================================================
4382
+ /**
4383
+ * Create a theme object with computed values
4536
4384
  *
4537
- * Compares two themes and highlights differences
4385
+ * @param options - Theme configuration options
4386
+ * @returns Complete theme object
4538
4387
  */
4388
+ function createThemeObject(...options) {
4389
+ // Merge all options
4390
+ const mergedOptions = _reduceInstanceProperty(options).call(options, ((acc, option) => deepMerge(acc, option)), {}), palette = {
4391
+ primary: createPaletteColor(mergedOptions.palette?.primary || DEFAULT_PALETTE.primary),
4392
+ secondary: createPaletteColor(mergedOptions.palette?.secondary || DEFAULT_PALETTE.secondary),
4393
+ error: createPaletteColor(mergedOptions.palette?.error || DEFAULT_PALETTE.error),
4394
+ warning: createPaletteColor(mergedOptions.palette?.warning || DEFAULT_PALETTE.warning),
4395
+ info: createPaletteColor(mergedOptions.palette?.info || DEFAULT_PALETTE.info),
4396
+ success: createPaletteColor(mergedOptions.palette?.success || DEFAULT_PALETTE.success),
4397
+ // Handle light and dark colors if provided
4398
+ ...mergedOptions.palette?.light && {
4399
+ light: createPaletteColor(mergedOptions.palette.light)
4400
+ },
4401
+ ...mergedOptions.palette?.dark && {
4402
+ dark: createPaletteColor(mergedOptions.palette.dark)
4403
+ },
4404
+ background: {
4405
+ default: mergedOptions.palette?.background?.default || DEFAULT_PALETTE.background.default,
4406
+ subtle: mergedOptions.palette?.background?.subtle || DEFAULT_PALETTE.background.subtle
4407
+ },
4408
+ text: {
4409
+ primary: mergedOptions.palette?.text?.primary || DEFAULT_PALETTE.text.primary,
4410
+ secondary: mergedOptions.palette?.text?.secondary || DEFAULT_PALETTE.text.secondary,
4411
+ disabled: mergedOptions.palette?.text?.disabled || DEFAULT_PALETTE.text.disabled
4412
+ }
4413
+ }, typography = deepMerge({
4414
+ ...DEFAULT_TYPOGRAPHY
4415
+ }, mergedOptions.typography || {}), spacing = function(spacingInput = 4) {
4416
+ // If it's already a function, return it
4417
+ return "function" == typeof spacingInput ? spacingInput :
4418
+ // If it's a number, create a function that multiplies by that number
4419
+ "number" == typeof spacingInput ? (...values) => 0 === values.length ? "0px" : values.map((value => value * spacingInput + "px")).join(" ") :
4420
+ // If it's an array, use it as a scale
4421
+ Array.isArray(spacingInput) ? (...values) => 0 === values.length ? "0px" : values.map((value => `${spacingInput[value] || value}px`)).join(" ") : (...values) => 0 === values.length ? "0px" : values.map((value => 4 * value + "px")).join(" ");
4422
+ }(mergedOptions.spacing), breakpoints = function(breakpointsInput) {
4423
+ const values = {
4424
+ xs: 0,
4425
+ sm: 576,
4426
+ md: 768,
4427
+ lg: 992,
4428
+ xl: 1200,
4429
+ xxl: 1440,
4430
+ ...breakpointsInput?.values
4431
+ }, unit = breakpointsInput?.unit || "px";
4432
+ return {
4433
+ values: values,
4434
+ unit: unit,
4435
+ up: key => `@media (min-width:${"number" == typeof key ? key : values[key] ?? 0}${unit})`,
4436
+ down: key => `@media (max-width:${("number" == typeof key ? key : values[key] ?? 0) - .05}${unit})`,
4437
+ between: (start, end) => {
4438
+ const startValue = "number" == typeof start ? start : values[start] ?? 0, endValue = "number" == typeof end ? end : values[end] ?? 0;
4439
+ return `@media (min-width:${startValue}${unit}) and (max-width:${endValue - .05}${unit})`;
4440
+ }
4441
+ };
4442
+ }(mergedOptions.breakpoints), shadows = deepMerge({
4443
+ ...DEFAULT_SHADOWS
4444
+ }, mergedOptions.shadows || {}), transitions = deepMerge({
4445
+ ...DEFAULT_TRANSITIONS
4446
+ }, mergedOptions.transitions || {}), zIndex = deepMerge({
4447
+ ...DEFAULT_ZINDEX
4448
+ }, mergedOptions.zIndex || {}), borderRadius = deepMerge({
4449
+ ...DEFAULT_BORDER_RADIUS
4450
+ }, mergedOptions.borderRadius || {});
4451
+ // Create palette
4452
+ return {
4453
+ // Metadata
4454
+ name: mergedOptions.name || "Custom Theme",
4455
+ class: mergedOptions.class,
4456
+ description: mergedOptions.description,
4457
+ author: mergedOptions.author,
4458
+ version: mergedOptions.version || "1.0.0",
4459
+ tags: mergedOptions.tags,
4460
+ supportsDarkMode: mergedOptions.supportsDarkMode,
4461
+ status: mergedOptions.status || "experimental",
4462
+ a11y: mergedOptions.a11y,
4463
+ color: mergedOptions.color || palette.primary.main,
4464
+ features: mergedOptions.features,
4465
+ dependencies: mergedOptions.dependencies,
4466
+ // Theme configuration
4467
+ palette: palette,
4468
+ typography: typography,
4469
+ spacing: spacing,
4470
+ breakpoints: breakpoints,
4471
+ shadows: shadows,
4472
+ transitions: transitions,
4473
+ zIndex: zIndex,
4474
+ borderRadius: borderRadius,
4475
+ custom: mergedOptions.custom || {},
4476
+ // Mark as JS theme
4477
+ __isJSTheme: !0
4478
+ };
4479
+ }
4480
+
4539
4481
  /**
4540
4482
  * useHistory Hook
4541
4483
  *
@@ -4553,8 +4495,7 @@ class ThemeValidator {
4553
4495
  * maxHistorySize: 50
4554
4496
  * });
4555
4497
  * ```
4556
- */
4557
- function useHistory(options = {}) {
4498
+ */ function useHistory(options = {}) {
4558
4499
  const {maxHistorySize: maxHistorySize = 50, initialState: initialState} = options, [state, setStateInternal] = useState(initialState), historyRef = useRef([ initialState ]), currentIndexRef = useRef(0), [canUndo, setCanUndo] = useState(!1), [canRedo, setCanRedo] = useState(!1), updateHistoryState = useCallback((() => {
4559
4500
  setCanUndo(currentIndexRef.current > 0), setCanRedo(currentIndexRef.current < historyRef.current.length - 1);
4560
4501
  }), []), setState = useCallback((newState => {
@@ -4995,6 +4936,23 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
4995
4936
  });
4996
4937
  };
4997
4938
 
4939
+ /**
4940
+ * Theme Adapter
4941
+ *
4942
+ * Converts between Theme objects and DesignTokens.
4943
+ */
4944
+ /**
4945
+ * Convert DesignTokens to Theme-compatible CSS variables
4946
+ *
4947
+ * @param tokens - DesignTokens object
4948
+ * @returns CSS variables object compatible with Theme.cssVars
4949
+ */ function designTokensToCSSVars(tokens) {
4950
+ const cssVars = {};
4951
+ return Object.entries(tokens).forEach((([key, value]) => {
4952
+ void 0 !== value && (cssVars[`--atomix-${key}`] = String(value));
4953
+ })), cssVars;
4954
+ }
4955
+
4998
4956
  /**
4999
4957
  * Map SCSS tokens to CSS custom properties
5000
4958
  *
@@ -5015,11 +4973,14 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
5015
4973
  /**
5016
4974
  * Apply CSS variables to an element
5017
4975
  *
5018
- * @param element - Target element (defaults to document.documentElement)
5019
4976
  * @param vars - CSS variables to apply
5020
- */ function applyCSSVariables(vars, element = document.documentElement) {
4977
+ * @param element - Target element (defaults to document.documentElement)
4978
+ */ function applyCSSVariables(vars, element) {
4979
+ if ("undefined" == typeof window) return;
4980
+ // SSR safety
4981
+ const target = element || document.documentElement;
5021
4982
  Object.entries(vars).forEach((([key, value]) => {
5022
- element.style.setProperty(key, String(value));
4983
+ target.style.setProperty(key, String(value));
5023
4984
  }));
5024
4985
  }
5025
4986
 
@@ -5028,9 +4989,12 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
5028
4989
  *
5029
4990
  * @param varNames - Variable names to remove
5030
4991
  * @param element - Target element (defaults to document.documentElement)
5031
- */ function removeCSSVariables(varNames, element = document.documentElement) {
4992
+ */ function removeCSSVariables(varNames, element) {
4993
+ if ("undefined" == typeof window) return;
4994
+ // SSR safety
4995
+ const target = element || document.documentElement;
5032
4996
  varNames.forEach((varName => {
5033
- element.style.removeProperty(varName);
4997
+ target.style.removeProperty(varName);
5034
4998
  }));
5035
4999
  }
5036
5000
 
@@ -5040,8 +5004,11 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
5040
5004
  * @param varName - Variable name to get
5041
5005
  * @param element - Target element (defaults to document.documentElement)
5042
5006
  * @returns Variable value or null if not found
5043
- */ function getCSSVariable(varName, element = document.documentElement) {
5044
- return getComputedStyle(element).getPropertyValue(varName).trim() || null;
5007
+ */ function getCSSVariable(varName, element) {
5008
+ if ("undefined" == typeof window) return null;
5009
+ // SSR safety
5010
+ const target = element || document.documentElement;
5011
+ return getComputedStyle(target).getPropertyValue(varName).trim() || null;
5045
5012
  }
5046
5013
 
5047
5014
  /**
@@ -5085,28 +5052,8 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
5085
5052
  /**
5086
5053
  * Theme Helper Functions
5087
5054
  *
5088
- * Utility functions for working with themes and DesignTokens
5055
+ * Utility functions for working with DesignTokens
5089
5056
  */
5090
- /**
5091
- * Get DesignTokens from current theme
5092
- *
5093
- * Converts a Theme object to DesignTokens. Useful when you need to
5094
- * work with DesignTokens but have a Theme object.
5095
- *
5096
- * @param theme - Theme object to convert
5097
- * @returns DesignTokens object
5098
- *
5099
- * @example
5100
- * ```typescript
5101
- * // If you have a Theme object, convert it to DesignTokens
5102
- * const tokens = getDesignTokensFromTheme(theme);
5103
- * // Now you can use tokens with unified theme system
5104
- * const css = createTheme(tokens);
5105
- * ```
5106
- */ function getDesignTokensFromTheme(theme) {
5107
- return theme ? createDesignTokensFromTheme(theme) : null;
5108
- }
5109
-
5110
5057
  /**
5111
5058
  * Check if a value is DesignTokens
5112
5059
  *
@@ -5126,17 +5073,6 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
5126
5073
  // Check if keys look like DesignTokens (kebab-case, no nesting)
5127
5074
  }
5128
5075
 
5129
- /**
5130
- * Check if a value is a Theme object
5131
- *
5132
- * Type guard to check if an object is a Theme.
5133
- *
5134
- * @param value - Value to check
5135
- * @returns True if value is Theme
5136
- */ function isThemeObject(value) {
5137
- return !(!value || "object" != typeof value) && ("__isJSTheme" in value || "palette" in value && "typography" in value);
5138
- }
5139
-
5140
5076
  /**
5141
5077
  * RTL (Right-to-Left) Support Utilities
5142
5078
  *
@@ -5325,13 +5261,13 @@ class RTLManager {
5325
5261
  /**
5326
5262
  * Theme System Exports
5327
5263
  *
5328
- * Unified theme system - handles both DesignTokens and Theme objects.
5264
+ * Simplified theme system using DesignTokens only.
5329
5265
  *
5330
5266
  * @example
5331
5267
  * ```typescript
5332
5268
  * import { createTheme, injectTheme } from '@shohojdhara/atomix/theme';
5333
5269
  *
5334
- * // Using DesignTokens (recommended - flat structure)
5270
+ * // Using DesignTokens
5335
5271
  * const css = createTheme({ 'primary': '#7AFFD7', 'spacing-4': '1rem' });
5336
5272
  * injectTheme(css);
5337
5273
  *
@@ -5344,7 +5280,7 @@ class RTLManager {
5344
5280
  // ============================================================================
5345
5281
  // Core Theme Functions
5346
5282
  // ============================================================================
5347
- // Unified createTheme (handles both DesignTokens and Theme objects)
5283
+ // Create theme CSS from DesignTokens
5348
5284
  /**
5349
5285
  * Inject theme CSS into DOM
5350
5286
  */ function injectTheme(css, id = "atomix-theme") {
@@ -5370,16 +5306,8 @@ class RTLManager {
5370
5306
  }),
5371
5307
  // Write file
5372
5308
  await fs.writeFile(filePath, css, "utf8");
5373
- }
5374
- /**
5375
- * Theme System Constants
5376
- *
5377
- * Centralized constants for the theme system to avoid magic numbers and strings.
5378
- */
5379
- /**
5380
- * Default storage key for theme persistence
5381
- */ (css, filePath);
5309
+ }(css, filePath);
5382
5310
  }
5383
5311
 
5384
- export { RTLManager, ThemeApplicator, ThemeComparator, ThemeContext, ThemeErrorBoundary, ThemeInspector, ThemeLiveEditor, ThemePreview, ThemeProvider, ThemeValidator, applyCSSVariables, applyComponentTheme, applyTheme, camelToKebab, clearThemes, createDesignTokensFromTheme, createTheme, createThemeObject, createThemeRegistry, createTokens, cssVarsToStyle, deepMerge, defaultTokens, designTokensToCSSVars, designTokensToTheme, extendTheme, extractComponentName, generateCSSVariableName, generateCSSVariables$1 as generateCSSVariables, generateCSSVariablesForSelector, generateClassName, generateComponentCSSVars, getAllThemes, getCSSVariable, getComponentThemeValue, getDesignTokensFromTheme, getTheme, getThemeApplicator, getThemeCount, getThemeIds, hasTheme, injectCSS$1 as injectCSS, injectTheme, isCSSInjected, isDesignTokens, isThemeObject, isValidCSSVariableName, loadThemeFromConfig, loadThemeFromConfigSync, mapSCSSTokensToCSSVars, mergeCSSVars, mergeTheme, normalizeThemeTokens, registerTheme, removeCSS, removeCSSVariables, removeTheme, saveTheme, themePropertyToCSSVar, themeToDesignTokens, unregisterTheme, useComponentTheme, useHistory, useTheme, useThemeTokens };
5312
+ export { RTLManager, ThemeApplicator, ThemeComparator, ThemeContext, ThemeErrorBoundary, ThemeInspector, ThemeLiveEditor, ThemePreview, ThemeProvider, ThemeValidator, applyCSSVariables, applyComponentTheme, applyTheme, camelToKebab, clearThemes, createTheme, createThemeRegistry, createTokens, cssVarsToStyle, deepMerge, defaultTokens, designTokensToCSSVars, extendTheme, extractComponentName, generateCSSVariableName, generateCSSVariables$1 as generateCSSVariables, generateCSSVariablesForSelector, generateClassName, generateComponentCSSVars, getAllThemes, getCSSVariable, getComponentThemeValue, getTheme, getThemeApplicator, getThemeCount, getThemeIds, hasTheme, injectCSS$1 as injectCSS, injectTheme, isCSSInjected, isDesignTokens, isValidCSSVariableName, loadThemeFromConfig, loadThemeFromConfigSync, mapSCSSTokensToCSSVars, mergeCSSVars, mergeTheme, normalizeThemeTokens, registerTheme, removeCSS, removeCSSVariables, removeTheme, saveTheme, themePropertyToCSSVar, unregisterTheme, useComponentTheme, useHistory, useTheme, useThemeTokens };
5385
5313
  //# sourceMappingURL=theme.js.map