tailwind-to-style 2.7.1 → 2.7.3

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tailwind-to-style v2.7.1
2
+ * tailwind-to-style v2.7.3
3
3
  * Convert tailwind classes to inline style
4
4
  *
5
5
  * @author Bigetion
@@ -1533,12 +1533,10 @@ function getConfigOptions() {
1533
1533
  const themeKeys = Object.keys(configOptions.theme);
1534
1534
  themeKeys.forEach(key => {
1535
1535
  newTheme[key] = theme[key] || configOptions.theme[key];
1536
- if (isFunction(newTheme[key])) {
1537
- newTheme[key] = newTheme[key]({
1538
- theme: keyRef => {
1539
- return configOptions.theme[keyRef];
1540
- }
1541
- });
1536
+ });
1537
+ themeKeys.forEach(key => {
1538
+ if (themeExtend[key] && newTheme[key]) {
1539
+ newTheme[key] = Object.assign({}, newTheme[key], themeExtend[key]);
1542
1540
  }
1543
1541
  });
1544
1542
  themeKeys.forEach(key => {
@@ -1549,9 +1547,6 @@ function getConfigOptions() {
1549
1547
  }
1550
1548
  });
1551
1549
  }
1552
- if (themeExtend[key]) {
1553
- newTheme[key] = Object.assign({}, newTheme[key], themeExtend[key]);
1554
- }
1555
1550
  });
1556
1551
  return {
1557
1552
  prefix: "",
@@ -6313,10 +6308,10 @@ function parseCustomClassWithPatterns(className) {
6313
6308
  return null;
6314
6309
  }
6315
6310
 
6316
- /**
6317
- * Resolve all CSS custom properties (var) in a CSS string and output only clear CSS (no custom property)
6318
- * @param {string} cssString
6319
- * @returns {string} e.g. 'color: rgba(255,255,255,1); background: #fff;'
6311
+ /**
6312
+ * Resolve all CSS custom properties (var) in a CSS string and output only clear CSS (no custom property)
6313
+ * @param {string} cssString
6314
+ * @returns {string} e.g. 'color: rgba(255,255,255,1); background: #fff;'
6320
6315
  */
6321
6316
  function resolveCssToClearCss(cssString) {
6322
6317
  const customVars = {};
@@ -6343,13 +6338,13 @@ function resolveCssToClearCss(cssString) {
6343
6338
  }).join(" ");
6344
6339
  }
6345
6340
 
6346
- // Cache untuk getConfigOptions
6341
+ // Cache for getConfigOptions
6347
6342
  const configOptionsCache = new Map();
6348
6343
  const cacheKey = options => JSON.stringify(options);
6349
6344
  function generateTailwindCssString() {
6350
6345
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6351
6346
  const pluginKeys = Object.keys(plugins);
6352
- // Menggunakan cache untuk mencegah pemrosesan ulang yang tidak perlu
6347
+ // Use cache to prevent unnecessary reprocessing
6353
6348
  const key = cacheKey(options);
6354
6349
  if (!configOptionsCache.has(key)) {
6355
6350
  configOptionsCache.set(key, getConfigOptions(options, pluginKeys));
@@ -6383,19 +6378,120 @@ function convertCssToObject(cssString) {
6383
6378
  }
6384
6379
  let twString = null;
6385
6380
  let cssObject = null;
6386
- if (!twString) {
6387
- twString = generateTailwindCssString().replace(/\s\s+/g, " ");
6381
+ let globalConfig = {
6382
+ theme: {
6383
+ extend: {
6384
+ colors: {}
6385
+ },
6386
+ screens: {
6387
+ sm: "640px",
6388
+ md: "768px",
6389
+ lg: "1024px",
6390
+ xl: "1280px",
6391
+ "2xl": "1536px"
6392
+ }
6393
+ },
6394
+ inject: true
6395
+ };
6396
+ function initializeCss() {
6397
+ if (!twString) {
6398
+ const configForGeneration = {
6399
+ ...globalConfig,
6400
+ theme: {
6401
+ ...globalConfig.theme
6402
+ }
6403
+ };
6404
+ twString = generateTailwindCssString(configForGeneration).replace(/\s\s+/g, " ");
6405
+ }
6406
+ if (!cssObject) {
6407
+ cssObject = convertCssToObject(twString);
6408
+ }
6409
+ }
6410
+ initializeCss();
6411
+ function convertScreensToBreakpoints(screens) {
6412
+ const breakpoints = {};
6413
+ for (const [key, value] of Object.entries(screens)) {
6414
+ breakpoints[key] = `@media (min-width: ${value})`;
6415
+ }
6416
+ return breakpoints;
6417
+ }
6418
+
6419
+ /**
6420
+ * Set global configuration for both tws and twsx functions
6421
+ * @param {Object} config - Global configuration object
6422
+ * @returns {Object} Current global configuration
6423
+ */
6424
+ function setConfig(config) {
6425
+ var _config$theme, _config$theme2, _config$theme2$extend, _config$theme3;
6426
+ // Reset CSS object cache when config changes
6427
+ twString = null;
6428
+ cssObject = null;
6429
+ configOptionsCache.clear();
6430
+ globalConfig = {
6431
+ ...globalConfig,
6432
+ ...config,
6433
+ theme: {
6434
+ ...globalConfig.theme,
6435
+ ...(config.theme || {}),
6436
+ extend: {
6437
+ ...globalConfig.theme.extend,
6438
+ ...(((_config$theme = config.theme) === null || _config$theme === void 0 ? void 0 : _config$theme.extend) || {}),
6439
+ colors: {
6440
+ ...globalConfig.theme.extend.colors,
6441
+ ...(((_config$theme2 = config.theme) === null || _config$theme2 === void 0 ? void 0 : (_config$theme2$extend = _config$theme2.extend) === null || _config$theme2$extend === void 0 ? void 0 : _config$theme2$extend.colors) || {})
6442
+ }
6443
+ }
6444
+ }
6445
+ };
6446
+
6447
+ // Handle screens configuration
6448
+ if ((_config$theme3 = config.theme) !== null && _config$theme3 !== void 0 && _config$theme3.screens) {
6449
+ globalConfig.theme.screens = {
6450
+ ...globalConfig.theme.screens,
6451
+ ...config.theme.screens
6452
+ };
6453
+ }
6454
+ initializeCss();
6455
+ return globalConfig;
6456
+ }
6457
+
6458
+ /**
6459
+ * Get current global configuration
6460
+ * @returns {Object} Current global configuration
6461
+ */
6462
+ function getConfig() {
6463
+ return {
6464
+ ...globalConfig
6465
+ };
6388
6466
  }
6389
- if (!cssObject) {
6467
+
6468
+ /**
6469
+ * Reset global configuration to default
6470
+ * @returns {Object} Default configuration
6471
+ */
6472
+ function resetConfig() {
6473
+ twString = null;
6474
+ cssObject = null;
6475
+ configOptionsCache.clear();
6476
+ globalConfig = {
6477
+ theme: {
6478
+ extend: {
6479
+ colors: {}
6480
+ },
6481
+ screens: {
6482
+ sm: "640px",
6483
+ md: "768px",
6484
+ lg: "1024px",
6485
+ xl: "1280px",
6486
+ "2xl": "1536px"
6487
+ }
6488
+ },
6489
+ inject: true
6490
+ };
6491
+ twString = generateTailwindCssString(globalConfig).replace(/\s\s+/g, " ");
6390
6492
  cssObject = convertCssToObject(twString);
6493
+ return globalConfig;
6391
6494
  }
6392
- const breakpoints = {
6393
- sm: "@media (min-width: 640px)",
6394
- md: "@media (min-width: 768px)",
6395
- lg: "@media (min-width: 1024px)",
6396
- xl: "@media (min-width: 1280px)",
6397
- "2xl": "@media (min-width: 1536px)"
6398
- };
6399
6495
  const pseudoVariants = new Set(["hover", "focus", "focus-within", "active", "visited", "disabled", "first", "last", "checked", "invalid", "required"]);
6400
6496
  const specialVariants = {
6401
6497
  group: (state, sel) => `.group:${state} ${sel}`,
@@ -6410,7 +6506,7 @@ const selectorVariants = {
6410
6506
  number: arg => `> :nth-child(${arg})`
6411
6507
  };
6412
6508
 
6413
- // Mengoptimalkan encoding/decoding bracket values dengan memoization
6509
+ // Optimize encoding/decoding bracket values with memoization
6414
6510
  const encodeBracketCache = new Map();
6415
6511
  function encodeBracketValues(input) {
6416
6512
  if (!input) return input;
@@ -6445,6 +6541,7 @@ function resolveVariants(selector, variants) {
6445
6541
  let media = null;
6446
6542
  let finalSelector = selector;
6447
6543
  for (const v of variants) {
6544
+ const breakpoints = convertScreensToBreakpoints(globalConfig.theme.screens || {});
6448
6545
  if (breakpoints[v]) {
6449
6546
  media = breakpoints[v];
6450
6547
  } else if (pseudoVariants.has(v)) {
@@ -6477,7 +6574,7 @@ function inlineStyleToJson(styleString) {
6477
6574
  return styleObject;
6478
6575
  }
6479
6576
 
6480
- // Cache untuk CSS resolusi
6577
+ // Cache for CSS resolution
6481
6578
  const cssResolutionCache = new Map();
6482
6579
 
6483
6580
  // Enhanced cache management with performance monitoring
@@ -6485,7 +6582,7 @@ function limitCacheSize(cache) {
6485
6582
  let maxSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
6486
6583
  if (cache.size > maxSize) {
6487
6584
  const cleanupMarker = performanceMonitor.start("cache:cleanup");
6488
- // Hapus 20% entri yang paling lama
6585
+ // Remove 20% of the oldest entries
6489
6586
  const entriesToRemove = Math.floor(cache.size * 0.2);
6490
6587
  const keys = Array.from(cache.keys()).slice(0, entriesToRemove);
6491
6588
  keys.forEach(key => cache.delete(key));
@@ -6506,7 +6603,7 @@ function debounce(func) {
6506
6603
  callCount++;
6507
6604
  clearTimeout(timeout);
6508
6605
  timeout = setTimeout(() => {
6509
- const marker = performanceMonitor.start(`debounced:${func.name || 'anonymous'}`);
6606
+ const marker = performanceMonitor.start(`debounced:${func.name || "anonymous"}`);
6510
6607
  try {
6511
6608
  const result = func.apply(context, args);
6512
6609
  performanceMonitor.end(marker);
@@ -6524,14 +6621,14 @@ function debounce(func) {
6524
6621
  function separateAndResolveCSS(arr) {
6525
6622
  const marker = performanceMonitor.start("css:resolve");
6526
6623
  try {
6527
- // Perbaiki: cacheKey harus unik untuk setiap input array
6624
+ // Fix: cacheKey must be unique for each input array
6528
6625
  const cacheKey = Array.isArray(arr) ? arr.join("|") : String(arr);
6529
6626
  if (cssResolutionCache.has(cacheKey)) {
6530
6627
  performanceMonitor.end(marker);
6531
6628
  return cssResolutionCache.get(cacheKey);
6532
6629
  }
6533
6630
 
6534
- // Batasi ukuran cache untuk menghindari memory leak
6631
+ // Limit cache size to avoid memory leaks
6535
6632
  limitCacheSize(cssResolutionCache);
6536
6633
  const cssProperties = {};
6537
6634
  arr.forEach(item => {
@@ -6544,7 +6641,7 @@ function separateAndResolveCSS(arr) {
6544
6641
  const key = declaration.substring(0, colonIndex).trim();
6545
6642
  const value = declaration.substring(colonIndex + 1).trim();
6546
6643
  if (key && value) {
6547
- // Prioritaskan nilai yang lebih spesifik (misalnya !important)
6644
+ // Prioritize more specific values (e.g., !important)
6548
6645
  if (value.includes("!important") || !cssProperties[key]) {
6549
6646
  cssProperties[key] = value;
6550
6647
  }
@@ -6594,15 +6691,82 @@ function separateAndResolveCSS(arr) {
6594
6691
  }
6595
6692
  }
6596
6693
 
6597
- /**
6598
- * Mengkonversi string kelas Tailwind menjadi inline styles CSS atau objek JSON
6599
- * @param {string} classNames - String berisi kelas Tailwind yang akan dikonversi
6600
- * @param {boolean} convertToJson - Jika true, hasil akan menjadi objek JSON, jika false menjadi string CSS
6601
- * @returns {string|Object} String CSS inline atau objek style JSON
6694
+ /**
6695
+ * Process opacity modifier from class name (e.g., text-red-500/50 -> 50% opacity)
6696
+ * @param {string} className - Class name with potential opacity modifier
6697
+ * @param {string} cssDeclaration - CSS declaration to modify
6698
+ * @returns {string} Modified CSS declaration with opacity applied
6699
+ */
6700
+ function processOpacityModifier(className, cssDeclaration) {
6701
+ const opacityMatch = className.match(/\/(\d+)$/);
6702
+ if (!opacityMatch) return cssDeclaration;
6703
+ const opacityValue = parseInt(opacityMatch[1], 10);
6704
+ if (opacityValue < 0 || opacityValue > 100) return cssDeclaration;
6705
+ const alphaValue = (opacityValue / 100).toString();
6706
+
6707
+ // Handle Tailwind's CSS custom property pattern
6708
+ let modifiedDeclaration = cssDeclaration;
6709
+
6710
+ // Replace opacity custom properties
6711
+ const opacityProperties = ["--text-opacity", "--bg-opacity", "--border-opacity", "--ring-opacity", "--divide-opacity", "--placeholder-opacity", "--text-decoration-opacity", "--outline-opacity", "--accent-opacity", "--caret-opacity"];
6712
+ opacityProperties.forEach(prop => {
6713
+ const propRegex = new RegExp(`${prop}\\s*:\\s*[\\d.]+`, "gi");
6714
+ modifiedDeclaration = modifiedDeclaration.replace(propRegex, `${prop}: ${alphaValue}`);
6715
+ });
6716
+
6717
+ // Also handle direct color values that might not use CSS variables
6718
+ const colorProperties = ["color", "background-color", "border-color", "text-decoration-color", "outline-color", "fill", "stroke", "caret-color", "accent-color"];
6719
+ colorProperties.forEach(prop => {
6720
+ // Match rgb(), rgba(), hsl(), hsla() functions
6721
+ const rgbRegex = new RegExp(`(${prop}\\s*:\\s*)rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)`, "gi");
6722
+ const rgbaRegex = new RegExp(`(${prop}\\s*:\\s*)rgba\\((\\d+),\\s*(\\d+),\\s*(\\d+),\\s*[\\d.]+\\)`, "gi");
6723
+ const hslRegex = new RegExp(`(${prop}\\s*:\\s*)hsl\\((\\d+),\\s*([\\d.]+%),\\s*([\\d.]+%)\\)`, "gi");
6724
+ const hslaRegex = new RegExp(`(${prop}\\s*:\\s*)hsla\\((\\d+),\\s*([\\d.]+%),\\s*([\\d.]+%),\\s*[\\d.]+\\)`, "gi");
6725
+
6726
+ // Convert rgb to rgba with opacity
6727
+ modifiedDeclaration = modifiedDeclaration.replace(rgbRegex, `$1rgba($2, $3, $4, ${alphaValue})`);
6728
+
6729
+ // Update existing rgba opacity
6730
+ modifiedDeclaration = modifiedDeclaration.replace(rgbaRegex, `$1rgba($2, $3, $4, ${alphaValue})`);
6731
+
6732
+ // Convert hsl to hsla with opacity
6733
+ modifiedDeclaration = modifiedDeclaration.replace(hslRegex, `$1hsla($2, $3, $4, ${alphaValue})`);
6734
+
6735
+ // Update existing hsla opacity
6736
+ modifiedDeclaration = modifiedDeclaration.replace(hslaRegex, `$1hsla($2, $3, $4, ${alphaValue})`);
6737
+
6738
+ // Handle hex colors
6739
+ const hexRegex = new RegExp(`(${prop}\\s*:\\s*)(#[0-9a-fA-F]{3,6})`, "gi");
6740
+ modifiedDeclaration = modifiedDeclaration.replace(hexRegex, (_, propPart, hexColor) => {
6741
+ // Convert hex to rgba
6742
+ const hex = hexColor.replace("#", "");
6743
+ let r, g, b;
6744
+ if (hex.length === 3) {
6745
+ r = parseInt(hex[0] + hex[0], 16);
6746
+ g = parseInt(hex[1] + hex[1], 16);
6747
+ b = parseInt(hex[2] + hex[2], 16);
6748
+ } else {
6749
+ r = parseInt(hex.substring(0, 2), 16);
6750
+ g = parseInt(hex.substring(2, 4), 16);
6751
+ b = parseInt(hex.substring(4, 6), 16);
6752
+ }
6753
+ return `${propPart}rgba(${r}, ${g}, ${b}, ${alphaValue})`;
6754
+ });
6755
+ });
6756
+ return modifiedDeclaration;
6757
+ }
6758
+
6759
+ /**
6760
+ * Convert Tailwind class string to inline CSS styles or JSON object
6761
+ * @param {string} classNames - String containing Tailwind classes to convert
6762
+ * @param {boolean} convertToJson - If true, result will be JSON object, if false becomes CSS string
6763
+ * @returns {string|Object} Inline CSS string or style JSON object
6602
6764
  */
6603
6765
  function tws(classNames, convertToJson) {
6604
6766
  const totalMarker = performanceMonitor.start("tws:total");
6605
6767
  try {
6768
+ // Ensure CSS is initialized with current global config
6769
+ initializeCss();
6606
6770
  if ([!classNames, typeof classNames !== "string", classNames.trim() === ""].includes(true)) {
6607
6771
  performanceMonitor.end(totalMarker);
6608
6772
  return convertToJson ? {} : "";
@@ -6610,10 +6774,10 @@ function tws(classNames, convertToJson) {
6610
6774
  let classes;
6611
6775
  try {
6612
6776
  const parseMarker = performanceMonitor.start("tws:parse");
6613
- classes = classNames.match(/[\w-\/]+(?:\[[^\]]+\])?/g);
6777
+ classes = classNames.match(/[\w-\/]+(?:\/\d+)?(?:\[[^\]]+\])?/g);
6614
6778
  performanceMonitor.end(parseMarker);
6615
6779
 
6616
- // Jika tidak ada class yang valid ditemukan
6780
+ // If no valid classes are found
6617
6781
  if (!classes || classes.length === 0) {
6618
6782
  console.warn(`No valid Tailwind classes found in input: "${classNames}"`);
6619
6783
  performanceMonitor.end(totalMarker);
@@ -6628,16 +6792,27 @@ function tws(classNames, convertToJson) {
6628
6792
  // Process classes with performance monitoring
6629
6793
  const processMarker = performanceMonitor.start("tws:process");
6630
6794
  let cssResult = classes.map(className => {
6631
- let result = cssObject[className] || cssObject[className.replace(/(\/)/g, "\\$1")] || cssObject[className.replace(/\./g, "\\.")];
6795
+ // Extract base class name without opacity modifier
6796
+ const baseClassName = className.replace(/\/\d+$/, "");
6797
+ let result = cssObject[baseClassName] || cssObject[baseClassName.replace(/(\/)/g, "\\$1")] || cssObject[baseClassName.replace(/\./g, "\\.")];
6632
6798
  if (result) {
6799
+ // Apply opacity modifier if present
6800
+ if (className.includes("/") && /\/\d+$/.test(className)) {
6801
+ result = processOpacityModifier(className, result);
6802
+ }
6633
6803
  return resolveCssToClearCss(result);
6634
- } else if (className.includes("[")) {
6635
- const match = className.match(/\[([^\]]+)\]/);
6804
+ } else if (baseClassName.includes("[")) {
6805
+ const match = baseClassName.match(/\[([^\]]+)\]/);
6636
6806
  if (match) {
6637
6807
  const customValue = match[1];
6638
- const baseKey = className.split("[")[0];
6808
+ const baseKey = baseClassName.split("[")[0];
6639
6809
  if (cssObject[`${baseKey}custom`]) {
6640
- return cssObject[`${baseKey}custom`].replace(/custom_value/g, customValue);
6810
+ let customResult = cssObject[`${baseKey}custom`].replace(/custom_value/g, customValue);
6811
+ // Apply opacity modifier to custom values too
6812
+ if (className.includes("/") && /\/\d+$/.test(className)) {
6813
+ customResult = processOpacityModifier(className, customResult);
6814
+ }
6815
+ return customResult;
6641
6816
  }
6642
6817
  }
6643
6818
  }
@@ -6768,9 +6943,12 @@ function processClass(cls, selector, styles) {
6768
6943
  media,
6769
6944
  finalSelector
6770
6945
  } = resolveVariants(selector, rawVariants);
6771
- let declarations = cssObject[pureClassName] || cssObject[pureClassName.replace(/(\/)/g, "\\$1")] || cssObject[pureClassName.replace(/\./g, "\\.")];
6772
- if (!declarations && pureClassName.includes("[")) {
6773
- const match = pureClassName.match(/^(.+?)\[(.+)\]$/);
6946
+
6947
+ // Extract base class name without opacity modifier for CSS lookup
6948
+ const baseClassName = pureClassName.replace(/\/\d+$/, "");
6949
+ let declarations = cssObject[baseClassName] || cssObject[baseClassName.replace(/(\/)/g, "\\$1")] || cssObject[baseClassName.replace(/\./g, "\\.")];
6950
+ if (!declarations && baseClassName.includes("[")) {
6951
+ const match = baseClassName.match(/^(.+?)\[(.+)\]$/);
6774
6952
  if (match) {
6775
6953
  const [, prefix, dynamicValue] = match;
6776
6954
  const customKey = `${prefix}custom`;
@@ -6781,17 +6959,22 @@ function processClass(cls, selector, styles) {
6781
6959
  }
6782
6960
  }
6783
6961
  if (!declarations) {
6784
- declarations = parseCustomClassWithPatterns(pureClassName);
6962
+ declarations = parseCustomClassWithPatterns(baseClassName);
6785
6963
  }
6786
6964
  if (!declarations) {
6787
6965
  return;
6788
6966
  }
6967
+
6968
+ // Apply opacity modifier if present
6969
+ if (pureClassName.includes("/") && /\/\d+$/.test(pureClassName)) {
6970
+ declarations = processOpacityModifier(pureClassName, declarations);
6971
+ }
6789
6972
  if (isImportant) {
6790
6973
  declarations = declarations.replace(/([^:;]+):([^;]+)(;?)/g, (_, prop, value) => {
6791
6974
  return prop.trim().startsWith("--") ? `${prop}:${value};` : `${prop}:${value.trim()} !important;`;
6792
6975
  });
6793
6976
  }
6794
- const isSpaceOrDivide = ["space-x-", "-space-x-", "space-y-", "-space-y-", "divide-"].some(prefix => pureClassName.startsWith(prefix));
6977
+ const isSpaceOrDivide = ["space-x-", "-space-x-", "space-y-", "-space-y-", "divide-"].some(prefix => baseClassName.startsWith(prefix));
6795
6978
  const expandedSelector = replaceSelector(finalSelector);
6796
6979
  const targetSelector = isSpaceOrDivide ? `${expandedSelector} > :not([hidden]) ~ :not([hidden])` : expandedSelector;
6797
6980
  if (media) {
@@ -6958,12 +7141,12 @@ function generateCssString(styles) {
6958
7141
  return cssString.trim();
6959
7142
  }
6960
7143
 
6961
- /**
6962
- * Menghasilkan string CSS dari objek style dengan sintaks mirip SCSS
6963
- * Mendukung nested selectors, state variants, responsive variants, dan @css directives
6964
- * @param {Object} obj - Objek dengan format style mirip SCSS
6965
- * @param {Object} [options] - Opsi tambahan, misal { inject: true/false }
6966
- * @returns {string} String CSS yang dihasilkan
7144
+ /**
7145
+ * Generate CSS string from style object with SCSS-like syntax
7146
+ * Supports nested selectors, state variants, responsive variants, and @css directives
7147
+ * @param {Object} obj - Object with SCSS-like style format
7148
+ * @param {Object} [options] - Additional options, merges with global config
7149
+ * @returns {string} Generated CSS string
6967
7150
  */
6968
7151
  function twsx(obj) {
6969
7152
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -6973,9 +7156,13 @@ function twsx(obj) {
6973
7156
  console.warn("twsx: Expected an object but received:", obj);
6974
7157
  return "";
6975
7158
  }
7159
+ const mergedOptions = {
7160
+ ...globalConfig,
7161
+ ...options
7162
+ };
6976
7163
  const {
6977
7164
  inject = true
6978
- } = options;
7165
+ } = mergedOptions;
6979
7166
  const styles = {};
6980
7167
 
6981
7168
  // Create walk function with closure over styles
@@ -7023,7 +7210,7 @@ function twsx(obj) {
7023
7210
  }
7024
7211
  }
7025
7212
 
7026
- // Fungsi hashCode sederhana untuk deduplikasi CSS
7213
+ // Simple hashCode function for CSS deduplication
7027
7214
  function getCssHash(str) {
7028
7215
  let hash = 0,
7029
7216
  i,
@@ -7037,7 +7224,7 @@ function getCssHash(str) {
7037
7224
  return hash;
7038
7225
  }
7039
7226
 
7040
- // Enhanced auto-inject CSS dengan performance monitoring
7227
+ // Enhanced auto-inject CSS with performance monitoring
7041
7228
  const injectedCssHashSet = new Set();
7042
7229
  function autoInjectCss(cssString) {
7043
7230
  const marker = performanceMonitor.start("css:inject");
@@ -7069,24 +7256,24 @@ function autoInjectCss(cssString) {
7069
7256
  }
7070
7257
  }
7071
7258
 
7072
- // Enhanced debounced functions dengan konfigurasi performance monitoring
7073
- /**
7074
- * Versi debounced dari fungsi tws dengan performance monitoring
7075
- * @param {string} classNames - String berisi kelas Tailwind yang akan dikonversi
7076
- * @param {boolean} convertToJson - Jika true, hasil akan menjadi objek JSON, jika false menjadi string CSS
7077
- * @returns {string|Object} String CSS inline atau objek style JSON
7259
+ // Enhanced debounced functions with performance monitoring configuration
7260
+ /**
7261
+ * Debounced version of tws function with performance monitoring
7262
+ * @param {string} classNames - String containing Tailwind classes to convert
7263
+ * @param {boolean} convertToJson - If true, result will be JSON object, if false becomes CSS string
7264
+ * @returns {string|Object} Inline CSS string or style JSON object
7078
7265
  */
7079
7266
  const debouncedTws = debounce(tws, 50); // Faster debounce for tws
7080
7267
 
7081
- /**
7082
- * Versi debounced dari fungsi twsx dengan performance monitoring
7083
- * @param {Object} obj - Objek dengan format style mirip SCSS
7084
- * @param {Object} [options] - Opsi tambahan
7085
- * @returns {string} String CSS yang dihasilkan
7268
+ /**
7269
+ * Debounced version of twsx function with performance monitoring
7270
+ * @param {Object} obj - Object with SCSS-like style format
7271
+ * @param {Object} [options] - Additional options
7272
+ * @returns {string} Generated CSS string
7086
7273
  */
7087
7274
  const debouncedTwsx = debounce(twsx, 100); // Standard debounce for twsx
7088
7275
 
7089
- // Export performance utilities untuk debugging
7276
+ // Export performance utilities for debugging
7090
7277
  const performanceUtils = {
7091
7278
  getStats() {
7092
7279
  return {
@@ -7114,12 +7301,15 @@ const performanceUtils = {
7114
7301
  enablePerformanceLogging() {
7115
7302
  let enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
7116
7303
  performanceMonitor.enabled = enabled && typeof performance !== "undefined";
7117
- console.log(`Performance monitoring ${enabled ? 'enabled' : 'disabled'}`);
7304
+ console.log(`Performance monitoring ${enabled ? "enabled" : "disabled"}`);
7118
7305
  }
7119
7306
  };
7120
7307
 
7121
7308
  exports.debouncedTws = debouncedTws;
7122
7309
  exports.debouncedTwsx = debouncedTwsx;
7310
+ exports.getConfig = getConfig;
7123
7311
  exports.performanceUtils = performanceUtils;
7312
+ exports.resetConfig = resetConfig;
7313
+ exports.setConfig = setConfig;
7124
7314
  exports.tws = tws;
7125
7315
  exports.twsx = twsx;
package/dist/index.d.ts CHANGED
@@ -7,6 +7,18 @@ export interface TwsxOptions {
7
7
  [key: string]: any;
8
8
  }
9
9
 
10
+ export interface GlobalConfig {
11
+ theme: {
12
+ extend: {
13
+ colors: Record<string, string | Record<string, string>>;
14
+ [key: string]: any;
15
+ };
16
+ screens: Record<string, string>;
17
+ [key: string]: any;
18
+ };
19
+ inject: boolean;
20
+ }
21
+
10
22
  export interface PerformanceStats {
11
23
  cacheStats: {
12
24
  cssResolution: number;
@@ -44,24 +56,37 @@ export function tws(classNames: string, convertToJson?: boolean): string | Recor
44
56
  * Generates CSS string from style object with SCSS-like syntax
45
57
  * Supports nested selectors, state variants, responsive variants, and @css directives
46
58
  * @param obj - Object with SCSS-like style format
47
- * @param options - Additional options
59
+ * @param options - Additional options, merges with global config
48
60
  * @returns Generated CSS string
49
61
  */
50
62
  export function twsx(obj: StyleObject, options?: TwsxOptions): string;
51
63
 
64
+ /**
65
+ * Set global configuration for both tws and twsx
66
+ * @param config - Global configuration object
67
+ * @returns Current global configuration
68
+ */
69
+ export function setConfig(config: Partial<GlobalConfig>): GlobalConfig;
70
+
71
+ /**
72
+ * Get current global configuration for both tws and twsx
73
+ * @returns Current global configuration
74
+ */
75
+ export function getConfig(): GlobalConfig;
76
+
77
+ /**
78
+ * Reset global configuration to default
79
+ * @returns Default configuration
80
+ */
81
+ export function resetConfig(): GlobalConfig;
82
+
52
83
  /**
53
84
  * Debounced version of tws function with performance monitoring
54
- * @param classNames - String containing Tailwind classes to convert
55
- * @param convertToJson - If true, returns JSON object, if false returns CSS string
56
- * @returns CSS inline string or style JSON object
57
85
  */
58
86
  export const debouncedTws: typeof tws;
59
87
 
60
88
  /**
61
89
  * Debounced version of twsx function with performance monitoring
62
- * @param obj - Object with SCSS-like style format
63
- * @param options - Additional options
64
- * @returns Generated CSS string
65
90
  */
66
91
  export const debouncedTwsx: typeof twsx;
67
92