@plumeria/vite-plugin 10.0.1 → 10.0.2

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 (2) hide show
  1. package/dist/index.js +584 -655
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -534,6 +534,448 @@ export function plumeria(options = {}) {
534
534
  },
535
535
  });
536
536
  const jsxOpeningElementMap = new Map();
537
+ const getSource = (node) => {
538
+ const start = node.span.start - baseByteOffset;
539
+ const end = node.span.end - baseByteOffset;
540
+ return sourceBuffer.subarray(start, end).toString('utf-8');
541
+ };
542
+ const resolveStyleObject = (expr) => {
543
+ if (t.isObjectExpression(expr)) {
544
+ return objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
545
+ }
546
+ else if (t.isMemberExpression(expr) &&
547
+ t.isIdentifier(expr.object) &&
548
+ (t.isIdentifier(expr.property) ||
549
+ expr.property.type === 'Computed')) {
550
+ if (expr.property.type === 'Computed')
551
+ return {};
552
+ const varName = expr.object.value;
553
+ const propName = expr.property.value;
554
+ const styleInfo = localCreateStyles[varName];
555
+ if (styleInfo?.obj[propName]) {
556
+ const style = styleInfo.obj[propName];
557
+ if (typeof style === 'object' && style !== null)
558
+ return style;
559
+ }
560
+ const hash = mergedCreateTable[varName];
561
+ if (hash) {
562
+ const obj = scannedTables.createObjectTable[hash];
563
+ if (obj?.[propName] && typeof obj[propName] === 'object')
564
+ return obj[propName];
565
+ }
566
+ }
567
+ else if (t.isIdentifier(expr)) {
568
+ const varName = expr.value;
569
+ const uniqueKey = `${resourcePath}-${varName}`;
570
+ let hash = scannedTables.createHashTable[uniqueKey];
571
+ if (!hash)
572
+ hash = mergedCreateTable[varName];
573
+ if (hash) {
574
+ const obj = scannedTables.createObjectTable[hash];
575
+ if (obj && typeof obj === 'object')
576
+ return obj;
577
+ }
578
+ const styleInfo = localCreateStyles[varName];
579
+ if (styleInfo?.obj)
580
+ return styleInfo.obj;
581
+ const vHash = mergedVariantsTable[varName];
582
+ if (vHash)
583
+ return scannedTables.variantsObjectTable[vHash];
584
+ }
585
+ return null;
586
+ };
587
+ const buildClassParts = (args, dynamicClassParts = [], existingClass = '') => {
588
+ const conditionals = [];
589
+ let groupIdCounter = 0;
590
+ let baseStyle = {};
591
+ let isOptimizable = true;
592
+ const collectConditions = (node, currentTestStrings = []) => {
593
+ const staticStyle = resolveStyleObject(node);
594
+ if (staticStyle) {
595
+ if (currentTestStrings.length === 0) {
596
+ baseStyle = deepMerge(baseStyle, staticStyle);
597
+ }
598
+ else {
599
+ conditionals.push({
600
+ test: node,
601
+ testString: currentTestStrings.join(' && '),
602
+ truthy: staticStyle,
603
+ falsy: {},
604
+ varName: undefined,
605
+ });
606
+ }
607
+ return true;
608
+ }
609
+ if (node.type === 'ConditionalExpression') {
610
+ const testSource = getSource(node.test);
611
+ if (currentTestStrings.length === 0) {
612
+ const trueStyle = resolveStyleObject(node.consequent);
613
+ const falseStyle = resolveStyleObject(node.alternate);
614
+ if (trueStyle && falseStyle) {
615
+ conditionals.push({
616
+ test: node,
617
+ testString: testSource,
618
+ truthy: trueStyle,
619
+ falsy: falseStyle,
620
+ varName: undefined,
621
+ });
622
+ return true;
623
+ }
624
+ }
625
+ collectConditions(node.consequent, [
626
+ ...currentTestStrings,
627
+ `(${testSource})`,
628
+ ]);
629
+ collectConditions(node.alternate, [
630
+ ...currentTestStrings,
631
+ `!(${testSource})`,
632
+ ]);
633
+ return true;
634
+ }
635
+ else if (node.type === 'BinaryExpression' &&
636
+ node.operator === '&&') {
637
+ collectConditions(node.right, [
638
+ ...currentTestStrings,
639
+ `(${getSource(node.left)})`,
640
+ ]);
641
+ return true;
642
+ }
643
+ else if (node.type === 'ParenthesisExpression') {
644
+ return collectConditions(node.expression, currentTestStrings);
645
+ }
646
+ return false;
647
+ };
648
+ for (const arg of args) {
649
+ const expr = arg.expression;
650
+ if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
651
+ const varName = expr.callee.value;
652
+ const uniqueKey = `${resourcePath}-${varName}`;
653
+ let variantObj;
654
+ let hash = scannedTables.variantsHashTable[uniqueKey];
655
+ if (!hash)
656
+ hash = mergedVariantsTable[varName];
657
+ if (hash && scannedTables.variantsObjectTable[hash])
658
+ variantObj = scannedTables.variantsObjectTable[hash];
659
+ if (!variantObj && localCreateStyles[varName]?.obj)
660
+ variantObj = localCreateStyles[varName].obj;
661
+ if (variantObj) {
662
+ const callArgs = expr.arguments;
663
+ if (callArgs.length === 1 && !callArgs[0].spread) {
664
+ const arg = callArgs[0].expression;
665
+ if (arg.type === 'ObjectExpression') {
666
+ for (const prop of arg.properties) {
667
+ let groupName;
668
+ let valExpr;
669
+ if (prop.type === 'KeyValueProperty' &&
670
+ prop.key.type === 'Identifier') {
671
+ groupName = prop.key.value;
672
+ valExpr = prop.value;
673
+ }
674
+ else if (prop.type === 'Identifier') {
675
+ groupName = prop.value;
676
+ valExpr = prop;
677
+ }
678
+ if (groupName && valExpr) {
679
+ const groupVariants = variantObj[groupName];
680
+ if (!groupVariants)
681
+ continue;
682
+ const currentGroupId = ++groupIdCounter;
683
+ const valSource = getSource(valExpr);
684
+ if (valExpr.type === 'StringLiteral') {
685
+ if (groupVariants[valExpr.value])
686
+ baseStyle = deepMerge(baseStyle, groupVariants[valExpr.value]);
687
+ continue;
688
+ }
689
+ Object.entries(groupVariants).forEach(([optionName, style]) => {
690
+ conditionals.push({
691
+ test: valExpr,
692
+ testLHS: valSource,
693
+ testString: `${valSource} === '${optionName}'`,
694
+ truthy: style,
695
+ falsy: {},
696
+ groupId: currentGroupId,
697
+ groupName,
698
+ valueName: optionName,
699
+ varName,
700
+ });
701
+ });
702
+ }
703
+ }
704
+ continue;
705
+ }
706
+ const argSource = getSource(arg);
707
+ if (t.isStringLiteral(arg)) {
708
+ if (variantObj[arg.value])
709
+ baseStyle = deepMerge(baseStyle, variantObj[arg.value]);
710
+ continue;
711
+ }
712
+ const currentGroupId = ++groupIdCounter;
713
+ Object.entries(variantObj).forEach(([key, style]) => {
714
+ conditionals.push({
715
+ test: arg,
716
+ testLHS: argSource,
717
+ testString: `${argSource} === '${key}'`,
718
+ truthy: style,
719
+ falsy: {},
720
+ groupId: currentGroupId,
721
+ groupName: undefined,
722
+ valueName: key,
723
+ varName,
724
+ });
725
+ });
726
+ continue;
727
+ }
728
+ isOptimizable = false;
729
+ break;
730
+ }
731
+ }
732
+ else if (t.isIdentifier(expr)) {
733
+ const varName = expr.value;
734
+ const uniqueKey = `${resourcePath}-${varName}`;
735
+ let variantObj;
736
+ let hash = scannedTables.variantsHashTable[uniqueKey];
737
+ if (!hash)
738
+ hash = mergedVariantsTable[varName];
739
+ if (hash && scannedTables.variantsObjectTable[hash])
740
+ variantObj = scannedTables.variantsObjectTable[hash];
741
+ if (!variantObj && localCreateStyles[varName]?.obj)
742
+ variantObj = localCreateStyles[varName].obj;
743
+ if (variantObj) {
744
+ Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
745
+ if (!groupVariants)
746
+ return;
747
+ const currentGroupId = ++groupIdCounter;
748
+ Object.entries(groupVariants).forEach(([optionName, style]) => {
749
+ conditionals.push({
750
+ test: expr,
751
+ testLHS: `props["${groupName}"]`,
752
+ testString: `props["${groupName}"] === '${optionName}'`,
753
+ truthy: style,
754
+ falsy: {},
755
+ groupId: currentGroupId,
756
+ groupName,
757
+ valueName: optionName,
758
+ varName,
759
+ });
760
+ });
761
+ });
762
+ continue;
763
+ }
764
+ }
765
+ const handled = collectConditions(expr);
766
+ if (handled)
767
+ continue;
768
+ isOptimizable = false;
769
+ break;
770
+ }
771
+ if (!isOptimizable ||
772
+ (args.length === 0 && Object.keys(baseStyle).length === 0)) {
773
+ return {
774
+ classParts: [...dynamicClassParts],
775
+ isOptimizable,
776
+ baseStyle,
777
+ };
778
+ }
779
+ const participation = {};
780
+ const registerParticipation = (style, sourceId) => {
781
+ Object.keys(style).forEach((key) => {
782
+ if (!participation[key])
783
+ participation[key] = new Set();
784
+ participation[key].add(sourceId);
785
+ });
786
+ };
787
+ registerParticipation(baseStyle, 'base');
788
+ conditionals
789
+ .filter((c) => c.groupId === undefined)
790
+ .forEach((c, idx) => {
791
+ registerParticipation(c.truthy, `std_${idx}`);
792
+ registerParticipation(c.falsy, `std_${idx}`);
793
+ });
794
+ const variantGroups = {};
795
+ conditionals.forEach((c) => {
796
+ if (c.groupId !== undefined) {
797
+ if (!variantGroups[c.groupId])
798
+ variantGroups[c.groupId] = [];
799
+ variantGroups[c.groupId].push(c);
800
+ }
801
+ });
802
+ Object.entries(variantGroups).forEach(([groupId, opts]) => {
803
+ opts.forEach((opt) => registerParticipation(opt.truthy, `var_${groupId}`));
804
+ });
805
+ const conflictingKeys = new Set();
806
+ Object.entries(participation).forEach(([key, sources]) => {
807
+ if (sources.size > 1)
808
+ conflictingKeys.add(key);
809
+ });
810
+ const baseIndependent = {};
811
+ const baseConflict = {};
812
+ Object.entries(baseStyle).forEach(([key, val]) => {
813
+ if (conflictingKeys.has(key))
814
+ baseConflict[key] = val;
815
+ else
816
+ baseIndependent[key] = val;
817
+ });
818
+ const indepConditionals = [];
819
+ const conflictConditionals = [];
820
+ conditionals.forEach((c) => {
821
+ const truthyIndep = {};
822
+ const truthyConf = {};
823
+ const falsyIndep = {};
824
+ const falsyConf = {};
825
+ let hasIndep = false;
826
+ let hasConf = false;
827
+ Object.entries(c.truthy).forEach(([k, v]) => {
828
+ if (conflictingKeys.has(k)) {
829
+ truthyConf[k] = v;
830
+ hasConf = true;
831
+ }
832
+ else {
833
+ truthyIndep[k] = v;
834
+ hasIndep = true;
835
+ }
836
+ });
837
+ Object.entries(c.falsy).forEach(([k, v]) => {
838
+ if (conflictingKeys.has(k)) {
839
+ falsyConf[k] = v;
840
+ hasConf = true;
841
+ }
842
+ else {
843
+ falsyIndep[k] = v;
844
+ hasIndep = true;
845
+ }
846
+ });
847
+ if (hasIndep)
848
+ indepConditionals.push({
849
+ ...c,
850
+ truthy: truthyIndep,
851
+ falsy: falsyIndep,
852
+ });
853
+ if (hasConf)
854
+ conflictConditionals.push({
855
+ ...c,
856
+ truthy: truthyConf,
857
+ falsy: falsyConf,
858
+ });
859
+ });
860
+ const classParts = [];
861
+ if (existingClass)
862
+ classParts.push(JSON.stringify(existingClass));
863
+ if (Object.keys(baseIndependent).length > 0) {
864
+ const className = getStyleRecords(baseIndependent)
865
+ .map((r) => r.hash)
866
+ .join(' ');
867
+ if (className)
868
+ classParts.push(JSON.stringify(className));
869
+ }
870
+ indepConditionals
871
+ .filter((c) => c.groupId === undefined)
872
+ .forEach((c) => {
873
+ const processBranch = (style) => {
874
+ if (Object.keys(style).length === 0)
875
+ return '""';
876
+ return JSON.stringify(getStyleRecords(style)
877
+ .map((r) => r.hash)
878
+ .join(' '));
879
+ };
880
+ const testStr = c.testString ?? getSource(c.test);
881
+ classParts.push(`(${testStr} ? ${processBranch(c.truthy)} : ${processBranch(c.falsy)})`);
882
+ });
883
+ const indepVarGroups = {};
884
+ indepConditionals.forEach((c) => {
885
+ if (c.groupId !== undefined) {
886
+ if (!indepVarGroups[c.groupId])
887
+ indepVarGroups[c.groupId] = [];
888
+ indepVarGroups[c.groupId].push(c);
889
+ }
890
+ });
891
+ Object.values(indepVarGroups).forEach((options) => {
892
+ const commonTestExpr = options[0].testLHS ??
893
+ options[0].testString ??
894
+ getSource(options[0].test);
895
+ const lookupMap = {};
896
+ options.forEach((opt) => {
897
+ if (opt.valueName && opt.truthy) {
898
+ const className = getStyleRecords(opt.truthy)
899
+ .map((r) => r.hash)
900
+ .join(' ');
901
+ if (className)
902
+ lookupMap[opt.valueName] = className;
903
+ }
904
+ });
905
+ if (Object.keys(lookupMap).length > 0) {
906
+ const entries = Object.entries(lookupMap)
907
+ .map(([k, v]) => `"${k}":"${v}"`)
908
+ .join(',');
909
+ classParts.push(`({${entries}}[${commonTestExpr}] || "")`);
910
+ }
911
+ });
912
+ if (Object.keys(baseConflict).length > 0 ||
913
+ conflictConditionals.length > 0) {
914
+ const dimensions = [];
915
+ conflictConditionals
916
+ .filter((c) => c.groupId === undefined)
917
+ .forEach((c) => {
918
+ dimensions.push({
919
+ type: 'std',
920
+ testExpr: c.testString ?? getSource(c.test),
921
+ options: [
922
+ { value: 0, style: c.falsy, label: 'false' },
923
+ { value: 1, style: c.truthy, label: 'true' },
924
+ ],
925
+ });
926
+ });
927
+ const conflictVarGroups = {};
928
+ conflictConditionals.forEach((c) => {
929
+ if (c.groupId !== undefined) {
930
+ if (!conflictVarGroups[c.groupId])
931
+ conflictVarGroups[c.groupId] = [];
932
+ conflictVarGroups[c.groupId].push(c);
933
+ }
934
+ });
935
+ Object.entries(conflictVarGroups).forEach(([, opts]) => {
936
+ dimensions.push({
937
+ type: 'var',
938
+ testExpr: opts[0].testLHS ??
939
+ opts[0].testString ??
940
+ getSource(opts[0].test),
941
+ options: opts.map((opt) => ({
942
+ value: opt.valueName,
943
+ style: opt.truthy,
944
+ label: opt.valueName || 'default',
945
+ })),
946
+ });
947
+ });
948
+ const results = {};
949
+ const recurse = (dimIndex, currentStyle, keyParts) => {
950
+ if (dimIndex >= dimensions.length) {
951
+ const className = getStyleRecords(currentStyle)
952
+ .map((r) => r.hash)
953
+ .join(' ');
954
+ if (className)
955
+ results[keyParts.join('__')] = className;
956
+ return;
957
+ }
958
+ dimensions[dimIndex].options.forEach((opt) => recurse(dimIndex + 1, deepMerge(currentStyle, opt.style), [
959
+ ...keyParts,
960
+ String(opt.value),
961
+ ]));
962
+ };
963
+ recurse(0, baseConflict, []);
964
+ const baseConflictClass = Object.keys(baseConflict).length > 0
965
+ ? getStyleRecords(baseConflict)
966
+ .map((r) => r.hash)
967
+ .join(' ')
968
+ : '';
969
+ const masterKeyExpr = dimensions
970
+ .map((dim) => dim.type === 'std'
971
+ ? `(${dim.testExpr} ? "1" : "0")`
972
+ : dim.testExpr || '""')
973
+ .join(' + "__" + ');
974
+ classParts.push(`(${JSON.stringify(results)}[${masterKeyExpr || '""'}] || ${baseConflictClass ? JSON.stringify(baseConflictClass) : '""'})`);
975
+ }
976
+ classParts.push(...dynamicClassParts);
977
+ return { classParts, isOptimizable, baseStyle };
978
+ };
537
979
  traverse(ast, {
538
980
  JSXOpeningElement({ node }) {
539
981
  jsxOpeningElementMap.set(node.span.start, node.attributes);
@@ -664,7 +1106,7 @@ export function plumeria(options = {}) {
664
1106
  if (!node.value || node.value.type !== 'JSXExpressionContainer')
665
1107
  return;
666
1108
  const expr = node.value.expression;
667
- const args = expr.type === 'ArrayExpression'
1109
+ let args = expr.type === 'ArrayExpression'
668
1110
  ? expr.elements
669
1111
  .filter(Boolean)
670
1112
  .map((el) => ({ expression: el.expression ?? el }))
@@ -708,668 +1150,105 @@ export function plumeria(options = {}) {
708
1150
  dynamicStyleParts.push(stripped);
709
1151
  }
710
1152
  }
711
- const resolveStyleObject = (expr) => {
712
- if (t.isObjectExpression(expr)) {
713
- return objectExpressionToObject(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
714
- }
715
- else if (t.isMemberExpression(expr) &&
716
- t.isIdentifier(expr.object) &&
717
- (t.isIdentifier(expr.property) ||
718
- expr.property.type === 'Computed')) {
719
- if (expr.property.type === 'Computed') {
720
- return {};
721
- }
722
- const varName = expr.object.value;
723
- const propName = expr.property.value;
724
- const styleInfo = localCreateStyles[varName];
725
- if (styleInfo && styleInfo.obj[propName]) {
726
- const style = styleInfo.obj[propName];
727
- if (typeof style === 'object' && style !== null) {
728
- return style;
729
- }
730
- }
731
- const hash = mergedCreateTable[varName];
732
- if (hash) {
733
- const obj = scannedTables.createObjectTable[hash];
734
- if (obj && obj[propName]) {
735
- const style = obj[propName];
736
- if (typeof style === 'object' && style !== null) {
737
- return style;
738
- }
739
- }
740
- }
741
- }
742
- else if (t.isIdentifier(expr)) {
743
- const varName = expr.value;
744
- const uniqueKey = `${resourcePath}-${varName}`;
745
- let hash = scannedTables.createHashTable[uniqueKey];
746
- if (!hash) {
747
- hash = mergedCreateTable[varName];
748
- }
749
- if (hash) {
750
- const obj = scannedTables.createObjectTable[hash];
751
- if (obj && typeof obj === 'object') {
752
- return obj;
753
- }
754
- }
755
- const styleInfo = localCreateStyles[varName];
756
- if (styleInfo && styleInfo.obj) {
757
- return styleInfo.obj;
758
- }
759
- if (localCreateStyles[varName]) {
760
- return localCreateStyles[varName].obj;
761
- }
762
- const vHash = mergedVariantsTable[varName];
763
- if (vHash) {
764
- return scannedTables.variantsObjectTable[vHash];
765
- }
766
- }
767
- return null;
768
- };
769
- const conditionals = [];
770
- let groupIdCounter = 0;
771
- let baseStyle = {};
772
- let isOptimizable = true;
773
- for (const arg of args) {
1153
+ args = args.filter((arg) => {
774
1154
  const expr = arg.expression;
775
- if (t.isCallExpression(expr) &&
776
- t.isMemberExpression(expr.callee)) {
777
- const callee = expr.callee;
778
- if (t.isIdentifier(callee.object) &&
779
- t.isIdentifier(callee.property)) {
780
- const varName = callee.object.value;
781
- const propKey = callee.property.value;
782
- const styleInfo = localCreateStyles[varName];
783
- const atomMap = styleInfo?.hashMap?.[propKey];
784
- if (atomMap?.['__cssVars__']) {
785
- const cssVarInfo = JSON.parse(atomMap['__cssVars__']);
786
- const hashes = Object.entries(atomMap)
787
- .filter(([k]) => k !== '__cssVars__')
788
- .map(([, v]) => v)
789
- .join(' ');
790
- if (hashes)
791
- dynamicClassParts.push(JSON.stringify(hashes));
792
- const args = expr.arguments;
793
- Object.entries(cssVarInfo).forEach(([_, { cssVar, propKey: targetProp }], i) => {
794
- const callArg = args[i];
795
- if (!callArg)
796
- return;
797
- const argStart = callArg.expression.span.start - baseByteOffset;
798
- const argEnd = callArg.expression.span.end - baseByteOffset;
799
- const argSource = sourceBuffer
800
- .subarray(argStart, argEnd)
801
- .toString('utf-8');
802
- let valueExpr;
803
- try {
804
- const maybeNumber = Number(argSource);
805
- if (!isNaN(maybeNumber) &&
806
- argSource.trim() === String(maybeNumber)) {
807
- const processed = applyCssValue(maybeNumber, targetProp);
808
- valueExpr = JSON.stringify(processed);
809
- }
810
- else if (argSource.startsWith('"') &&
811
- argSource.endsWith('"')) {
812
- const processed = applyCssValue(argSource.slice(1, -1), targetProp);
813
- valueExpr = JSON.stringify(processed);
814
- }
815
- else {
816
- const exception = [
817
- 'animationIterationCount',
818
- 'aspectRatio',
819
- 'columnCount',
820
- 'columns',
821
- 'fillOpacity',
822
- 'flex',
823
- 'flexGrow',
824
- 'flexShrink',
825
- 'floodOpacity',
826
- 'fontSizeAdjust',
827
- 'fontWeight',
828
- 'gridColumn',
829
- 'gridColumnEnd',
830
- 'gridColumnStart',
831
- 'gridRow',
832
- 'gridRowEnd',
833
- 'gridRowStart',
834
- 'hyphenateLimitChars',
835
- 'initialLetter',
836
- 'lineHeight',
837
- 'mathDepth',
838
- 'opacity',
839
- 'order',
840
- 'orphans',
841
- 'scale',
842
- 'shapeImageThreshold',
843
- 'stopOpacity',
844
- 'strokeMiterlimit',
845
- 'strokeOpacity',
846
- 'tabSize',
847
- 'widows',
848
- 'zIndex',
849
- 'zoom',
850
- ];
851
- if (!exception.includes(targetProp)) {
852
- valueExpr = `(typeof ${argSource} === 'number' ? ${argSource} + 'px' : ${argSource})`;
853
- }
854
- else {
855
- valueExpr = argSource;
856
- }
857
- }
858
- }
859
- catch {
860
- valueExpr = argSource;
861
- }
862
- dynamicStyleParts.push(`"${cssVar}": ${valueExpr}`);
863
- });
864
- continue;
865
- }
866
- }
867
- }
868
- if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
869
- const varName = expr.callee.value;
870
- let variantObj;
871
- const uniqueKey = `${resourcePath}-${varName}`;
872
- let hash = scannedTables.variantsHashTable[uniqueKey];
873
- if (!hash) {
874
- hash = mergedVariantsTable[varName];
875
- }
876
- if (hash && scannedTables.variantsObjectTable[hash]) {
877
- variantObj = scannedTables.variantsObjectTable[hash];
878
- }
879
- if (!variantObj) {
880
- if (localCreateStyles[varName] &&
881
- localCreateStyles[varName].obj) {
882
- variantObj = localCreateStyles[varName].obj;
883
- }
884
- }
885
- if (variantObj) {
886
- const callArgs = expr.arguments;
887
- if (callArgs.length === 1 && !callArgs[0].spread) {
888
- const arg = callArgs[0].expression;
889
- if (arg.type === 'ObjectExpression') {
890
- for (const prop of arg.properties) {
891
- let groupName;
892
- let valExpr;
893
- if (prop.type === 'KeyValueProperty' &&
894
- prop.key.type === 'Identifier') {
895
- groupName = prop.key.value;
896
- valExpr = prop.value;
897
- }
898
- else if (prop.type === 'Identifier') {
899
- groupName = prop.value;
900
- valExpr = prop;
901
- }
902
- if (groupName && valExpr) {
903
- const groupVariants = variantObj[groupName];
904
- if (!groupVariants)
905
- continue;
906
- const currentGroupId = ++groupIdCounter;
907
- const valStart = valExpr.span.start - baseByteOffset;
908
- const valEnd = valExpr.span.end - baseByteOffset;
909
- const valSource = sourceBuffer
910
- .subarray(valStart, valEnd)
911
- .toString('utf-8');
912
- if (valExpr.type === 'StringLiteral') {
913
- if (groupVariants[valExpr.value]) {
914
- baseStyle = deepMerge(baseStyle, groupVariants[valExpr.value]);
915
- }
916
- continue;
917
- }
918
- Object.entries(groupVariants).forEach(([optionName, style]) => {
919
- conditionals.push({
920
- test: valExpr,
921
- testLHS: valSource,
922
- testString: `${valSource} === '${optionName}'`,
923
- truthy: style,
924
- falsy: {},
925
- groupId: currentGroupId,
926
- groupName,
927
- valueName: optionName,
928
- varName,
929
- });
930
- });
931
- }
932
- }
933
- continue;
934
- }
935
- const argStart = arg.span.start - baseByteOffset;
936
- const argEnd = arg.span.end - baseByteOffset;
937
- const argSource = sourceBuffer
938
- .subarray(argStart, argEnd)
939
- .toString('utf-8');
940
- if (t.isStringLiteral(arg)) {
941
- if (variantObj[arg.value]) {
942
- baseStyle = deepMerge(baseStyle, variantObj[arg.value]);
943
- }
944
- continue;
945
- }
946
- const currentGroupId = ++groupIdCounter;
947
- Object.entries(variantObj).forEach(([key, style]) => {
948
- conditionals.push({
949
- test: arg,
950
- testLHS: argSource,
951
- testString: `${argSource} === '${key}'`,
952
- truthy: style,
953
- falsy: {},
954
- groupId: currentGroupId,
955
- groupName: undefined,
956
- valueName: key,
957
- varName,
958
- });
959
- });
960
- continue;
961
- }
962
- isOptimizable = false;
963
- break;
964
- }
965
- }
966
- else if (t.isIdentifier(expr)) {
967
- const varName = expr.value;
968
- let variantObj;
969
- const uniqueKey = `${resourcePath}-${varName}`;
970
- let hash = scannedTables.variantsHashTable[uniqueKey];
971
- if (!hash) {
972
- hash = mergedVariantsTable[varName];
973
- }
974
- if (hash && scannedTables.variantsObjectTable[hash]) {
975
- variantObj = scannedTables.variantsObjectTable[hash];
976
- }
977
- if (!variantObj) {
978
- if (localCreateStyles[varName] &&
979
- localCreateStyles[varName].obj) {
980
- variantObj = localCreateStyles[varName].obj;
981
- }
982
- }
983
- if (variantObj) {
984
- Object.entries(variantObj).forEach(([groupName, groupVariants]) => {
985
- if (!groupVariants)
986
- return;
987
- const currentGroupId = ++groupIdCounter;
988
- Object.entries(groupVariants).forEach(([optionName, style]) => {
989
- conditionals.push({
990
- test: expr,
991
- testLHS: `props["${groupName}"]`,
992
- testString: `props["${groupName}"] === '${optionName}'`,
993
- truthy: style,
994
- falsy: {},
995
- groupId: currentGroupId,
996
- groupName: groupName,
997
- valueName: optionName,
998
- varName: varName,
999
- });
1000
- });
1001
- });
1002
- continue;
1003
- }
1004
- }
1005
- const getSource = (node) => {
1006
- const start = node.span.start - baseByteOffset;
1007
- const end = node.span.end - baseByteOffset;
1008
- return sourceBuffer.subarray(start, end).toString('utf-8');
1009
- };
1010
- const collectConditions = (node, currentTestStrings = []) => {
1011
- const staticStyle = resolveStyleObject(node);
1012
- if (staticStyle) {
1013
- if (currentTestStrings.length === 0) {
1014
- baseStyle = deepMerge(baseStyle, staticStyle);
1015
- }
1016
- else {
1017
- const combinedTest = currentTestStrings.join(' && ');
1018
- conditionals.push({
1019
- test: node,
1020
- testString: combinedTest,
1021
- truthy: staticStyle,
1022
- falsy: {},
1023
- varName: undefined,
1024
- });
1025
- }
1026
- return true;
1027
- }
1028
- if (node.type === 'ConditionalExpression') {
1029
- const testSource = getSource(node.test);
1030
- if (currentTestStrings.length === 0) {
1031
- const trueStyle = resolveStyleObject(node.consequent);
1032
- const falseStyle = resolveStyleObject(node.alternate);
1033
- if (trueStyle && falseStyle) {
1034
- conditionals.push({
1035
- test: node,
1036
- testString: testSource,
1037
- truthy: trueStyle,
1038
- falsy: falseStyle,
1039
- varName: undefined,
1040
- });
1041
- return true;
1042
- }
1043
- }
1044
- collectConditions(node.consequent, [
1045
- ...currentTestStrings,
1046
- `(${testSource})`,
1047
- ]);
1048
- collectConditions(node.alternate, [
1049
- ...currentTestStrings,
1050
- `!(${testSource})`,
1051
- ]);
1052
- return true;
1155
+ if (!t.isCallExpression(expr) || !t.isMemberExpression(expr.callee))
1156
+ return true;
1157
+ const callee = expr.callee;
1158
+ if (!t.isIdentifier(callee.object) ||
1159
+ !t.isIdentifier(callee.property))
1160
+ return true;
1161
+ const varName = callee.object.value;
1162
+ const propKey = callee.property.value;
1163
+ const styleInfo = localCreateStyles[varName];
1164
+ const atomMap = styleInfo?.hashMap?.[propKey];
1165
+ if (!atomMap?.['__cssVars__'])
1166
+ return true;
1167
+ const cssVarInfo = JSON.parse(atomMap['__cssVars__']);
1168
+ const hashes = Object.entries(atomMap)
1169
+ .filter(([k]) => k !== '__cssVars__')
1170
+ .map(([, v]) => v)
1171
+ .join(' ');
1172
+ if (hashes)
1173
+ dynamicClassParts.push(JSON.stringify(hashes));
1174
+ const callArgs = expr.arguments;
1175
+ Object.entries(cssVarInfo).forEach(([_, { cssVar, propKey: targetProp }], i) => {
1176
+ const callArg = callArgs[i];
1177
+ if (!callArg)
1178
+ return;
1179
+ const argStart = callArg.expression.span.start - baseByteOffset;
1180
+ const argEnd = callArg.expression.span.end - baseByteOffset;
1181
+ const argSource = sourceBuffer
1182
+ .subarray(argStart, argEnd)
1183
+ .toString('utf-8');
1184
+ let valueExpr;
1185
+ const maybeNumber = Number(argSource);
1186
+ if (!isNaN(maybeNumber) &&
1187
+ argSource.trim() === String(maybeNumber)) {
1188
+ valueExpr = JSON.stringify(applyCssValue(maybeNumber, targetProp));
1053
1189
  }
1054
- else if (node.type === 'BinaryExpression' &&
1055
- node.operator === '&&') {
1056
- const leftSource = getSource(node.left);
1057
- collectConditions(node.right, [
1058
- ...currentTestStrings,
1059
- `(${leftSource})`,
1060
- ]);
1061
- return true;
1190
+ else if (argSource.startsWith('"') &&
1191
+ argSource.endsWith('"')) {
1192
+ valueExpr = JSON.stringify(applyCssValue(argSource.slice(1, -1), targetProp));
1062
1193
  }
1063
- else if (node.type === 'ParenthesisExpression') {
1064
- return collectConditions(node.expression, currentTestStrings);
1194
+ else {
1195
+ const exception = [
1196
+ 'animationIterationCount',
1197
+ 'aspectRatio',
1198
+ 'columnCount',
1199
+ 'columns',
1200
+ 'fillOpacity',
1201
+ 'flex',
1202
+ 'flexGrow',
1203
+ 'flexShrink',
1204
+ 'floodOpacity',
1205
+ 'fontSizeAdjust',
1206
+ 'fontWeight',
1207
+ 'gridColumn',
1208
+ 'gridColumnEnd',
1209
+ 'gridColumnStart',
1210
+ 'gridRow',
1211
+ 'gridRowEnd',
1212
+ 'gridRowStart',
1213
+ 'hyphenateLimitChars',
1214
+ 'initialLetter',
1215
+ 'lineHeight',
1216
+ 'mathDepth',
1217
+ 'opacity',
1218
+ 'order',
1219
+ 'orphans',
1220
+ 'scale',
1221
+ 'shapeImageThreshold',
1222
+ 'stopOpacity',
1223
+ 'strokeMiterlimit',
1224
+ 'strokeOpacity',
1225
+ 'tabSize',
1226
+ 'widows',
1227
+ 'zIndex',
1228
+ 'zoom',
1229
+ ];
1230
+ valueExpr = exception.includes(targetProp)
1231
+ ? argSource
1232
+ : `(typeof ${argSource} === 'number' ? ${argSource} + 'px' : ${argSource})`;
1065
1233
  }
1066
- return false;
1067
- };
1068
- const handled = collectConditions(expr);
1069
- if (handled)
1070
- continue;
1071
- isOptimizable = false;
1072
- break;
1073
- }
1234
+ dynamicStyleParts.push(`"${cssVar}": ${valueExpr}`);
1235
+ });
1236
+ return false;
1237
+ });
1074
1238
  const styleAttr = dynamicStyleParts.length > 0
1075
1239
  ? ` style={{${dynamicStyleParts.join(', ')}}}`
1076
1240
  : '';
1241
+ const { classParts, isOptimizable, baseStyle } = buildClassParts(args, dynamicClassParts, existingClass);
1077
1242
  if (isOptimizable &&
1078
- (args.length > 0 || Object.keys(baseStyle).length > 0)) {
1079
- if (conditionals.length === 0) {
1080
- const records = getStyleRecords(baseStyle);
1081
- const staticClass = records
1082
- .map((r) => r.hash)
1083
- .join(' ');
1084
- const allParts = [
1085
- ...(existingClass ? [JSON.stringify(existingClass)] : []),
1086
- ...(staticClass ? [JSON.stringify(staticClass)] : []),
1087
- ...dynamicClassParts,
1088
- ].join(' + " " + ');
1089
- replacements.push({
1090
- start: node.span.start - baseByteOffset,
1091
- end: node.span.end - baseByteOffset,
1092
- content: `className={${allParts || '""'}}${styleAttr}`,
1093
- });
1094
- }
1095
- else {
1096
- const propertyCounts = {};
1097
- const addCounts = (style) => {
1098
- Object.keys(style).forEach((key) => {
1099
- propertyCounts[key] = (propertyCounts[key] || 0) + 1;
1100
- });
1101
- };
1102
- addCounts(baseStyle);
1103
- const participation = {};
1104
- const registerParticipation = (style, sourceId) => {
1105
- Object.keys(style).forEach((key) => {
1106
- if (!participation[key])
1107
- participation[key] = new Set();
1108
- participation[key].add(sourceId);
1109
- });
1110
- };
1111
- registerParticipation(baseStyle, 'base');
1112
- conditionals
1113
- .filter((c) => c.groupId === undefined)
1114
- .forEach((c, idx) => {
1115
- const sourceId = `std_${idx}`;
1116
- registerParticipation(c.truthy, sourceId);
1117
- registerParticipation(c.falsy, sourceId);
1118
- });
1119
- const variantGroups = {};
1120
- conditionals.forEach((c) => {
1121
- if (c.groupId !== undefined) {
1122
- if (!variantGroups[c.groupId])
1123
- variantGroups[c.groupId] = [];
1124
- variantGroups[c.groupId].push(c);
1125
- }
1126
- });
1127
- Object.entries(variantGroups).forEach(([groupId, opts]) => {
1128
- const sourceId = `var_${groupId}`;
1129
- opts.forEach((opt) => {
1130
- registerParticipation(opt.truthy, sourceId);
1131
- registerParticipation(opt.falsy, sourceId);
1132
- });
1133
- });
1134
- const conflictingKeys = new Set();
1135
- Object.entries(participation).forEach(([key, sources]) => {
1136
- if (sources.size > 1) {
1137
- conflictingKeys.add(key);
1138
- }
1139
- });
1140
- const baseIndependent = {};
1141
- const baseConflict = {};
1142
- Object.entries(baseStyle).forEach(([key, val]) => {
1143
- if (conflictingKeys.has(key)) {
1144
- baseConflict[key] = val;
1145
- }
1146
- else {
1147
- baseIndependent[key] = val;
1148
- }
1149
- });
1150
- const indepConditionals = [];
1151
- const conflictConditionals = [];
1152
- const splitConditional = (c) => {
1153
- const truthyIndep = {};
1154
- const truthyConf = {};
1155
- const falsyIndep = {};
1156
- const falsyConf = {};
1157
- let hasIndep = false;
1158
- let hasConf = false;
1159
- Object.entries(c.truthy).forEach(([k, v]) => {
1160
- if (conflictingKeys.has(k)) {
1161
- truthyConf[k] = v;
1162
- hasConf = true;
1163
- }
1164
- else {
1165
- truthyIndep[k] = v;
1166
- hasIndep = true;
1167
- }
1168
- });
1169
- Object.entries(c.falsy).forEach(([k, v]) => {
1170
- if (conflictingKeys.has(k)) {
1171
- falsyConf[k] = v;
1172
- hasConf = true;
1173
- }
1174
- else {
1175
- falsyIndep[k] = v;
1176
- hasIndep = true;
1177
- }
1178
- });
1179
- if (hasIndep) {
1180
- indepConditionals.push({
1181
- ...c,
1182
- truthy: truthyIndep,
1183
- falsy: falsyIndep,
1184
- });
1185
- }
1186
- if (hasConf) {
1187
- conflictConditionals.push({
1188
- ...c,
1189
- truthy: truthyConf,
1190
- falsy: falsyConf,
1191
- });
1192
- }
1193
- };
1194
- conditionals.forEach(splitConditional);
1195
- const classParts = [];
1196
- if (existingClass)
1197
- classParts.push(JSON.stringify(existingClass));
1198
- if (Object.keys(baseIndependent).length > 0) {
1199
- const records = getStyleRecords(baseIndependent);
1200
- const className = records.map((r) => r.hash).join(' ');
1201
- if (className)
1202
- classParts.push(JSON.stringify(className));
1203
- }
1204
- const indepStd = indepConditionals.filter((c) => c.groupId === undefined);
1205
- indepStd.forEach((c) => {
1206
- const processBranch = (style) => {
1207
- if (Object.keys(style).length === 0)
1208
- return '""';
1209
- const records = getStyleRecords(style);
1210
- return JSON.stringify(records.map((r) => r.hash).join(' '));
1211
- };
1212
- const tClass = processBranch(c.truthy);
1213
- const fClass = processBranch(c.falsy);
1214
- let testStr = c.testString;
1215
- if (!testStr && c.test) {
1216
- const start = c.test.span.start - baseByteOffset;
1217
- const end = c.test.span.end - baseByteOffset;
1218
- testStr = sourceBuffer.subarray(start, end).toString('utf-8');
1219
- }
1220
- classParts.push(`(${testStr} ? ${tClass} : ${fClass})`);
1221
- });
1222
- const indepVarGroups = {};
1223
- indepConditionals.forEach((c) => {
1224
- if (c.groupId !== undefined) {
1225
- if (!indepVarGroups[c.groupId])
1226
- indepVarGroups[c.groupId] = [];
1227
- indepVarGroups[c.groupId].push(c);
1228
- }
1229
- });
1230
- Object.values(indepVarGroups).forEach((options) => {
1231
- let commonTestExpr = null;
1232
- const lookupMap = {};
1233
- if (options.length > 0) {
1234
- if (options[0].testLHS) {
1235
- commonTestExpr = options[0].testLHS;
1236
- }
1237
- else if (options[0].testString) {
1238
- commonTestExpr = options[0].testString;
1239
- }
1240
- else {
1241
- const firstTest = options[0].test;
1242
- const firstStart = firstTest.span.start - baseByteOffset;
1243
- const firstEnd = firstTest.span.end - baseByteOffset;
1244
- commonTestExpr = sourceBuffer
1245
- .subarray(firstStart, firstEnd)
1246
- .toString('utf-8');
1247
- }
1248
- options.forEach((opt) => {
1249
- if (opt.valueName && opt.truthy) {
1250
- const records = getStyleRecords(opt.truthy);
1251
- const className = records.map((r) => r.hash).join(' ');
1252
- if (className) {
1253
- lookupMap[opt.valueName] = className;
1254
- }
1255
- }
1256
- });
1257
- }
1258
- if (commonTestExpr && Object.keys(lookupMap).length > 0) {
1259
- const entries = Object.entries(lookupMap)
1260
- .map(([key, val]) => `"${key}":"${val}"`)
1261
- .join(',');
1262
- classParts.push(`({${entries}}[${commonTestExpr}] || "")`);
1263
- }
1264
- });
1265
- if (Object.keys(baseConflict).length > 0 ||
1266
- conflictConditionals.length > 0) {
1267
- const conflictStd = conflictConditionals.filter((c) => c.groupId === undefined);
1268
- const conflictVarGroups = {};
1269
- conflictConditionals.forEach((c) => {
1270
- if (c.groupId !== undefined) {
1271
- if (!conflictVarGroups[c.groupId])
1272
- conflictVarGroups[c.groupId] = [];
1273
- conflictVarGroups[c.groupId].push(c);
1274
- }
1275
- });
1276
- const dimensions = [];
1277
- conflictStd.forEach((c) => {
1278
- let testStr = c.testString;
1279
- if (!testStr && c.test) {
1280
- const start = c.test.span.start - baseByteOffset;
1281
- const end = c.test.span.end - baseByteOffset;
1282
- testStr = sourceBuffer
1283
- .subarray(start, end)
1284
- .toString('utf-8');
1285
- }
1286
- dimensions.push({
1287
- type: 'std',
1288
- testExpr: testStr,
1289
- options: [
1290
- { value: 0, style: c.falsy, label: 'false' },
1291
- { value: 1, style: c.truthy, label: 'true' },
1292
- ],
1293
- });
1294
- });
1295
- Object.entries(conflictVarGroups).forEach(([_groupId, opts]) => {
1296
- let commonTestExpr = null;
1297
- if (opts.length > 0) {
1298
- if (opts[0].testLHS) {
1299
- commonTestExpr = opts[0].testLHS;
1300
- }
1301
- else if (opts[0].testString) {
1302
- commonTestExpr = opts[0].testString;
1303
- }
1304
- else {
1305
- const firstTest = opts[0].test;
1306
- const firstStart = firstTest.span.start - baseByteOffset;
1307
- const firstEnd = firstTest.span.end - baseByteOffset;
1308
- commonTestExpr = sourceBuffer
1309
- .subarray(firstStart, firstEnd)
1310
- .toString('utf-8');
1311
- }
1312
- }
1313
- const options = opts.map((opt) => ({
1314
- value: opt.valueName,
1315
- style: opt.truthy,
1316
- label: opt.valueName || 'default',
1317
- }));
1318
- dimensions.push({
1319
- type: 'var',
1320
- testExpr: commonTestExpr || '""',
1321
- options: options,
1322
- });
1323
- });
1324
- const results = {};
1325
- const recurse = (dimIndex, currentStyle, keyParts) => {
1326
- if (dimIndex >= dimensions.length) {
1327
- const records = getStyleRecords(currentStyle);
1328
- const className = records.map((r) => r.hash).join(' ');
1329
- const finalKey = keyParts.join('__');
1330
- if (className)
1331
- results[finalKey] = className;
1332
- return;
1333
- }
1334
- const dim = dimensions[dimIndex];
1335
- dim.options.forEach((opt) => {
1336
- const nextStyle = deepMerge(currentStyle, opt.style);
1337
- recurse(dimIndex + 1, nextStyle, [
1338
- ...keyParts,
1339
- String(opt.value),
1340
- ]);
1341
- });
1342
- };
1343
- recurse(0, baseConflict, []);
1344
- let baseConflictClass = '';
1345
- if (Object.keys(baseConflict).length > 0) {
1346
- const records = getStyleRecords(baseConflict);
1347
- baseConflictClass = records.map((r) => r.hash).join(' ');
1348
- }
1349
- const keyExprs = [];
1350
- dimensions.forEach((dim) => {
1351
- if (dim.type === 'std') {
1352
- keyExprs.push(`(${dim.testExpr} ? "1" : "0")`);
1353
- }
1354
- else {
1355
- keyExprs.push(dim.testExpr || '""');
1356
- }
1357
- });
1358
- const masterKeyExpr = keyExprs.length > 0 ? keyExprs.join(' + "__" + ') : '""';
1359
- const tableJson = JSON.stringify(results);
1360
- const fallback = baseConflictClass
1361
- ? JSON.stringify(baseConflictClass)
1362
- : '""';
1363
- classParts.push(`(${tableJson}[${masterKeyExpr}] || ${fallback})`);
1364
- }
1365
- classParts.push(...dynamicClassParts);
1366
- const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
1367
- replacements.push({
1368
- start: node.span.start - baseByteOffset,
1369
- end: node.span.end - baseByteOffset,
1370
- content: `className={${replacement}}${styleAttr}`,
1371
- });
1372
- }
1243
+ (args.length > 0 ||
1244
+ Object.keys(baseStyle).length > 0 ||
1245
+ dynamicClassParts.length > 0)) {
1246
+ const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
1247
+ replacements.push({
1248
+ start: node.span.start - baseByteOffset,
1249
+ end: node.span.end - baseByteOffset,
1250
+ content: `className={${replacement}}${styleAttr}`,
1251
+ });
1373
1252
  }
1374
1253
  else {
1375
1254
  replacements.push({
@@ -1379,6 +1258,56 @@ export function plumeria(options = {}) {
1379
1258
  });
1380
1259
  }
1381
1260
  },
1261
+ CallExpression({ node }) {
1262
+ const callee = node.callee;
1263
+ let isUseCall = false;
1264
+ if (t.isMemberExpression(callee) &&
1265
+ t.isIdentifier(callee.object) &&
1266
+ t.isIdentifier(callee.property)) {
1267
+ const objectName = callee.object.value;
1268
+ const propertyName = callee.property.value;
1269
+ const alias = plumeriaAliases[objectName];
1270
+ if (alias === 'NAMESPACE' && propertyName === 'use') {
1271
+ isUseCall = true;
1272
+ }
1273
+ }
1274
+ else if (t.isIdentifier(callee)) {
1275
+ const calleeName = callee.value;
1276
+ const originalName = plumeriaAliases[calleeName];
1277
+ if (originalName === 'use') {
1278
+ isUseCall = true;
1279
+ }
1280
+ }
1281
+ if (!isUseCall)
1282
+ return;
1283
+ const args = node.arguments;
1284
+ for (const arg of args) {
1285
+ const expr = arg.expression;
1286
+ if (!t.isCallExpression(expr) || !t.isMemberExpression(expr.callee))
1287
+ continue;
1288
+ const callee = expr.callee;
1289
+ if (!t.isIdentifier(callee.object) ||
1290
+ !t.isIdentifier(callee.property))
1291
+ continue;
1292
+ const varName = callee.object.value;
1293
+ const propKey = callee.property.value;
1294
+ const styleInfo = localCreateStyles[varName];
1295
+ const atomMap = styleInfo?.hashMap?.[propKey];
1296
+ if (atomMap?.['__cssVars__']) {
1297
+ throw new Error(`Plumeria: css.use(${getSource(expr)}) does not support dynamic function keys.\n`);
1298
+ }
1299
+ }
1300
+ const { classParts, isOptimizable, baseStyle } = buildClassParts(args);
1301
+ if (isOptimizable &&
1302
+ (args.length > 0 || Object.keys(baseStyle).length > 0)) {
1303
+ const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
1304
+ replacements.push({
1305
+ start: node.span.start - baseByteOffset,
1306
+ end: node.span.end - baseByteOffset,
1307
+ content: replacement,
1308
+ });
1309
+ }
1310
+ },
1382
1311
  });
1383
1312
  Object.values(localCreateStyles).forEach((info) => {
1384
1313
  if (info.type === 'constant') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/vite-plugin",
3
- "version": "10.0.1",
3
+ "version": "10.0.2",
4
4
  "type": "module",
5
5
  "description": "Plumeria Vite plugin",
6
6
  "author": "Refirst 11",
@@ -22,7 +22,7 @@
22
22
  "dist/"
23
23
  ],
24
24
  "dependencies": {
25
- "@plumeria/utils": "^10.0.1"
25
+ "@plumeria/utils": "^10.0.2"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@swc/core": "1.15.18",