shru-design-system 0.1.2 → 0.1.4

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.
package/dist/index.mjs CHANGED
@@ -688,6 +688,39 @@ function resolveReferences(tokens, palette) {
688
688
  traverse(resolved);
689
689
  return resolved;
690
690
  }
691
+ function hexToHSL(hex) {
692
+ hex = hex.replace("#", "");
693
+ const r = parseInt(hex.substring(0, 2), 16) / 255;
694
+ const g = parseInt(hex.substring(2, 4), 16) / 255;
695
+ const b = parseInt(hex.substring(4, 6), 16) / 255;
696
+ const max = Math.max(r, g, b);
697
+ const min = Math.min(r, g, b);
698
+ let h = 0;
699
+ let s = 0;
700
+ const l = (max + min) / 2;
701
+ if (max !== min) {
702
+ const d = max - min;
703
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
704
+ switch (max) {
705
+ case r:
706
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
707
+ break;
708
+ case g:
709
+ h = ((b - r) / d + 2) / 6;
710
+ break;
711
+ case b:
712
+ h = ((r - g) / d + 4) / 6;
713
+ break;
714
+ }
715
+ }
716
+ h = Math.round(h * 360);
717
+ s = Math.round(s * 100);
718
+ const lPercent = Math.round(l * 100);
719
+ return `${h} ${s}% ${lPercent}%`;
720
+ }
721
+ function isHexColor(value) {
722
+ return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value);
723
+ }
691
724
  function flattenToCSS(tokens, prefix = "", result = {}, isColorContext = false) {
692
725
  for (const key in tokens) {
693
726
  const value = tokens[key];
@@ -711,7 +744,11 @@ function flattenToCSS(tokens, prefix = "", result = {}, isColorContext = false)
711
744
  } else {
712
745
  cssKey = `--${prefix}-${key}`;
713
746
  }
714
- result[cssKey] = value;
747
+ let finalValue = value;
748
+ if (isColorContext && typeof value === "string" && isHexColor(value)) {
749
+ finalValue = hexToHSL(value);
750
+ }
751
+ result[cssKey] = finalValue;
715
752
  }
716
753
  }
717
754
  return result;
@@ -732,6 +769,30 @@ function mapToTailwindVars(cssVars) {
732
769
  } else if (cssVars["--spacing-component-md"]) {
733
770
  mapped["--spacing"] = cssVars["--spacing-component-md"];
734
771
  }
772
+ if (cssVars["--spacing-component-xs"]) {
773
+ mapped["--spacing-component-xs"] = cssVars["--spacing-component-xs"];
774
+ }
775
+ if (cssVars["--spacing-component-sm"]) {
776
+ mapped["--spacing-component-sm"] = cssVars["--spacing-component-sm"];
777
+ }
778
+ if (cssVars["--spacing-component-md"]) {
779
+ mapped["--spacing-component-md"] = cssVars["--spacing-component-md"];
780
+ }
781
+ if (cssVars["--spacing-component-lg"]) {
782
+ mapped["--spacing-component-lg"] = cssVars["--spacing-component-lg"];
783
+ }
784
+ if (cssVars["--spacing-component-xl"]) {
785
+ mapped["--spacing-component-xl"] = cssVars["--spacing-component-xl"];
786
+ }
787
+ if (cssVars["--duration-fast"]) {
788
+ mapped["--duration-fast"] = cssVars["--duration-fast"];
789
+ }
790
+ if (cssVars["--duration-normal"]) {
791
+ mapped["--duration-normal"] = cssVars["--duration-normal"];
792
+ }
793
+ if (cssVars["--duration-slow"]) {
794
+ mapped["--duration-slow"] = cssVars["--duration-slow"];
795
+ }
735
796
  return mapped;
736
797
  }
737
798
  function generateCSSString(cssVars) {
@@ -1202,6 +1263,232 @@ function ThemeRingAsync({
1202
1263
  ] });
1203
1264
  }
1204
1265
 
1205
- export { Badge, Button, Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ThemeToggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, getTheme, getThemeCategories, getThemeFilePath, getThemesForCategory, registerTheme, useTheme, useThemeToggle };
1266
+ // src/themes/applyThemeSync.ts
1267
+ var STORAGE_KEY2 = "design-system-theme";
1268
+ function applyThemeSync() {
1269
+ if (typeof window === "undefined" || typeof document === "undefined") {
1270
+ return;
1271
+ }
1272
+ let selectedThemes = getDefaultThemes();
1273
+ try {
1274
+ const stored = localStorage.getItem(STORAGE_KEY2);
1275
+ if (stored) {
1276
+ selectedThemes = JSON.parse(stored);
1277
+ }
1278
+ } catch {
1279
+ }
1280
+ try {
1281
+ const base = loadJSONSync("/tokens/base.json");
1282
+ const palettes = loadJSONSync("/tokens/palettes.json");
1283
+ const palette = palettes?.palette || {};
1284
+ let merged = deepMergeSync(base || {}, { palette });
1285
+ const categoryOrder = ["color", "typography", "shape", "density", "animation"];
1286
+ for (const category of categoryOrder) {
1287
+ const themeId = selectedThemes[category];
1288
+ if (!themeId) continue;
1289
+ try {
1290
+ const themeData = loadJSONSync(`/tokens/themes/${category}/${themeId}.json`);
1291
+ if (themeData) {
1292
+ merged = deepMergeSync(merged, themeData);
1293
+ }
1294
+ } catch {
1295
+ }
1296
+ }
1297
+ if (selectedThemes.custom) {
1298
+ try {
1299
+ const customData = loadJSONSync(`/tokens/themes/custom/${selectedThemes.custom}.json`);
1300
+ if (customData) {
1301
+ merged = deepMergeSync(merged, customData);
1302
+ }
1303
+ } catch {
1304
+ }
1305
+ }
1306
+ const resolved = resolveReferencesSync(merged, palette);
1307
+ const cssVars = flattenToCSSSync(resolved);
1308
+ const mappedVars = mapToTailwindVarsSync(cssVars);
1309
+ const css = `:root {
1310
+ ${Object.entries(mappedVars).map(([key, value]) => ` ${key}: ${value};`).join("\n")}
1311
+ }`;
1312
+ let styleTag = document.getElementById("dynamic-theme");
1313
+ if (!styleTag) {
1314
+ styleTag = document.createElement("style");
1315
+ styleTag.id = "dynamic-theme";
1316
+ document.head.insertBefore(styleTag, document.head.firstChild);
1317
+ }
1318
+ styleTag.textContent = css;
1319
+ } catch (error) {
1320
+ console.warn("Sync theme application failed, will apply via React:", error);
1321
+ }
1322
+ }
1323
+ function loadJSONSync(path) {
1324
+ try {
1325
+ const xhr = new XMLHttpRequest();
1326
+ xhr.open("GET", path, false);
1327
+ xhr.send(null);
1328
+ if (xhr.status === 200 || xhr.status === 0) {
1329
+ return JSON.parse(xhr.responseText);
1330
+ }
1331
+ } catch {
1332
+ }
1333
+ return null;
1334
+ }
1335
+ function deepMergeSync(target, source) {
1336
+ const output = { ...target };
1337
+ if (isObjectSync(target) && isObjectSync(source)) {
1338
+ Object.keys(source).forEach((key) => {
1339
+ if (isObjectSync(source[key])) {
1340
+ if (!(key in target)) {
1341
+ Object.assign(output, { [key]: source[key] });
1342
+ } else {
1343
+ output[key] = deepMergeSync(target[key], source[key]);
1344
+ }
1345
+ } else {
1346
+ Object.assign(output, { [key]: source[key] });
1347
+ }
1348
+ });
1349
+ }
1350
+ return output;
1351
+ }
1352
+ function isObjectSync(item) {
1353
+ return item && typeof item === "object" && !Array.isArray(item);
1354
+ }
1355
+ function resolveReferencesSync(tokens, palette) {
1356
+ const resolved = JSON.parse(JSON.stringify(tokens));
1357
+ function resolveValue(value) {
1358
+ if (typeof value !== "string") return value;
1359
+ const match = value.match(/^\{([^}]+)\}$/);
1360
+ if (!match) return value;
1361
+ const path = match[1].split(".");
1362
+ let current = { palette, ...resolved };
1363
+ for (const key of path) {
1364
+ if (current && typeof current === "object" && key in current) {
1365
+ current = current[key];
1366
+ } else {
1367
+ return value;
1368
+ }
1369
+ }
1370
+ return typeof current === "string" ? current : value;
1371
+ }
1372
+ function traverse(obj) {
1373
+ for (const key in obj) {
1374
+ if (typeof obj[key] === "object" && obj[key] !== null) {
1375
+ traverse(obj[key]);
1376
+ } else {
1377
+ obj[key] = resolveValue(obj[key]);
1378
+ }
1379
+ }
1380
+ }
1381
+ traverse(resolved);
1382
+ return resolved;
1383
+ }
1384
+ function hexToHSL2(hex) {
1385
+ hex = hex.replace("#", "");
1386
+ const r = parseInt(hex.substring(0, 2), 16) / 255;
1387
+ const g = parseInt(hex.substring(2, 4), 16) / 255;
1388
+ const b = parseInt(hex.substring(4, 6), 16) / 255;
1389
+ const max = Math.max(r, g, b);
1390
+ const min = Math.min(r, g, b);
1391
+ let h = 0;
1392
+ let s = 0;
1393
+ const l = (max + min) / 2;
1394
+ if (max !== min) {
1395
+ const d = max - min;
1396
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1397
+ switch (max) {
1398
+ case r:
1399
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
1400
+ break;
1401
+ case g:
1402
+ h = ((b - r) / d + 2) / 6;
1403
+ break;
1404
+ case b:
1405
+ h = ((r - g) / d + 4) / 6;
1406
+ break;
1407
+ }
1408
+ }
1409
+ h = Math.round(h * 360);
1410
+ s = Math.round(s * 100);
1411
+ const lPercent = Math.round(l * 100);
1412
+ return `${h} ${s}% ${lPercent}%`;
1413
+ }
1414
+ function isHexColor2(value) {
1415
+ return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value);
1416
+ }
1417
+ function flattenToCSSSync(tokens, prefix = "", result = {}, isColorContext = false) {
1418
+ for (const key in tokens) {
1419
+ const value = tokens[key];
1420
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
1421
+ const enteringColor = key === "color" && prefix === "";
1422
+ const inColorContext = isColorContext || enteringColor;
1423
+ if (enteringColor) {
1424
+ flattenToCSSSync(value, "", result, true);
1425
+ } else if (inColorContext) {
1426
+ flattenToCSSSync(value, "", result, true);
1427
+ } else {
1428
+ const newPrefix = prefix ? `${prefix}-${key}` : key;
1429
+ flattenToCSSSync(value, newPrefix, result, false);
1430
+ }
1431
+ } else {
1432
+ let cssKey;
1433
+ if (isColorContext || prefix === "" && key === "color") {
1434
+ cssKey = `--${key}`;
1435
+ } else if (prefix === "") {
1436
+ cssKey = `--${key}`;
1437
+ } else {
1438
+ cssKey = `--${prefix}-${key}`;
1439
+ }
1440
+ let finalValue = value;
1441
+ if (isColorContext && typeof value === "string" && isHexColor2(value)) {
1442
+ finalValue = hexToHSL2(value);
1443
+ }
1444
+ result[cssKey] = finalValue;
1445
+ }
1446
+ }
1447
+ return result;
1448
+ }
1449
+ function mapToTailwindVarsSync(cssVars) {
1450
+ const mapped = { ...cssVars };
1451
+ if (cssVars["--radius-button"]) {
1452
+ mapped["--radius"] = cssVars["--radius-button"];
1453
+ }
1454
+ if (cssVars["--radius-card"]) {
1455
+ mapped["--radius-lg"] = cssVars["--radius-card"];
1456
+ }
1457
+ if (cssVars["--font-body"]) {
1458
+ mapped["--font-sans"] = cssVars["--font-body"];
1459
+ }
1460
+ if (cssVars["--spacing-base"]) {
1461
+ mapped["--spacing"] = cssVars["--spacing-base"];
1462
+ } else if (cssVars["--spacing-component-md"]) {
1463
+ mapped["--spacing"] = cssVars["--spacing-component-md"];
1464
+ }
1465
+ if (cssVars["--spacing-component-xs"]) {
1466
+ mapped["--spacing-component-xs"] = cssVars["--spacing-component-xs"];
1467
+ }
1468
+ if (cssVars["--spacing-component-sm"]) {
1469
+ mapped["--spacing-component-sm"] = cssVars["--spacing-component-sm"];
1470
+ }
1471
+ if (cssVars["--spacing-component-md"]) {
1472
+ mapped["--spacing-component-md"] = cssVars["--spacing-component-md"];
1473
+ }
1474
+ if (cssVars["--spacing-component-lg"]) {
1475
+ mapped["--spacing-component-lg"] = cssVars["--spacing-component-lg"];
1476
+ }
1477
+ if (cssVars["--spacing-component-xl"]) {
1478
+ mapped["--spacing-component-xl"] = cssVars["--spacing-component-xl"];
1479
+ }
1480
+ if (cssVars["--duration-fast"]) {
1481
+ mapped["--duration-fast"] = cssVars["--duration-fast"];
1482
+ }
1483
+ if (cssVars["--duration-normal"]) {
1484
+ mapped["--duration-normal"] = cssVars["--duration-normal"];
1485
+ }
1486
+ if (cssVars["--duration-slow"]) {
1487
+ mapped["--duration-slow"] = cssVars["--duration-slow"];
1488
+ }
1489
+ return mapped;
1490
+ }
1491
+
1492
+ export { Badge, Button, Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ThemeToggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyThemeSync, badgeVariants, buttonVariants, getTheme, getThemeCategories, getThemeFilePath, getThemesForCategory, registerTheme, useTheme, useThemeToggle };
1206
1493
  //# sourceMappingURL=index.mjs.map
1207
1494
  //# sourceMappingURL=index.mjs.map