@figma-vars/hooks 1.3.3 → 1.4.4
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.
- package/README.md +85 -19
- package/dist/figma-vars-hooks.js +314 -296
- package/dist/figma-vars-hooks.umd.cjs +3 -3
- package/dist/src/api/fetcher.d.ts +28 -0
- package/dist/src/api/index.d.ts +25 -0
- package/dist/src/api/mutator.d.ts +33 -0
- package/dist/src/api/mutator.test.d.ts +1 -0
- package/dist/src/constants/index.d.ts +89 -0
- package/dist/src/contexts/FigmaVarsProvider.d.ts +56 -0
- package/dist/src/contexts/index.d.ts +21 -0
- package/dist/src/hooks/index.d.ts +143 -0
- package/dist/src/hooks/useBulkUpdateVariables.d.ts +46 -0
- package/dist/src/hooks/useCreateVariable.d.ts +45 -0
- package/dist/src/hooks/useDeleteVariable.d.ts +33 -0
- package/dist/src/hooks/useFigmaToken.d.ts +21 -0
- package/dist/src/hooks/useMutation.d.ts +53 -0
- package/dist/src/hooks/useUpdateVariable.d.ts +40 -0
- package/dist/src/hooks/useVariableCollections.d.ts +35 -0
- package/dist/src/hooks/useVariableModes.d.ts +32 -0
- package/dist/src/hooks/useVariables.d.ts +32 -0
- package/dist/src/index.d.ts +80 -0
- package/dist/src/types/contexts.d.ts +77 -0
- package/dist/src/types/figma.d.ts +244 -0
- package/dist/src/types/hooks.d.ts +67 -0
- package/dist/src/types/index.d.ts +30 -0
- package/dist/src/types/mutations.d.ts +314 -0
- package/dist/src/utils/filterVariables.d.ts +31 -0
- package/dist/src/utils/index.d.ts +21 -0
- package/dist/tests/FigmaVarsProvider.test.d.ts +1 -0
- package/dist/tests/api/fetcher.test.d.ts +1 -0
- package/dist/tests/api/mutator.test.d.ts +1 -0
- package/dist/tests/constants/index.test.d.ts +1 -0
- package/dist/tests/contexts/index.test.d.ts +1 -0
- package/dist/tests/hooks/index.test.d.ts +1 -0
- package/dist/tests/hooks/useBulkUpdateVariables.test.d.ts +1 -0
- package/dist/tests/hooks/useCreateVariable.test.d.ts +1 -0
- package/dist/tests/hooks/useDeleteVariable.test.d.ts +1 -0
- package/dist/tests/hooks/useFigmaToken.test.d.ts +1 -0
- package/dist/tests/hooks/useMutation.test.d.ts +1 -0
- package/dist/tests/hooks/useUpdateVariable.test.d.ts +1 -0
- package/dist/tests/hooks/useVariableCollections.test.d.ts +1 -0
- package/dist/tests/hooks/useVariableModes.test.d.ts +1 -0
- package/dist/tests/hooks/useVariables.test.d.ts +1 -0
- package/dist/tests/index.test.d.ts +1 -0
- package/dist/tests/mocks/variables.d.ts +2 -0
- package/dist/tests/setup.d.ts +0 -0
- package/dist/tests/test-utils.d.ts +10 -0
- package/dist/tests/test-utils.test.d.ts +1 -0
- package/dist/tests/types.test.d.ts +1 -0
- package/dist/tests/utils/filterVariables.test.d.ts +1 -0
- package/dist/tests/utils/index.test.d.ts +1 -0
- package/package.json +4 -2
- package/dist/index.d.ts +0 -1221
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(y,Z){typeof exports=="object"&&typeof module<"u"?Z(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],Z):(y=typeof globalThis<"u"?globalThis:y||self,Z(y["@figma-vars/hooks"]={},y["react/jsx-runtime"],y.React))})(this,function(y,Z,p){"use strict";const Pe=p.createContext(void 0),dt=({children:e,token:t,fileKey:n})=>Z.jsx(Pe.Provider,{value:{token:t,fileKey:n},children:e}),ee=()=>{const e=p.useContext(Pe);if(e===void 0)throw new Error("useFigmaTokenContext must be used within a FigmaVarsProvider");return e};var se={exports:{}},Ee={};/**
|
|
2
2
|
* @license React
|
|
3
3
|
* use-sync-external-store-shim.production.js
|
|
4
4
|
*
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This source code is licensed under the MIT license found in the
|
|
8
8
|
* LICENSE file in the root directory of this source tree.
|
|
9
|
-
*/var
|
|
9
|
+
*/var je;function Et(){if(je)return Ee;je=1;var e=p;function t(c,d){return c===d&&(c!==0||1/c===1/d)||c!==c&&d!==d}var n=typeof Object.is=="function"?Object.is:t,r=e.useState,o=e.useEffect,s=e.useLayoutEffect,i=e.useDebugValue;function E(c,d){var u=d(),m=r({inst:{value:u,getSnapshot:d}}),l=m[0].inst,I=m[1];return s(function(){l.value=u,l.getSnapshot=d,S(l)&&I({inst:l})},[c,u,d]),o(function(){return S(l)&&I({inst:l}),c(function(){S(l)&&I({inst:l})})},[c]),i(u),u}function S(c){var d=c.getSnapshot;c=c.value;try{var u=d();return!n(c,u)}catch{return!0}}function D(c,d){return d()}var O=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?D:E;return Ee.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:O,Ee}var me={};/**
|
|
10
10
|
* @license React
|
|
11
11
|
* use-sync-external-store-shim.development.js
|
|
12
12
|
*
|
|
@@ -14,4 +14,4 @@
|
|
|
14
14
|
*
|
|
15
15
|
* This source code is licensed under the MIT license found in the
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
|
-
*/var je;function ht(){return je||(je=1,process.env.NODE_ENV!=="production"&&function(){function e(u,E){return u===E&&(u!==0||1/u===1/E)||u!==u&&E!==E}function t(u,E){O||o.startTransition===void 0||(O=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var l=E();if(!c){var C=E();s(l,C)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),c=!0)}C=a({inst:{value:l,getSnapshot:E}});var i=C[0].inst,q=C[1];return S(function(){i.value=l,i.getSnapshot=E,n(i)&&q({inst:i})},[u,l,E]),h(function(){return n(i)&&q({inst:i}),u(function(){n(i)&&q({inst:i})})},[u]),D(l),l}function n(u){var E=u.getSnapshot;u=u.value;try{var l=E();return!s(u,l)}catch{return!0}}function r(u,E){return E()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var o=m,s=typeof Object.is=="function"?Object.is:e,a=o.useState,h=o.useEffect,S=o.useLayoutEffect,D=o.useDebugValue,O=!1,c=!1,d=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?r:t;me.useSyncExternalStore=o.useSyncExternalStore!==void 0?o.useSyncExternalStore:d,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),me}var xe;function St(){return xe||(xe=1,process.env.NODE_ENV==="production"?se.exports=pt():se.exports=ht()),se.exports}var _t=St();const Ue=0,ke=1,qe=2,Ge=3;var We=Object.prototype.hasOwnProperty;function pe(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&pe(e[r],t[r]););return r===-1}if(!n||typeof e=="object"){r=0;for(n in e)if(We.call(e,n)&&++r&&!We.call(t,n)||!(n in t)||!pe(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}const P=new WeakMap,U=()=>{},R=U(),he=Object,f=e=>e===R,N=e=>typeof e=="function",k=(e,t)=>({...e,...t}),Be=e=>N(e.then),Se={},ie={},_e="undefined",ee=typeof window!=_e,ve=typeof document!=_e,vt=ee&&"Deno"in window,Ot=()=>ee&&typeof window.requestAnimationFrame!=_e,He=(e,t)=>{const n=P.get(e);return[()=>!f(t)&&e.get(t)||Se,r=>{if(!f(t)){const o=e.get(t);t in ie||(ie[t]=o),n[5](t,k(o,r),o||Se)}},n[6],()=>!f(t)&&t in ie?ie[t]:!f(t)&&e.get(t)||Se]};let Oe=!0;const wt=()=>Oe,[we,ge]=ee&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[U,U],gt=()=>{const e=ve&&document.visibilityState;return f(e)||e!=="hidden"},yt=e=>(ve&&document.addEventListener("visibilitychange",e),we("focus",e),()=>{ve&&document.removeEventListener("visibilitychange",e),ge("focus",e)}),Tt=e=>{const t=()=>{Oe=!0,e()},n=()=>{Oe=!1};return we("online",t),we("offline",n),()=>{ge("online",t),ge("offline",n)}},At={isOnline:wt,isVisible:gt},Rt={initFocus:yt,initReconnect:Tt},$e=!m.useId,te=!ee||vt,Dt=e=>Ot()?window.requestAnimationFrame(e):setTimeout(e,1),ye=te?m.useEffect:m.useLayoutEffect,Te=typeof navigator<"u"&&navigator.connection,Ke=!te&&Te&&(["slow-2g","2g"].includes(Te.effectiveType)||Te.saveData),ae=new WeakMap,Ae=(e,t)=>he.prototype.toString.call(e)===`[object ${t}]`;let It=0;const Re=e=>{const t=typeof e,n=Ae(e,"Date"),r=Ae(e,"RegExp"),o=Ae(e,"Object");let s,a;if(he(e)===e&&!n&&!r){if(s=ae.get(e),s)return s;if(s=++It+"~",ae.set(e,s),Array.isArray(e)){for(s="@",a=0;a<e.length;a++)s+=Re(e[a])+",";ae.set(e,s)}if(o){s="#";const h=he.keys(e).sort();for(;!f(a=h.pop());)f(e[a])||(s+=a+":"+Re(e[a])+",");ae.set(e,s)}}else s=n?e.toJSON():t=="symbol"?e.toString():t=="string"?JSON.stringify(e):""+e;return s},De=e=>{if(N(e))try{e=e()}catch{e=""}const t=e;return e=typeof e=="string"?e:(Array.isArray(e)?e.length:e)?Re(e):"",[e,t]};let Ct=0;const Ie=()=>++Ct;async function Je(...e){const[t,n,r,o]=e,s=k({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let a=s.populateCache;const h=s.rollbackOnError;let S=s.optimisticData;const D=d=>typeof h=="function"?h(d):h!==!1,O=s.throwOnError;if(N(n)){const d=n,u=[],E=t.keys();for(const l of E)!/^\$(inf|sub)\$/.test(l)&&d(t.get(l)._k)&&u.push(l);return Promise.all(u.map(c))}return c(n);async function c(d){const[u]=De(d);if(!u)return;const[E,l]=He(t,u),[C,i,q,re]=P.get(t),G=()=>{const V=C[u];return(N(s.revalidate)?s.revalidate(E().data,d):s.revalidate!==!1)&&(delete q[u],delete re[u],V&&V[0])?V[0](qe).then(()=>E().data):E().data};if(e.length<3)return G();let T=r,b;const $=Ie();i[u]=[$,0];const v=!f(S),K=E(),M=K.data,J=K._c,W=f(J)?M:J;if(v&&(S=N(S)?S(W,M):S,l({data:S,_c:W})),N(T))try{T=T(W)}catch(V){b=V}if(T&&Be(T))if(T=await T.catch(V=>{b=V}),$!==i[u][0]){if(b)throw b;return T}else b&&v&&D(b)&&(a=!0,l({data:W,_c:R}));if(a&&!b)if(N(a)){const V=a(T,W);l({data:V,error:R,_c:R})}else l({data:T,error:R,_c:R});if(i[u][1]=Ie(),Promise.resolve(G()).then(()=>{l({_c:R})}),b){if(O)throw b;return}return T}}const Ye=(e,t)=>{for(const n in e)e[n][0]&&e[n][0](t)},bt=(e,t)=>{if(!P.has(e)){const n=k(Rt,t),r=Object.create(null),o=Je.bind(R,e);let s=U;const a=Object.create(null),h=(O,c)=>{const d=a[O]||[];return a[O]=d,d.push(c),()=>d.splice(d.indexOf(c),1)},S=(O,c,d)=>{e.set(O,c);const u=a[O];if(u)for(const E of u)E(c,d)},D=()=>{if(!P.has(e)&&(P.set(e,[r,Object.create(null),Object.create(null),Object.create(null),o,S,h]),!te)){const O=n.initFocus(setTimeout.bind(R,Ye.bind(R,r,Ue))),c=n.initReconnect(setTimeout.bind(R,Ye.bind(R,r,ke)));s=()=>{O&&O(),c&&c(),P.delete(e)}}};return D(),[e,o,D,s]}return[e,P.get(e)[4]]},Lt=(e,t,n,r,o)=>{const s=n.errorRetryCount,a=o.retryCount,h=~~((Math.random()+.5)*(1<<(a<8?a:8)))*n.errorRetryInterval;!f(s)&&a>s||setTimeout(r,h,o)},Vt=pe,[ze,Ft]=bt(new Map),Nt=k({onLoadingSlow:U,onSuccess:U,onError:U,onErrorRetry:Lt,onDiscarded:U,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:Ke?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:Ke?5e3:3e3,compare:Vt,isPaused:()=>!1,cache:ze,mutate:Ft,fallback:{}},At),Mt=(e,t)=>{const n=k(e,t);if(t){const{use:r,fallback:o}=e,{use:s,fallback:a}=t;r&&s&&(n.use=r.concat(s)),o&&a&&(n.fallback=k(o,a))}return n},Pt=m.createContext({}),jt="$inf$",Xe=ee&&window.__SWR_DEVTOOLS_USE__,xt=Xe?window.__SWR_DEVTOOLS_USE__:[],Ut=()=>{Xe&&(window.__SWR_DEVTOOLS_REACT__=m)},kt=e=>N(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],qt=()=>k(Nt,m.useContext(Pt)),Gt=e=>(t,n,r)=>e(t,n&&((...s)=>{const[a]=De(t),[,,,h]=P.get(ze);if(a.startsWith(jt))return n(...s);const S=h[a];return f(S)?n(...s):(delete h[a],S)}),r),Wt=xt.concat(Gt),Bt=e=>function(...n){const r=qt(),[o,s,a]=kt(n),h=Mt(r,a);let S=e;const{use:D}=h,O=(D||[]).concat(Wt);for(let c=O.length;c--;)S=O[c](S);return S(o,s||h.fetcher||null,h)},Ht=(e,t,n)=>{const r=t[e]||(t[e]=[]);return r.push(n),()=>{const o=r.indexOf(n);o>=0&&(r[o]=r[r.length-1],r.pop())}};Ut();const Ce=m.use||(e=>{switch(e.status){case"pending":throw e;case"fulfilled":return e.value;case"rejected":throw e.reason;default:throw e.status="pending",e.then(t=>{e.status="fulfilled",e.value=t},t=>{e.status="rejected",e.reason=t}),e}}),be={dedupe:!0},$t=Bt((e,t,n)=>{const{cache:r,compare:o,suspense:s,fallbackData:a,revalidateOnMount:h,revalidateIfStale:S,refreshInterval:D,refreshWhenHidden:O,refreshWhenOffline:c,keepPreviousData:d}=n,[u,E,l,C]=P.get(r),[i,q]=De(e),re=m.useRef(!1),G=m.useRef(!1),T=m.useRef(i),b=m.useRef(t),$=m.useRef(n),v=()=>$.current,K=()=>v().isVisible()&&v().isOnline(),[M,J,W,V]=He(r,i),Y=m.useRef({}).current,le=f(a)?f(n.fallback)?R:n.fallback[i]:a,st=(_,p)=>{for(const A in Y){const w=A;if(w==="data"){if(!o(_[w],p[w])&&(!f(_[w])||!o(de,p[w])))return!1}else if(p[w]!==_[w])return!1}return!0},it=m.useMemo(()=>{const _=!i||!t?!1:f(h)?v().isPaused()||s?!1:S!==!1:h,p=I=>{const j=k(I);return delete j._k,_?{isValidating:!0,isLoading:!0,...j}:j},A=M(),w=V(),F=p(A),Q=A===w?F:p(w);let y=F;return[()=>{const I=p(M());return st(I,y)?(y.data=I.data,y.isLoading=I.isLoading,y.isValidating=I.isValidating,y.error=I.error,y):(y=I,I)},()=>Q]},[r,i]),z=_t.useSyncExternalStore(m.useCallback(_=>W(i,(p,A)=>{st(A,p)||_()}),[r,i]),it[0],it[1]),at=!re.current,sn=u[i]&&u[i].length>0,X=z.data,B=f(X)?le&&Be(le)?Ce(le):le:X,fe=z.error,Ve=m.useRef(B),de=d?f(X)?f(Ve.current)?B:Ve.current:X:B,ut=sn&&!f(fe)?!1:at&&!f(h)?h:v().isPaused()?!1:s?f(B)?!1:S:f(B)||S,ct=!!(i&&t&&at&&ut),an=f(z.isValidating)?ct:z.isValidating,un=f(z.isLoading)?ct:z.isLoading,oe=m.useCallback(async _=>{const p=b.current;if(!i||!p||G.current||v().isPaused())return!1;let A,w,F=!0;const Q=_||{},y=!l[i]||!Q.dedupe,I=()=>$e?!G.current&&i===T.current&&re.current:i===T.current,j={isValidating:!1,isLoading:!1},ft=()=>{J(j)},dt=()=>{const L=l[i];L&&L[1]===w&&delete l[i]},Et={isValidating:!0};f(M().data)&&(Et.isLoading=!0);try{if(y&&(J(Et),n.loadingTimeout&&f(M().data)&&setTimeout(()=>{F&&I()&&v().onLoadingSlow(i,n)},n.loadingTimeout),l[i]=[p(q),Ie()]),[A,w]=l[i],A=await A,y&&setTimeout(dt,n.dedupingInterval),!l[i]||l[i][1]!==w)return y&&I()&&v().onDiscarded(i),!1;j.error=R;const L=E[i];if(!f(L)&&(w<=L[0]||w<=L[1]||L[1]===0))return ft(),y&&I()&&v().onDiscarded(i),!1;const x=M().data;j.data=o(x,A)?x:A,y&&I()&&v().onSuccess(A,i,n)}catch(L){dt();const x=v(),{shouldRetryOnError:Fe}=x;x.isPaused()||(j.error=L,y&&I()&&(x.onError(L,i,x),(Fe===!0||N(Fe)&&Fe(L))&&(!v().revalidateOnFocus||!v().revalidateOnReconnect||K())&&x.onErrorRetry(L,i,x,cn=>{const Ne=u[i];Ne&&Ne[0]&&Ne[0](Ge,cn)},{retryCount:(Q.retryCount||0)+1,dedupe:!0})))}return F=!1,ft(),!0},[i,r]),lt=m.useCallback((..._)=>Je(r,T.current,..._),[]);if(ye(()=>{b.current=t,$.current=n,f(X)||(Ve.current=X)}),ye(()=>{if(!i)return;const _=oe.bind(R,be);let p=0;v().revalidateOnFocus&&(p=Date.now()+v().focusThrottleInterval);const w=Ht(i,u,(F,Q={})=>{if(F==Ue){const y=Date.now();v().revalidateOnFocus&&y>p&&K()&&(p=y+v().focusThrottleInterval,_())}else if(F==ke)v().revalidateOnReconnect&&K()&&_();else{if(F==qe)return oe();if(F==Ge)return oe(Q)}});return G.current=!1,T.current=i,re.current=!0,J({_k:q}),ut&&(f(B)||te?_():Dt(_)),()=>{G.current=!0,w()}},[i]),ye(()=>{let _;function p(){const w=N(D)?D(M().data):D;w&&_!==-1&&(_=setTimeout(A,w))}function A(){!M().error&&(O||v().isVisible())&&(c||v().isOnline())?oe(be).then(p):p()}return p(),()=>{_&&(clearTimeout(_),_=-1)}},[D,O,c,i]),m.useDebugValue(de),s&&f(B)&&i){if(!$e&&te)throw new Error("Fallback data is required when using Suspense in SSR.");b.current=t,$.current=n,G.current=!1;const _=C[i];if(!f(_)){const p=lt(_);Ce(p)}if(f(fe)){const p=oe(be);f(de)||(p.status="fulfilled",p.value=!0),Ce(p)}else throw fe}return{mutate:lt,get data(){return Y.data=!0,de},get error(){return Y.error=!0,fe},get isValidating(){return Y.isValidating=!0,an},get isLoading(){return Y.isLoading=!0,un}}}),Qe="https://api.figma.com",Kt=`${Qe}/v1/files`,Ze=`${Qe}/v1/variables`,et=Ze,tt=e=>`${Ze}/${e}`,Jt=e=>`${Kt}/${e}/variables/local`,nt="application/json",rt="X-FIGMA-TOKEN",ne="A Figma API token is required.",ot="An error occurred while fetching data from the Figma API.",Yt=async(e,t)=>{if(!t)throw new Error(ne);const n=await fetch(e,{headers:{[rt]:t,"Content-Type":nt}});if(!n.ok){const r=await n.json();throw new Error(r.message||ot)}return n.json()},Le=()=>{const{token:e,fileKey:t}=H(),n=t?Jt(t):null,{data:r,error:o,isLoading:s,isValidating:a}=$t(e&&n?[n,e]:null,Yt);return{data:r,isLoading:s,isValidating:a,error:o}},zt=()=>{const{data:e}=Le(),t=m.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),n=m.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:t,collectionsById:n}},Xt=()=>{const{data:e}=Le();return m.useMemo(()=>{const t=[],n={},r={};if(e!=null&&e.meta)for(const o of Object.values(e.meta.variableCollections)){t.push(...o.modes),n[o.id]=o.modes;for(const s of o.modes)r[s.modeId]=s}return{modes:t,modesByCollectionId:n,modesById:r}},[e])},Qt=()=>{const{token:e}=H();return e};function Zt(e,t){switch(t.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:t.payload};case"error":return{...e,status:"error",error:t.payload};default:return e}}const ue=e=>{const t={status:"idle",data:null,error:null},[n,r]=m.useReducer(Zt,t);return{mutate:m.useCallback(async s=>{r({type:"loading"});try{const a=await e(s);return r({type:"success",payload:a}),a}catch(a){r({type:"error",payload:a});return}},[e]),...n,isLoading:n.status==="loading",isSuccess:n.status==="success",isError:n.status==="error"}},ce=async(e,t,n,r)=>{if(!t)throw new Error(ne);const o=await fetch(e,{method:n,headers:{[rt]:t,"Content-Type":nt},...r&&{body:JSON.stringify(r)}});if(!o.ok){const s=await o.json();throw new Error(s.message||ot)}return o.status===204?Promise.resolve(void 0):o.json()},en=()=>{const{token:e}=H();if(!e)throw new Error(ne);return ue(async n=>await ce(et,e,"POST",n))},tn=()=>{const{token:e}=H();if(!e)throw new Error(ne);return ue(async n=>await ce(tt(n),e,"DELETE"))},nn=()=>{const{token:e}=H();return ue(async({variableId:n,payload:r})=>{if(!e)throw new Error("A Figma API token is required.");const o=tt(n);return await ce(o,e,"PUT",r)})},rn=()=>{const{token:e}=H();return ue(async n=>{if(!e)throw new Error(ne);return await ce(et,e,"PUT",n)})};function on(e,t){return e.filter(n=>{let r=!0;return t.resolvedType&&(r=r&&n.resolvedType===t.resolvedType),t.name&&(r=r&&n.name.includes(t.name)),r})}g.FigmaVarsProvider=mt,g.filterVariables=on,g.useBulkUpdateVariables=rn,g.useCreateVariable=en,g.useDeleteVariable=tn,g.useFigmaToken=Qt,g.useUpdateVariable=nn,g.useVariableCollections=zt,g.useVariableModes=Xt,g.useVariables=Le,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
|
|
17
|
+
*/var xe;function mt(){return xe||(xe=1,process.env.NODE_ENV!=="production"&&function(){function e(u,m){return u===m&&(u!==0||1/u===1/m)||u!==u&&m!==m}function t(u,m){O||o.startTransition===void 0||(O=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var l=m();if(!c){var I=m();s(l,I)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),c=!0)}I=i({inst:{value:l,getSnapshot:m}});var a=I[0].inst,W=I[1];return S(function(){a.value=l,a.getSnapshot=m,n(a)&&W({inst:a})},[u,l,m]),E(function(){return n(a)&&W({inst:a}),u(function(){n(a)&&W({inst:a})})},[u]),D(l),l}function n(u){var m=u.getSnapshot;u=u.value;try{var l=m();return!s(u,l)}catch{return!0}}function r(u,m){return m()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var o=p,s=typeof Object.is=="function"?Object.is:e,i=o.useState,E=o.useEffect,S=o.useLayoutEffect,D=o.useDebugValue,O=!1,c=!1,d=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?r:t;me.useSyncExternalStore=o.useSyncExternalStore!==void 0?o.useSyncExternalStore:d,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),me}var Ue;function pt(){return Ue||(Ue=1,process.env.NODE_ENV==="production"?se.exports=Et():se.exports=mt()),se.exports}var ht=pt();const Ge=0,We=1,ke=2,qe=3;var Be=Object.prototype.hasOwnProperty;function pe(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&pe(e[r],t[r]););return r===-1}if(!n||typeof e=="object"){r=0;for(n in e)if(Be.call(e,n)&&++r&&!Be.call(t,n)||!(n in t)||!pe(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}const P=new WeakMap,U=()=>{},R=U(),he=Object,f=e=>e===R,F=e=>typeof e=="function",G=(e,t)=>({...e,...t}),$e=e=>F(e.then),Se={},ie={},_e="undefined",te=typeof window!=_e,ve=typeof document!=_e,St=te&&"Deno"in window,_t=()=>te&&typeof window.requestAnimationFrame!=_e,He=(e,t)=>{const n=P.get(e);return[()=>!f(t)&&e.get(t)||Se,r=>{if(!f(t)){const o=e.get(t);t in ie||(ie[t]=o),n[5](t,G(o,r),o||Se)}},n[6],()=>!f(t)&&t in ie?ie[t]:!f(t)&&e.get(t)||Se]};let Oe=!0;const vt=()=>Oe,[we,Te]=te&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[U,U],Ot=()=>{const e=ve&&document.visibilityState;return f(e)||e!=="hidden"},wt=e=>(ve&&document.addEventListener("visibilitychange",e),we("focus",e),()=>{ve&&document.removeEventListener("visibilitychange",e),Te("focus",e)}),Tt=e=>{const t=()=>{Oe=!0,e()},n=()=>{Oe=!1};return we("online",t),we("offline",n),()=>{Te("online",t),Te("offline",n)}},yt={isOnline:vt,isVisible:Ot},gt={initFocus:wt,initReconnect:Tt},Ke=!p.useId,ne=!te||St,At=e=>_t()?window.requestAnimationFrame(e):setTimeout(e,1),ye=ne?p.useEffect:p.useLayoutEffect,ge=typeof navigator<"u"&&navigator.connection,Je=!ne&&ge&&(["slow-2g","2g"].includes(ge.effectiveType)||ge.saveData),ae=new WeakMap,Ae=(e,t)=>he.prototype.toString.call(e)===`[object ${t}]`;let Rt=0;const Re=e=>{const t=typeof e,n=Ae(e,"Date"),r=Ae(e,"RegExp"),o=Ae(e,"Object");let s,i;if(he(e)===e&&!n&&!r){if(s=ae.get(e),s)return s;if(s=++Rt+"~",ae.set(e,s),Array.isArray(e)){for(s="@",i=0;i<e.length;i++)s+=Re(e[i])+",";ae.set(e,s)}if(o){s="#";const E=he.keys(e).sort();for(;!f(i=E.pop());)f(e[i])||(s+=i+":"+Re(e[i])+",");ae.set(e,s)}}else s=n?e.toJSON():t=="symbol"?e.toString():t=="string"?JSON.stringify(e):""+e;return s},De=e=>{if(F(e))try{e=e()}catch{e=""}const t=e;return e=typeof e=="string"?e:(Array.isArray(e)?e.length:e)?Re(e):"",[e,t]};let Dt=0;const Ce=()=>++Dt;async function Ye(...e){const[t,n,r,o]=e,s=G({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let i=s.populateCache;const E=s.rollbackOnError;let S=s.optimisticData;const D=d=>typeof E=="function"?E(d):E!==!1,O=s.throwOnError;if(F(n)){const d=n,u=[],m=t.keys();for(const l of m)!/^\$(inf|sub)\$/.test(l)&&d(t.get(l)._k)&&u.push(l);return Promise.all(u.map(c))}return c(n);async function c(d){const[u]=De(d);if(!u)return;const[m,l]=He(t,u),[I,a,W,re]=P.get(t),k=()=>{const V=I[u];return(F(s.revalidate)?s.revalidate(m().data,d):s.revalidate!==!1)&&(delete W[u],delete re[u],V&&V[0])?V[0](ke).then(()=>m().data):m().data};if(e.length<3)return k();let g=r,b;const H=Ce();a[u]=[H,0];const v=!f(S),K=m(),M=K.data,J=K._c,q=f(J)?M:J;if(v&&(S=F(S)?S(q,M):S,l({data:S,_c:q})),F(g))try{g=g(q)}catch(V){b=V}if(g&&$e(g))if(g=await g.catch(V=>{b=V}),H!==a[u][0]){if(b)throw b;return g}else b&&v&&D(b)&&(i=!0,l({data:q,_c:R}));if(i&&!b)if(F(i)){const V=i(g,q);l({data:V,error:R,_c:R})}else l({data:g,error:R,_c:R});if(a[u][1]=Ce(),Promise.resolve(k()).then(()=>{l({_c:R})}),b){if(O)throw b;return}return g}}const ze=(e,t)=>{for(const n in e)e[n][0]&&e[n][0](t)},Ct=(e,t)=>{if(!P.has(e)){const n=G(gt,t),r=Object.create(null),o=Ye.bind(R,e);let s=U;const i=Object.create(null),E=(O,c)=>{const d=i[O]||[];return i[O]=d,d.push(c),()=>d.splice(d.indexOf(c),1)},S=(O,c,d)=>{e.set(O,c);const u=i[O];if(u)for(const m of u)m(c,d)},D=()=>{if(!P.has(e)&&(P.set(e,[r,Object.create(null),Object.create(null),Object.create(null),o,S,E]),!ne)){const O=n.initFocus(setTimeout.bind(R,ze.bind(R,r,Ge))),c=n.initReconnect(setTimeout.bind(R,ze.bind(R,r,We)));s=()=>{O&&O(),c&&c(),P.delete(e)}}};return D(),[e,o,D,s]}return[e,P.get(e)[4]]},It=(e,t,n,r,o)=>{const s=n.errorRetryCount,i=o.retryCount,E=~~((Math.random()+.5)*(1<<(i<8?i:8)))*n.errorRetryInterval;!f(s)&&i>s||setTimeout(r,E,o)},bt=pe,[Xe,Lt]=Ct(new Map),Vt=G({onLoadingSlow:U,onSuccess:U,onError:U,onErrorRetry:It,onDiscarded:U,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:Je?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:Je?5e3:3e3,compare:bt,isPaused:()=>!1,cache:Xe,mutate:Lt,fallback:{}},yt),Nt=(e,t)=>{const n=G(e,t);if(t){const{use:r,fallback:o}=e,{use:s,fallback:i}=t;r&&s&&(n.use=r.concat(s)),o&&i&&(n.fallback=G(o,i))}return n},Ft=p.createContext({}),Mt="$inf$",Qe=te&&window.__SWR_DEVTOOLS_USE__,Pt=Qe?window.__SWR_DEVTOOLS_USE__:[],jt=()=>{Qe&&(window.__SWR_DEVTOOLS_REACT__=p)},xt=e=>F(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],Ut=()=>G(Vt,p.useContext(Ft)),Gt=e=>(t,n,r)=>e(t,n&&((...s)=>{const[i]=De(t),[,,,E]=P.get(Xe);if(i.startsWith(Mt))return n(...s);const S=E[i];return f(S)?n(...s):(delete E[i],S)}),r),Wt=Pt.concat(Gt),kt=e=>function(...n){const r=Ut(),[o,s,i]=xt(n),E=Nt(r,i);let S=e;const{use:D}=E,O=(D||[]).concat(Wt);for(let c=O.length;c--;)S=O[c](S);return S(o,s||E.fetcher||null,E)},qt=(e,t,n)=>{const r=t[e]||(t[e]=[]);return r.push(n),()=>{const o=r.indexOf(n);o>=0&&(r[o]=r[r.length-1],r.pop())}};jt();const Ie=p.use||(e=>{switch(e.status){case"pending":throw e;case"fulfilled":return e.value;case"rejected":throw e.reason;default:throw e.status="pending",e.then(t=>{e.status="fulfilled",e.value=t},t=>{e.status="rejected",e.reason=t}),e}}),be={dedupe:!0},Bt=kt((e,t,n)=>{const{cache:r,compare:o,suspense:s,fallbackData:i,revalidateOnMount:E,revalidateIfStale:S,refreshInterval:D,refreshWhenHidden:O,refreshWhenOffline:c,keepPreviousData:d}=n,[u,m,l,I]=P.get(r),[a,W]=De(e),re=p.useRef(!1),k=p.useRef(!1),g=p.useRef(a),b=p.useRef(t),H=p.useRef(n),v=()=>H.current,K=()=>v().isVisible()&&v().isOnline(),[M,J,q,V]=He(r,a),Y=p.useRef({}).current,le=f(i)?f(n.fallback)?R:n.fallback[a]:i,rt=(_,h)=>{for(const A in Y){const w=A;if(w==="data"){if(!o(_[w],h[w])&&(!f(_[w])||!o(de,h[w])))return!1}else if(h[w]!==_[w])return!1}return!0},ot=p.useMemo(()=>{const _=!a||!t?!1:f(E)?v().isPaused()||s?!1:S!==!1:E,h=C=>{const j=G(C);return delete j._k,_?{isValidating:!0,isLoading:!0,...j}:j},A=M(),w=V(),N=h(A),Q=A===w?N:h(w);let T=N;return[()=>{const C=h(M());return rt(C,T)?(T.data=C.data,T.isLoading=C.isLoading,T.isValidating=C.isValidating,T.error=C.error,T):(T=C,C)},()=>Q]},[r,a]),z=ht.useSyncExternalStore(p.useCallback(_=>q(a,(h,A)=>{rt(A,h)||_()}),[r,a]),ot[0],ot[1]),st=!re.current,on=u[a]&&u[a].length>0,X=z.data,B=f(X)?le&&$e(le)?Ie(le):le:X,fe=z.error,Ne=p.useRef(B),de=d?f(X)?f(Ne.current)?B:Ne.current:X:B,it=on&&!f(fe)?!1:st&&!f(E)?E:v().isPaused()?!1:s?f(B)?!1:S:f(B)||S,at=!!(a&&t&&st&&it),sn=f(z.isValidating)?at:z.isValidating,an=f(z.isLoading)?at:z.isLoading,oe=p.useCallback(async _=>{const h=b.current;if(!a||!h||k.current||v().isPaused())return!1;let A,w,N=!0;const Q=_||{},T=!l[a]||!Q.dedupe,C=()=>Ke?!k.current&&a===g.current&&re.current:a===g.current,j={isValidating:!1,isLoading:!1},ct=()=>{J(j)},lt=()=>{const L=l[a];L&&L[1]===w&&delete l[a]},ft={isValidating:!0};f(M().data)&&(ft.isLoading=!0);try{if(T&&(J(ft),n.loadingTimeout&&f(M().data)&&setTimeout(()=>{N&&C()&&v().onLoadingSlow(a,n)},n.loadingTimeout),l[a]=[h(W),Ce()]),[A,w]=l[a],A=await A,T&&setTimeout(lt,n.dedupingInterval),!l[a]||l[a][1]!==w)return T&&C()&&v().onDiscarded(a),!1;j.error=R;const L=m[a];if(!f(L)&&(w<=L[0]||w<=L[1]||L[1]===0))return ct(),T&&C()&&v().onDiscarded(a),!1;const x=M().data;j.data=o(x,A)?x:A,T&&C()&&v().onSuccess(A,a,n)}catch(L){lt();const x=v(),{shouldRetryOnError:Fe}=x;x.isPaused()||(j.error=L,T&&C()&&(x.onError(L,a,x),(Fe===!0||F(Fe)&&Fe(L))&&(!v().revalidateOnFocus||!v().revalidateOnReconnect||K())&&x.onErrorRetry(L,a,x,un=>{const Me=u[a];Me&&Me[0]&&Me[0](qe,un)},{retryCount:(Q.retryCount||0)+1,dedupe:!0})))}return N=!1,ct(),!0},[a,r]),ut=p.useCallback((..._)=>Ye(r,g.current,..._),[]);if(ye(()=>{b.current=t,H.current=n,f(X)||(Ne.current=X)}),ye(()=>{if(!a)return;const _=oe.bind(R,be);let h=0;v().revalidateOnFocus&&(h=Date.now()+v().focusThrottleInterval);const w=qt(a,u,(N,Q={})=>{if(N==Ge){const T=Date.now();v().revalidateOnFocus&&T>h&&K()&&(h=T+v().focusThrottleInterval,_())}else if(N==We)v().revalidateOnReconnect&&K()&&_();else{if(N==ke)return oe();if(N==qe)return oe(Q)}});return k.current=!1,g.current=a,re.current=!0,J({_k:W}),it&&(f(B)||ne?_():At(_)),()=>{k.current=!0,w()}},[a]),ye(()=>{let _;function h(){const w=F(D)?D(M().data):D;w&&_!==-1&&(_=setTimeout(A,w))}function A(){!M().error&&(O||v().isVisible())&&(c||v().isOnline())?oe(be).then(h):h()}return h(),()=>{_&&(clearTimeout(_),_=-1)}},[D,O,c,a]),p.useDebugValue(de),s&&f(B)&&a){if(!Ke&&ne)throw new Error("Fallback data is required when using Suspense in SSR.");b.current=t,H.current=n,k.current=!1;const _=I[a];if(!f(_)){const h=ut(_);Ie(h)}if(f(fe)){const h=oe(be);f(de)||(h.status="fulfilled",h.value=!0),Ie(h)}else throw fe}return{mutate:ut,get data(){return Y.data=!0,de},get error(){return Y.error=!0,fe},get isValidating(){return Y.isValidating=!0,sn},get isLoading(){return Y.isLoading=!0,an}}}),Le="https://api.figma.com",$t=`${Le}/v1/files`,Ze=`${Le}/v1/variables`,et=Ze,tt=e=>`${Ze}/${e}`,Ht=e=>`${$t}/${e}/variables/local`,Kt="application/json",nt="X-FIGMA-TOKEN",$="A Figma API token is required.",Jt="An error occurred while fetching data from the Figma API.";async function Yt(e,t){if(!t)throw new Error($);const n=await fetch(e,{method:"GET",headers:{[nt]:t,"Content-Type":Kt}});if(!n.ok){let r=Jt;try{const o=await n.json();o!=null&&o.message&&(r=o.message)}catch{}throw new Error(r)}return n.json()}const Ve=()=>{const{token:e,fileKey:t}=ee(),n=t?Ht(t):null,{data:r,error:o,isLoading:s,isValidating:i,mutate:E}=Bt(e&&n?[n,e]:null,Yt);return{data:r,isLoading:s,isValidating:i,error:o,mutate:E}},zt=()=>{const{data:e}=Ve(),t=p.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),n=p.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:t,collectionsById:n}},Xt=()=>{const{data:e}=Ve();return p.useMemo(()=>{const t=[],n={},r={};if(e!=null&&e.meta)for(const o of Object.values(e.meta.variableCollections)){t.push(...o.modes),n[o.id]=o.modes;for(const s of o.modes)r[s.modeId]=s}return{modes:t,modesByCollectionId:n,modesById:r}},[e])};function Qt(e,t){switch(t.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:t.payload};case"error":return{...e,status:"error",error:t.payload};default:return e}}const ue=e=>{const t={status:"idle",data:null,error:null},[n,r]=p.useReducer(Qt,t);return{mutate:p.useCallback(async s=>{r({type:"loading"});try{const i=await e(s);return r({type:"success",payload:i}),i}catch(i){r({type:"error",payload:i});return}},[e]),...n,isLoading:n.status==="loading",isSuccess:n.status==="success",isError:n.status==="error"}};async function ce(e,t,n,r){if(!t)throw new Error($);const s={CREATE:"POST",UPDATE:"PUT",DELETE:"DELETE"}[n],i=await fetch(`${Le}${e}`,{method:s,headers:{"Content-Type":"application/json",[nt]:t},body:r?JSON.stringify(r):void 0});if(!i.ok){const E=await i.json().catch(()=>({}));throw new Error(E.err||E.message||"An API error occurred")}return i.status===204||!i.body?{}:i.json()}const Zt=()=>{const{token:e}=ee();return ue(async n=>{if(!e)throw new Error($);return await ce(et,e,"CREATE",n)})},en=()=>{const{token:e}=ee();return ue(async({variableId:n,payload:r})=>{if(!e)throw new Error($);const o=tt(n);return await ce(o,e,"UPDATE",r)})},tn=()=>{const{token:e}=ee();return ue(async n=>{if(!e)throw new Error($);return await ce(tt(n),e,"DELETE",void 0)})},nn=()=>{const{token:e}=ee();return ue(async n=>{if(!e)throw new Error($);return await ce(et,e,"CREATE",n)})};function rn(e,t){return e.filter(n=>{let r=!0;return t.resolvedType&&(r=r&&n.resolvedType===t.resolvedType),t.name&&(r=r&&n.name.includes(t.name)),r})}y.FigmaVarsProvider=dt,y.filterVariables=rn,y.useBulkUpdateVariables=nn,y.useCreateVariable=Zt,y.useDeleteVariable=tn,y.useUpdateVariable=en,y.useVariableCollections=zt,y.useVariableModes=Xt,y.useVariables=Ve,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level utility to fetch data from the Figma Variables REST API with authentication.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Sends an authenticated HTTP GET request to the given Figma API endpoint using the provided Personal Access Token (PAT).
|
|
6
|
+
* Parses JSON responses and throws detailed errors for failed requests.
|
|
7
|
+
* Intended for internal use by hooks but can be used directly for custom API interactions.
|
|
8
|
+
*
|
|
9
|
+
* @param url - The full Figma REST API endpoint URL (e.g., 'https://api.figma.com/v1/files/{file_key}/variables').
|
|
10
|
+
* @param token - Figma Personal Access Token (PAT) for authentication.
|
|
11
|
+
*
|
|
12
|
+
* @returns A Promise resolving to the parsed JSON response from the Figma API.
|
|
13
|
+
*
|
|
14
|
+
* @throws Throws an Error if the token is not provided.
|
|
15
|
+
* @throws Throws an Error if the HTTP response is not ok, including the message returned by the Figma API or a default error message.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { fetcher } from '@figma-vars/hooks/api';
|
|
20
|
+
*
|
|
21
|
+
* async function loadVariables(fileKey: string, token: string) {
|
|
22
|
+
* const url = `https://api.figma.com/v1/files/${fileKey}/variables`;
|
|
23
|
+
* const data = await fetcher(url, token);
|
|
24
|
+
* return data;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function fetcher(url: string, token: string): Promise<any>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Barrel file for API utilities and mutators in @figma-vars/hooks.
|
|
4
|
+
*
|
|
5
|
+
* @summary
|
|
6
|
+
* Central entry point for all API-related utilities used to interact with the Figma Variables REST API.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* This module re-exports the core fetch and mutation functions that provide network communication and RESTful operations for Figma Variables.
|
|
10
|
+
* Import from here to access low-level API functions supporting hooks and other utilities.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { fetcher, mutator } from '@figma-vars/hooks/api';
|
|
15
|
+
*
|
|
16
|
+
* async function loadVariables() {
|
|
17
|
+
* const variables = await fetcher('/variables', 'YOUR_FIGMA_TOKEN');
|
|
18
|
+
* // process variables
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export { fetcher } from './fetcher';
|
|
25
|
+
export { mutator } from './mutator';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { VariableAction } from '../types/mutations';
|
|
2
|
+
/**
|
|
3
|
+
* Low-level utility to send authenticated POST, PUT, or DELETE requests to the Figma Variables REST API.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* This function performs authenticated HTTP mutations (POST, PUT, DELETE) against the specified Figma API endpoint.
|
|
7
|
+
* It handles JSON serialization of the request body, parses JSON responses, and propagates detailed errors.
|
|
8
|
+
* Intended primarily for internal use by mutation hooks, but also suitable for direct custom API mutations.
|
|
9
|
+
*
|
|
10
|
+
* @typeParam T - The expected response type returned from the Figma API.
|
|
11
|
+
* @param url - The full Figma REST API endpoint URL (e.g., 'https://api.figma.com/v1/files/{file_key}/variables').
|
|
12
|
+
* @param token - Figma Personal Access Token (PAT) used for authentication.
|
|
13
|
+
* @param action - The action for the mutation: 'CREATE', 'UPDATE', or 'DELETE'.
|
|
14
|
+
* @param body - Optional request payload sent as a JSON string.
|
|
15
|
+
*
|
|
16
|
+
* @returns A Promise resolving to the parsed JSON response from the Figma API.
|
|
17
|
+
*
|
|
18
|
+
* @throws Throws an Error if the token is not provided.
|
|
19
|
+
* @throws Throws an Error if the HTTP response is unsuccessful, including the error message from the API or a default message.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { mutator } from '@figma-vars/hooks/api';
|
|
24
|
+
*
|
|
25
|
+
* async function updateVariable(fileKey: string, token: string, variableId: string) {
|
|
26
|
+
* const url = `https://api.figma.com/v1/files/${fileKey}/variables/${variableId}`;
|
|
27
|
+
* const payload = { name: 'Updated Name' };
|
|
28
|
+
* const result = await mutator(url, token, 'PUT', payload);
|
|
29
|
+
* return result;
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function mutator(url: string, token: string, action: VariableAction, body?: any): Promise<any>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Constants and error messages used across the @figma-vars/hooks library.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Includes base URLs for the Figma API, endpoint builders, HTTP content types, header keys, and consistent error message strings for various failure scenarios.
|
|
7
|
+
*
|
|
8
|
+
* Use these constants to ensure consistent API interaction and error handling throughout the library.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export declare const FIGMA_API_BASE_URL = "https://api.figma.com";
|
|
13
|
+
export declare const FIGMA_FILES_ENDPOINT = "https://api.figma.com/v1/files";
|
|
14
|
+
/**
|
|
15
|
+
* Builds the Figma Variables endpoint URL for a given file key.
|
|
16
|
+
*
|
|
17
|
+
* @param fileKey - The unique key of the Figma file.
|
|
18
|
+
* @returns The URL string to access variables in the specified file.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const url = FIGMA_VARIABLES_ENDPOINT('your-file-key')
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare const FIGMA_VARIABLES_ENDPOINT: (fileKey: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* The base endpoint for creating new variables via POST requests.
|
|
28
|
+
*/
|
|
29
|
+
export declare const FIGMA_POST_VARIABLES_ENDPOINT = "https://api.figma.com/v1/variables";
|
|
30
|
+
/**
|
|
31
|
+
* Builds the URL to access a specific Figma variable by its ID.
|
|
32
|
+
*
|
|
33
|
+
* @param variableId - The unique ID of the Figma variable.
|
|
34
|
+
* @returns The URL string to access the variable.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const url = FIGMA_VARIABLE_BY_ID_ENDPOINT('variable-id')
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare const FIGMA_VARIABLE_BY_ID_ENDPOINT: (variableId: string) => string;
|
|
42
|
+
/**
|
|
43
|
+
* Builds the URL to fetch local variables for a given Figma file.
|
|
44
|
+
*
|
|
45
|
+
* @param fileKey - The unique key of the Figma file.
|
|
46
|
+
* @returns The URL string to access local variables.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const url = FIGMA_LOCAL_VARIABLES_ENDPOINT('your-file-key')
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare const FIGMA_LOCAL_VARIABLES_ENDPOINT: (fileKey: string) => string;
|
|
54
|
+
/**
|
|
55
|
+
* The HTTP Content-Type header value for JSON requests.
|
|
56
|
+
*/
|
|
57
|
+
export declare const CONTENT_TYPE_JSON = "application/json";
|
|
58
|
+
/**
|
|
59
|
+
* The HTTP header key used to pass the Figma Personal Access Token.
|
|
60
|
+
*/
|
|
61
|
+
export declare const FIGMA_TOKEN_HEADER = "X-FIGMA-TOKEN";
|
|
62
|
+
/**
|
|
63
|
+
* Error message when no Figma API token is provided.
|
|
64
|
+
*/
|
|
65
|
+
export declare const ERROR_MSG_TOKEN_REQUIRED = "A Figma API token is required.";
|
|
66
|
+
/**
|
|
67
|
+
* Error message when both the Figma API token and file key are missing.
|
|
68
|
+
*/
|
|
69
|
+
export declare const ERROR_MSG_TOKEN_FILE_KEY_REQUIRED = "A Figma API token is required. and file key are required.";
|
|
70
|
+
/**
|
|
71
|
+
* Error message when a bulk update operation fails.
|
|
72
|
+
*/
|
|
73
|
+
export declare const ERROR_MSG_BULK_UPDATE_FAILED = "Failed to perform bulk update.";
|
|
74
|
+
/**
|
|
75
|
+
* Error message when creating a Figma variable fails.
|
|
76
|
+
*/
|
|
77
|
+
export declare const ERROR_MSG_CREATE_VARIABLE_FAILED = "Failed to create Figma variable.";
|
|
78
|
+
/**
|
|
79
|
+
* Error message when deleting a Figma variable fails.
|
|
80
|
+
*/
|
|
81
|
+
export declare const ERROR_MSG_DELETE_VARIABLE_FAILED = "Failed to delete Figma variable.";
|
|
82
|
+
/**
|
|
83
|
+
* Error message when updating a Figma variable fails.
|
|
84
|
+
*/
|
|
85
|
+
export declare const ERROR_MSG_UPDATE_VARIABLE_FAILED = "Failed to update Figma variable.";
|
|
86
|
+
/**
|
|
87
|
+
* Error message when fetching data from the Figma API fails.
|
|
88
|
+
*/
|
|
89
|
+
export declare const ERROR_MSG_FETCH_FIGMA_DATA_FAILED = "An error occurred while fetching data from the Figma API.";
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { FigmaTokenContextType, FigmaVarsProviderProps } from '../types/contexts';
|
|
2
|
+
/**
|
|
3
|
+
* React context provider that supplies the Figma Personal Access Token and file key to all descendant components.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Wrap your application or feature subtree with this provider to securely and type-safely provide the Figma Personal Access Token (PAT) and target Figma file key. This enables all child hooks and utilities to access the Figma Variables REST API with consistent authentication and scoping.
|
|
7
|
+
*
|
|
8
|
+
* This is the central source of truth for Figma authentication and file context within the app.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { FigmaVarsProvider } from '@figma-vars/hooks/contexts';
|
|
13
|
+
*
|
|
14
|
+
* function App() {
|
|
15
|
+
* return (
|
|
16
|
+
* <FigmaVarsProvider token={process.env.FIGMA_PAT!} fileKey="AbC123">
|
|
17
|
+
* <MyDashboard />
|
|
18
|
+
* </FigmaVarsProvider>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export declare const FigmaVarsProvider: ({ children, token, fileKey, }: FigmaVarsProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
/**
|
|
27
|
+
* React hook to access the current Figma Personal Access Token and file key from context.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* Retrieves the token and file key provided by the nearest `FigmaVarsProvider`.
|
|
31
|
+
* Throws a descriptive error if used outside of the provider to prevent silent failures.
|
|
32
|
+
*
|
|
33
|
+
* Use this hook in any component or hook that requires authenticated access to the Figma Variables API scoped to a file.
|
|
34
|
+
*
|
|
35
|
+
* @returns The current FigmaTokenContextType containing `{ token, fileKey }`.
|
|
36
|
+
*
|
|
37
|
+
* @throws Throws if called outside of a `FigmaVarsProvider` context.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* import { useFigmaTokenContext } from '@figma-vars/hooks/contexts';
|
|
42
|
+
*
|
|
43
|
+
* function DebugToken() {
|
|
44
|
+
* const { token, fileKey } = useFigmaTokenContext();
|
|
45
|
+
* return (
|
|
46
|
+
* <div>
|
|
47
|
+
* <p>Token: {token?.slice(0, 6)}... (hidden for security)</p>
|
|
48
|
+
* <p>File Key: {fileKey}</p>
|
|
49
|
+
* </div>
|
|
50
|
+
* );
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export declare const useFigmaTokenContext: () => FigmaTokenContextType;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Barrel file for React context providers and related hooks in @figma-vars/hooks.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Re-exports the `FigmaVarsProvider` React context provider and the `useFigmaTokenContext` hook. Use this module to provide and access Figma API authentication and file scoping context throughout your app.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { FigmaVarsProvider, useFigmaTokenContext } from '@figma-vars/hooks';
|
|
11
|
+
*
|
|
12
|
+
* function App() {
|
|
13
|
+
* return (
|
|
14
|
+
* <FigmaVarsProvider token={process.env.FIGMA_PAT!} fileKey="your-file-key">
|
|
15
|
+
* <App />
|
|
16
|
+
* </FigmaVarsProvider>
|
|
17
|
+
* );
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export { FigmaVarsProvider, useFigmaTokenContext, } from './FigmaVarsProvider';
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module hooks
|
|
3
|
+
* Barrel file for all Figma Variables React hooks.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Re-exports all hooks for convenient importing.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* React hook to fetch all local variables, collections, and modes for the current Figma file.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* Uses SWR for efficient data fetching and caching.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { useVariables } from '@figma-vars/hooks';
|
|
21
|
+
* const { data, isLoading } = useVariables();
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export { useVariables } from './useVariables';
|
|
27
|
+
/**
|
|
28
|
+
* React hook to select and memoize variable collections from the loaded Figma variables data.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* Returns collections in both array and lookup formats for convenience.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* import { useVariableCollections } from '@figma-vars/hooks';
|
|
36
|
+
* const { collections } = useVariableCollections();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export { useVariableCollections } from './useVariableCollections';
|
|
42
|
+
/**
|
|
43
|
+
* React hook to select and memoize variable modes from the loaded Figma variables data.
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* Returns all modes, modes by collection, and modes by ID for efficient access.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* import { useVariableModes } from '@figma-vars/hooks';
|
|
51
|
+
* const { modes, modesById } = useVariableModes();
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export { useVariableModes } from './useVariableModes';
|
|
57
|
+
/**
|
|
58
|
+
* React hook to access the Figma Personal Access Token from context.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* Returns the token provided to the FigmaVarsProvider, or null if not available.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* import { useFigmaToken } from '@figma-vars/hooks';
|
|
66
|
+
* const token = useFigmaToken();
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export { default as useFigmaToken } from './useFigmaToken';
|
|
72
|
+
/**
|
|
73
|
+
* React hook to create a new Figma variable in the current file.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* Returns a mutation object with state, error, and a trigger function.
|
|
77
|
+
*
|
|
78
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* import { useCreateVariable } from '@figma-vars/hooks';
|
|
83
|
+
* const { mutate, isLoading } = useCreateVariable();
|
|
84
|
+
* // mutate({ name: 'Primary Color', ... })
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
export { useCreateVariable } from './useCreateVariable';
|
|
90
|
+
/**
|
|
91
|
+
* React hook to update an existing Figma variable by ID.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* Returns a mutation object for updating variable properties.
|
|
95
|
+
*
|
|
96
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* import { useUpdateVariable } from '@figma-vars/hooks';
|
|
101
|
+
* const { mutate } = useUpdateVariable();
|
|
102
|
+
* // mutate({ variableId: 'id', payload: { name: 'Updated' } })
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
export { useUpdateVariable } from './useUpdateVariable';
|
|
108
|
+
/**
|
|
109
|
+
* React hook to delete a Figma variable by ID.
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* Returns a mutation object for deleting variables.
|
|
113
|
+
*
|
|
114
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```tsx
|
|
118
|
+
* import { useDeleteVariable } from '@figma-vars/hooks';
|
|
119
|
+
* const { mutate } = useDeleteVariable();
|
|
120
|
+
* // mutate('variable-id')
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
export { useDeleteVariable } from './useDeleteVariable';
|
|
126
|
+
/**
|
|
127
|
+
* React hook to perform a bulk update of multiple Figma variables in a single request.
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* Returns a mutation object for bulk updates.
|
|
131
|
+
*
|
|
132
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```tsx
|
|
136
|
+
* import { useBulkUpdateVariables } from '@figma-vars/hooks';
|
|
137
|
+
* const { mutate } = useBulkUpdateVariables();
|
|
138
|
+
* // mutate({ variableIds: [...], updates: {...} })
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @public
|
|
142
|
+
*/
|
|
143
|
+
export { useBulkUpdateVariables } from './useBulkUpdateVariables';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { BulkUpdatePayload } from '../types/mutations';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that performs a bulk update of multiple Figma variables in a single request via the Figma Variables API.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Returns a mutation object with status flags and error info.
|
|
7
|
+
* Call `mutate(payload)` with a `BulkUpdatePayload` object to trigger the update—`payload` must include:
|
|
8
|
+
* - `variableIds`: array of Figma variable IDs to update
|
|
9
|
+
* - `variableCollectionId`: the collection context for the update
|
|
10
|
+
* - `updates`: an object mapping variable IDs to their updated values or properties
|
|
11
|
+
*
|
|
12
|
+
* The hook throws if the Figma Personal Access Token (PAT) is missing from context.
|
|
13
|
+
* Use for advanced workflows requiring atomic, multi-variable updates.
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { useBulkUpdateVariables } from '@figma-vars/hooks';
|
|
20
|
+
*
|
|
21
|
+
* function BulkUpdateComponent() {
|
|
22
|
+
* const { mutate, isLoading, isSuccess, error } = useBulkUpdateVariables();
|
|
23
|
+
*
|
|
24
|
+
* const handleBulkUpdate = () => {
|
|
25
|
+
* mutate({
|
|
26
|
+
* variableIds: ['VariableID:123:456', 'VariableID:123:457'],
|
|
27
|
+
* variableCollectionId: 'VariableCollectionId:123:456',
|
|
28
|
+
* updates: {
|
|
29
|
+
* 'VariableID:123:456': { name: 'Primary Color Updated' },
|
|
30
|
+
* 'VariableID:123:457': { name: 'Secondary Color Updated' }
|
|
31
|
+
* }
|
|
32
|
+
* });
|
|
33
|
+
* };
|
|
34
|
+
*
|
|
35
|
+
* if (!mutate) return <div>Not authorized. Figma token missing.</div>;
|
|
36
|
+
* if (isLoading) return <div>Updating variables…</div>;
|
|
37
|
+
* if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
|
|
38
|
+
* if (isSuccess) return <div>Variables updated successfully!</div>;
|
|
39
|
+
*
|
|
40
|
+
* return <button onClick={handleBulkUpdate}>Update All Variables</button>;
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare const useBulkUpdateVariables: () => import('../types/mutations').MutationResult<any, BulkUpdatePayload>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { CreateVariablePayload } from '../types/mutations';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that creates a new Figma variable in the current file using the Figma Variables API.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Returns a mutation object with status flags and error info. To trigger creation, call `mutate(payload)` with a `CreateVariablePayload` object containing:
|
|
7
|
+
* - `name`: the variable name
|
|
8
|
+
* - `variableCollectionId`: target collection ID
|
|
9
|
+
* - `resolvedType`: variable type
|
|
10
|
+
* - `valuesByMode`: values for one or more modes
|
|
11
|
+
*
|
|
12
|
+
* Throws if the Figma Personal Access Token (PAT) is missing from context.
|
|
13
|
+
* Use for advanced workflows, automated variable management, or custom UI tooling.
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { useCreateVariable } from '@figma-vars/hooks';
|
|
20
|
+
*
|
|
21
|
+
* function CreateVariableComponent() {
|
|
22
|
+
* const { mutate, isLoading, isSuccess, error } = useCreateVariable();
|
|
23
|
+
*
|
|
24
|
+
* const handleCreate = () => {
|
|
25
|
+
* mutate({
|
|
26
|
+
* name: 'Primary Color',
|
|
27
|
+
* variableCollectionId: 'VariableCollectionId:123:456',
|
|
28
|
+
* resolvedType: 'COLOR',
|
|
29
|
+
* valuesByMode: {
|
|
30
|
+
* '42:0': { r: 0.2, g: 0.4, b: 0.8, a: 1 }
|
|
31
|
+
* }
|
|
32
|
+
* });
|
|
33
|
+
* };
|
|
34
|
+
*
|
|
35
|
+
* if (isLoading) return <div>Creating variable…</div>;
|
|
36
|
+
* if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
|
|
37
|
+
* if (isSuccess) return <div>Variable created successfully!</div>;
|
|
38
|
+
*
|
|
39
|
+
* return <button onClick={handleCreate}>Create Variable</button>;
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export declare const useCreateVariable: () => import('../types/mutations').MutationResult<any, CreateVariablePayload>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook that deletes a Figma variable by ID using the Figma Variables API.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Returns a mutation object with status flags and error info. To trigger deletion, call `mutate(variableId)` with the variable's ID as a string.
|
|
6
|
+
* Throws if the Figma Personal Access Token (PAT) is missing from context.
|
|
7
|
+
* Use this for advanced workflows, admin tooling, or custom variable management UIs.
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { useDeleteVariable } from '@figma-vars/hooks';
|
|
14
|
+
*
|
|
15
|
+
* function DeleteVariableButton({ variableId }: { variableId: string }) {
|
|
16
|
+
* const { mutate, isLoading, isSuccess, error } = useDeleteVariable();
|
|
17
|
+
*
|
|
18
|
+
* const handleDelete = () => {
|
|
19
|
+
* mutate(variableId); // variableId must be a string
|
|
20
|
+
* };
|
|
21
|
+
*
|
|
22
|
+
* if (!mutate) return <div>Not authorized. Figma token missing.</div>;
|
|
23
|
+
* if (isLoading) return <div>Deleting variable…</div>;
|
|
24
|
+
* if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
|
|
25
|
+
* if (isSuccess) return <div>Variable deleted successfully!</div>;
|
|
26
|
+
*
|
|
27
|
+
* return <button onClick={handleDelete}>Delete Variable</button>;
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export declare const useDeleteVariable: () => import('..').MutationResult<any, string>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook that provides access to the Figma Personal Access Token (PAT) from context.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Returns the PAT provided to the FigmaVarsProvider, or `null` if no token is available. Use this hook to authenticate API requests, secure routes, or prompt users to enter their token if missing. Centralizes Figma authentication for all hooks and utilities.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { useFigmaToken } from '@figma-vars/hooks';
|
|
10
|
+
*
|
|
11
|
+
* function AuthStatus() {
|
|
12
|
+
* const token = useFigmaToken();
|
|
13
|
+
* if (!token) return <div>Please provide a Figma API token.</div>;
|
|
14
|
+
* return <div>Token available.</div>;
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
declare const useFigmaToken: () => string | null;
|
|
21
|
+
export default useFigmaToken;
|