@mgcrea/react-native-tailwind 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +21 -22
  2. package/dist/babel/index.cjs +342 -17
  3. package/dist/babel/plugin/state.d.ts +4 -0
  4. package/dist/babel/plugin/state.ts +8 -0
  5. package/dist/babel/plugin/visitors/className.test.ts +313 -0
  6. package/dist/babel/plugin/visitors/className.ts +36 -8
  7. package/dist/babel/plugin/visitors/imports.ts +16 -1
  8. package/dist/babel/plugin/visitors/program.ts +19 -2
  9. package/dist/babel/plugin/visitors/tw.test.ts +151 -0
  10. package/dist/babel/utils/directionalModifierProcessing.d.ts +34 -0
  11. package/dist/babel/utils/directionalModifierProcessing.ts +99 -0
  12. package/dist/babel/utils/styleInjection.d.ts +16 -0
  13. package/dist/babel/utils/styleInjection.ts +138 -7
  14. package/dist/babel/utils/twProcessing.d.ts +2 -0
  15. package/dist/babel/utils/twProcessing.ts +92 -3
  16. package/dist/parser/borders.js +1 -1
  17. package/dist/parser/borders.test.js +1 -1
  18. package/dist/parser/index.d.ts +2 -2
  19. package/dist/parser/index.js +1 -1
  20. package/dist/parser/layout.js +1 -1
  21. package/dist/parser/layout.test.js +1 -1
  22. package/dist/parser/modifiers.d.ts +32 -2
  23. package/dist/parser/modifiers.js +1 -1
  24. package/dist/parser/modifiers.test.js +1 -1
  25. package/dist/parser/spacing.d.ts +1 -1
  26. package/dist/parser/spacing.js +1 -1
  27. package/dist/parser/spacing.test.js +1 -1
  28. package/dist/parser/typography.test.js +1 -1
  29. package/dist/runtime.cjs +1 -1
  30. package/dist/runtime.cjs.map +3 -3
  31. package/dist/runtime.js +1 -1
  32. package/dist/runtime.js.map +3 -3
  33. package/package.json +6 -6
  34. package/src/babel/plugin/state.ts +8 -0
  35. package/src/babel/plugin/visitors/className.test.ts +313 -0
  36. package/src/babel/plugin/visitors/className.ts +36 -8
  37. package/src/babel/plugin/visitors/imports.ts +16 -1
  38. package/src/babel/plugin/visitors/program.ts +19 -2
  39. package/src/babel/plugin/visitors/tw.test.ts +151 -0
  40. package/src/babel/utils/directionalModifierProcessing.ts +99 -0
  41. package/src/babel/utils/styleInjection.ts +138 -7
  42. package/src/babel/utils/twProcessing.ts +92 -3
  43. package/src/parser/borders.test.ts +104 -0
  44. package/src/parser/borders.ts +50 -7
  45. package/src/parser/index.ts +2 -0
  46. package/src/parser/layout.test.ts +74 -0
  47. package/src/parser/layout.ts +94 -0
  48. package/src/parser/modifiers.test.ts +206 -0
  49. package/src/parser/modifiers.ts +62 -3
  50. package/src/parser/spacing.test.ts +66 -0
  51. package/src/parser/spacing.ts +15 -5
  52. package/src/parser/typography.test.ts +8 -0
  53. package/src/parser/typography.ts +4 -0
@@ -349,3 +349,69 @@ describe("parseSpacing - comprehensive coverage", () => {
349
349
  expect(parseSpacing("pl-[50px]")).toEqual({ paddingLeft: 50 });
350
350
  });
351
351
  });
352
+
353
+ describe("parseSpacing - logical margin (RTL-aware)", () => {
354
+ it("should parse margin start", () => {
355
+ expect(parseSpacing("ms-0")).toEqual({ marginStart: 0 });
356
+ expect(parseSpacing("ms-4")).toEqual({ marginStart: 16 });
357
+ expect(parseSpacing("ms-8")).toEqual({ marginStart: 32 });
358
+ });
359
+
360
+ it("should parse margin end", () => {
361
+ expect(parseSpacing("me-0")).toEqual({ marginEnd: 0 });
362
+ expect(parseSpacing("me-4")).toEqual({ marginEnd: 16 });
363
+ expect(parseSpacing("me-8")).toEqual({ marginEnd: 32 });
364
+ });
365
+
366
+ it("should parse margin start/end with fractional values", () => {
367
+ expect(parseSpacing("ms-0.5")).toEqual({ marginStart: 2 });
368
+ expect(parseSpacing("me-1.5")).toEqual({ marginEnd: 6 });
369
+ expect(parseSpacing("ms-2.5")).toEqual({ marginStart: 10 });
370
+ });
371
+
372
+ it("should parse margin start/end with arbitrary values", () => {
373
+ expect(parseSpacing("ms-[16px]")).toEqual({ marginStart: 16 });
374
+ expect(parseSpacing("ms-[16]")).toEqual({ marginStart: 16 });
375
+ expect(parseSpacing("me-[24px]")).toEqual({ marginEnd: 24 });
376
+ expect(parseSpacing("me-[24]")).toEqual({ marginEnd: 24 });
377
+ });
378
+
379
+ it("should parse negative margin start/end", () => {
380
+ expect(parseSpacing("-ms-4")).toEqual({ marginStart: -16 });
381
+ expect(parseSpacing("-me-4")).toEqual({ marginEnd: -16 });
382
+ expect(parseSpacing("-ms-8")).toEqual({ marginStart: -32 });
383
+ expect(parseSpacing("-me-8")).toEqual({ marginEnd: -32 });
384
+ });
385
+
386
+ it("should parse negative margin start/end with arbitrary values", () => {
387
+ expect(parseSpacing("-ms-[16px]")).toEqual({ marginStart: -16 });
388
+ expect(parseSpacing("-me-[24]")).toEqual({ marginEnd: -24 });
389
+ });
390
+ });
391
+
392
+ describe("parseSpacing - logical padding (RTL-aware)", () => {
393
+ it("should parse padding start", () => {
394
+ expect(parseSpacing("ps-0")).toEqual({ paddingStart: 0 });
395
+ expect(parseSpacing("ps-4")).toEqual({ paddingStart: 16 });
396
+ expect(parseSpacing("ps-8")).toEqual({ paddingStart: 32 });
397
+ });
398
+
399
+ it("should parse padding end", () => {
400
+ expect(parseSpacing("pe-0")).toEqual({ paddingEnd: 0 });
401
+ expect(parseSpacing("pe-4")).toEqual({ paddingEnd: 16 });
402
+ expect(parseSpacing("pe-8")).toEqual({ paddingEnd: 32 });
403
+ });
404
+
405
+ it("should parse padding start/end with fractional values", () => {
406
+ expect(parseSpacing("ps-0.5")).toEqual({ paddingStart: 2 });
407
+ expect(parseSpacing("pe-1.5")).toEqual({ paddingEnd: 6 });
408
+ expect(parseSpacing("ps-2.5")).toEqual({ paddingStart: 10 });
409
+ });
410
+
411
+ it("should parse padding start/end with arbitrary values", () => {
412
+ expect(parseSpacing("ps-[16px]")).toEqual({ paddingStart: 16 });
413
+ expect(parseSpacing("ps-[16]")).toEqual({ paddingStart: 16 });
414
+ expect(parseSpacing("pe-[24px]")).toEqual({ paddingEnd: 24 });
415
+ expect(parseSpacing("pe-[24]")).toEqual({ paddingEnd: 24 });
416
+ });
417
+ });
@@ -69,12 +69,13 @@ function parseArbitrarySpacing(value: string): number | null {
69
69
 
70
70
  /**
71
71
  * Parse spacing classes (margin, padding, gap)
72
- * Examples: m-4, mx-2, mt-8, p-4, px-2, pt-8, gap-4, m-[16px], pl-[4.5px], -m-4, -mt-[10px]
72
+ * Examples: m-4, mx-2, mt-8, p-4, px-2, pt-8, gap-4, m-[16px], pl-[4.5px], -m-4, -mt-[10px], ms-4, pe-2
73
73
  */
74
74
  export function parseSpacing(cls: string): StyleObject | null {
75
- // Margin: m-4, mx-2, mt-8, m-[16px], -m-4, -mt-2, etc.
75
+ // Margin: m-4, mx-2, mt-8, ms-4, me-2, m-[16px], -m-4, -mt-2, etc.
76
76
  // Supports negative values for margins (but not padding or gap)
77
- const marginMatch = cls.match(/^(-?)m([xytrbls]?)-(.+)$/);
77
+ // s = start (RTL-aware), e = end (RTL-aware)
78
+ const marginMatch = cls.match(/^(-?)m([xytrblse]?)-(.+)$/);
78
79
  if (marginMatch) {
79
80
  const [, negativePrefix, dir, valueStr] = marginMatch;
80
81
  const isNegative = negativePrefix === "-";
@@ -94,8 +95,9 @@ export function parseSpacing(cls: string): StyleObject | null {
94
95
  }
95
96
  }
96
97
 
97
- // Padding: p-4, px-2, pt-8, p-[16px], etc.
98
- const paddingMatch = cls.match(/^p([xytrbls]?)-(.+)$/);
98
+ // Padding: p-4, px-2, pt-8, ps-4, pe-2, p-[16px], etc.
99
+ // s = start (RTL-aware), e = end (RTL-aware)
100
+ const paddingMatch = cls.match(/^p([xytrblse]?)-(.+)$/);
99
101
  if (paddingMatch) {
100
102
  const [, dir, valueStr] = paddingMatch;
101
103
 
@@ -152,6 +154,10 @@ function getMarginStyle(dir: string, value: number): StyleObject {
152
154
  return { marginBottom: value };
153
155
  case "l":
154
156
  return { marginLeft: value };
157
+ case "s":
158
+ return { marginStart: value };
159
+ case "e":
160
+ return { marginEnd: value };
155
161
  default:
156
162
  return {};
157
163
  }
@@ -176,6 +182,10 @@ function getPaddingStyle(dir: string, value: number): StyleObject {
176
182
  return { paddingBottom: value };
177
183
  case "l":
178
184
  return { paddingLeft: value };
185
+ case "s":
186
+ return { paddingStart: value };
187
+ case "e":
188
+ return { paddingEnd: value };
179
189
  default:
180
190
  return {};
181
191
  }
@@ -91,6 +91,14 @@ describe("parseTypography - text alignment", () => {
91
91
  expect(parseTypography("text-right")).toEqual({ textAlign: "right" });
92
92
  expect(parseTypography("text-justify")).toEqual({ textAlign: "justify" });
93
93
  });
94
+
95
+ it("should not parse text-start/text-end (handled via directional modifier expansion)", () => {
96
+ // text-start/text-end are now handled by splitModifierClasses() in modifiers.ts
97
+ // They expand to ltr:text-left rtl:text-right and ltr:text-right rtl:text-left
98
+ // respectively for true RTL support
99
+ expect(parseTypography("text-start")).toBeNull();
100
+ expect(parseTypography("text-end")).toBeNull();
101
+ });
94
102
  });
95
103
 
96
104
  describe("parseTypography - text decoration", () => {
@@ -58,6 +58,10 @@ const FONT_STYLE_MAP: Record<string, StyleObject> = {
58
58
  };
59
59
 
60
60
  // Text alignment utilities
61
+ // Note: text-start and text-end are handled via automatic expansion to directional modifiers
62
+ // in splitModifierClasses() for true RTL support:
63
+ // text-start -> ltr:text-left rtl:text-right
64
+ // text-end -> ltr:text-right rtl:text-left
61
65
  const TEXT_ALIGN_MAP: Record<string, StyleObject> = {
62
66
  "text-left": { textAlign: "left" },
63
67
  "text-center": { textAlign: "center" },