@@ -4,6 +4,7 @@ import { rgbaToHex } from '../utils/rgba-to-hex'
44import { styleNameToTypography } from '../utils/style-name-to-typography'
55import { textSegmentToTypography } from '../utils/text-segment-to-typography'
66import { toCamel } from '../utils/to-camel'
7+ import { uploadFile } from '../utils/upload-file'
78import { variableAliasToValue } from '../utils/variable-alias-to-value'
89import { type Devup , DevupTypography } from './types'
910import { getDevupColorCollection } from './utils/get-devup-color-collection'
@@ -132,3 +133,106 @@ export async function exportDevup() {
132133
133134 return downloadFile ( 'devup.json' , JSON . stringify ( devup ) )
134135}
136+
137+ export async function importDevup ( ) {
138+ const devup : Devup = JSON . parse ( await uploadFile ( '.json' ) )
139+ if ( devup . theme ?. colors ) {
140+ const collection = ( await getDevupColorCollection ( ) ) ?? ( await figma . variables . createVariableCollection ( 'Devup Colors' ) )
141+ const themes = new Set ( )
142+ const colors = new Set ( )
143+ for ( const [ theme , value ] of Object . entries ( devup . theme . colors ) ) {
144+ const modeId = collection . modes . find ( ( mode ) => mode . name === theme ) ?. modeId ?? collection . addMode ( theme )
145+
146+ const variables = await figma . variables . getLocalVariablesAsync ( )
147+ for ( const [ colorKey , colorValue ] of Object . entries ( value ) ) {
148+ const variable = variables . find ( ( variable ) => variable . name === colorKey ) ?? figma . variables . createVariable ( colorKey , collection , 'COLOR' )
149+
150+ variable . setValueForMode ( modeId , figma . util . rgba ( colorValue ) )
151+ colors . add ( colorKey )
152+ }
153+ themes . add ( theme )
154+ }
155+ for ( const theme of collection . modes . filter ( ( mode ) => ! themes . has ( mode . name ) ) )
156+ collection . removeMode ( theme . modeId )
157+
158+ const variables = await figma . variables . getLocalVariablesAsync ( )
159+ for ( const variable of variables . filter ( ( variable ) => ! colors . has ( variable . name ) ) )
160+ variable . remove ( )
161+ }
162+ if ( devup . theme ?. typography ) {
163+ const styles = await figma . getLocalTextStylesAsync ( )
164+ for ( const [ style , value ] of Object . entries ( devup . theme . typography ) ) {
165+ const targetStyleNames :[ target :string , typography :DevupTypography ] [ ] = [ ]
166+ if ( Array . isArray ( value ) ) {
167+ for ( const v in value ) {
168+ if ( v && value [ v ] ) {
169+
170+ targetStyleNames . push ( [ `${ {
171+ 0 : 'mobile' ,
172+ 2 : 'tablet' ,
173+ 4 : 'desktop' ,
174+ } [ v ] } /${ style } `, value [ v ] ] )
175+ }
176+ }
177+ } else {
178+ targetStyleNames . push ( [ `mobile/${ style } ` , value ] )
179+ }
180+
181+ for ( const [ target , typography ] of targetStyleNames ) {
182+ const st = styles . find ( ( s ) => s . name === target ) ?? figma . createTextStyle ( )
183+ st . name = target
184+
185+ if ( typography . fontWeight || typography . fontStyle ) {
186+ const fontFamily = {
187+ family : typography . fontFamily ?? "Inter" ,
188+ style : typography . fontStyle == 'italic' ? 'Italic' : 'Regular' ,
189+ }
190+ await figma . loadFontAsync ( fontFamily )
191+ st . fontName = fontFamily
192+ }
193+ if ( typography . fontSize ) {
194+ st . fontSize = parseInt ( typography . fontSize )
195+ }
196+ if ( typography . letterSpacing ) {
197+ if ( typography . letterSpacing . endsWith ( 'em' ) ) {
198+
199+ st . letterSpacing = {
200+ unit : 'PERCENT' ,
201+ value : parseFloat ( typography . letterSpacing ) ,
202+ }
203+ } else {
204+ st . letterSpacing = {
205+ unit : 'PIXELS' ,
206+ value : parseFloat ( typography . letterSpacing ) * 100 ,
207+ }
208+ }
209+ }
210+ if ( typography . lineHeight ) {
211+ if ( typography . lineHeight === 'normal' ) {
212+ st . lineHeight = {
213+ unit : 'AUTO' ,
214+ }
215+ } else {
216+ if ( typeof typography . lineHeight === 'string' ) {
217+ st . lineHeight = {
218+ unit : 'PIXELS' ,
219+ value : parseInt ( typography . lineHeight ) ,
220+ }
221+ } else {
222+ st . lineHeight = {
223+ unit : 'PERCENT' ,
224+ value : Math . round ( typography . lineHeight / 10 ) / 10 ,
225+ }
226+ }
227+ }
228+ }
229+ if ( typography . textTransform ) {
230+ st . textCase = typography . textTransform . toUpperCase ( ) as TextCase
231+ }
232+ if ( typography . textDecoration ) {
233+ st . textDecoration = typography . textDecoration . toUpperCase ( ) as TextDecoration
234+ }
235+ }
236+ }
237+ }
238+ }
0 commit comments