Skip to content

Commit d504c3b

Browse files
committed
fix: at-rule is not converted if base rule is not defined
1 parent 1776231 commit d504c3b

File tree

7 files changed

+601
-783
lines changed

7 files changed

+601
-783
lines changed

src/TailwindConverter.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,22 +180,27 @@ export class TailwindConverter {
180180
): TailwindNode {
181181
let { baseSelector, classPrefix } = this.parseSelector(rule.selector);
182182

183-
const containerClassPrefix = this.convertContainerToClassPrefix(
183+
const classPrefixByParentNodes = this.convertContainerToClassPrefix(
184184
rule.parent
185185
);
186186

187-
if (containerClassPrefix) {
187+
if (classPrefixByParentNodes) {
188188
return {
189189
key: baseSelector,
190+
rootRuleSelector: baseSelector,
190191
originalRule: rule,
191-
classesPrefix: containerClassPrefix + classPrefix,
192+
classesPrefix: classPrefixByParentNodes + classPrefix,
192193
tailwindClasses,
193194
};
194195
}
195196

196197
if (classPrefix) {
198+
const key = TailwindNodesManager.convertRuleToKey(rule, baseSelector);
199+
const isRootRule = key === baseSelector;
200+
197201
return {
198-
key: TailwindNodesManager.convertRuleToKey(rule, baseSelector),
202+
key: key,
203+
rootRuleSelector: isRootRule ? baseSelector : null,
199204
originalRule: rule,
200205
classesPrefix: classPrefix,
201206
tailwindClasses,

src/TailwindNodesManager.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface ResolvedTailwindNode {
99

1010
export interface UnresolvedTailwindNode {
1111
key: string;
12+
rootRuleSelector?: string | null;
1213
originalRule: Rule;
1314
classesPrefix: string;
1415
tailwindClasses: string[];
@@ -60,18 +61,23 @@ export class TailwindNodesManager {
6061
if (nodeIsResolved) {
6162
this.nodesMap.set(nodeKey, node);
6263
} else {
63-
const newRule = new Rule({
64-
// TODO: CONVERT NODE KEY TO RULE!!
65-
selector: nodeKey,
66-
});
67-
68-
const rootChild = this.upToRootChild(node.originalRule);
69-
if (rootChild) {
70-
node.originalRule.root().insertBefore(rootChild, newRule);
64+
let rule;
65+
66+
if (node.rootRuleSelector) {
67+
rule = new Rule({
68+
selector: node.rootRuleSelector,
69+
});
70+
71+
const rootChild = this.upToRootChild(node.originalRule);
72+
if (rootChild) {
73+
node.originalRule.root().insertBefore(rootChild, rule);
74+
}
75+
} else {
76+
rule = node.originalRule;
7177
}
7278

7379
this.nodesMap.set(nodeKey, {
74-
rule: newRule,
80+
rule,
7581
tailwindClasses: node.tailwindClasses.map(
7682
className => `${node.classesPrefix}${className}`
7783
),

test/TailwindConverter.spec.ts

Lines changed: 129 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -258,17 +258,13 @@ describe('TailwindConverter', () => {
258258
{
259259
rule: expect.objectContaining({ selector: '.foo' }),
260260
tailwindClasses: [
261-
'accent-custom-color-gold',
262-
'content-center',
263-
'items-start',
261+
'md:accent-custom-color-gold',
264262
'animate-spin',
265-
'appearance-none',
266263
'aspect-video',
267264
'content-center',
268265
'content-end',
269266
'portrait:text-[black]',
270267
"after:content-['*']",
271-
'after:select-text',
272268
'after:align-text-top',
273269
'after:origin-top',
274270
'hidden:delay-150',
@@ -277,67 +273,20 @@ describe('TailwindConverter', () => {
277273
'hidden:ease-in',
278274
],
279275
},
280-
{
281-
rule: expect.objectContaining({
282-
selector: ".foo [aria-role='button']",
283-
}),
284-
tailwindClasses: [
285-
'uppercase',
286-
'underline-offset-[1rem]',
287-
'touch-pan-left',
288-
'origin-bottom-right',
289-
'transition-none',
290-
'top-3',
291-
],
292-
},
293-
{
294-
rule: expect.objectContaining({
295-
selector: ".foo[aria-hidden='false']",
296-
}),
297-
tailwindClasses: [
298-
'collapse',
299-
'whitespace-pre-line',
300-
'w-6/12',
301-
'will-change-transform',
302-
'break-all',
303-
'z-40',
304-
'translate-x-3',
305-
'translate-y-[-0.5em]',
306-
'skew-x-1',
307-
'skew-y-3',
308-
'rotate-[-0.25turn]',
309-
'transition-colors',
310-
'duration-200',
311-
'ease-out',
312-
'-scale-x-75',
313-
'scale-y-105',
314-
],
315-
},
316-
{
317-
rule: expect.objectContaining({ selector: '.foo .bar' }),
318-
tailwindClasses: [
319-
'translate-x-[10px_0.625rem]',
320-
'skew-x-2',
321-
'-rotate-45',
322-
'pl-[12%]',
323-
'pr-[100vw]',
324-
'pt-64',
325-
'pb-1',
326-
'px-6',
327-
'py-8',
328-
'-scale-75',
329-
],
330-
},
331276
{
332277
rule: expect.objectContaining({ selector: '.foo .baz' }),
333278
tailwindClasses: [
279+
'md:text-center',
334280
'place-content-around',
335281
'place-items-center',
336282
'place-self-stretch',
337283
'pointer-events-auto',
338284
'relative',
339285
'resize-x',
340286
'-right-32',
287+
'lg:backdrop-brightness-90',
288+
'lg:backdrop-sepia-[25%]',
289+
'lg:backdrop-blur-none',
341290
'motion-safe:custom-screen:supports-flex:order-[-123]',
342291
'motion-safe:custom-screen:supports-flex:tracking-[0.25rem]',
343292
'motion-safe:custom-screen:supports-flex:leading-snug',
@@ -369,58 +318,19 @@ describe('TailwindConverter', () => {
369318
'supports-[scroll-snap-align:end]:scroll-p-[100px]',
370319
],
371320
},
372-
{
373-
rule: expect.objectContaining({ selector: '.foo .baz > .foo-bar' }),
374-
tailwindClasses: [
375-
'text-left',
376-
'text-[length:var(--some-size)]',
377-
'text-[color:var(--some-color)]',
378-
'active:focus:break-after-avoid',
379-
'active:focus:break-before-left',
380-
'active:focus:break-inside-auto',
381-
'xl:isolate',
382-
'xl:justify-center',
383-
'xl:active:text-sky-800',
384-
'xl:active:focus:justify-items-start',
385-
'xl:active:focus:justify-self-end',
386-
'motion-safe:custom-screen:supports-flex:opacity-20',
387-
'motion-safe:custom-screen:supports-flex:-order-last',
388-
'motion-safe:custom-screen:supports-flex:outline-lime-600',
389-
'motion-safe:custom-screen:supports-flex:outline-offset-2',
390-
'motion-safe:custom-screen:supports-flex:outline-dotted',
391-
'motion-safe:custom-screen:supports-flex:outline-2',
392-
'motion-safe:custom-screen:supports-flex:overflow-hidden',
393-
'motion-safe:custom-screen:supports-flex:break-words',
394-
'motion-safe:custom-screen:supports-flex:overflow-x-scroll',
395-
'motion-safe:custom-screen:supports-flex:overflow-y-visible',
396-
'motion-safe:custom-screen:supports-flex:overscroll-contain',
397-
'motion-safe:custom-screen:supports-flex:overscroll-x-auto',
398-
'motion-safe:custom-screen:supports-flex:overscroll-y-none',
399-
],
400-
},
401-
{
402-
rule: expect.objectContaining({ selector: '.foo div > [data-zoo]' }),
403-
tailwindClasses: [
404-
'border',
405-
'pl-[25%]',
406-
'pr-[1.5em]',
407-
'pt-0',
408-
'pb-px',
409-
'bottom-full',
410-
],
411-
},
412321
{
413322
rule: expect.objectContaining({ selector: '.bar' }),
414323
tailwindClasses: [
415-
'backdrop-brightness-90',
416-
'backdrop-sepia-[25%]',
417-
'backdrop-blur-none',
418-
'animate-[some-animation_2s_linear_infinite]',
419-
'origin-[12%_25.5%]',
420-
'ease-[cubic-bezier(0.23,0,0.25,1)]',
324+
'md:content-center',
325+
'md:items-start',
421326
'lg:backdrop-brightness-75',
422327
'lg:backdrop-sepia',
423328
'lg:bg-local',
329+
'lg:content-end',
330+
'lg:items-center',
331+
'animate-[some-animation_2s_linear_infinite]',
332+
'origin-[12%_25.5%]',
333+
'ease-[cubic-bezier(0.23,0,0.25,1)]',
424334
'lg:bg-blend-difference',
425335
'lg:bg-clip-padding',
426336
'lg:bg-[hsl(30,51%,22%)]',
@@ -488,23 +398,126 @@ describe('TailwindConverter', () => {
488398
'xl:font-semibold',
489399
],
490400
},
401+
{
402+
rule: expect.objectContaining({ selector: '.foo' }),
403+
tailwindClasses: [
404+
'appearance-none',
405+
'disabled:opacity-0',
406+
'disabled:invisible',
407+
'disabled:select-none',
408+
],
409+
},
410+
{
411+
rule: expect.objectContaining({ selector: '.foo[some-attribute]' }),
412+
tailwindClasses: ['select-text'],
413+
},
414+
{
415+
rule: expect.objectContaining({
416+
selector: ".foo [aria-role='button']",
417+
}),
418+
tailwindClasses: [
419+
'uppercase',
420+
'underline-offset-[1rem]',
421+
'touch-pan-left',
422+
'origin-bottom-right',
423+
'transition-none',
424+
],
425+
},
426+
{
427+
rule: expect.objectContaining({
428+
selector: ".foo[aria-hidden='false']",
429+
}),
430+
tailwindClasses: [
431+
'collapse',
432+
'whitespace-pre-line',
433+
'w-6/12',
434+
'will-change-transform',
435+
'break-all',
436+
'z-40',
437+
'translate-x-3',
438+
'translate-y-[-0.5em]',
439+
'skew-x-1',
440+
'skew-y-3',
441+
'rotate-[-0.25turn]',
442+
'transition-colors',
443+
'duration-200',
444+
'ease-out',
445+
'-scale-x-75',
446+
'scale-y-105',
447+
],
448+
},
449+
{
450+
rule: expect.objectContaining({ selector: '.foo .bar' }),
451+
tailwindClasses: [
452+
'translate-x-[10px_0.625rem]',
453+
'skew-x-2',
454+
'-rotate-45',
455+
'pl-[12%]',
456+
'pr-[100vw]',
457+
'pt-64',
458+
'pb-1',
459+
'px-6',
460+
'py-8',
461+
'-scale-75',
462+
],
463+
},
464+
{
465+
rule: expect.objectContaining({ selector: '.foo .baz > .foo-bar' }),
466+
tailwindClasses: [
467+
'text-left',
468+
'text-[length:var(--some-size)]',
469+
'text-[color:var(--some-color)]',
470+
'active:focus:break-after-avoid',
471+
'active:focus:break-before-left',
472+
'active:focus:break-inside-auto',
473+
'xl:isolate',
474+
'xl:justify-center',
475+
'xl:active:text-sky-800',
476+
'xl:active:focus:justify-items-start',
477+
'xl:active:focus:justify-self-end',
478+
'motion-safe:custom-screen:supports-flex:opacity-20',
479+
'motion-safe:custom-screen:supports-flex:-order-last',
480+
'motion-safe:custom-screen:supports-flex:outline-lime-600',
481+
'motion-safe:custom-screen:supports-flex:outline-offset-2',
482+
'motion-safe:custom-screen:supports-flex:outline-dotted',
483+
'motion-safe:custom-screen:supports-flex:outline-2',
484+
'motion-safe:custom-screen:supports-flex:overflow-hidden',
485+
'motion-safe:custom-screen:supports-flex:break-words',
486+
'motion-safe:custom-screen:supports-flex:overflow-x-scroll',
487+
'motion-safe:custom-screen:supports-flex:overflow-y-visible',
488+
'motion-safe:custom-screen:supports-flex:overscroll-contain',
489+
'motion-safe:custom-screen:supports-flex:overscroll-x-auto',
490+
'motion-safe:custom-screen:supports-flex:overscroll-y-none',
491+
],
492+
},
493+
{
494+
rule: expect.objectContaining({ selector: '.foo div > [data-zoo]' }),
495+
tailwindClasses: [
496+
'border',
497+
'pl-[25%]',
498+
'pr-[1.5em]',
499+
'pt-0',
500+
'pb-px',
501+
'bottom-full',
502+
],
503+
},
491504
{
492505
rule: expect.objectContaining({ selector: '.loving .bar > .testing' }),
493506
tailwindClasses: [
494-
"bg-[url('/some-path/to/large\\_image.jpg')]",
495-
'border-custom-color-gold',
496-
'border-b-custom-color-200',
497-
'border-b-[length:var(--some-size)]',
498-
'border-neutral-600',
499-
'border-t-custom-color-400',
500-
'rounded-br-sm',
501-
'rounded-bl',
502-
'border-b-[2em]',
503-
'border-b-[#ff0000]',
504-
'border-4',
505-
'border-solid',
506-
'border-dashed',
507-
'border-separate',
507+
"lg:bg-[url('/some-path/to/large\\_image.jpg')]",
508+
'lg:border-custom-color-gold',
509+
'lg:border-b-custom-color-200',
510+
'lg:border-b-[length:var(--some-size)]',
511+
'lg:border-neutral-600',
512+
'lg:border-t-custom-color-400',
513+
'lg:rounded-br-sm',
514+
'lg:rounded-bl',
515+
'lg:border-b-[2em]',
516+
'lg:border-b-[#ff0000]',
517+
'lg:border-4',
518+
'lg:border-solid',
519+
'lg:border-dashed',
520+
'lg:border-separate',
508521
],
509522
},
510523
{

0 commit comments

Comments
 (0)