11import { getCommonRadius } from "../../common/commonRadius" ;
22import { commonStroke } from "../../common/commonStroke" ;
3- import { nearestValue , pxToBorderRadius } from "../conversionTables" ;
3+ import {
4+ nearestValue ,
5+ pxToBorderRadius ,
6+ pxToBorderWidth ,
7+ pxToRing ,
8+ } from "../conversionTables" ;
9+ import { numberToFixedString } from "../../common/numToAutoFixed" ;
10+ import { addWarning } from "../../common/commonConversionWarnings" ;
11+
12+ const getBorder = ( weight : number , kind : string , isRing : boolean = false ) => {
13+ // Use ring utilities for outside strokes
14+ if ( isRing ) {
15+ // Special case: ring (without width) is 3px in Tailwind
16+ if ( weight === 3 ) {
17+ return "ring" ;
18+ }
19+
20+ const ringWidth = pxToRing ( weight ) ;
21+ if ( ringWidth === null ) {
22+ return `ring-[${ numberToFixedString ( weight ) } px]` ;
23+ } else if ( ringWidth === "3" ) {
24+ // Ring is 3px
25+ return `ring` ;
26+ } else {
27+ return `ring-${ ringWidth } ` ;
28+ }
29+ }
30+
31+ // Special case: border (without width) is 1px in Tailwind
32+ if ( weight === 1 ) {
33+ return `border${ kind } ` ;
34+ }
35+
36+ // Use border utilities for default and inside strokes
37+ const borderWidth = pxToBorderWidth ( weight ) ;
38+ if ( borderWidth === null ) {
39+ return `border${ kind } -[${ numberToFixedString ( weight ) } px]` ;
40+ } else if ( borderWidth === "DEFAULT" ) {
41+ // Border is 1px
42+ return `border${ kind } ` ;
43+ } else {
44+ return `border${ kind } -${ borderWidth } ` ;
45+ }
46+ } ;
447
548/**
649 * https://tailwindcss.com/docs/border-width/
750 * example: border-2
851 */
9- export const tailwindBorderWidth = ( node : SceneNode ) : string => {
52+ export const tailwindBorderWidth = (
53+ node : SceneNode ,
54+ ) : {
55+ isRing : boolean ;
56+ property : string ;
57+ } => {
1058 const commonBorder = commonStroke ( node ) ;
1159 if ( ! commonBorder ) {
12- return "" ;
60+ return {
61+ isRing : false ,
62+ property : "" ,
63+ } ;
1364 }
1465
15- const getBorder = ( weight : number , kind : string ) => {
16- const allowedValues = [ 1 , 2 , 4 , 8 ] ;
17- console . log ( "weight" , weight ) ;
18- const nearest = nearestValue ( weight , allowedValues ) ;
19- console . log ( "nearest" , nearest ) ;
20-
21- if ( nearest === 1 ) {
22- // special case
23- return `border${ kind } ` ;
24- } else {
25- return `border${ kind } -${ nearest } ` ;
26- }
27- } ;
66+ // Check if stroke is outside
67+ const isRing =
68+ "strokeAlign" in node &&
69+ ( node . strokeAlign === "OUTSIDE" || node . strokeAlign === "CENTER" ) ;
2870
2971 if ( "all" in commonBorder ) {
3072 if ( commonBorder . all === 0 ) {
31- return "" ;
73+ return {
74+ isRing : false ,
75+ property : "" ,
76+ } ;
3277 }
33- return getBorder ( commonBorder . all , "" ) ;
78+ return {
79+ isRing,
80+ property : getBorder ( commonBorder . all , "" , isRing ) ,
81+ } ;
82+ } else {
83+ addWarning (
84+ 'Non-uniform borders are only supported with strokeAlign set to "inside". Will paint inside.' ,
85+ ) ;
3486 }
3587
88+ // If borders are non-uniform, always use border utilities for better control
89+ // regardless of whether the stroke is outside or not
3690 const comp = [ ] ;
3791 if ( commonBorder . left !== 0 ) {
3892 comp . push ( getBorder ( commonBorder . left , "-l" ) ) ;
@@ -46,7 +100,11 @@ export const tailwindBorderWidth = (node: SceneNode): string => {
46100 if ( commonBorder . bottom !== 0 ) {
47101 comp . push ( getBorder ( commonBorder . bottom , "-b" ) ) ;
48102 }
49- return comp . join ( " " ) ;
103+
104+ return {
105+ isRing,
106+ property : comp . join ( " " ) ,
107+ } ;
50108} ;
51109
52110/**
0 commit comments