@designid/tokens 1.2.15 → 1.2.16

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.
@@ -0,0 +1,2 @@
1
+ figma.showUI(__html__,{width:800,height:600,themeColors:!0});(async()=>{let K=await figma.variables.getLocalVariableCollectionsAsync();figma.ui.postMessage({type:"init",payload:{documentName:figma.root.name,collections:K}})})();figma.ui.onmessage=async(K)=>{switch(K.type){case"load-tokens":await i(K.payload&&K.payload.config);break;case"sync-tokens":await t(K.payload.tokens,K.payload&&K.payload.config);break;case"fix-broken-references":await a(K.payload.tokens,K.payload&&K.payload.config);break;case"export-tokens":await o();break;case"find-replace-variables":await n(K.payload);break;case"find-replace-pattern":await r(K.payload);break;case"get-available-variables":await l();break;case"close":figma.closePlugin();break;default:console.warn("Unknown message type:",K.type)}};async function i(K){try{let J=K&&K.basePixelSize||16,Q=await p(J);figma.ui.postMessage({type:"tokens-loaded",payload:{tokens:Q}})}catch(J){figma.ui.postMessage({type:"error",payload:{message:`Failed to load tokens: ${J&&J.message?J.message:String(J)}`}})}}async function t(K,J){try{figma.ui.postMessage({type:"sync-progress",payload:{message:"Starting sync...",progress:0}});let Q=J&&J.basePixelSize||16,Z=J&&J.collectionName||"@DesignID Tokens",Y=v(K),X=await m(Z,Y),$=await JJ(K,X,Q);figma.ui.postMessage({type:"sync-complete",payload:{message:"Tokens synced successfully!",result:$}}),figma.notify("✓ Tokens synced successfully!")}catch(Q){figma.ui.postMessage({type:"error",payload:{message:`Sync failed: ${Q&&Q.message?Q.message:String(Q)}`}}),figma.notify("✗ Sync failed. Check console for details.")}}async function n(K){try{let{searchVariableId:J,replaceVariableId:Q,applyToWholePage:Z}=K;figma.ui.postMessage({type:"find-replace-progress",payload:{message:"Searching for variable references..."}});let Y=await figma.variables.getVariableByIdAsync(J),X=await figma.variables.getVariableByIdAsync(Q);if(!Y||!X)throw Error("One or both variables not found");let $=[];if(Z)await figma.currentPage.loadAsync(),$=[figma.currentPage];else{if(figma.currentPage.selection.length===0)throw Error('No nodes selected. Please select nodes or choose "Apply to whole page"');$=[...figma.currentPage.selection]}let A=0,H=0;async function _(G){if(H++,"boundVariables"in G&&G.boundVariables)for(let[q,D]of Object.entries(G.boundVariables)){if(!D)continue;let B=Array.isArray(D)?D:[D];for(let E of B){if(!E||typeof E!=="object"||!("id"in E))continue;if(E.id===J)try{G.setBoundVariable(q,Q),A++}catch(M){console.warn(`Failed to replace variable on property ${q}:`,M)}}}if("fills"in G&&G.fills!==figma.mixed&&Array.isArray(G.fills)){let q=[...G.fills],D=!1;for(let B=0;B<q.length;B++){let E=q[B];if(E.type==="SOLID"&&"boundVariables"in E&&E.boundVariables){if(E.boundVariables.color&&"id"in E.boundVariables.color){if(E.boundVariables.color.id===J)try{G.setBoundVariable("fills",Q),A++,D=!0;break}catch(M){console.warn("Failed to replace fill variable:",M)}}}}}if("strokes"in G&&Array.isArray(G.strokes))for(let q=0;q<G.strokes.length;q++){let D=G.strokes[q];if(D.type==="SOLID"&&"boundVariables"in D&&D.boundVariables){if(D.boundVariables.color&&"id"in D.boundVariables.color){if(D.boundVariables.color.id===J)try{G.setBoundVariable("strokes",Q),A++;break}catch(B){console.warn("Failed to replace stroke variable:",B)}}}}if("children"in G)for(let q of G.children)await _(q)}for(let G of $)await _(G);let L=A>0?`✓ Replaced ${A} variable reference${A>1?"s":""} (scanned ${H} nodes)`:`No references to "${Y.name}" found (scanned ${H} nodes)`;figma.ui.postMessage({type:"find-replace-complete",payload:{message:L,replacedCount:A,scannedCount:H}}),figma.notify(L)}catch(J){let Q=`Find/Replace failed: ${J&&J.message?J.message:String(J)}`;figma.ui.postMessage({type:"error",payload:{message:Q}}),figma.notify("✗ "+Q)}}async function r(K){try{let{searchPattern:J,replacePattern:Q,applyToWholePage:Z,libraryCollectionName:Y}=K;figma.ui.postMessage({type:"find-replace-progress",payload:{message:"Finding matching variables..."}});let X=await figma.variables.getLocalVariableCollectionsAsync(),$=new RegExp(J),A=null;if(Y){if(A=X.find((W)=>W.name===Y)||null,!A)A=X.find((W)=>W.name.toLowerCase()===Y.toLowerCase())||null;if(!A)A=X.find((W)=>W.name.includes(Y)||Y.includes(W.name))||null}let H=new Map,_=A?[A]:X;for(let W of _)for(let U of W.variableIds){let j=await figma.variables.getVariableByIdAsync(U);if(j)H.set(j.id,j)}let L=new Map;if(Y)try{figma.ui.postMessage({type:"find-replace-progress",payload:{message:"Loading library collection..."}});let W=await figma.teamLibrary.getAvailableLibraryVariableCollectionsAsync(),U=W.find((j)=>j.name===Y);if(!U)U=W.find((j)=>j.name.toLowerCase()===Y.toLowerCase());if(!U)U=W.find((j)=>j.name.includes(Y)||Y.includes(j.name));if(U)figma.ui.postMessage({type:"find-replace-progress",payload:{message:`Loading variables from "${U.name}"...`}}),(await figma.teamLibrary.getVariablesInLibraryCollectionAsync(U.key)).forEach((O)=>{L.set(O.name,O)})}catch(W){console.error("Error accessing team library:",W)}figma.ui.postMessage({type:"find-replace-progress",payload:{message:"Scanning for variables in use..."}});let G=[];if(Z)G=[figma.currentPage];else{if(figma.currentPage.selection.length===0)throw Error('No nodes selected. Please select nodes or choose "Apply to whole page"');G=[...figma.currentPage.selection]}let q=new Set;async function D(W){if("boundVariables"in W&&W.boundVariables)for(let U in W.boundVariables){let j=W.boundVariables[U];if(Array.isArray(j))j.forEach((O)=>O&&O.id&&q.add(O.id));else if(j&&j.id)q.add(j.id)}if("fills"in W&&W.fills!==figma.mixed&&Array.isArray(W.fills)){for(let U of W.fills)if(U.boundVariables)for(let j in U.boundVariables){let O=U.boundVariables[j];if(O&&O.id)q.add(O.id)}}if("strokes"in W&&Array.isArray(W.strokes)){for(let U of W.strokes)if(U.boundVariables)for(let j in U.boundVariables){let O=U.boundVariables[j];if(O&&O.id)q.add(O.id)}}if("effects"in W&&Array.isArray(W.effects)){for(let U of W.effects)if(U.boundVariables)for(let j in U.boundVariables){let O=U.boundVariables[j];if(O&&O.id)q.add(O.id)}}if("children"in W)for(let U of W.children)await D(U)}for(let W of G)await D(W);figma.ui.postMessage({type:"find-replace-progress",payload:{message:"Building replacement map..."}});let B=new Map;for(let W of q){let U=await figma.variables.getVariableByIdAsync(W);if(!U)continue;if($.test(U.name)){let j=U.name.replace($,Q),O=L.get(j);if(O)try{let N=await figma.variables.importVariableByKeyAsync(O.key);if(N)B.set(W,N.id)}catch(N){console.error("Failed to import variable:",N)}}}if(B.size===0){let W=`No replacements found. Either no variables in use match the pattern "${J}" or their replacements don't exist in the library collection.`;figma.ui.postMessage({type:"find-replace-complete",payload:{message:W,replacedCount:0,scannedCount:q.size}}),figma.notify(W);return}figma.ui.postMessage({type:"find-replace-progress",payload:{message:`Replacing ${B.size} variable(s)...`}});let E=0,M=0;async function F(W){if(M++,W.type==="TEXT")await figma.loadFontAsync(W.fontName);if("fills"in W&&W.fills!==figma.mixed&&Array.isArray(W.fills)){let U=JSON.parse(JSON.stringify(W.fills)),j=!1;for(let O=0;O<U.length;O++){let N=U[O];if(N.boundVariables)for(let S in N.boundVariables){let P=N.boundVariables[S];if(P&&P.id&&B.has(P.id)){let f=B.get(P.id);N.boundVariables[S]={type:"VARIABLE_ALIAS",id:f},j=!0,E++}}}if(j)W.fills=U}if("strokes"in W&&Array.isArray(W.strokes)){let U=JSON.parse(JSON.stringify(W.strokes)),j=!1;for(let O=0;O<U.length;O++){let N=U[O];if(N.boundVariables)for(let S in N.boundVariables){let P=N.boundVariables[S];if(P&&P.id&&B.has(P.id)){let f=B.get(P.id);N.boundVariables[S]={type:"VARIABLE_ALIAS",id:f},j=!0,E++}}}if(j)W.strokes=U}if("boundVariables"in W&&W.boundVariables){let U=W.boundVariables;for(let j in U){if(j==="fills"||j==="strokes")continue;let O=U[j];if(O&&O.id&&B.has(O.id)){let N=B.get(O.id);if(N){let S=await figma.variables.getVariableByIdAsync(N);if(S&&"setBoundVariable"in W&&typeof W.setBoundVariable==="function")try{W.setBoundVariable(j,S),E++}catch(P){console.error(`Failed to set bound variable ${j} on node:`,P)}}}}}if("children"in W)for(let U of W.children)await F(U)}for(let W of G)await F(W);let z=E>0?`✓ Replaced ${E} variable reference${E>1?"s":""} matching pattern (scanned ${M} nodes)`:`No variable references found matching pattern (scanned ${M} nodes)`;figma.ui.postMessage({type:"find-replace-complete",payload:{message:z,replacedCount:E,scannedCount:M}}),figma.notify(z)}catch(J){let Q=`Pattern Find/Replace failed: ${J&&J.message?J.message:String(J)}`;figma.ui.postMessage({type:"error",payload:{message:Q}}),figma.notify("✗ "+Q)}}async function l(){try{let K=await figma.variables.getLocalVariableCollectionsAsync(),J=[],Q=new Set;for(let Y of K)for(let X of Y.variableIds){let $=await figma.variables.getVariableByIdAsync(X);if($){Q.add($.id);let H=Object.values($.valuesByMode).some((_)=>typeof _==="object"&&_!==null&&("type"in _)&&_.type==="VARIABLE_ALIAS");J.push({id:$.id,name:$.name,collectionName:Y.name,resolvedType:$.resolvedType,isAlias:H,isLibrary:!1})}}async function Z(Y){if("boundVariables"in Y&&Y.boundVariables){let X=Y.boundVariables;for(let $ in X){let A=X[$];if(A&&typeof A==="object"){let H=Array.isArray(A)?A[0]&&A[0].id:A.id;if(H&&!Q.has(H)){let _=await figma.variables.getVariableByIdAsync(H);if(_){Q.add(H);let G=Object.values(_.valuesByMode).some((q)=>typeof q==="object"&&q!==null&&("type"in q)&&q.type==="VARIABLE_ALIAS");J.push({id:_.id,name:_.name,collectionName:"(Library)",resolvedType:_.resolvedType,isAlias:G,isLibrary:!0})}}}}}if("children"in Y)for(let X of Y.children)await Z(X)}await Z(figma.currentPage),J.sort((Y,X)=>{let $=Y.collectionName.localeCompare(X.collectionName);if($!==0)return $;return Y.name.localeCompare(X.name)}),figma.ui.postMessage({type:"available-variables",payload:{variables:J}})}catch(K){let J=`Failed to load variables: ${K&&K.message?K.message:String(K)}`;figma.ui.postMessage({type:"error",payload:{message:J}})}}async function o(){try{let K=await p();figma.ui.postMessage({type:"tokens-exported",payload:{tokens:K}})}catch(K){figma.ui.postMessage({type:"error",payload:{message:`Export failed: ${K&&K.message?K.message:String(K)}`}})}}async function a(K,J){try{figma.ui.postMessage({type:"sync-progress",payload:{message:"Scanning for broken references..."}});let Q=J&&J.basePixelSize||16,Z=J&&J.collectionName||"@DesignID Tokens",Y=v(K),X=await m(Z,Y),$=new Map;for(let G of X.variableIds){let q=await figma.variables.getVariableByIdAsync(G);if(q)$.set(q.name,q)}let A=0,H=0;async function _(G){if(H++,"fills"in G&&G.fills!==figma.mixed&&Array.isArray(G.fills))for(let q=0;q<G.fills.length;q++){let D=G.fills[q];if(D.type==="SOLID"){let B=D.boundVariables;if(B&&B.color){let E=B.color;if("id"in E){let M=E.id,F=!1,z="";try{let W=await figma.variables.getVariableByIdAsync(M);if(!W)F=!0;else{z=W.name;try{let U=await figma.variables.getVariableCollectionByIdAsync(W.variableCollectionId);if(!U)F=!0;else if(U.name!==Z)F=!0;else for(let j of X.modes)try{let O=W.valuesByMode[j.modeId];if(!O||typeof O==="object"&&"type"in O&&O.type==="VARIABLE_ALIAS"&&!await figma.variables.getVariableByIdAsync(O.id))F=!0}catch(O){}}catch(U){F=!0}}}catch(W){F=!0}if(F){let W=!1;if(z){let U=$.get(z);if(U)try{let j=Array.isArray(G.fills)?[...G.fills]:[];if(j[q]){let O=figma.variables.setBoundVariableForPaint(j[q],"color",U);j[q]=O,G.fills=j,A++,W=!0}}catch(j){}}if(!W){for(let[U,j]of $.entries())if(j.resolvedType==="COLOR")try{let O=Array.isArray(G.fills)?[...G.fills]:[];if(O[q]){let N=figma.variables.setBoundVariableForPaint(O[q],"color",j);O[q]=N,G.fills=O,A++,W=!0;break}}catch(O){continue}}}}}}}if("strokes"in G&&Array.isArray(G.strokes))for(let q=0;q<G.strokes.length;q++){let D=G.strokes[q];if(D.type==="SOLID"&&"boundVariables"in D&&D.boundVariables){if(D.boundVariables.color&&"id"in D.boundVariables.color){let B=D.boundVariables.color.id,E=!1,M="";try{let F=await figma.variables.getVariableByIdAsync(B);if(!F)E=!0;else try{if(!await figma.variables.getVariableCollectionByIdAsync(F.variableCollectionId))E=!0,M=F.name}catch(z){E=!0,M=F.name}}catch(F){E=!0}if(E){let F=!1;if(M){let z=$.get(M);if(z)try{let W=[...G.strokes];W[q]=figma.variables.setBoundVariableForPaint(D,"color",z),G.strokes=W,A++,F=!0}catch(W){}}if(!F){for(let[z,W]of $.entries())if(W.resolvedType==="COLOR")try{let U=[...G.strokes];U[q]=figma.variables.setBoundVariableForPaint(D,"color",W),G.strokes=U,A++;break}catch(U){continue}}}}}}if("boundVariables"in G&&G.boundVariables)for(let[q,D]of Object.entries(G.boundVariables)){if(!D)continue;let B=Array.isArray(D)?D:[D];for(let E of B){if(!E||typeof E!=="object"||!("id"in E))continue;let M=!1,F="";try{let z=await figma.variables.getVariableByIdAsync(E.id);if(!z)M=!0;else try{if(!await figma.variables.getVariableCollectionByIdAsync(z.variableCollectionId))M=!0,F=z.name}catch(W){M=!0,F=z.name}}catch(z){M=!0}if(M){let z=!1;if(F){let W=$.get(F);if(W)try{await G.setBoundVariable(q,W),A++,z=!0}catch(U){}}if(!z)for(let[W,U]of $.entries())try{await G.setBoundVariable(q,U),A++;break}catch(j){continue}}}}if("children"in G)for(let q of G.children)await _(q)}for(let G of figma.root.children)await G.loadAsync(),await _(G);let L=A>0?`✓ Fixed ${A} broken reference${A>1?"s":""} (scanned ${H} nodes)`:`No broken references found (scanned ${H} nodes)`;figma.ui.postMessage({type:"fix-references-complete",payload:{message:L}}),figma.notify(L)}catch(Q){figma.ui.postMessage({type:"error",payload:{message:`Fix broken references failed: ${Q&&Q.message?Q.message:String(Q)}`}}),figma.notify("✗ Fix failed. Check console for details.")}}function v(K){let J=new Set;function Q(Z){if(!Z||typeof Z!=="object")return;if(Z.$extensions&&Z.$extensions.$mode)Object.keys(Z.$extensions.$mode).forEach((Y)=>J.add(Y));Object.values(Z).forEach((Y)=>{if(Y&&typeof Y==="object")Q(Y)})}return Q(K),Array.from(J)}async function m(K,J){let Z=(await figma.variables.getLocalVariableCollectionsAsync()).find((Y)=>Y.name===K);if(!Z)Z=figma.variables.createVariableCollection(K);if(J&&J.length>0){if(!Z.modes.some((X)=>X.name==="light"||X.name==="Light"))Z.renameMode(Z.modes[0].modeId,"light");for(let X of J)if(!Z.modes.some((A)=>A.name===X))Z.addMode(X)}else{let Y=Z.modes.some(($)=>$.name==="light"||$.name==="Light"),X=Z.modes.some(($)=>$.name==="dark"||$.name==="Dark");if(!Y&&!X)Z.renameMode(Z.modes[0].modeId,"light"),Z.addMode("dark");else if(!Y)Z.renameMode(Z.modes[0].modeId,"light");else if(!X)Z.addMode("dark")}return Z}async function p(K=16){let J={},Q=await figma.variables.getLocalVariableCollectionsAsync();for(let $ of Q){let A=$.variableIds.map((_)=>figma.variables.getVariableByIdAsync(_)),H=await Promise.all(A);for(let _ of H){if(!_)continue;let L=_.name.replace(/\//g,"."),G=await PJ(_,K);if(G)w(J,L,G)}}let Z=await figma.getLocalPaintStylesAsync();for(let $ of Z){let A=$.name.replace(/\//g,"."),H=SJ($);if(H)w(J,A,H)}let Y=await figma.getLocalTextStylesAsync();for(let $ of Y){let A=$.name.replace(/\//g,"."),H=TJ($);if(H)w(J,A,H)}let X=await figma.getLocalEffectStylesAsync();for(let $ of X){let A=$.name.replace(/\//g,"."),H=wJ($);if(H)w(J,A,H)}return J}async function e(K,J,Q){let Z=K.variableIds.map((X)=>figma.variables.getVariableByIdAsync(X)),Y=await Promise.all(Z);for(let X of Y){if(!X)continue;let $=X.name.replace(/\//g,".");if(!J.has($))X.remove(),Q.removed++}}async function JJ(K,J,Q){let Z={variables:0,paintStyles:0,textStyles:0,effectStyles:0,removed:0,errors:[]},Y=new Set;return await h(K,"",J,Z,Q,!0,Y),await h(K,"",J,Z,Q,!1,Y),await e(J,Y,Z),Z}async function h(K,J,Q,Z,Y,X=!1,$){for(let[A,H]of Object.entries(K)){if(A.startsWith("$"))continue;let _=J?`${J}.${A}`:A;if(A==="icons"&&typeof H==="object"&&H!==null)continue;if(WJ(H)){let L=H;if(L.$type==="icon")continue;if($)$.add(_);try{await KJ(_,L,Q,Z,Y,X)}catch(q){let D=q;Z.errors.push({path:_,error:D&&D.message?D.message:String(q)})}}else if(typeof H==="object"&&H!==null)await h(H,_,Q,Z,Y,X,$)}}async function KJ(K,J,Q,Z,Y,X=!1){let $=J.$type;if($==="icon")return;switch($){case"color":if(await QJ(K,J,Q,X),X)Z.variables++;break;case"dimension":case"number":if(await YJ(K,J,Q,Y,X),X)Z.variables++;break;case"fontFamily":case"fontWeight":if(await ZJ(K,J,Q,X),X)Z.variables++;break;case"typography":if(!X)await $J(K,J),Z.textStyles++;break;case"shadow":if(!X)await XJ(K,J),Z.effectStyles++;break;case"duration":if(await AJ(K,J,Q,X),X)Z.variables++;break;default:console.warn(`Unsupported token type: ${$} for path: ${K}`)}}async function QJ(K,J,Q,Z=!1){let Y=K.replace(/\./g,"/"),X=await x(Q,Y,"COLOR"),$=async(H,_)=>{if(T(_))if(Z){let G=C("#FF00FF");X.setValueForMode(H,G);return}else{let G=await V(_,Q);if(G){X.setValueForMode(H,{type:"VARIABLE_ALIAS",id:G.id});return}}let L=C(_);X.setValueForMode(H,L)},A=J.$extensions&&J.$extensions.$mode;for(let H of Q.modes){let _=y(J,H.name);await $(H.modeId,_)}if(J.$description)X.description=J.$description}async function YJ(K,J,Q,Z=16,Y=!1){let X=K.replace(/\./g,"/"),$=await x(Q,X,"FLOAT"),A=async(L,G)=>{if(T(G))if(Y){$.setValueForMode(L,0);return}else{let B=await V(G,Q);if(B){$.setValueForMode(L,{type:"VARIABLE_ALIAS",id:B.id});return}}let q=G;if(typeof G==="string"&&G.toLowerCase().includes("calc(")&&G.includes("{"))q=await NJ(G,Q,L,Z);let D=R(q,Z);$.setValueForMode(L,D)},H=J.$extensions&&J.$extensions.$mode;for(let L of Q.modes){let G=y(J,L.name);await A(L.modeId,G)}let _=J.$description||"";if(typeof J.$value==="string"&&J.$value.toLowerCase().includes("calc(")){let L={$value:J.$value};if(H)L.$extensions={$mode:H};let G=`__ORIGINAL_TOKEN__: ${JSON.stringify(L)}`;_=_?`${_}
2
+ ${G}`:G}if(_)$.description=_}async function ZJ(K,J,Q,Z=!1){let Y=K.replace(/\./g,"/"),X=J.$type,$="FLOAT",A,H=async(G,q)=>{if(T(q))if(Z){let B=$==="FLOAT"?400:"Placeholder";_.setValueForMode(G,B);return}else{let B=await V(q,Q);if(B){_.setValueForMode(G,{type:"VARIABLE_ALIAS",id:B.id});return}}let D;switch(X){case"fontFamily":D=q;break;case"fontWeight":D=typeof q==="string"?g(q):q;break;default:return}_.setValueForMode(G,D)};switch(X){case"fontFamily":$="STRING";break;case"fontWeight":$="FLOAT";break;default:return}let _=await x(Q,Y,$),L=J.$extensions&&J.$extensions.$mode;for(let G of Q.modes){let q=y(J,G.name);await H(G.modeId,q)}if(J.$description)_.description=J.$description}async function $J(K,J){let Q=K.replace(/\./g,"/"),Z=await GJ(Q),Y=J.$value;if(Y.fontFamily)Z.fontName={family:Y.fontFamily,style:"Regular"};if(Y.fontSize)Z.fontSize=R(Y.fontSize);if(Y.fontWeight){let X=typeof Y.fontWeight==="string"?g(Y.fontWeight):Y.fontWeight,$=Z.fontName.family;Z.fontName={family:$,style:RJ(X)}}if(Y.lineHeight){let X=R(Y.lineHeight);Z.lineHeight={value:X,unit:"PIXELS"}}if(Y.letterSpacing){let X=R(Y.letterSpacing);Z.letterSpacing={value:X,unit:"PIXELS"}}if(J.$description)Z.description=J.$description}async function XJ(K,J){let Q=K.replace(/\./g,"/"),Z=await HJ(Q),Y=J.$value,X=Array.isArray(Y)?Y:[Y];if(Z.effects=X.map(($)=>{if($.inset)return{type:"INNER_SHADOW",color:C($.color),offset:{x:R($.offsetX||0),y:R($.offsetY||0)},radius:R($.blur||0),spread:R($.spread||0),visible:!0,blendMode:"NORMAL"};else return{type:"DROP_SHADOW",color:C($.color),offset:{x:R($.offsetX||0),y:R($.offsetY||0)},radius:R($.blur||0),spread:R($.spread||0),visible:!0,blendMode:"NORMAL"}}),J.$description)Z.description=J.$description}async function AJ(K,J,Q,Z=!1){let Y=K.replace(/\./g,"/"),X=await x(Q,Y,"FLOAT"),$=async(H,_)=>{if(T(_))if(Z){X.setValueForMode(H,0);return}else{let G=await V(_,Q);if(G){X.setValueForMode(H,{type:"VARIABLE_ALIAS",id:G.id});return}}let L=IJ(_);X.setValueForMode(H,L)},A=J.$extensions&&J.$extensions.$mode;for(let H of Q.modes){let _=y(J,H.name);await $(H.modeId,_)}if(J.$description)X.description=J.$description}async function x(K,J,Q){let Z=K.variableIds.map(($)=>figma.variables.getVariableByIdAsync($)),X=(await Promise.all(Z)).find(($)=>$&&$.name===J);if(X&&X.resolvedType===Q)return X;if(X)X.remove();return figma.variables.createVariable(J,K,Q)}async function GJ(K){let J=(await figma.getLocalTextStylesAsync()).find((Z)=>Z.name===K);if(J)return J;let Q=figma.createTextStyle();return Q.name=K,Q}async function HJ(K){let J=(await figma.getLocalEffectStylesAsync()).find((Z)=>Z.name===K);if(J)return J;let Q=figma.createEffectStyle();return Q.name=K,Q}function WJ(K){return typeof K==="object"&&K!==null&&"$type"in K&&"$value"in K}function y(K,J){let Q=K.$extensions&&K.$extensions.$mode;if(!Q)return K.$value;if(Q[J])return Q[J];if(Q[J.toLowerCase()])return Q[J.toLowerCase()];if((J==="light"||J==="Light")&&Q.light)return Q.light;return K.$value}function w(K,J,Q){let Z=J.split("."),Y=K;for(let X=0;X<Z.length-1;X++){let $=Z[X];if(!Y[$])Y[$]={};Y=Y[$]}Y[Z[Z.length-1]]=Q}function C(K){if(typeof K==="string"){let J=K.trim();try{if(J.startsWith("#"))return _J(J);if(J.startsWith("rgb"))return qJ(J);if(J.startsWith("hsl"))return UJ(J);if(J.startsWith("oklch"))return jJ(J);if(J.startsWith("oklab"))return OJ(J);if(J.startsWith("lab"))return LJ(J);if(J.startsWith("lch"))return DJ(J);if(J.startsWith("hwb"))return EJ(J);if(J.startsWith("color("))return BJ(J);return console.warn(`Unsupported color format: ${K}`),{r:0,g:0,b:0}}catch(Q){return console.warn(`Failed to parse color: ${K}`,Q),{r:0,g:0,b:0}}}if(typeof K==="object"&&"components"in K){let[J,Q,Z]=K.components;return{r:J,g:Q,b:Z}}return{r:0,g:0,b:0}}function _J(K){let J=K.slice(1);if(J.length===3){let Q=parseInt(J[0]+J[0],16)/255,Z=parseInt(J[1]+J[1],16)/255,Y=parseInt(J[2]+J[2],16)/255;return{r:Q,g:Z,b:Y}}if(J.length===6){let Q=parseInt(J.slice(0,2),16)/255,Z=parseInt(J.slice(2,4),16)/255,Y=parseInt(J.slice(4,6),16)/255;return{r:Q,g:Z,b:Y}}if(J.length===8){let Q=parseInt(J.slice(0,2),16)/255,Z=parseInt(J.slice(2,4),16)/255,Y=parseInt(J.slice(4,6),16)/255,X=parseInt(J.slice(6,8),16)/255;return{r:Q,g:Z,b:Y,a:X}}return{r:0,g:0,b:0}}function qJ(K){let J=K.match(/rgba?\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s,/]+/).filter(($)=>$.length>0),Z=parseFloat(Q[0])/255,Y=parseFloat(Q[1])/255,X=parseFloat(Q[2])/255;if(Q.length>=4){let $=I(Q[3]);return{r:Z,g:Y,b:X,a:$}}return{r:Z,g:Y,b:X}}function UJ(K){let J=K.match(/hsla?\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s,/]+/).filter((H)=>H.length>0),Z=parseFloat(Q[0])/360,Y=I(Q[1]),X=I(Q[2]),$=Q.length>=4?I(Q[3]):1,A=u(Z,Y,X);if($!==1)return{r:A.r,g:A.g,b:A.b,a:$};return A}function jJ(K){let J=K.match(/oklch\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s/]+/).filter((L)=>L.length>0),Z=I(Q[0]),Y=parseFloat(Q[1]),X=parseFloat(Q[2]),$=Q.length>=4?I(Q[3]):1,A=FJ(Z,Y,X),H=b(A.l,A.a,A.b),_=c(H.r,H.g,H.b);if($!==1)return{r:_.r,g:_.g,b:_.b,a:$};return _}function OJ(K){let J=K.match(/oklab\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s/]+/).filter((_)=>_.length>0),Z=I(Q[0]),Y=parseFloat(Q[1]),X=parseFloat(Q[2]),$=Q.length>=4?I(Q[3]):1,A=b(Z,Y,X),H=c(A.r,A.g,A.b);if($!==1)return{r:H.r,g:H.g,b:H.b,a:$};return H}function LJ(K){let J=K.match(/lab\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s/]+/).filter((_)=>_.length>0),Z=I(Q[0]),Y=parseFloat(Q[1]),X=parseFloat(Q[2]),$=Q.length>=4?I(Q[3]):1,A=d(Z*100,Y,X),H=s(A.x,A.y,A.z);if($!==1)return{r:H.r,g:H.g,b:H.b,a:$};return H}function DJ(K){let J=K.match(/lch\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s/]+/).filter((q)=>q.length>0),Z=I(Q[0]),Y=parseFloat(Q[1]),X=parseFloat(Q[2]),$=Q.length>=4?I(Q[3]):1,A=X*Math.PI/180,H=Y*Math.cos(A),_=Y*Math.sin(A),L=d(Z*100,H,_),G=s(L.x,L.y,L.z);if($!==1)return{r:G.r,g:G.g,b:G.b,a:$};return G}function EJ(K){let J=K.match(/hwb\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s/]+/).filter((H)=>H.length>0),Z=parseFloat(Q[0])/360,Y=I(Q[1]),X=I(Q[2]),$=Q.length>=4?I(Q[3]):1,A=MJ(Z,Y,X);if($!==1)return{r:A.r,g:A.g,b:A.b,a:$};return A}function BJ(K){let J=K.match(/color\s*\(\s*([^)]+)\s*\)/);if(!J)return{r:0,g:0,b:0};let Q=J[1].split(/[\s/]+/).filter((H)=>H.length>0),Z=Q[0],Y=parseFloat(Q[1]),X=parseFloat(Q[2]),$=parseFloat(Q[3]),A=Q.length>=5?I(Q[4]):1;if(A!==1)return{r:Y,g:X,b:$,a:A};return{r:Y,g:X,b:$}}function I(K){if(K.includes("%"))return parseFloat(K)/100;return parseFloat(K)}function u(K,J,Q){let Z,Y,X;if(J===0)Z=Y=X=Q;else{let $=(_,L,G)=>{if(G<0)G+=1;if(G>1)G-=1;if(G<0.16666666666666666)return _+(L-_)*6*G;if(G<0.5)return L;if(G<0.6666666666666666)return _+(L-_)*(0.6666666666666666-G)*6;return _},A=Q<0.5?Q*(1+J):Q+J-Q*J,H=2*Q-A;Z=$(H,A,K+0.3333333333333333),Y=$(H,A,K),X=$(H,A,K-0.3333333333333333)}return{r:Z,g:Y,b:X}}function FJ(K,J,Q){let Z=Q*Math.PI/180;return{l:K,a:J*Math.cos(Z),b:J*Math.sin(Z)}}function b(K,J,Q){let Z=K+0.3963377774*J+0.2158037573*Q,Y=K-0.1055613458*J-0.0638541728*Q,X=K-0.0894841775*J-1.291485548*Q,$=Z*Z*Z,A=Y*Y*Y,H=X*X*X;return{r:4.0767416621*$-3.3077115913*A+0.2309699292*H,g:-1.2684380046*$+2.6097574011*A-0.3413193965*H,b:-0.0041960863*$-0.7034186147*A+1.707614701*H}}function c(K,J,Q){let Z=(Y)=>{return Y=Math.max(0,Math.min(1,Y)),Y<=0.0031308?12.92*Y:1.055*Math.pow(Y,0.4166666666666667)-0.055};return{r:Z(K),g:Z(J),b:Z(Q)}}function d(K,J,Q){let Z=(K+16)/116,Y=J/500+Z,X=Z-Q/200,$=Y*Y*Y>0.008856?Y*Y*Y:(Y-0.13793103448275862)/7.787,A=Z*Z*Z>0.008856?Z*Z*Z:(Z-0.13793103448275862)/7.787,H=X*X*X>0.008856?X*X*X:(X-0.13793103448275862)/7.787;return{x:$*0.95047,y:A*1,z:H*1.08883}}function s(K,J,Q){let Z=K*3.2404542+J*-1.5371385+Q*-0.4985314,Y=K*-0.969266+J*1.8760108+Q*0.041556,X=K*0.0556434+J*-0.2040259+Q*1.0572252,$=(A)=>{return A=Math.max(0,Math.min(1,A)),A<=0.0031308?12.92*A:1.055*Math.pow(A,0.4166666666666667)-0.055};return{r:$(Z),g:$(Y),b:$(X)}}function MJ(K,J,Q){let Z=J+Q;if(Z>1)J=J/Z,Q=Q/Z;let Y=u(K,1,0.5);return{r:Y.r*(1-J-Q)+J,g:Y.g*(1-J-Q)+J,b:Y.b*(1-J-Q)+J}}function R(K,J=16){if(typeof K==="number")return K;if(typeof K==="string"){if(K.toLowerCase().includes("calc(")){let Z=zJ(K,J);if(Z!==null)return Z}let Q=parseFloat(K);if(isNaN(Q))return 0;if(K.includes("rem"))return Q*J;return Q}return 0}function zJ(K,J=16){try{let Q=K.match(/calc\s*\(([^)]+)\)/i);if(!Q)return null;let Z=Q[1].trim();if(Z.includes("{")&&Z.includes("}"))return console.warn("calc() contains unresolved token reference:",K),null;let Y=Z.match(/([0-9.]+)(px|rem|em|%)?|\+|\-|\*|\//g);if(!Y)return null;let X=0,$="+";for(let A of Y)if(A==="+"||A==="-"||A==="*"||A==="/")$=A;else{let H=A.match(/([0-9.]+)(px|rem|em|%)?/);if(H){let _=parseFloat(H[1]),L=H[2];if(L==="rem"||L==="em")_=_*J;switch($){case"+":X+=_;break;case"-":X-=_;break;case"*":X*=_;break;case"/":X/=_;break}}}return X}catch(Q){return console.error("Error evaluating calc:",Q),null}}async function NJ(K,J,Q,Z=16){let Y=K,X=/\{([^}]+)\}/g,$=[],A;while((A=X.exec(K))!==null)$.push(A);for(let H of $){let _=H[0],G=H[1].replace(/\./g,"/"),q=J.variableIds.map((E)=>figma.variables.getVariableByIdAsync(E)),B=(await Promise.all(q)).find((E)=>E&&E.name===G);if(B){let E=B.valuesByMode[Q];if(E!==void 0&&typeof E==="number")Y=Y.split(_).join(`${E}px`)}}return Y}function T(K){if(typeof K!=="string"||!K.startsWith("{")||!K.endsWith("}"))return!1;let J=K.slice(1,-1);return!J.includes("{")&&!J.includes("}")&&J.trim()!==""}async function V(K,J){if(!T(K))return null;let Z=K.slice(1,-1).replace(/\./g,"/"),Y=J.variableIds.map(($)=>figma.variables.getVariableByIdAsync($));return(await Promise.all(Y)).find(($)=>$&&$.name===Z)||null}function IJ(K){if(typeof K==="number")return K;if(typeof K==="string"){let J=parseFloat(K);if(K.includes("s")&&!K.includes("ms"))return J*1000;return J}return 0}function g(K){return{thin:100,"extra-light":200,light:300,normal:400,regular:400,medium:500,"semi-bold":600,bold:700,"extra-bold":800,black:900}[K.toLowerCase()]||400}function RJ(K){return{100:"Thin",200:"Extra Light",300:"Light",400:"Regular",500:"Medium",600:"Semi Bold",700:"Bold",800:"Extra Bold",900:"Black"}[K]||"Regular"}async function PJ(K,J=16){let Q=K.variableCollectionId?await figma.variables.getVariableCollectionByIdAsync(K.variableCollectionId):null;if(!Q)return null;let Z=K.resolvedType,Y;switch(Z){case"COLOR":Y="color";break;case"FLOAT":Y="dimension";break;case"STRING":Y="string";break;default:return null}let X=Q.modes,$=X.find((q)=>q.name==="light"||q.name==="Light")||X[0],A=K.valuesByMode[$.modeId],H=await k(A,Z,Q,J),_={$type:Y,$value:H};if(K.description)_.$description=K.description;let L={},G=!1;for(let q of X){if(q.modeId===$.modeId)continue;let D=K.valuesByMode[q.modeId],B=await k(D,Z,Q,J);if(JSON.stringify(B)!==JSON.stringify(H))L[q.name]=B,G=!0}if(G)_.$extensions={$mode:L};return _}async function k(K,J,Q,Z=16){if(typeof K==="object"&&K!==null&&"type"in K&&K.type==="VARIABLE_ALIAS"){let Y=K,X=await figma.variables.getVariableByIdAsync(Y.id);if(X)return`{${X.name.replace(/\//g,".")}}`}switch(J){case"COLOR":if(typeof K==="object"&&"r"in K){let Y=K,X=Math.round(Y.r*255).toString(16).padStart(2,"0"),$=Math.round(Y.g*255).toString(16).padStart(2,"0"),A=Math.round(Y.b*255).toString(16).padStart(2,"0");return`#${X}${$}${A}`}break;case"FLOAT":if(typeof K==="number"){let Y=K/Z;if(Y===Math.round(Y*4)/4)return`${Y}rem`;return`${K}px`}break;case"STRING":return String(K)}return K}function SJ(K){if(K.paints.length===0)return null;let J=K.paints[0];if(J.type!=="SOLID")return null;let{r:Q,g:Z,b:Y}=J.color,X=J.opacity!==void 0?J.opacity:1;return{$type:"color",$value:`rgba(${Math.round(Q*255)}, ${Math.round(Z*255)}, ${Math.round(Y*255)}, ${X})`,$description:K.description||void 0}}function TJ(K){return{$type:"typography",$value:{fontFamily:K.fontName.family,fontSize:K.fontSize,fontWeight:g(K.fontName.style),lineHeight:K.lineHeight?K.lineHeight:0,letterSpacing:K.letterSpacing?K.letterSpacing:0},$description:K.description||void 0}}function wJ(K){let J=K.effects.filter((Z)=>Z.type==="DROP_SHADOW"||Z.type==="INNER_SHADOW");if(J.length===0)return null;let Q=J.map((Z)=>{let Y=Z;return{color:`rgba(${Math.round(Y.color.r*255)}, ${Math.round(Y.color.g*255)}, ${Math.round(Y.color.b*255)}, ${Y.color.a||1})`,offsetX:`${Y.offset.x}px`,offsetY:`${Y.offset.y}px`,blur:`${Y.radius}px`,spread:`${Y.spread||0}px`,inset:Z.type==="INNER_SHADOW"}});return{$type:"shadow",$value:Q.length===1?Q[0]:Q,$description:K.description||void 0}}
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@DesignID Tokens - Figma",
3
+ "id": "designid-tokens-sync-figma",
4
+ "api": "1.0.0",
5
+ "main": "code.js",
6
+ "ui": "ui.html",
7
+ "editorType": [
8
+ "figma"
9
+ ],
10
+ "documentAccess": "dynamic-page",
11
+ "networkAccess": {
12
+ "allowedDomains": [
13
+ "none"
14
+ ]
15
+ },
16
+ "permissions": [
17
+ "currentuser",
18
+ "teamlibrary"
19
+ ]
20
+ }