@figma-vars/hooks 1.5.1 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +66 -1
  2. package/dist/api/fetcher.d.ts +2 -1
  3. package/dist/api/fetcher.d.ts.map +1 -0
  4. package/dist/api/index.d.ts +1 -0
  5. package/dist/api/index.d.ts.map +1 -0
  6. package/dist/api/mutator.d.ts +2 -1
  7. package/dist/api/mutator.d.ts.map +1 -0
  8. package/dist/constants/index.d.ts +1 -0
  9. package/dist/constants/index.d.ts.map +1 -0
  10. package/dist/contexts/FigmaTokenContext.d.ts +3 -0
  11. package/dist/contexts/FigmaTokenContext.d.ts.map +1 -0
  12. package/dist/contexts/FigmaVarsProvider.d.ts +3 -33
  13. package/dist/contexts/FigmaVarsProvider.d.ts.map +1 -0
  14. package/dist/contexts/index.d.ts +4 -1
  15. package/dist/contexts/index.d.ts.map +1 -0
  16. package/dist/contexts/useFigmaTokenContext.d.ts +3 -0
  17. package/dist/contexts/useFigmaTokenContext.d.ts.map +1 -0
  18. package/dist/hooks/index.d.ts +1 -0
  19. package/dist/hooks/index.d.ts.map +1 -0
  20. package/dist/hooks/useBulkUpdateVariables.d.ts +10 -25
  21. package/dist/hooks/useBulkUpdateVariables.d.ts.map +1 -0
  22. package/dist/hooks/useCreateVariable.d.ts +8 -25
  23. package/dist/hooks/useCreateVariable.d.ts.map +1 -0
  24. package/dist/hooks/useDeleteVariable.d.ts +9 -17
  25. package/dist/hooks/useDeleteVariable.d.ts.map +1 -0
  26. package/dist/hooks/useFigmaToken.d.ts +1 -0
  27. package/dist/hooks/useFigmaToken.d.ts.map +1 -0
  28. package/dist/hooks/useMutation.d.ts +1 -52
  29. package/dist/hooks/useMutation.d.ts.map +1 -0
  30. package/dist/hooks/useUpdateVariable.d.ts +14 -25
  31. package/dist/hooks/useUpdateVariable.d.ts.map +1 -0
  32. package/dist/hooks/useVariableCollections.d.ts +1 -0
  33. package/dist/hooks/useVariableCollections.d.ts.map +1 -0
  34. package/dist/hooks/useVariableModes.d.ts +1 -0
  35. package/dist/hooks/useVariableModes.d.ts.map +1 -0
  36. package/dist/hooks/useVariables.d.ts +9 -25
  37. package/dist/hooks/useVariables.d.ts.map +1 -0
  38. package/dist/index.cjs +1 -0
  39. package/dist/index.d.cts +81 -0
  40. package/dist/index.d.mts +2 -0
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.mjs +115 -752
  44. package/dist/types/contexts.d.ts +11 -0
  45. package/dist/types/contexts.d.ts.map +1 -0
  46. package/dist/types/figma.d.ts +4 -3
  47. package/dist/types/figma.d.ts.map +1 -0
  48. package/dist/types/hooks.d.ts +1 -0
  49. package/dist/types/hooks.d.ts.map +1 -0
  50. package/dist/types/index.d.ts +1 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/mutations.d.ts +4 -3
  53. package/dist/types/mutations.d.ts.map +1 -0
  54. package/dist/utils/filterVariables.d.ts +1 -0
  55. package/dist/utils/filterVariables.d.ts.map +1 -0
  56. package/dist/utils/index.d.ts +1 -0
  57. package/dist/utils/index.d.ts.map +1 -0
  58. package/package.json +43 -15
  59. package/dist/index.js +0 -17
package/README.md CHANGED
@@ -26,6 +26,8 @@ Built for the modern web, this library provides a suite of hooks to fetch, manag
26
26
  - **✍️ Ergonomic Mutations**: A `useMutation`-style API for creating, updating, and deleting variables, providing clear loading and error states.
27
27
  - **🔒 TypeScript-first**: Strictly typed for an ergonomic and safe developer experience. Get autocompletion for all API responses.
28
28
  - **📖 Storybook & Next.js Ready**: Perfect for building live design token dashboards or style guides.
29
+ - **🔄 Local JSON Support**: Use local JSON files exported from Figma Dev Mode plugins when you don't have a Figma Enterprise account, enabling offline development and static deployments.
30
+ - **🚧 Style Dictionary Integration**: Coming soon in future beta releases - seamless integration with Amazon's Style Dictionary for multi-platform design token distribution.
29
31
 
30
32
  ---
31
33
 
@@ -162,6 +164,61 @@ function CreateVariableForm({ collectionId }: { collectionId: string }) {
162
164
  }
163
165
  ```
164
166
 
167
+ ### Using Local JSON Files (No Enterprise Account Required)
168
+
169
+ If you don't have a Figma Enterprise account (required for the Variables API), you can still use this library with local JSON files exported from Figma Dev Mode plugins. This is perfect for:
170
+
171
+ - **Offline Development**: Work on your design system without an internet connection
172
+ - **Static Deployments**: Deploy design token dashboards to static hosting
173
+ - **CI/CD Pipelines**: Use exported JSON files in automated workflows
174
+ - **Team Collaboration**: Share design tokens without API access
175
+
176
+ #### Getting Your JSON File
177
+
178
+ We recommend using the [Variables Exporter for Dev Mode](https://www.figma.com/community/plugin/1491572182178544621) plugin:
179
+
180
+ 1. Install the plugin in Figma
181
+ 2. Open your Figma file in Dev Mode
182
+ 3. Run the plugin and export your variables as JSON
183
+ 4. Save the JSON file to your project (e.g., `src/assets/figma-variables.json`)
184
+
185
+ This plugin exports the exact same format that the Figma Variables API returns, ensuring perfect compatibility with this library.
186
+
187
+ #### Using the Fallback File
188
+
189
+ ```tsx
190
+ // src/main.tsx or App.tsx
191
+ import React from 'react'
192
+ import ReactDOM from 'react-dom/client'
193
+ import { FigmaVarsProvider } from '@figma-vars/hooks'
194
+ import App from './App'
195
+ import variablesData from './assets/figma-variables.json'
196
+
197
+ ReactDOM.createRoot(document.getElementById('root')!).render(
198
+ <React.StrictMode>
199
+ <FigmaVarsProvider
200
+ token={null} // No token needed when using fallbackFile
201
+ fileKey="your-figma-file-key"
202
+ fallbackFile={variablesData}>
203
+ <App />
204
+ </FigmaVarsProvider>
205
+ </React.StrictMode>
206
+ )
207
+ ```
208
+
209
+ You can also pass the JSON as a string if you prefer:
210
+
211
+ ```tsx
212
+ import variablesJson from './assets/figma-variables.json?raw'
213
+
214
+ <FigmaVarsProvider
215
+ token={null}
216
+ fileKey="your-figma-file-key"
217
+ fallbackFile={variablesJson}>
218
+ <App />
219
+ </FigmaVarsProvider>
220
+ ```
221
+
165
222
  ### Figma PAT Security
166
223
 
167
224
  When using the Figma API, it's essential to keep your Personal Access Token (PAT) secure. Here are some best practices:
@@ -231,11 +288,19 @@ function ErrorHandling() {
231
288
 
232
289
  ### Core Hooks
233
290
 
234
- - `useVariables()`: Fetches all local variables for the file key provided to the `FigmaVarsProvider`. Returns a SWR hook state with `data`, `isLoading`, and `error` properties. The actual Figma response is in `data.data`.
291
+ - `useVariables()`: Fetches all local variables for the file key provided to the `FigmaVarsProvider`. Returns a SWR hook state with `data`, `isLoading`, and `error` properties. The actual Figma response is in `data.data`. When `fallbackFile` is provided, it uses the local JSON data instead of making an API request.
235
292
  - `useVariableCollections()`: A convenience hook that returns just the variable collections from the main `useVariables` data.
236
293
  - `useVariableModes()`: A convenience hook that returns just the variable modes from the main `useVariables` data.
237
294
  - `useFigmaToken()`: A simple hook to access the token and file key from the context.
238
295
 
296
+ ### Provider Props
297
+
298
+ The `FigmaVarsProvider` accepts the following props:
299
+
300
+ - `token`: Figma Personal Access Token (PAT) for API authentication. Can be `null` when using `fallbackFile`.
301
+ - `fileKey`: Figma file key for the target file. Required for API requests but can be any string when using `fallbackFile`.
302
+ - `fallbackFile`: Optional local JSON file (as object or string) to use instead of API requests. Perfect for users without Figma Enterprise accounts.
303
+
239
304
  ### Mutation Hooks
240
305
 
241
306
  All mutation hooks return an object with the following shape: `{ mutate, data, isLoading, error }`.
@@ -25,4 +25,5 @@
25
25
  * }
26
26
  * ```
27
27
  */
28
- export declare function fetcher(url: string, token: string): Promise<any>;
28
+ export declare function fetcher<TResponse = unknown>(url: string, token: string): Promise<TResponse>;
29
+ //# sourceMappingURL=fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/api/fetcher.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,OAAO,CAAC,SAAS,GAAG,OAAO,EAC/C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,CAAC,CA2BpB"}
@@ -23,3 +23,4 @@
23
23
  */
24
24
  export { fetcher } from './fetcher';
25
25
  export { mutator } from './mutator';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
@@ -30,4 +30,5 @@ import { VariableAction } from '../types/mutations';
30
30
  * }
31
31
  * ```
32
32
  */
33
- export declare function mutator(url: string, token: string, action: VariableAction, body?: any): Promise<any>;
33
+ export declare function mutator<TResponse = unknown, TBody extends Record<string, unknown> = Record<string, unknown>>(url: string, token: string, action: VariableAction, body?: TBody): Promise<TResponse>;
34
+ //# sourceMappingURL=mutator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutator.d.ts","sourceRoot":"","sources":["../../src/api/mutator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,OAAO,CAAC,SAAS,GAAG,OAAO,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChH,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,KAAK,GACX,OAAO,CAAC,SAAS,CAAC,CAqCpB"}
@@ -87,3 +87,4 @@ export declare const ERROR_MSG_UPDATE_VARIABLE_FAILED = "Failed to update Figma
87
87
  * Error message when fetching data from the Figma API fails.
88
88
  */
89
89
  export declare const ERROR_MSG_FETCH_FIGMA_DATA_FAILED = "An error occurred while fetching data from the Figma API.";
90
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAE1D,eAAO,MAAM,oBAAoB,mCAAmC,CAAC;AAIrE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,WACR,CAAC;AAEjD;;GAEG;AACH,eAAO,MAAM,6BAA6B,uCAAmC,CAAC;AAE9E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6BAA6B,GAAI,YAAY,MAAM,WACX,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,GAAI,SAAS,MAAM,WACR,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,wBAAwB,mCAAmC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,iCAAiC,8DAA2D,CAAC;AAE1G;;GAEG;AACH,eAAO,MAAM,4BAA4B,mCAAmC,CAAC;AAE7E;;GAEG;AACH,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,iCAAiC,8DACe,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { FigmaTokenContextType } from '../types/contexts';
2
+ export declare const FigmaTokenContext: import('react').Context<FigmaTokenContextType | undefined>;
3
+ //# sourceMappingURL=FigmaTokenContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FigmaTokenContext.d.ts","sourceRoot":"","sources":["../../src/contexts/FigmaTokenContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D,eAAO,MAAM,iBAAiB,4DAA8D,CAAC"}
@@ -1,4 +1,4 @@
1
- import { FigmaTokenContextType, FigmaVarsProviderProps } from '../types/contexts';
1
+ import { FigmaVarsProviderProps } from '../types/contexts';
2
2
  /**
3
3
  * React context provider that supplies the Figma Personal Access Token and file key to all descendant components.
4
4
  *
@@ -22,35 +22,5 @@ import { FigmaTokenContextType, FigmaVarsProviderProps } from '../types/contexts
22
22
  *
23
23
  * @public
24
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;
25
+ export declare const FigmaVarsProvider: ({ children, token, fileKey, fallbackFile, }: FigmaVarsProviderProps) => import("react/jsx-runtime").JSX.Element;
26
+ //# sourceMappingURL=FigmaVarsProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FigmaVarsProvider.d.ts","sourceRoot":"","sources":["../../src/contexts/FigmaVarsProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAGpF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,iBAAiB,GAAI,6CAK/B,sBAAsB,4CAUxB,CAAC"}
@@ -18,4 +18,7 @@
18
18
  * }
19
19
  * ```
20
20
  */
21
- export { FigmaVarsProvider, useFigmaTokenContext, } from './FigmaVarsProvider';
21
+ export { FigmaVarsProvider, } from './FigmaVarsProvider';
22
+ export { useFigmaTokenContext } from './useFigmaTokenContext';
23
+ export { FigmaTokenContext } from './FigmaTokenContext';
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { FigmaTokenContextType } from '../types/contexts';
2
+ export declare const useFigmaTokenContext: () => FigmaTokenContextType;
3
+ //# sourceMappingURL=useFigmaTokenContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFigmaTokenContext.d.ts","sourceRoot":"","sources":["../../src/contexts/useFigmaTokenContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D,eAAO,MAAM,oBAAoB,QAAO,qBAMvC,CAAC"}
@@ -141,3 +141,4 @@ export { useDeleteVariable } from './useDeleteVariable';
141
141
  * @public
142
142
  */
143
143
  export { useBulkUpdateVariables } from './useBulkUpdateVariables';
144
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -3,44 +3,29 @@ import { BulkUpdatePayload } from '../types/mutations';
3
3
  * React hook that performs a bulk update of multiple Figma variables in a single request via the Figma Variables API.
4
4
  *
5
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}
6
+ * This hook is designed to perform a batch operation for creating, updating, and deleting variables, collections, and modes.
7
+ * It provides an ergonomic API with `mutate` and loading/error state for easy integration.
16
8
  *
17
9
  * @example
18
10
  * ```tsx
19
11
  * import { useBulkUpdateVariables } from '@figma-vars/hooks';
20
12
  *
21
- * function BulkUpdateComponent() {
22
- * const { mutate, isLoading, isSuccess, error } = useBulkUpdateVariables();
13
+ * function BulkUpdateButton() {
14
+ * const { mutate, isLoading, error } = useBulkUpdateVariables();
23
15
  *
24
16
  * const handleBulkUpdate = () => {
25
17
  * 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
- * }
18
+ * variables: [{ action: 'UPDATE', id: 'VariableId:123', name: 'new-name' }],
32
19
  * });
33
20
  * };
34
21
  *
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>;
22
+ * if (isLoading) return <div>Updating...</div>;
23
+ * if (error) return <div>Error: {error.message}</div>;
24
+ * return <button onClick={handleBulkUpdate}>Bulk Update</button>;
41
25
  * }
42
26
  * ```
43
27
  *
44
28
  * @public
45
29
  */
46
- export declare const useBulkUpdateVariables: () => import('../types/mutations').MutationResult<any, BulkUpdatePayload>;
30
+ export declare const useBulkUpdateVariables: () => import('../types/mutations').MutationResult<unknown, BulkUpdatePayload>;
31
+ //# sourceMappingURL=useBulkUpdateVariables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBulkUpdateVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/useBulkUpdateVariables.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAOzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,sBAAsB,4EAclC,CAAC"}
@@ -3,43 +3,26 @@ import { CreateVariablePayload } from '../types/mutations';
3
3
  * React hook that creates a new Figma variable in the current file using the Figma Variables API.
4
4
  *
5
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}
6
+ * The hook returns a `mutate` function to trigger the creation along with state flags and data.
16
7
  *
17
8
  * @example
18
9
  * ```tsx
19
10
  * import { useCreateVariable } from '@figma-vars/hooks';
20
11
  *
21
- * function CreateVariableComponent() {
22
- * const { mutate, isLoading, isSuccess, error } = useCreateVariable();
12
+ * function CreateVariableButton() {
13
+ * const { mutate, isLoading, error } = useCreateVariable();
23
14
  *
24
15
  * 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
- * });
16
+ * mutate({ name: 'new-variable', variableCollectionId: 'VariableCollectionId:1:1', resolvedType: 'COLOR' });
33
17
  * };
34
18
  *
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
- *
19
+ * if (isLoading) return <div>Creating...</div>;
20
+ * if (error) return <div>Error: {error.message}</div>;
39
21
  * return <button onClick={handleCreate}>Create Variable</button>;
40
22
  * }
41
23
  * ```
42
24
  *
43
25
  * @public
44
26
  */
45
- export declare const useCreateVariable: () => import('../types/mutations').MutationResult<any, CreateVariablePayload>;
27
+ export declare const useCreateVariable: () => import('../types/mutations').MutationResult<unknown, CreateVariablePayload>;
28
+ //# sourceMappingURL=useCreateVariable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCreateVariable.d.ts","sourceRoot":"","sources":["../../src/hooks/useCreateVariable.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAO7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,iBAAiB,gFAc7B,CAAC"}
@@ -2,32 +2,24 @@
2
2
  * React hook that deletes a Figma variable by ID using the Figma Variables API.
3
3
  *
4
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}
5
+ * This hook provides a `mutate` function to trigger the deletion and exposes loading and error states.
10
6
  *
11
7
  * @example
12
8
  * ```tsx
13
9
  * import { useDeleteVariable } from '@figma-vars/hooks';
14
10
  *
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
- * };
11
+ * function DeleteVariableButton({ id }: { id: string }) {
12
+ * const { mutate, isLoading, error } = useDeleteVariable();
21
13
  *
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>;
14
+ * const onDelete = () => mutate(id);
26
15
  *
27
- * return <button onClick={handleDelete}>Delete Variable</button>;
16
+ * if (isLoading) return <div>Deleting...</div>;
17
+ * if (error) return <div>Error: {error.message}</div>;
18
+ * return <button onClick={onDelete}>Delete Variable</button>;
28
19
  * }
29
20
  * ```
30
21
  *
31
22
  * @public
32
23
  */
33
- export declare const useDeleteVariable: () => import('..').MutationResult<any, string>;
24
+ export declare const useDeleteVariable: () => import('..').MutationResult<unknown, string>;
25
+ //# sourceMappingURL=useDeleteVariable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDeleteVariable.d.ts","sourceRoot":"","sources":["../../src/hooks/useDeleteVariable.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,iBAAiB,oDAc7B,CAAC"}
@@ -19,3 +19,4 @@
19
19
  */
20
20
  declare const useFigmaToken: () => string | null;
21
21
  export default useFigmaToken;
22
+ //# sourceMappingURL=useFigmaToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFigmaToken.d.ts","sourceRoot":"","sources":["../../src/hooks/useFigmaToken.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,QAAA,MAAM,aAAa,QAAO,MAAM,GAAG,IAGlC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -1,53 +1,2 @@
1
- import { MutationState, MutationResult } from '../types/mutations';
2
- type MutationStatus = 'idle' | 'loading' | 'success' | 'error';
3
- /**
4
- * Internal reducer to manage async mutation state for all mutation hooks.
5
- *
6
- * @remarks
7
- * Handles mutation status transitions (`loading`, `success`, `error`) and enforces consistent error/data handling across the library.
8
- * Used by {@link useMutation} and not intended for direct use in external code.
9
- *
10
- * @typeParam TData - The type of data returned by the mutation.
11
- *
12
- * @example
13
- * ```ts
14
- * import { mutationReducer } from '@figma-vars/hooks';
15
- * const [state, dispatch] = useReducer(mutationReducer, initialState);
16
- * // Internal pattern for mutation state management
17
- * ```
18
- *
19
- * @internal
20
- */
21
- export declare function mutationReducer<TData>(state: MutationState<TData>, action: {
22
- type: MutationStatus;
23
- payload?: TData | Error;
24
- }): MutationState<TData>;
25
- /**
26
- * Internal React hook for async mutation state, status flags, and mutation trigger.
27
- *
28
- * @remarks
29
- * Returns a mutation object with status, error, and result data. Preferred pattern: use higher-level hooks (e.g., `useCreateVariable`, `useUpdateVariable`) rather than using this directly in production code.
30
- * The provided `mutationFn` must be an async function that performs the actual mutation (API call, etc). See example for pattern.
31
- *
32
- * @typeParam TData - Type returned by the mutation.
33
- * @typeParam TPayload - Payload accepted by the mutation function.
34
- * @param mutationFn - Async function performing the mutation logic.
35
- * @returns Mutation state, status flags, and a `mutate(payload)` trigger function.
36
- *
37
- * @example
38
- * ```ts
39
- * import { useMutation } from '@figma-vars/hooks';
40
- *
41
- * // Example: use for custom async logic
42
- * const { mutate, isLoading, isSuccess, error } = useMutation(async (payload: MyPayload) => {
43
- * // Your async mutation logic here (e.g., API call)
44
- * return result;
45
- * });
46
- *
47
- * // Call mutate(payload) to trigger the mutation.
48
- * ```
49
- *
50
- * @internal
51
- */
52
- export declare const useMutation: <TData, TPayload>(mutationFn: (payload: TPayload) => Promise<TData>) => MutationResult<TData, TPayload>;
53
1
  export {};
2
+ //# sourceMappingURL=useMutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../../src/hooks/useMutation.ts"],"names":[],"mappings":""}
@@ -1,40 +1,29 @@
1
- import { UpdateVariableArgs } from '../types/hooks';
1
+ import { UpdateVariablePayload } from '../types/mutations';
2
2
  /**
3
- * React hook that updates a Figma variable by its ID via the Figma Variables API.
3
+ * React hook that updates an existing Figma variable by ID using the Figma Variables API.
4
4
  *
5
5
  * @remarks
6
- * Returns a mutation object with status flags, error info, and a trigger function. Call `mutate({ variableId, payload })` to update a variable—provide the target variable's ID and the update payload.
7
- * Throws if the Figma Personal Access Token (PAT) is missing from context.
8
- * Use for advanced UI tooling or bulk edit workflows.
9
- *
10
- * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
6
+ * The hook returns a `mutate` function to trigger the update with given payload and exposes state flags.
11
7
  *
12
8
  * @example
13
9
  * ```tsx
14
10
  * import { useUpdateVariable } from '@figma-vars/hooks';
15
11
  *
16
- * function UpdateVariableButton({ variableId }: { variableId: string }) {
17
- * const { mutate, isLoading, isSuccess, error } = useUpdateVariable();
18
- *
19
- * const handleUpdate = () => {
20
- * mutate({
21
- * variableId,
22
- * payload: {
23
- * name: 'Updated Name',
24
- * description: 'Updated description',
25
- * },
26
- * });
27
- * };
12
+ * function UpdateVariableButton({ id }: { id: string }) {
13
+ * const { mutate, isLoading, error } = useUpdateVariable();
28
14
  *
29
- * if (!mutate) return <div>Not authorized. Figma token missing.</div>;
30
- * if (isLoading) return <div>Updating variable…</div>;
31
- * if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
32
- * if (isSuccess) return <div>Variable updated successfully!</div>;
15
+ * const onUpdate = () => mutate({ variableId: id, payload: { name: 'new-name' } });
33
16
  *
34
- * return <button onClick={handleUpdate}>Update Variable</button>;
17
+ * if (isLoading) return <div>Updating...</div>;
18
+ * if (error) return <div>Error: {error.message}</div>;
19
+ * return <button onClick={onUpdate}>Update Variable</button>;
35
20
  * }
36
21
  * ```
37
22
  *
38
23
  * @public
39
24
  */
40
- export declare const useUpdateVariable: () => import('..').MutationResult<any, UpdateVariableArgs>;
25
+ export declare const useUpdateVariable: () => import('../types/mutations').MutationResult<unknown, {
26
+ variableId: string;
27
+ payload: UpdateVariablePayload;
28
+ }>;
29
+ //# sourceMappingURL=useUpdateVariable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUpdateVariable.d.ts","sourceRoot":"","sources":["../../src/hooks/useUpdateVariable.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAI7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,iBAAiB;gBAGoB,MAAM;aAAW,qBAAqB;EAavF,CAAC"}
@@ -33,3 +33,4 @@ export declare const useVariableCollections: () => {
33
33
  collections: FigmaCollection[];
34
34
  collectionsById: Record<string, FigmaCollection>;
35
35
  };
36
+ //# sourceMappingURL=useVariableCollections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVariableCollections.d.ts","sourceRoot":"","sources":["../../src/hooks/useVariableCollections.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,sBAAsB;;;CAiBlC,CAAC"}
@@ -30,3 +30,4 @@ import { UseVariableModesResult } from '../types/hooks';
30
30
  * @public
31
31
  */
32
32
  export declare const useVariableModes: () => UseVariableModesResult;
33
+ //# sourceMappingURL=useVariableModes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVariableModes.d.ts","sourceRoot":"","sources":["../../src/hooks/useVariableModes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,gBAAgB,QAAO,sBAwBnC,CAAC"}
@@ -1,32 +1,16 @@
1
- import { SWRResponse } from 'swr';
2
- import { LocalVariablesResponse } from 'types';
1
+ import { LocalVariablesResponse } from '../types/figma';
3
2
  /**
4
- * React hook that fetches all local variables, collections, and modes for the current Figma file via the Variables API.
3
+ * Hook to fetch and manage Figma Variables, including collections and modes.
5
4
  *
6
5
  * @remarks
7
- * Returns an object with SWR state for the Figma local variables endpoint, including:
8
- * - `data`: the variables response object (or undefined)
9
- * - `isLoading`: boolean loading state
10
- * - `isValidating`: boolean validation state
11
- * - `error`: error object (if any)
6
+ * This hook uses SWR for caching and revalidation. It fetches the variables for the
7
+ * file key provided via the FigmaVarsProvider context. If a fallbackFile is provided,
8
+ * it will use that instead of making an API request, which is useful for users without
9
+ * Figma Enterprise accounts or for offline development.
12
10
  *
13
- * Use this as the single source of truth for all variables, collections, and modes within the current file context.
14
- *
15
- * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
16
- *
17
- * @example
18
- * ```tsx
19
- * import { useVariables } from '@figma-vars/hooks';
20
- *
21
- * function VariablesPanel() {
22
- * const { data, isLoading, error } = useVariables();
23
- * if (isLoading) return <span>Loading variables…</span>;
24
- * if (error) return <span style={{ color: 'red' }}>Error: {error.message}</span>;
25
- * if (!data) return <span>No variables found.</span>;
26
- * return <pre>{JSON.stringify(data, null, 2)}</pre>;
27
- * }
28
- * ```
11
+ * @returns SWR response object with `data`, `error`, `isLoading`, and `isValidating`.
29
12
  *
30
13
  * @public
31
14
  */
32
- export declare const useVariables: () => SWRResponse<LocalVariablesResponse>;
15
+ export declare const useVariables: () => import('swr').SWRResponse<LocalVariablesResponse, any, import('swr').SWRConfiguration<LocalVariablesResponse, any, import('swr').BareFetcher<LocalVariablesResponse>> | undefined>;
16
+ //# sourceMappingURL=useVariables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/useVariables.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAG1D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,0LAoBxB,CAAC"}
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("react/jsx-runtime"),i=require("react"),_=require("swr"),p=i.createContext(void 0),g=({children:e,token:r,fileKey:t,fallbackFile:o})=>{const s=o===void 0?{token:r,fileKey:t}:{token:r,fileKey:t,fallbackFile:o};return b.jsx(p.Provider,{value:s,children:e})},l=()=>{const e=i.useContext(p);if(e===void 0)throw new Error("useFigmaTokenContext must be used within a FigmaVarsProvider");return e},h="https://api.figma.com",w=`${h}/v1/variables`,T=w,y=e=>`${w}/${e}`,v="application/json",A="X-FIGMA-TOKEN",u="A Figma API token is required.",I="An error occurred while fetching data from the Figma API.";async function V(e,r){if(!r)throw new Error(u);const t=await fetch(e,{method:"GET",headers:{[A]:r,"Content-Type":v}});if(!t.ok){let o=I;try{const s=await t.json();s!=null&&s.message&&(o=s.message)}catch{}throw new Error(o)}return t.json()}const E=()=>{const{token:e,fileKey:r,fallbackFile:t}=l(),o=async(n,a)=>t?typeof t=="string"?JSON.parse(t):t:V(n,a),s=e&&r?`https://api.figma.com/v1/files/${r}/variables/local`:null;return _(s&&e?[s,e]:null,s&&e?([n,a])=>o(n,a):()=>Promise.resolve(void 0))},R=()=>{const{data:e}=E(),r=i.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),t=i.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:r,collectionsById:t}},C=()=>{const{data:e}=E();return i.useMemo(()=>{const r=[],t={},o={};if(e!=null&&e.meta)for(const s of Object.values(e.meta.variableCollections)){r.push(...s.modes),t[s.id]=s.modes;for(const c of s.modes)o[c.modeId]=c}return{modes:r,modesByCollectionId:t,modesById:o}},[e])};function M(e,r){switch(r.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:r.payload};case"error":return{...e,status:"error",error:r.payload};default:return e}}const d=e=>{const r={status:"idle",data:null,error:null},[t,o]=i.useReducer(M,r);return{mutate:i.useCallback(async c=>{o({type:"loading"});try{const n=await e(c);return o({type:"success",payload:n}),n}catch(n){o({type:"error",payload:n});return}},[e]),...t,isLoading:t.status==="loading",isSuccess:t.status==="success",isError:t.status==="error"}};async function m(e,r,t,o){if(!r)throw new Error(u);const n={method:{CREATE:"POST",UPDATE:"PUT",DELETE:"DELETE"}[t],headers:{"Content-Type":"application/json",[A]:r}};o&&(n.body=JSON.stringify(o));const a=await fetch(`${h}${e}`,n);if(!a.ok){const f=await a.json().catch(()=>({}));throw new Error(f.err||f.message||"An API error occurred")}return a.status===204||!a.body?{}:a.json()}const P=()=>{const{token:e}=l();return d(async t=>{if(!e)throw new Error(u);return await m(T,e,"CREATE",t)})},F=()=>{const{token:e}=l();return d(async({variableId:t,payload:o})=>{if(!e)throw new Error(u);return await m(y(t),e,"UPDATE",o)})},O=()=>{const{token:e}=l();return d(async t=>{if(!e)throw new Error(u);return await m(y(t),e,"DELETE",void 0)})},S=()=>{const{token:e}=l();return d(async t=>{if(!e)throw new Error(u);return await m(T,e,"CREATE",t)})};function D(e,r){return e.filter(t=>{let o=!0;return r.resolvedType&&(o=o&&t.resolvedType===r.resolvedType),r.name&&(o=o&&t.name.includes(r.name)),o})}exports.FigmaVarsProvider=g;exports.filterVariables=D;exports.useBulkUpdateVariables=S;exports.useCreateVariable=P;exports.useDeleteVariable=O;exports.useUpdateVariable=F;exports.useVariableCollections=R;exports.useVariableModes=C;exports.useVariables=E;