eddev 2.3.12 → 2.3.13

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 (95) hide show
  1. package/dist/app/entry/MetaTags.d.ts.map +1 -1
  2. package/dist/app/entry/MetaTags.js +2 -0
  3. package/dist/app/lib/blocks/block-utils.d.ts +2 -2
  4. package/dist/app/lib/blocks/block-utils.d.ts.map +1 -1
  5. package/dist/app/lib/blocks/block-utils.js +10 -3
  6. package/dist/app/lib/blocks/editor/root-blocks.d.ts.map +1 -1
  7. package/dist/app/lib/blocks/editor/root-blocks.js +2 -2
  8. package/dist/app/lib/devtools/hooks/useTailwind.d.ts +45 -45
  9. package/dist/app/lib/hooks/query-hooks.d.ts +8 -8
  10. package/dist/app/lib/hooks/query-hooks.d.ts.map +1 -1
  11. package/dist/app/lib/hooks/query-hooks.js +2 -1
  12. package/dist/app/lib/runtime/apiConfig.d.ts +15 -0
  13. package/dist/app/lib/runtime/apiConfig.d.ts.map +1 -1
  14. package/dist/app/server/proxy-wp-admin.d.ts.map +1 -1
  15. package/dist/app/server/proxy-wp-admin.js +1 -0
  16. package/dist/app/server/server-context.d.ts +2 -2
  17. package/dist/app/server/server-context.d.ts.map +1 -1
  18. package/dist/app/utils/trpc-client.d.ts.map +1 -1
  19. package/dist/app/utils/trpc-client.js +19 -3
  20. package/dist/node/cli/version.d.ts +1 -1
  21. package/dist/node/cli/version.js +1 -1
  22. package/dist/node/compiler/dev-server.js +1 -1
  23. package/dist/node/compiler/get-vite-config.d.ts.map +1 -1
  24. package/dist/node/compiler/get-vite-config.js +1 -0
  25. package/dist/node/compiler/vinxi-app.d.ts +1 -1
  26. package/dist/node/compiler/vinxi-app.d.ts.map +1 -1
  27. package/dist/node/utils/fetch-wp.d.ts.map +1 -1
  28. package/dist/node/utils/fetch-wp.js +2 -1
  29. package/dist/node/utils/fs.d.ts +22 -19
  30. package/dist/node/utils/fs.d.ts.map +1 -1
  31. package/package.json +2 -2
  32. package/skills/eddev/SKILL.md +156 -0
  33. package/skills/eddev/docs/acf/admin-panel-widgets.mdx +99 -0
  34. package/skills/eddev/docs/acf/custom-enums.mdx +75 -0
  35. package/skills/eddev/docs/acf/custom-fields.mdx +131 -0
  36. package/skills/eddev/docs/acf.mdx +31 -0
  37. package/skills/eddev/docs/blocks/block-definition.mdx +189 -0
  38. package/skills/eddev/docs/blocks/core-blocks.mdx +86 -0
  39. package/skills/eddev/docs/blocks/data-and-editing.mdx +219 -0
  40. package/skills/eddev/docs/blocks/editor-config.mdx +157 -0
  41. package/skills/eddev/docs/blocks/nested-blocks.mdx +129 -0
  42. package/skills/eddev/docs/blocks/overview.mdx +58 -0
  43. package/skills/eddev/docs/blocks/template-parts.mdx +131 -0
  44. package/skills/eddev/docs/config.mdx +200 -0
  45. package/skills/eddev/docs/design/color.mdx +185 -0
  46. package/skills/eddev/docs/design/favicons.mdx +103 -0
  47. package/skills/eddev/docs/design/grid.mdx +120 -0
  48. package/skills/eddev/docs/design/icons.mdx +197 -0
  49. package/skills/eddev/docs/design/responsive-scaling.mdx +312 -0
  50. package/skills/eddev/docs/design/type.mdx +125 -0
  51. package/skills/eddev/docs/devtool/cli.mdx +201 -0
  52. package/skills/eddev/docs/devtool/overlay.mdx +5 -0
  53. package/skills/eddev/docs/getting-started.mdx +53 -0
  54. package/skills/eddev/docs/graphql/extending.mdx +186 -0
  55. package/skills/eddev/docs/graphql/fragments.mdx +107 -0
  56. package/skills/eddev/docs/graphql/global-data.mdx +47 -0
  57. package/skills/eddev/docs/graphql/infinite-queries.mdx +95 -0
  58. package/skills/eddev/docs/graphql/mutation-hooks.mdx +111 -0
  59. package/skills/eddev/docs/graphql/query-hooks.mdx +122 -0
  60. package/skills/eddev/docs/graphql/tooling.mdx +50 -0
  61. package/skills/eddev/docs/graphql.mdx +97 -0
  62. package/skills/eddev/docs/guides/color-schemes.mdx +204 -0
  63. package/skills/eddev/docs/guides/integrations.mdx +3 -0
  64. package/skills/eddev/docs/guides/page-transitions.mdx +5 -0
  65. package/skills/eddev/docs/guides/seo.mdx +5 -0
  66. package/skills/eddev/docs/guides/state-management.mdx +5 -0
  67. package/skills/eddev/docs/infra/caching.mdx +9 -0
  68. package/skills/eddev/docs/infra/deployment.mdx +13 -0
  69. package/skills/eddev/docs/infra/local.mdx +5 -0
  70. package/skills/eddev/docs/infra/security.mdx +11 -0
  71. package/skills/eddev/docs/routing/api.mdx +731 -0
  72. package/skills/eddev/docs/routing/custom.mdx +123 -0
  73. package/skills/eddev/docs/routing/full-details.mdx +37 -0
  74. package/skills/eddev/docs/routing/wordpress.mdx +70 -0
  75. package/skills/eddev/docs/routing.mdx +18 -0
  76. package/skills/eddev/docs/serverless/functions.mdx +436 -0
  77. package/skills/eddev/docs/serverless.mdx +202 -0
  78. package/skills/eddev/docs/snippets/automated-block-layouts.mdx +97 -0
  79. package/skills/eddev/docs/snippets/custom-routes-and-urls.mdx +91 -0
  80. package/skills/eddev/docs/snippets/multiple-editable-zones.mdx +87 -0
  81. package/skills/eddev/docs/snippets/querying-specific-blocks.mdx +164 -0
  82. package/skills/eddev/docs/snippets/submitting-forms-to-rpc.mdx +91 -0
  83. package/skills/eddev/docs/snippets/svgs.mdx +38 -0
  84. package/skills/eddev/docs/snippets/type-safe-acf-dropdowns.mdx +72 -0
  85. package/skills/eddev/docs/snippets.mdx +19 -0
  86. package/skills/eddev/docs/software.mdx +19 -0
  87. package/skills/eddev/docs/stack/how-it-works.mdx +50 -0
  88. package/skills/eddev/docs/stack/overview.mdx +56 -0
  89. package/skills/eddev/docs/stack/spa-vs-ssr.mdx +52 -0
  90. package/skills/eddev/docs/views/app-view.mdx +97 -0
  91. package/skills/eddev/docs/views/page-templates.mdx +82 -0
  92. package/skills/eddev/docs/views/queries.mdx +116 -0
  93. package/skills/eddev/docs/views.mdx +63 -0
  94. package/skills/eddev/index.mdx +79 -0
  95. package/tsconfig.app.json +2 -2
@@ -0,0 +1,185 @@
1
+ # Colours (/docs/design/color)
2
+
3
+ **Configure colour tokens and Figma handoff output for Tailwind.**
4
+
5
+ Current eddev themes still use Tailwind v3, so design tokens are wired through
6
+ `tailwind.config.ts`. The starter theme currently includes `tailwind-helper/`,
7
+ and real sites copy or adjust that helper in the theme rather than relying on a
8
+ shared package.
9
+
10
+ The Figma handoff plugin can produce ED. Tailwind snippets for colours,
11
+ typography, spacing, size, and radius tokens. Treat that output as a starting
12
+ point, then keep the final contract in `tailwind.config.ts`.
13
+
14
+ ## Configuration [#configuration]
15
+
16
+ Import `responsiveTheme` from the local helper and pass colour tokens into the
17
+ plugin config.
18
+
19
+ ```ts filename="tailwind.config.ts"
20
+ import ContainerQueries from "@tailwindcss/container-queries"
21
+ import { Config } from "tailwindcss"
22
+ import { responsiveTheme } from "./tailwind-helper/plugin"
23
+
24
+ export default {
25
+ content: [
26
+ "./views/**/*.{ts,tsx}",
27
+ "./blocks/**/*.{ts,tsx}",
28
+ "./components/**/*.{ts,tsx}",
29
+ "./backend/**/*.{ts,tsx}",
30
+ "./features/**/*.{ts,tsx}",
31
+ "./utils/**/*.{ts,tsx}",
32
+ ],
33
+ plugins: [
34
+ responsiveTheme({
35
+ screens: { sm: 600, md: 900, lg: 1200, xl: 1600, xxl: 2000 },
36
+ breakpoints: ["lg"],
37
+ interpolate: {
38
+ sm: {},
39
+ md: { base: "sm", lerp: true },
40
+ lg: { base: "lg", lerp: true },
41
+ xl: { base: "lg", lerp: true },
42
+ xxl: { base: "lg" },
43
+ },
44
+ colors: {
45
+ base: {
46
+ black: "#212121",
47
+ white: "#ffffff",
48
+ grey: {
49
+ DEFAULT: "#757575",
50
+ light: "#ecebea",
51
+ dark: "#585858",
52
+ },
53
+ glass: "#f9f9f9",
54
+ },
55
+ semantic: {
56
+ bg: "glass",
57
+ fg: "black",
58
+ muted: "grey",
59
+ },
60
+ subthemes: {
61
+ "theme-dark": {
62
+ bg: "black",
63
+ fg: "glass",
64
+ muted: "grey",
65
+ },
66
+ },
67
+ },
68
+ }),
69
+ ContainerQueries,
70
+ ],
71
+ } satisfies Config
72
+ ```
73
+
74
+ `base` colours become normal Tailwind colour names such as `text-black`,
75
+ `bg-grey-light`, and `border-grey-dark`. Nested `DEFAULT` values are exposed as
76
+ the parent name.
77
+
78
+ The helper stores colours as CSS variables using Tailwind's alpha-aware colour
79
+ format, so opacity modifiers keep working:
80
+
81
+ ```tsx
82
+ <div className="bg-grey-light text-black">
83
+ <p className="text-black/60">Secondary text</p>
84
+ </div>
85
+ ```
86
+
87
+ Use solid hex or `rgb(...)` values for generated colour tokens.
88
+
89
+ ## Figma Export [#figma-export]
90
+
91
+ Open `Plugins -> From ED. -> ED. Web Handoff` in Figma and use the Colours
92
+ panel. The plugin reads local paint styles and colour variables, reports naming
93
+ or unsupported-fill issues, and shows an ED. Tailwind code block.
94
+
95
+ Naming rules to keep exports clean:
96
+
97
+ | Figma Source | Tailwind Token |
98
+ | --------------------------- | -------------------------------------------------- |
99
+ | `Black` | `black` |
100
+ | `Grey/Light` | `grey.light` in config, `bg-grey-light` in classes |
101
+ | `Grey/Default` | `grey.DEFAULT` in config, `bg-grey` in classes |
102
+ | Theme variable `Background` | `bg` semantic token |
103
+
104
+ Paint styles or variables whose name starts with `_`, or contains `/_`, are
105
+ ignored by the extractor. Use that for design-only swatches that should not
106
+ ship as code tokens.
107
+
108
+ ## Semantic Colours [#semantic-colours]
109
+
110
+ Semantic colours are the theme-ready layer. Use them when a component or
111
+ section should adapt to a subtheme or colour scheme rather than lock itself to
112
+ specific named colours.
113
+
114
+ ```tsx
115
+ export function Panel(props: { children: React.ReactNode }) {
116
+ return (
117
+ <section className="theme-dark bg-bg text-fg p-5 rounded-md">
118
+ {props.children}
119
+ </section>
120
+ )
121
+ }
122
+ ```
123
+
124
+ The `semantic` map defines the default CSS variables:
125
+
126
+ ```ts filename="tailwind.config.ts"
127
+ colors: {
128
+ semantic: {
129
+ bg: "glass",
130
+ fg: "black",
131
+ "fg-secondary": "grey",
132
+ },
133
+ }
134
+ ```
135
+
136
+ The helper adds `--color-bg`, `--color-fg`, and matching Tailwind colours. A
137
+ subtheme class overrides the same variables inside that subtree.
138
+
139
+ ## Subthemes [#subthemes]
140
+
141
+ Subthemes are Tailwind classes that remap semantic colour variables inside a
142
+ subtree. They let the same component keep using classes such as `bg-bg`,
143
+ `text-fg`, and `text-fg-secondary` while the wrapper decides which base colours
144
+ those classes resolve to.
145
+
146
+ Subtheme keys are literal class names. If the key is `"theme-dark"`, the class
147
+ is `.theme-dark` and the generated ancestor variant is `is-theme-dark:`.
148
+
149
+ ```ts filename="tailwind.config.ts"
150
+ colors: {
151
+ subthemes: {
152
+ "theme-light": {
153
+ bg: "white",
154
+ fg: "black",
155
+ "fg-secondary": "grey",
156
+ },
157
+ "theme-dark": {
158
+ bg: "black",
159
+ fg: "white",
160
+ "fg-secondary": "grey.light",
161
+ },
162
+ },
163
+ }
164
+ ```
165
+
166
+ ```tsx
167
+ <section className="theme-dark bg-bg text-fg">
168
+ <h2 className="type-title-l">Dark section</h2>
169
+ <a className="text-fg-secondary hover:text-fg">Read more</a>
170
+ </section>
171
+ ```
172
+
173
+ Use the generated `is-*` variants when a child needs to react to an ancestor
174
+ theme:
175
+
176
+ ```tsx
177
+ <article className="bg-orange text-fg is-theme-dark:theme-light is-theme-dark:bg-white">
178
+ ...
179
+ </article>
180
+ ```
181
+
182
+ <Callout type="info">
183
+ For author-selectable schemes and TypeScript mapping helpers, see
184
+ [Colour Schemes](/docs/guides/color-schemes).
185
+ </Callout>
@@ -0,0 +1,103 @@
1
+ # Favicons (/docs/design/favicons)
2
+
3
+ **Configure how eddev generates or delegates favicon assets.**
4
+
5
+ eddev can either leave favicons to WordPress, generate them from SVG sources,
6
+ or generate them from a set of PNG files. The mode is configured in
7
+ `ed.config.json`.
8
+
9
+ ```json filename="ed.config.json"
10
+ {
11
+ "$schema": ".ed.config.schema.json",
12
+ "version": "2",
13
+ "favicon": {
14
+ "mode": "svg"
15
+ }
16
+ }
17
+ ```
18
+
19
+ ## Modes [#modes]
20
+
21
+ | Mode | Use When |
22
+ | ------ | ------------------------------------------------------------------------------------- |
23
+ | `auto` | WordPress Site Icon should handle favicons. eddev does not generate `.ico` output. |
24
+ | `svg` | The project has a single SVG favicon source, optionally with light and dark variants. |
25
+ | `pngs` | The project has a prepared set of PNG favicon files. |
26
+
27
+ `auto` is the schema default, but current sites that keep favicon assets in the
28
+ theme should set the mode explicitly.
29
+
30
+ ## SVG Favicons [#svg-favicons]
31
+
32
+ SVG mode uses these default paths:
33
+
34
+ | Config Field | Default |
35
+ | ------------ | --------------------------- |
36
+ | `default` | `/assets/favicon.svg` |
37
+ | `light` | `/assets/favicon-light.svg` |
38
+ | `dark` | `/assets/favicon-dark.svg` |
39
+
40
+ ```json filename="ed.config.json"
41
+ {
42
+ "favicon": {
43
+ "mode": "svg",
44
+ "default": "/assets/favicon.svg",
45
+ "light": "/assets/favicon-light.svg",
46
+ "dark": "/assets/favicon-dark.svg"
47
+ }
48
+ }
49
+ ```
50
+
51
+ The SVG is linked directly for modern browsers, and eddev generates a raster
52
+ `.ico` for compatibility. If light and dark variants are provided, the `.ico`
53
+ uses the default/light source.
54
+
55
+ A single SVG can also carry its own colour-scheme media query:
56
+
57
+ ```tsx filename="assets/favicon.svg"
58
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
59
+ <style>
60
+ .icon-dark { display: none; }
61
+ @media (prefers-color-scheme: dark) {
62
+ .icon-light { display: none; }
63
+ .icon-dark { display: inline; }
64
+ }
65
+ </style>
66
+ <g class="icon-light">...</g>
67
+ <g class="icon-dark">...</g>
68
+ </svg>
69
+ ```
70
+
71
+ ## PNG Favicons [#png-favicons]
72
+
73
+ PNG mode collects files from these default globs:
74
+
75
+ | Config Field | Default |
76
+ | ------------ | ------------------------------------- |
77
+ | `default` | `/assets/favicon/favicon-*.png` |
78
+ | `light` | `/assets/favicon/favicon-*-light.png` |
79
+ | `dark` | `/assets/favicon/favicon-*-dark.png` |
80
+
81
+ ```json filename="ed.config.json"
82
+ {
83
+ "favicon": {
84
+ "mode": "pngs",
85
+ "default": "/assets/favicon/favicon-*.png"
86
+ }
87
+ }
88
+ ```
89
+
90
+ Use PNG mode when the design handoff already includes multiple raster sizes
91
+ such as `favicon-16x16.png`, `favicon-32x32.png`, and Apple touch icons.
92
+
93
+ ## Theme Colour [#theme-colour]
94
+
95
+ Favicons do not set the browser theme colour. Add that separately from PHP if
96
+ the site needs it:
97
+
98
+ ```php filename="backend/head.php"
99
+ <?php
100
+ add_action("wp_head", function () {
101
+ echo '<meta name="theme-color" content="#000000">';
102
+ });
103
+ ```
@@ -0,0 +1,120 @@
1
+ # Grid System (/docs/design/grid)
2
+
3
+ **Configure grid tokens, gutters, and layout utilities.**
4
+
5
+ The grid is configured through the local `tailwind-helper` in
6
+ `tailwind.config.ts`. Current projects use Tailwind v3, so this config file is
7
+ still the source of truth for breakpoints, gutters, margins, and generated grid
8
+ utilities.
9
+
10
+ ## Configuration [#configuration]
11
+
12
+ ```ts filename="tailwind.config.ts"
13
+ responsiveTheme({
14
+ screens: { sm: 600, md: 900, lg: 1200, xl: 1600, xxl: 2000 },
15
+ breakpoints: ["lg"],
16
+ interpolate: {
17
+ sm: {},
18
+ md: { base: "sm", lerp: true },
19
+ lg: { base: "lg", lerp: true },
20
+ xl: { base: "lg", lerp: true },
21
+ xxl: { base: "lg" },
22
+ },
23
+ grid: {
24
+ BASE: {
25
+ container: "100vw",
26
+ gutter: "16px",
27
+ margin: "16px",
28
+ },
29
+ EDITOR: {
30
+ container: "var(--vw100)",
31
+ gutter: "16px",
32
+ margin: "16px",
33
+ },
34
+ md: {
35
+ container: "100vw",
36
+ gutter: "24px",
37
+ margin: "24px",
38
+ },
39
+ lg: {
40
+ container: "100vw",
41
+ gutter: "2vw",
42
+ margin: "2vw",
43
+ },
44
+ xxl: {
45
+ container: "2000px",
46
+ gutter: "32px",
47
+ margin: "32px",
48
+ },
49
+ },
50
+ })
51
+ ```
52
+
53
+ `BASE` is the normal mobile value. `EDITOR` is applied inside the WordPress
54
+ admin, where viewport sizing can differ from the frontend. Other keys map to
55
+ the configured Tailwind screens.
56
+
57
+ The helper writes CSS variables such as `--tw-grid-container`,
58
+ `--tw-grid-margin`, `--tw-grid-gutter`, and `--tw-grid-col-width`. Tailwind
59
+ classes are then built on top of those variables.
60
+
61
+ ## Layout Classes [#layout-classes]
62
+
63
+ Use `grid-auto` for the standard 12-column site grid.
64
+
65
+ ```tsx
66
+ <section className="grid-auto py-grid-margin">
67
+ <div className="col-span-12 md:col-span-8">
68
+ <h1 className="type-title-xl">Page title</h1>
69
+ </div>
70
+ <aside className="col-span-12 md:col-span-4">
71
+ ...
72
+ </aside>
73
+ </section>
74
+ ```
75
+
76
+ Common helper classes:
77
+
78
+ | Class | Use |
79
+ | --------------------------- | -------------------------------------------------- |
80
+ | `grid-auto` | Standard centred 12-column CSS grid. |
81
+ | `grid-container` | Centred container width without creating a grid. |
82
+ | `grid-breakout` | Expand an element out to the grid margin. |
83
+ | `grid-pl` | Add left grid margin padding. |
84
+ | `col-span-*` | Span 1 to 12 columns. |
85
+ | `col-start-*` / `col-end-*` | Manually place a grid item. |
86
+ | `auto-cols-*` | Change the active column count for nested layouts. |
87
+
88
+ Spacing keys are also exposed, so layout code can use `w-grid`,
89
+ `px-grid-margin`, `gap-grid-gutter`, and `pb-grid-margin-full`.
90
+
91
+ ## Column Widths [#column-widths]
92
+
93
+ The helper adds fixed column size utilities from the current grid variables:
94
+
95
+ ```tsx
96
+ <div className="w-grid mx-auto">
97
+ <div className="w-cols-6">Six-column width</div>
98
+ <div className="w-col">One-column width</div>
99
+ </div>
100
+ ```
101
+
102
+ These widths are useful for cards, media blocks, and controls that need to align
103
+ to the same rhythm as the grid without becoming grid children.
104
+
105
+ ## Blocks And Admin [#blocks-and-admin]
106
+
107
+ Blocks often need separate frontend and editor layout classes. Use normal
108
+ `className` for the frontend and `adminClassName` where eddev block helpers
109
+ provide it.
110
+
111
+ ```tsx
112
+ <InnerBlocks
113
+ className="grid-auto gap-y-grid-gutter"
114
+ adminClassName="grid col-span-12 gap-grid-gutter"
115
+ allowedBlocks={["content/card-grid-item"]}
116
+ />
117
+ ```
118
+
119
+ Keep full-width blocks responsible for their outer background, then place
120
+ content on the grid inside the block.
@@ -0,0 +1,197 @@
1
+ # Using Icons (/docs/design/icons)
2
+
3
+ **Export and use Figma icons as React-friendly SVG components.**
4
+
5
+ ## Icons from Figma [#icons-from-figma]
6
+
7
+ The ED. Web Handoff Figma plugin exports icon code from Figma as a single
8
+ React/TypeScript file, along with a helper `<Icon />` component.
9
+
10
+ When an exported SVG only uses one colour, the export replaces `fill` and
11
+ `stroke` with `currentColor`. This is ideal for UI glyphs, but it is not a good
12
+ fit for multi-colour illustrations.
13
+
14
+ ### Artworking [#artworking]
15
+
16
+ The export requires that icons have been artworked correctly, with these requirements:
17
+
18
+ 1. Icons must be defined as individual Figma components.
19
+ 2. Icon component names must be named `Icon/{name}` or `Icons/{name}`, eg. `Icon/User`.
20
+ 3. Icons must live in the `⚛️ UI Kit` page.
21
+
22
+ <Callout type="warning">
23
+ If these requirements are not met, then the Figma plugin will not find the icons.
24
+ </Callout>
25
+
26
+ ### Exporting Process [#exporting-process]
27
+
28
+ <Steps>
29
+ <Step>
30
+ ### Open the Plugin [#open-the-plugin]
31
+
32
+ In *Figma Design Mode*, navigate to 'Plugins → From ED. → ED. Web Handoff'.
33
+ </Step>
34
+
35
+ <Step>
36
+ ### Preview Icons [#preview-icons]
37
+
38
+ Select 'Icons' from the sidebar. Verify that the icons display correctly.
39
+
40
+ <img alt="Icon Listing" src="__img0" />
41
+ </Step>
42
+
43
+ <Step>
44
+ ### Export [#export]
45
+
46
+ Click 'Get Code'.
47
+
48
+ <img alt="Code Export" src="__img1" />
49
+ </Step>
50
+
51
+ <Step>
52
+ ### Copy and Paste [#copy-and-paste]
53
+
54
+ Copy and paste the output into your codebase, into a single file. If the icons are adjusted later, you can come back and repeat the process again, overriding the file.
55
+ </Step>
56
+ </Steps>
57
+
58
+ ### Development [#development]
59
+
60
+ #### `<Icon />` [#icon-]
61
+
62
+ The generated file contains an `Icon` component. You can use this component like so:
63
+
64
+ ```tsx
65
+ import { Icon, IconClose } from '~/components/atoms/icons'
66
+
67
+ // Icon colour will inherit text color
68
+ <Icon name="plus" />
69
+
70
+ // Override icon colour
71
+ <Icon name="delete" className="text-red" />
72
+
73
+ // Render an icon directly
74
+ <IconClose />
75
+ ```
76
+
77
+ <Callout type="info">
78
+ Note that in the example above, if `icon` is `undefined`, the `<Icon />` component will render `null`.
79
+ </Callout>
80
+
81
+ #### `IconName` and `IconRef` [#iconname-and-iconref]
82
+
83
+ The `IconName` and `IconRef` types can be used for type-safety when creating components that accept icons as props.
84
+
85
+ Here's an example of what the Figma plugin generates:
86
+
87
+ ```typescript filename="icons.ts"
88
+ // The `IconName` type is a union of the icon names, camel-cased.
89
+ export type IconName =
90
+ | "close"
91
+ | "dot"
92
+ | "down"
93
+ | "menu"
94
+ | "plus"
95
+ | "right"
96
+ | "circleClose"
97
+ | "circleMinus"
98
+ | "circlePlus"
99
+
100
+ // The `IconRef` type accepts either an icon name, or a JSX element like <svg />
101
+ export type IconRef = IconName | ReactElement
102
+ ```
103
+
104
+ You can use the `IconName` like so:
105
+
106
+ ```tsx
107
+ import { type IconName } from '~/components/atoms/icons'
108
+
109
+ type Props = {
110
+ icon?: IconName
111
+ label: string
112
+ }
113
+
114
+ export function Button(props: Props) {
115
+ return <button>
116
+ <Icon name={props.icon} />
117
+ {props.label}
118
+ </button>
119
+ }
120
+
121
+ // Usage with an icon:
122
+ <Button icon="plus" label="Add" />
123
+
124
+ // Without an icon:
125
+ <Button label="Add" />
126
+
127
+ // ❌ TypeScript error:
128
+ <Button icon="jshfkajsdhfahsdf" label="Add" />
129
+ ```
130
+
131
+ Alternatively, if your component should *also* accept icons from other component libraries, or inline-svg, you can use `IconRef` instead.
132
+
133
+ ```tsx
134
+ import { type IconRef } from '~/components/atoms/icons'
135
+
136
+ type Props = {
137
+ icon?: IconRef
138
+ label: string
139
+ }
140
+
141
+ export function Button(props: Props) {
142
+ return <button>
143
+ <Icon name={props.icon} />
144
+ {props.label}
145
+ </button>
146
+ }
147
+
148
+ // Usage with an icon name:
149
+ <Button icon="plus" label="Add" />
150
+
151
+ // Usage with an icon component
152
+ <Button icon={<IconPlus />} label="Add" />
153
+
154
+ // Usage with an arbitrary SVG
155
+ <Button icon={<svg />} label="Add" />
156
+ ```
157
+
158
+ You can also create your own subset of icon names, based on some prefix:
159
+
160
+ ```typescript
161
+ export type CircleIcon = Extract<IconName, `circle${string}`>
162
+ // ^ type CircleIcon = "circleClose" | "circleMinus" | "circlePlus"
163
+ ```
164
+
165
+ #### `const ICONS` [#const-icons]
166
+
167
+ Finally, you can also access the full set of icons using the `ICONS` variable that is exported.
168
+
169
+ ```tsx
170
+ import { ICONS } from '~/components/atoms/icons'
171
+
172
+ <select>
173
+ {Object.keys(ICONS).map(name => (
174
+ <option key={name} value={name}>{name}</option>
175
+ ))}
176
+ </select>
177
+ ```
178
+
179
+ #### Icon Styles [#icon-styles]
180
+
181
+ For one-off styles, add `className` to the icon when it is used.
182
+
183
+ ```tsx
184
+ <Icon name="delete" className="size-6 text-red" />
185
+ ```
186
+
187
+ You can also apply global styling to all icons, since an `.icon` class name is automatically added to every icon rendered with the `<Icon />` component:
188
+
189
+ ```css filename="index.css"
190
+ @layer components {
191
+ .icon {
192
+ @apply block flex-none aspect-square size-[1.5em];
193
+ }
194
+ }
195
+ ```
196
+
197
+ The example above ensures that icons don't grow/shrink when used in a flex container, and scale up and down automatically based on font size (which you may or may not want).