@primer/react 38.4.0-rc.08b86440d → 38.4.0-rc.2d74b7d78

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.

Potentially problematic release.


This version of @primer/react might be problematic. Click here for more details.

@@ -9,10 +9,8 @@
9
9
  "a11yReviewed": "2025-01-08",
10
10
  "stories": [
11
11
  {
12
- "id": "components-actionbar--default"
13
- },
14
- {
15
- "id": "experimental-components-actionbar--default"
12
+ "id": "experimental-components-actionbar--default",
13
+ "code": "() => (\n <ActionBar aria-label=\"Toolbar\">\n <ActionBar.IconButton\n icon={BoldIcon}\n aria-label=\"Bold\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ItalicIcon}\n aria-label=\"Italic\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={CodeIcon}\n aria-label=\"Code\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={LinkIcon}\n aria-label=\"Link\"\n ></ActionBar.IconButton>\n <ActionBar.Divider />\n <ActionBar.IconButton\n icon={FileAddedIcon}\n aria-label=\"File Added\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={SearchIcon}\n aria-label=\"Search\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={QuoteIcon}\n aria-label=\"Insert Quote\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ListUnorderedIcon}\n aria-label=\"Unordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ListOrderedIcon}\n aria-label=\"Ordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={TasklistIcon}\n aria-label=\"Task List\"\n ></ActionBar.IconButton>\n </ActionBar>\n)"
16
14
  }
17
15
  ],
18
16
  "importPath": "@primer/react",
@@ -153,112 +151,148 @@
153
151
  "a11yReviewed": "2025-01-08",
154
152
  "stories": [
155
153
  {
156
- "id": "components-actionlist--default"
154
+ "id": "components-actionlist--default",
155
+ "code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n)"
157
156
  },
158
157
  {
159
- "id": "components-actionlist-features--simple-list"
158
+ "id": "components-actionlist-features--simple-list",
159
+ "code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
160
160
  },
161
161
  {
162
- "id": "components-actionlist-features--with-visual-list-heading"
162
+ "id": "components-actionlist-features--with-visual-list-heading",
163
+ "code": "() => (\n <ActionList>\n <ActionList.Heading as=\"h2\" size=\"small\">\n Filter by\n </ActionList.Heading>\n <ActionList.Group>\n <ActionList.GroupHeading as=\"h3\">Repositories</ActionList.GroupHeading>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n app/assets/modules\n </ActionList.Item>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n src/react/components\n </ActionList.Item>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n memex/shared-ui/components\n </ActionList.Item>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n views/assets/modules\n </ActionList.Item>\n </ActionList.Group>\n\n <ActionList.Group>\n <ActionList.GroupHeading as=\"h3\">Advanced</ActionList.GroupHeading>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <PlusCircleIcon />\n </ActionList.LeadingVisual>\n Owner\n </ActionList.Item>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <PlusCircleIcon />\n </ActionList.LeadingVisual>\n Symbol\n </ActionList.Item>\n <ActionList.Item onSelect={() => {}}>\n <ActionList.LeadingVisual>\n <PlusCircleIcon />\n </ActionList.LeadingVisual>\n Exclude archived\n </ActionList.Item>\n </ActionList.Group>\n </ActionList>\n)"
163
164
  },
164
165
  {
165
- "id": "components-actionlist-features--with-custom-heading"
166
+ "id": "components-actionlist-features--with-custom-heading",
167
+ "code": "() => (\n <>\n <Heading as=\"h1\" id=\"list-heading\" className={classes.HeadingLarge}>\n Details\n </Heading>\n <ActionList aria-labelledby=\"list-heading\">\n <ActionList.LinkItem href=\"https://github.com/primer/react#readme\">\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n Readme\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/blob/main/LICENSE\">\n <ActionList.LeadingVisual>\n <LawIcon />\n </ActionList.LeadingVisual>\n MIT License\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/stargazers\">\n <ActionList.LeadingVisual>\n <StarIcon />\n </ActionList.LeadingVisual>\n <strong>1.5k</strong> stars\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/watchers\">\n <ActionList.LeadingVisual>\n <EyeIcon />\n </ActionList.LeadingVisual>\n <strong>21</strong> watching\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/network/members\">\n <ActionList.LeadingVisual>\n <RepoForkedIcon />\n </ActionList.LeadingVisual>\n <strong>225</strong> forks\n </ActionList.LinkItem>\n </ActionList>\n </>\n)"
166
168
  },
167
169
  {
168
- "id": "components-actionlist-features--with-icons"
170
+ "id": "components-actionlist-features--with-icons",
171
+ "code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <LinkIcon />\n </ActionList.LeadingVisual>\n github.com/primer\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <LawIcon />\n </ActionList.LeadingVisual>\n MIT License\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <StarIcon />\n </ActionList.LeadingVisual>\n 256 stars\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <RepoForkedIcon />\n </ActionList.LeadingVisual>\n 3 forks\n </ActionList.Item>\n <ActionList.Item variant=\"danger\">\n <ActionList.LeadingVisual>\n <AlertIcon />\n </ActionList.LeadingVisual>\n 4 vulnerabilities\n </ActionList.Item>\n </ActionList>\n)"
169
172
  },
170
173
  {
171
- "id": "components-actionlist-features--with-avatars"
174
+ "id": "components-actionlist-features--with-avatars",
175
+ "code": "() => (\n <ActionList>\n {users.map((user) => (\n <ActionList.Item key={user.login}>\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n </ActionList.Item>\n ))}\n </ActionList>\n)"
172
176
  },
173
177
  {
174
- "id": "components-actionlist-features--item-dividers"
178
+ "id": "components-actionlist-features--item-dividers",
179
+ "code": "() => (\n <ActionList showDividers>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n)"
175
180
  },
176
181
  {
177
- "id": "components-actionlist-features--single-divider"
182
+ "id": "components-actionlist-features--single-divider",
183
+ "code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
178
184
  },
179
185
  {
180
- "id": "components-actionlist-features--inline-description"
186
+ "id": "components-actionlist-features--inline-description",
187
+ "code": "() => (\n <ActionList>\n {users.map((user) => (\n <ActionList.Item key={user.login}>\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>{user.name}</ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n)"
181
188
  },
182
189
  {
183
- "id": "components-actionlist-features--block-description"
190
+ "id": "components-actionlist-features--block-description",
191
+ "code": "() => (\n <ActionList>\n {users.map((user) => (\n <ActionList.Item key={user.login}>\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description variant=\"block\">\n {user.name}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n)"
184
192
  },
185
193
  {
186
- "id": "components-actionlist-features--single-select"
194
+ "id": "components-actionlist-features--single-select",
195
+ "code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n return (\n <ActionList\n selectionVariant=\"single\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemradio\"\n selected={index === selectedIndex}\n aria-checked={index === selectedIndex}\n onSelect={() => setSelectedIndex(index)}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
187
196
  },
188
197
  {
189
- "id": "components-actionlist-features--inactive-single-select"
198
+ "id": "components-actionlist-features--inactive-single-select",
199
+ "code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState(1)\n return (\n <ActionList\n selectionVariant=\"single\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {/* menuitem because state is inactive */}\n <ActionList.Item\n role=\"menuitem\"\n selected={false}\n inactiveText=\"Unavailable due to an outage\"\n >\n Inactive item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemradio\"\n selected={selectedIndex === 1}\n aria-checked={selectedIndex === 1}\n onSelect={() => setSelectedIndex(1)}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n )\n}"
190
200
  },
191
201
  {
192
- "id": "components-actionlist-features--multi-select"
202
+ "id": "components-actionlist-features--multi-select",
203
+ "code": "() => {\n const [selectedIndices, setSelectedIndices] = React.useState<number[]>([0])\n const handleSelect = (index: number) => {\n if (selectedIndices.includes(index)) {\n setSelectedIndices(selectedIndices.filter((i) => i !== index))\n } else {\n setSelectedIndices([...selectedIndices, index])\n }\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemcheckbox\"\n selected={selectedIndices.includes(index)}\n aria-checked={selectedIndices.includes(index)}\n onSelect={() => handleSelect(index)}\n disabled={index === 3 ? true : undefined}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
193
204
  },
194
205
  {
195
- "id": "components-actionlist-features--listbox-single-select"
206
+ "id": "components-actionlist-features--listbox-single-select",
207
+ "code": "() => {\n const [selectedIndice, setSelectedIndice] = React.useState<number>(0)\n const handleSelect = (index: number) => {\n setSelectedIndice(index)\n }\n return (\n <ActionList selectionVariant=\"single\" role=\"listbox\" aria-label=\"Projects\">\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n selected={selectedIndice === index}\n aria-checked={selectedIndice === index}\n onSelect={() => handleSelect(index)}\n disabled={index === 3 ? true : undefined}\n role=\"option\"\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
196
208
  },
197
209
  {
198
- "id": "components-actionlist-features--listbox-multi-select"
210
+ "id": "components-actionlist-features--listbox-multi-select",
211
+ "code": "() => {\n const [selectedIndices, setSelectedIndices] = React.useState<number[]>([0])\n const handleSelect = (index: number) => {\n if (selectedIndices.includes(index)) {\n setSelectedIndices(selectedIndices.filter((i) => i !== index))\n } else {\n setSelectedIndices([...selectedIndices, index])\n }\n }\n return (\n <ActionList role=\"menu\" selectionVariant=\"multiple\" aria-label=\"Projects\">\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemcheckbox\"\n selected={selectedIndices.includes(index)}\n aria-checked={selectedIndices.includes(index)}\n onSelect={() => handleSelect(index)}\n disabled={index === 3 ? true : undefined}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
199
212
  },
200
213
  {
201
- "id": "components-actionlist-features--with-dynamic-content"
214
+ "id": "components-actionlist-features--with-dynamic-content",
215
+ "code": "() => {\n const [isTrue, setIsTrue] = React.useState(false)\n return (\n <FeatureFlags\n flags={{\n primer_react_action_list_item_as_button: true,\n }}\n >\n <ActionList>\n <ActionList.Item\n onSelect={() => {\n setIsTrue(!isTrue)\n }}\n >\n Activated? {isTrue ? 'Yes' : 'No'}\n </ActionList.Item>\n </ActionList>\n </FeatureFlags>\n )\n}"
202
216
  },
203
217
  {
204
- "id": "components-actionlist-features--disabled-selected-multiselect"
218
+ "id": "components-actionlist-features--disabled-selected-multiselect",
219
+ "code": "() => (\n <ActionList selectionVariant=\"multiple\" role=\"menu\" aria-label=\"Project\">\n <ActionList.Item role=\"menuitemcheckbox\" selected aria-checked disabled>\n Selected disabled item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={false}\n aria-checked={false}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n)"
205
220
  },
206
221
  {
207
- "id": "components-actionlist-features--disabled-multiselect"
222
+ "id": "components-actionlist-features--disabled-multiselect",
223
+ "code": "() => (\n <ActionList selectionVariant=\"multiple\" role=\"menu\" aria-label=\"Project\">\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={false}\n aria-checked={false}\n disabled\n >\n Disabled item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={false}\n aria-checked={false}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n)"
208
224
  },
209
225
  {
210
- "id": "components-actionlist-features--inactive-multiselect"
226
+ "id": "components-actionlist-features--inactive-multiselect",
227
+ "code": "() => {\n const [selectedIndices, setSelectedIndices] = React.useState<number[]>([0])\n const handleSelect = (index: number) => {\n if (selectedIndices.includes(index)) {\n setSelectedIndices(selectedIndices.filter((i) => i !== index))\n } else {\n setSelectedIndices([...selectedIndices, index])\n }\n }\n return (\n <ActionList selectionVariant=\"multiple\" role=\"menu\" aria-label=\"Project\">\n {/* menuitem because state is inactive */}\n <ActionList.Item\n role=\"menuitem\"\n selected={false}\n inactiveText=\"Unavailable due to an outage\"\n >\n Inactive item\n </ActionList.Item>\n <ActionList.Item\n role=\"menuitemcheckbox\"\n selected={selectedIndices.includes(1)}\n aria-checked={selectedIndices.includes(1)}\n onSelect={() => handleSelect(1)}\n >\n Item 2\n </ActionList.Item>\n </ActionList>\n )\n}"
211
228
  },
212
229
  {
213
- "id": "components-actionlist-features--disabled-item"
230
+ "id": "components-actionlist-features--disabled-item",
231
+ "code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n return (\n <ActionList\n selectionVariant=\"single\"\n showDividers\n role=\"menu\"\n aria-label=\"Project\"\n >\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n role=\"menuitemradio\"\n selected={index === selectedIndex}\n aria-checked={index === selectedIndex}\n onSelect={() => setSelectedIndex(index)}\n disabled={index === 1}\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
214
232
  },
215
233
  {
216
- "id": "components-actionlist-features--inactive-item"
234
+ "id": "components-actionlist-features--inactive-item",
235
+ "code": "() => {\n return (\n <ActionList aria-label=\"Project\">\n {projects.map((project, index) => (\n <ActionList.Item\n key={index}\n inactiveText={\n index === 1 ? 'Unavailable due to an outage' : undefined\n }\n >\n <ActionList.LeadingVisual>\n <TableIcon />\n </ActionList.LeadingVisual>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
217
236
  },
218
237
  {
219
- "id": "components-actionlist-features--loading-item"
238
+ "id": "components-actionlist-features--loading-item",
239
+ "code": "() => {\n return (\n <ActionList aria-label=\"Project\">\n {projects.map((project, index) => (\n <ActionList.Item key={index} loading={index === 1}>\n {project.name}\n <ActionList.Description variant=\"block\">\n {project.scope}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
220
240
  },
221
241
  {
222
- "id": "components-actionlist-features--links"
242
+ "id": "components-actionlist-features--links",
243
+ "code": "() => (\n <ActionList>\n <ActionList.Heading as=\"h1\" className={classes.HeadingSmall}>\n Details\n </ActionList.Heading>\n <ActionList.LinkItem href=\"https://github.com/primer/react#readme\">\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n Readme\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/blob/main/LICENSE\">\n <ActionList.LeadingVisual>\n <LawIcon />\n </ActionList.LeadingVisual>\n MIT License\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/stargazers\">\n <ActionList.LeadingVisual>\n <StarIcon />\n </ActionList.LeadingVisual>\n <strong>1.5k</strong> stars\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/watchers\">\n <ActionList.LeadingVisual>\n <EyeIcon />\n </ActionList.LeadingVisual>\n <strong>21</strong> watching\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com/primer/react/network/members\">\n <ActionList.LeadingVisual>\n <RepoForkedIcon />\n </ActionList.LeadingVisual>\n <strong>225</strong> forks\n </ActionList.LinkItem>\n </ActionList>\n)"
223
244
  },
224
245
  {
225
- "id": "components-actionlist-features--custom-item-children"
246
+ "id": "components-actionlist-features--custom-item-children",
247
+ "code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n <Label>Choose this one</Label>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n)"
226
248
  },
227
249
  {
228
- "id": "components-actionlist-features--text-wrap-and-truncation"
250
+ "id": "components-actionlist-features--text-wrap-and-truncation",
251
+ "code": "() => (\n <div className={classes.BoxWithMaxWidth}>\n <ActionList showDividers>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Block Description. Long text should wrap\n <ActionList.Description variant=\"block\">\n This description is long, but it is block so it wraps\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Inline Description\n <ActionList.Description truncate>\n This description gets truncated because it is inline with truncation\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Description with truncation and complex children\n <ActionList.Description truncate>\n With <strong>bold</strong> and <em>italic</em> text, and it should\n truncate if it is too long\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Inline Description\n <ActionList.Description>\n This description wraps because it is inline without truncation\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n Really long text without a description should wrap so it wraps\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ArrowRightIcon />\n </ActionList.LeadingVisual>\n SomethingSomething/SomethingElse.Some.Thing.Lalala.la\n <ActionList.TrailingVisual>\n <ArrowLeftIcon />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </div>\n)"
229
252
  },
230
253
  {
231
- "id": "components-actionlist-features--conditional-children"
254
+ "id": "components-actionlist-features--conditional-children",
255
+ "code": "() => {\n type reviewerType = {\n name: string\n id?: string\n type?: string\n login?: string\n slug?: string\n members?: number\n }\n const potentialReviewers: reviewerType[] = [...teams, ...users]\n return (\n <ActionList showDividers>\n {potentialReviewers.map((reviewer, index) => (\n <ActionList.Item key={index}>\n <ActionList.LeadingVisual>\n {reviewer.type === 'team' ? (\n <Avatar\n src={`https://avatars.githubusercontent.com/t/${reviewer.id}`}\n />\n ) : (\n <Avatar\n src={`https://avatars.githubusercontent.com/${reviewer.login}`}\n />\n )}\n </ActionList.LeadingVisual>\n {reviewer.login || reviewer.slug}\n {reviewer.type === 'team' ? (\n <ActionList.Description variant=\"block\">\n {reviewer.name}\n </ActionList.Description>\n ) : (\n <ActionList.Description>{reviewer.name}</ActionList.Description>\n )}\n {reviewer.type === 'team' && (\n <ActionList.TrailingVisual>\n <PeopleIcon />\n {reviewer.members}\n </ActionList.TrailingVisual>\n )}\n </ActionList.Item>\n ))}\n </ActionList>\n )\n}"
232
256
  },
233
257
  {
234
- "id": "components-actionlist-features--child-with-side-effects"
258
+ "id": "components-actionlist-features--child-with-side-effects",
259
+ "code": "() => {\n const user = users[0]\n const [selected, setSelected] = React.useState(true)\n const SideEffectDescription = () => {\n const [seconds, setSeconds] = React.useState(0)\n React.useEffect(() => {\n const fn = () => setSeconds((s) => s + 1)\n const interval = window.setInterval(fn, 1000)\n return () => window.clearInterval(interval)\n }, [])\n return <>{seconds} seconds passed</>\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n role=\"listbox\"\n aria-label=\"Assignees\"\n >\n <ActionList.Item\n selected={selected}\n onSelect={() => setSelected(!selected)}\n role=\"option\"\n >\n <ActionList.LeadingVisual>\n <Avatar src={`https://avatars.githubusercontent.com/${user.login}`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>\n <SideEffectDescription />\n </ActionList.Description>\n </ActionList.Item>\n </ActionList>\n )\n}"
235
260
  },
236
261
  {
237
- "id": "components-actionlist-features--inside-overlay"
262
+ "id": "components-actionlist-features--inside-overlay",
263
+ "code": "() => {\n const [open, setOpen] = React.useState(false)\n const toggle = () => setOpen(!open)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={toggle}\n onClose={toggle}\n renderAnchor={(props) => (\n <button type=\"button\" {...props}>\n toggle overlay\n </button>\n )}\n >\n <ActionList role=\"menu\">\n <ActionList.Item role=\"menuitem\">\n Use your arrow keys\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item role=\"menuitem\">\n keep going\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item role=\"menuitem\">\n more more\n <ActionList.TrailingVisual>↓</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\" role=\"menuitem\">\n now go up!\n <ActionList.TrailingVisual>↑</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </AnchoredOverlay>\n )\n}"
238
264
  },
239
265
  {
240
- "id": "components-actionlist-features--group-with-subtle-title"
266
+ "id": "components-actionlist-features--group-with-subtle-title",
267
+ "code": "() => {\n const [assignees, setAssignees] = React.useState(users.slice(0, 1))\n const toggleAssignee = (assignee: (typeof users)[number]) => {\n const assigneeIndex = assignees.findIndex((a) => a.login === assignee.login)\n if (assigneeIndex === -1) setAssignees([...assignees, assignee])\n else setAssignees(assignees.filter((_, index) => index !== assigneeIndex))\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n role=\"menu\"\n showDividers\n aria-label=\"Reviewers\"\n >\n <ActionList.Group>\n <ActionList.GroupHeading>Everyone</ActionList.GroupHeading>\n {users.slice(2).map((user) => (\n <ActionList.Item\n role=\"menuitemcheckbox\"\n key={user.login}\n selected={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n aria-checked={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n onSelect={() => toggleAssignee(user)}\n >\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>{user.name}</ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList.Group>\n </ActionList>\n )\n}"
241
268
  },
242
269
  {
243
- "id": "components-actionlist-features--group-with-filled-title"
270
+ "id": "components-actionlist-features--group-with-filled-title",
271
+ "code": "() => {\n const [assignees, setAssignees] = React.useState(users.slice(0, 1))\n const toggleAssignee = (assignee: (typeof users)[number]) => {\n const assigneeIndex = assignees.findIndex((a) => a.login === assignee.login)\n if (assigneeIndex === -1) setAssignees([...assignees, assignee])\n else setAssignees(assignees.filter((_, index) => index !== assigneeIndex))\n }\n return (\n <ActionList\n selectionVariant=\"multiple\"\n role=\"menu\"\n showDividers\n aria-label=\"Reviewers\"\n >\n <ActionList.Group>\n <ActionList.GroupHeading variant=\"filled\">\n Everyone\n </ActionList.GroupHeading>\n {users.slice(2).map((user) => (\n <ActionList.Item\n role=\"menuitemcheckbox\"\n key={user.login}\n selected={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n aria-checked={Boolean(\n assignees.find((assignee) => assignee.login === user.login),\n )}\n onSelect={() => toggleAssignee(user)}\n >\n <ActionList.LeadingVisual>\n <Avatar src={`https://github.com/${user.login}.png`} />\n </ActionList.LeadingVisual>\n {user.login}\n <ActionList.Description>{user.name}</ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList.Group>\n </ActionList>\n )\n}"
244
272
  },
245
273
  {
246
- "id": "components-actionlist-features--with-custom-trailing-visuals"
274
+ "id": "components-actionlist-features--with-custom-trailing-visuals",
275
+ "code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <IssueOpenedIcon />\n </ActionList.LeadingVisual>\n Issues\n <ActionList.TrailingVisual>\n <CounterLabel>20</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <GitPullRequestIcon />\n </ActionList.LeadingVisual>\n PRs\n <ActionList.TrailingVisual>\n <CounterLabel>12</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ProjectIcon />\n </ActionList.LeadingVisual>\n Projects\n <ActionList.TrailingVisual>\n <CounterLabel>2</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n)"
247
276
  },
248
277
  {
249
- "id": "components-actionlist-features--with-keyboard-shortcuts"
278
+ "id": "components-actionlist-features--with-keyboard-shortcuts",
279
+ "code": "() => (\n <ActionList>\n <ActionList.Item>\n New file\n <ActionList.TrailingVisual>\n <KeybindingHint keys=\"Mod+N\" />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n Open file\n <ActionList.TrailingVisual>\n <KeybindingHint keys=\"Mod+O\" />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n Save\n <ActionList.TrailingVisual>\n <KeybindingHint keys=\"Mod+S\" />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">\n Delete\n <ActionList.TrailingVisual>\n <KeybindingHint keys=\"Mod+D\" />\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n)"
250
280
  },
251
281
  {
252
- "id": "components-actionlist-features--with-trailing-count"
282
+ "id": "components-actionlist-features--with-trailing-count",
283
+ "code": "() => (\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <IssueOpenedIcon />\n </ActionList.LeadingVisual>\n Open issues\n <ActionList.TrailingVisual>\n <CounterLabel>24</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <GitPullRequestIcon />\n </ActionList.LeadingVisual>\n Pull requests\n <ActionList.TrailingVisual>\n <CounterLabel>8</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <ProjectIcon />\n </ActionList.LeadingVisual>\n Projects\n <ActionList.TrailingVisual>\n <CounterLabel>3</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item variant=\"danger\">\n <ActionList.LeadingVisual>\n <AlertIcon />\n </ActionList.LeadingVisual>\n Alerts\n <ActionList.TrailingVisual>\n <CounterLabel>12</CounterLabel>\n </ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n)"
253
284
  },
254
285
  {
255
- "id": "components-actionlist-features--with-trailing-action"
286
+ "id": "components-actionlist-features--with-trailing-action",
287
+ "code": "() => {\n const [loadingState, setLoadingState] = React.useState(false)\n\n // Auto-toggle every 2.5 seconds to continuously show transitions\n React.useEffect(() => {\n const interval = setInterval(() => {\n setLoadingState((prev) => !prev)\n }, 2500)\n return () => clearInterval(interval)\n }, [])\n return (\n <FeatureFlags\n flags={{\n primer_react_action_list_item_as_button: true,\n }}\n >\n <ActionList>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <FileDirectoryIcon />\n </ActionList.LeadingVisual>\n Item 1 (with default TrailingAction)\n <ActionList.TrailingAction\n label=\"Expand sidebar\"\n icon={ArrowLeftIcon}\n />\n </ActionList.Item>\n <ActionList.Item>\n Item 2 (with link TrailingAction)\n <ActionList.TrailingAction\n as=\"a\"\n href=\"#\"\n label=\"Some action 1\"\n icon={ArrowRightIcon}\n />\n </ActionList.Item>\n <ActionList.Item>\n Item 3\n <ActionList.Description>\n This is an inline description.\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Some action 2\" icon={BookIcon} />\n </ActionList.Item>\n <ActionList.Item>\n Item 4\n <ActionList.Description variant=\"block\">\n This is a block description.\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Some action 3\" icon={BookIcon} />\n </ActionList.Item>\n <ActionList.Item>\n Item 5\n <ActionList.Description variant=\"block\">\n This is a block description.\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Some action 4\" />\n </ActionList.Item>\n <ActionList.Item>\n Item 6\n <ActionList.TrailingAction href=\"#\" as=\"a\" label=\"Some action 5\" />\n </ActionList.Item>\n <ActionList.Item>\n Icon button loading state\n <ActionList.Description>\n Shows how IconButton maintains width and centers spinner when\n loading\n </ActionList.Description>\n <ActionList.TrailingAction\n label=\"Process item\"\n icon={ArrowRightIcon}\n loading\n />\n </ActionList.Item>\n <ActionList.Item>\n Icon button with transitions\n <ActionList.Description>\n Automatically toggles loading state every 2.5 seconds to show\n transitions\n </ActionList.Description>\n <ActionList.TrailingAction\n label=\"Toggle loading\"\n icon={ArrowRightIcon}\n loading={loadingState}\n />\n </ActionList.Item>\n <ActionList.Item>\n Text button loading state\n <ActionList.Description>\n Shows how text button aligns spinner to the right and preserves\n width\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Save changes\" loading />\n </ActionList.Item>\n <ActionList.Item>\n Text button with transitions\n <ActionList.Description>\n Automatically toggles loading state every 2.5 seconds to show\n transitions\n </ActionList.Description>\n <ActionList.TrailingAction\n label=\"Apply settings\"\n loading={loadingState}\n />\n </ActionList.Item>\n <ActionList.LinkItem href=\"#\">\n LinkItem 1\n <ActionList.Description>\n with TrailingAction this is a long description and should not cause\n horizontal scroll on smaller screen sizes\n </ActionList.Description>\n <ActionList.TrailingAction label=\"Another action\" />\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"#\">\n LinkItem 2\n <ActionList.Description>\n with TrailingVisual this is a long description and should not cause\n horizontal scroll on smaller screen sizes\n </ActionList.Description>\n <ActionList.TrailingVisual>\n <TableIcon />\n </ActionList.TrailingVisual>\n </ActionList.LinkItem>\n <ActionList.Item inactiveText=\"Unavailable due to an outage\">\n Inactive Item\n <ActionList.Description>With TrailingAction</ActionList.Description>\n <ActionList.TrailingAction\n as=\"a\"\n href=\"#\"\n label=\"Some action 8\"\n icon={ArrowRightIcon}\n />\n </ActionList.Item>\n </ActionList>\n </FeatureFlags>\n )\n}"
256
288
  },
257
289
  {
258
- "id": "components-actionlist-features--full-variant"
290
+ "id": "components-actionlist-features--full-variant",
291
+ "code": "() => (\n <ActionList variant=\"full\">\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
259
292
  },
260
293
  {
261
- "id": "components-actionlist-features--large-item"
294
+ "id": "components-actionlist-features--large-item",
295
+ "code": "() => (\n <ActionList>\n <ActionList.Item size=\"large\">Large item</ActionList.Item>\n <ActionList.Item size=\"large\">\n Large item\n <ActionList.Description>With inline description</ActionList.Description>\n </ActionList.Item>\n <ActionList.Item size=\"large\">\n Large item\n <ActionList.Description variant=\"block\">\n With block description\n </ActionList.Description>\n </ActionList.Item>\n </ActionList>\n)"
262
296
  }
263
297
  ],
264
298
  "importPath": "@primer/react",
@@ -615,25 +649,32 @@
615
649
  "a11yReviewed": "2025-01-08",
616
650
  "stories": [
617
651
  {
618
- "id": "components-actionmenu--default"
652
+ "id": "components-actionmenu--default",
653
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Open menu</ActionMenu.Button>\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Copy link clicked')}>\n Copy link\n <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Quote reply clicked')}>\n Quote reply\n <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Edit comment clicked')}>\n Edit comment\n <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item\n variant=\"danger\"\n onSelect={() => alert('Delete file clicked')}\n >\n Delete file\n <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
619
654
  },
620
655
  {
621
- "id": "components-actionmenu-features--links-and-actions"
656
+ "id": "components-actionmenu-features--links-and-actions",
657
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Open menu</ActionMenu.Button>\n <ActionMenu.Overlay width=\"auto\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Workflows clicked')}>\n Workflows\n <ActionList.LeadingVisual>\n <WorkflowIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Archived items clicked')}>\n Archived items\n <ActionList.LeadingVisual>\n <ArchiveIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.LinkItem href=\"/\">\n Settings\n <ActionList.LeadingVisual>\n <GearIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.Item onSelect={() => alert('Make a copy clicked')}>\n Make a copy\n <ActionList.LeadingVisual>\n <CopyIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Group>\n <ActionList.GroupHeading>GitHub projects</ActionList.GroupHeading>\n <ActionList.LinkItem href=\"/\">\n What&apos;s new\n <ActionList.LeadingVisual>\n <RocketIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n Give feedback\n <ActionList.LeadingVisual>\n <CommentIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n GitHub Docs\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n </ActionList.Group>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
622
658
  },
623
659
  {
624
- "id": "components-actionmenu-features--single-select"
660
+ "id": "components-actionmenu-features--single-select",
661
+ "code": "() => {\n const options = [\n {\n name: 'Fast forward',\n },\n {\n name: 'Recursive',\n },\n {\n name: 'Ours',\n },\n {\n name: 'Octopus',\n },\n {\n name: 'Resolve',\n },\n {\n name: 'Subtree',\n },\n ]\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n const selectedType = options[selectedIndex]\n return (\n <ActionMenu>\n <ActionMenu.Button>\n <span className={classes.MutedText}>Options:</span> {selectedType.name}\n </ActionMenu.Button>\n <ActionMenu.Overlay width=\"auto\">\n <ActionList selectionVariant=\"single\">\n {options.map((options, index) => (\n <ActionList.Item\n key={index}\n selected={index === selectedIndex}\n onSelect={() => setSelectedIndex(index)}\n >\n {options.name}\n </ActionList.Item>\n ))}\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n )\n}"
625
662
  },
626
663
  {
627
- "id": "components-actionmenu-features--multi-select"
664
+ "id": "components-actionmenu-features--multi-select",
665
+ "code": "() => {\n type Option = {\n name: string\n selected: boolean\n }\n const [options, setOptions] = React.useState<Option[]>([\n {\n name: 'Show code folding buttons',\n selected: true,\n },\n {\n name: 'Wrap lines',\n selected: false,\n },\n {\n name: 'Center content',\n selected: false,\n },\n ])\n const toggle = (name: string) => {\n setOptions(\n options.map((option) => {\n if (option.name === name) option.selected = !option.selected\n return option\n }),\n )\n }\n return (\n <ActionMenu>\n <ActionMenu.Button>Display</ActionMenu.Button>\n <ActionMenu.Overlay width=\"auto\">\n <ActionList selectionVariant=\"multiple\">\n {options.map((options) => (\n <ActionList.Item\n key={options.name}\n selected={options.selected}\n onSelect={() => toggle(options.name)}\n >\n {options.name}\n </ActionList.Item>\n ))}\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n )\n}"
628
666
  },
629
667
  {
630
- "id": "components-actionmenu-features--inactive-items"
668
+ "id": "components-actionmenu-features--inactive-items",
669
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Open menu</ActionMenu.Button>\n <ActionMenu.Overlay width=\"auto\">\n <ActionList>\n <ActionList.Item\n onSelect={() => alert('Workflows clicked')}\n inactiveText=\"Unavailable due to an outage\"\n >\n Workflows\n <ActionList.LeadingVisual>\n <WorkflowIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Item\n onSelect={() => alert('Archived items clicked')}\n inactiveText=\"Unavailable due to an outage\"\n >\n Archived items\n <ActionList.LeadingVisual>\n <ArchiveIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.LinkItem\n href=\"/\"\n inactiveText=\"Unavailable due to an outage\"\n >\n Settings\n <ActionList.LeadingVisual>\n <GearIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.Item\n onSelect={() => alert('Make a copy clicked')}\n inactiveText=\"Unavailable due to an outage\"\n >\n Make a copy\n <ActionList.LeadingVisual>\n <CopyIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Group>\n <ActionList.GroupHeading>Github projects</ActionList.GroupHeading>\n <ActionList.LinkItem href=\"/\">\n What&apos;s new\n <ActionList.LeadingVisual>\n <RocketIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n Give feedback\n <ActionList.LeadingVisual>\n <CommentIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n GitHub Docs\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n </ActionList.Group>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
631
670
  },
632
671
  {
633
- "id": "components-actionmenu-features--loading-items"
672
+ "id": "components-actionmenu-features--loading-items",
673
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Open menu</ActionMenu.Button>\n <ActionMenu.Overlay width=\"auto\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Workflows clicked')} loading>\n Workflows\n <ActionList.LeadingVisual>\n <WorkflowIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Item\n onSelect={() => alert('Archived items clicked')}\n loading\n >\n Archived items\n <ActionList.LeadingVisual>\n <ArchiveIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Make a copy clicked')} loading>\n Make a copy\n <ActionList.LeadingVisual>\n <CopyIcon />\n </ActionList.LeadingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Group>\n <ActionList.GroupHeading>Github projects</ActionList.GroupHeading>\n <ActionList.LinkItem href=\"/\">\n What&apos;s new\n <ActionList.LeadingVisual>\n <RocketIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n Give feedback\n <ActionList.LeadingVisual>\n <CommentIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"/\">\n GitHub Docs\n <ActionList.LeadingVisual>\n <BookIcon />\n </ActionList.LeadingVisual>\n </ActionList.LinkItem>\n </ActionList.Group>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
634
674
  },
635
675
  {
636
- "id": "components-actionmenu-features--submenus"
676
+ "id": "components-actionmenu-features--submenus",
677
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Button>Edit</ActionMenu.Button>\n <ActionMenu.Overlay>\n <ActionList>\n <ActionList.Item>Cut</ActionList.Item>\n <ActionList.Item>Copy</ActionList.Item>\n <ActionList.Item>Paste</ActionList.Item>\n <ActionMenu>\n <ActionMenu.Anchor>\n <ActionList.Item>\n <ActionList.LeadingVisual>\n <SparkleFillIcon />\n </ActionList.LeadingVisual>\n Paste special\n </ActionList.Item>\n </ActionMenu.Anchor>\n <ActionMenu.Overlay>\n <ActionList>\n <ActionList.Item>Paste plain text</ActionList.Item>\n <ActionList.Item>Paste formulas</ActionList.Item>\n <ActionList.Item>Paste with formatting</ActionList.Item>\n <ActionMenu>\n <ActionMenu.Anchor>\n <ActionList.Item>Paste from</ActionList.Item>\n </ActionMenu.Anchor>\n <ActionMenu.Overlay>\n <ActionList>\n <ActionList.Item>Current clipboard</ActionList.Item>\n <ActionList.Item>History</ActionList.Item>\n <ActionList.Item>Another device</ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
637
678
  }
638
679
  ],
639
680
  "importPath": "@primer/react",
@@ -750,40 +791,52 @@
750
791
  "a11yReviewed": "2025-01-08",
751
792
  "stories": [
752
793
  {
753
- "id": "components-anchoredoverlay--default"
794
+ "id": "components-anchoredoverlay--default",
795
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n style: {\n minWidth: '320px',\n },\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n {hoverCard}\n </AnchoredOverlay>\n )\n}"
754
796
  },
755
797
  {
756
- "id": "components-anchoredoverlay-features--portal-inside-scrolling-element"
798
+ "id": "components-anchoredoverlay-features--portal-inside-scrolling-element",
799
+ "code": "(args: Args) => {\n const rows = 20\n const columns = 10\n return (\n <HeaderAndLayout>\n <table>\n <tbody>\n {Array(rows)\n .fill(null)\n .map((_, i) => (\n <tr key={i}>\n {Array(columns)\n .fill(null)\n .map((_1, j) => (\n <td key={`${i}${j}`}>\n <div className={classes.PlaygroundCell}>\n <Playground\n {...{\n ...args,\n portalContainerName: 'scrollingPortal',\n }}\n />\n </div>\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </HeaderAndLayout>\n )\n}"
757
800
  },
758
801
  {
759
- "id": "components-anchoredoverlay-features--custom-anchor-id"
802
+ "id": "components-anchoredoverlay-features--custom-anchor-id",
803
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n anchorId=\"my-custom-anchor-id\"\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
760
804
  },
761
805
  {
762
- "id": "components-anchoredoverlay-features--height"
806
+ "id": "components-anchoredoverlay-features--height",
807
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n height=\"large\"\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
763
808
  },
764
809
  {
765
- "id": "components-anchoredoverlay-features--width"
810
+ "id": "components-anchoredoverlay-features--width",
811
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n width=\"large\"\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
766
812
  },
767
813
  {
768
- "id": "components-anchoredoverlay-features--anchor-alignment"
814
+ "id": "components-anchoredoverlay-features--anchor-alignment",
815
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => (\n <Button {...props} block>\n Button\n </Button>\n )}\n align=\"center\"\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
769
816
  },
770
817
  {
771
- "id": "components-anchoredoverlay-features--anchor-side"
818
+ "id": "components-anchoredoverlay-features--anchor-side",
819
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n side=\"outside-right\"\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
772
820
  },
773
821
  {
774
- "id": "components-anchoredoverlay-features--offset-position-from-anchor"
822
+ "id": "components-anchoredoverlay-features--offset-position-from-anchor",
823
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n anchorOffset={100}\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
775
824
  },
776
825
  {
777
- "id": "components-anchoredoverlay-features--offset-alignment-from-anchor"
826
+ "id": "components-anchoredoverlay-features--offset-alignment-from-anchor",
827
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n alignmentOffset={100}\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
778
828
  },
779
829
  {
780
- "id": "components-anchoredoverlay-features--focus-trap-overrides"
830
+ "id": "components-anchoredoverlay-features--focus-trap-overrides",
831
+ "code": "() => {\n const initialFocusRef = useRef<HTMLButtonElement>(null)\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n focusTrapSettings={{\n initialFocusRef,\n }}\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'Focus Trap Demo Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <Button>First button</Button>\n <Button ref={initialFocusRef}>Initial focus</Button>\n </AnchoredOverlay>\n )\n}"
781
832
  },
782
833
  {
783
- "id": "components-anchoredoverlay-features--focus-zone-overrides"
834
+ "id": "components-anchoredoverlay-features--focus-zone-overrides",
835
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n focusZoneSettings={{\n bindKeys: FocusKeys.JK,\n }}\n overlayProps={{\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'Focus Zone Demo Overlay',\n className: classes.Overlay,\n }}\n preventOverflow={false}\n >\n <p>\n Use <kbd>J</kbd> and <kbd>K</kbd> keys to move focus.\n </p>\n <Button>First</Button>\n <Button>Second</Button>\n <Button>Third</Button>\n </AnchoredOverlay>\n )\n}"
784
836
  },
785
837
  {
786
- "id": "components-anchoredoverlay-features--overlay-props-overrides"
838
+ "id": "components-anchoredoverlay-features--overlay-props-overrides",
839
+ "code": "() => {\n const [open, setOpen] = useState(false)\n return (\n <AnchoredOverlay\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n renderAnchor={(props) => <Button {...props}>Button</Button>}\n overlayProps={{\n overflow: 'auto',\n maxHeight: 'xsmall',\n role: 'dialog',\n 'aria-modal': true,\n 'aria-label': 'User Card Overlay',\n className: classes.Overlay,\n }}\n focusZoneSettings={{\n disabled: true,\n }}\n preventOverflow={false}\n >\n <div>Overlay props have been overridden to set: </div>\n <pre>\n <li>overflow: `auto`</li>\n <li>maxHeight: `xsmall`</li>\n </pre>\n <div className={classes.FlexColFill}>{hoverCard}</div>\n </AnchoredOverlay>\n )\n}"
787
840
  }
788
841
  ],
789
842
  "importPath": "@primer/react",
@@ -931,37 +984,48 @@
931
984
  "a11yReviewed": "2025-01-08",
932
985
  "stories": [
933
986
  {
934
- "id": "components-autocomplete--default"
987
+ "id": "components-autocomplete--default",
988
+ "code": "() => {\n return (\n <form\n className={classes.DefaultForm}\n onSubmit={(event) => event.preventDefault()}\n >\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel-default\">\n Label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n selectedItemIds={[]}\n aria-labelledby=\"autocompleteLabel-default\"\n items={items}\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </FormControl>\n </form>\n )\n}"
935
989
  },
936
990
  {
937
- "id": "components-autocomplete-features--with-token-input"
991
+ "id": "components-autocomplete-features--with-token-input",
992
+ "code": "() => {\n const [tokens, setTokens] = useState<Datum[]>([])\n const selectedTokenIds = tokens.map((token) => token.id)\n const [selectedItemIds, setSelectedItemIds] =\n useState<Array<string>>(selectedTokenIds)\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n setSelectedItemIds(selectedItemIds.filter((id) => id !== tokenId))\n }\n const onSelectedChange = (newlySelectedItems: Datum | Datum[]) => {\n if (!Array.isArray(newlySelectedItems)) {\n return\n }\n setSelectedItemIds(newlySelectedItems.map((item) => item.id))\n if (newlySelectedItems.length < selectedItemIds.length) {\n const newlySelectedItemIds = newlySelectedItems.map(({ id }) => id)\n const removedItemIds = selectedTokenIds.filter(\n (id) => !newlySelectedItemIds.includes(id),\n )\n for (const removedItemId of removedItemIds) {\n onTokenRemove(removedItemId)\n }\n return\n }\n setTokens(\n newlySelectedItems.map(({ id, text }) => ({\n id,\n text,\n })),\n )\n }\n return (\n <form className={classes.FormPadding}>\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input\n as={TextInputTokens}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n block\n />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n items={items}\n selectedItemIds={selectedItemIds}\n onSelectedChange={onSelectedChange}\n selectionVariant=\"multiple\"\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </FormControl>\n </form>\n )\n}"
938
993
  },
939
994
  {
940
- "id": "components-autocomplete-features--add-new-item"
995
+ "id": "components-autocomplete-features--add-new-item",
996
+ "code": "() => {\n const [inputValue, setInputValue] = React.useState<string>('')\n return (\n <form className={classes.FormPadding}>\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel-add-new\">\n Label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input\n value={inputValue}\n onChange={(e) => {\n setInputValue(e.currentTarget.value)\n }}\n />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n selectedItemIds={[]}\n aria-labelledby=\"autocompleteLabel-add-new\"\n addNewItem={\n inputValue &&\n !items.map((item) => item.text).includes(inputValue)\n ? {\n text: inputValue,\n id: inputValue,\n handleAddItem: (selectedItem) => {\n // eslint-disable-next-line no-console\n console.log('added item:', selectedItem)\n return\n },\n }\n : undefined\n }\n items={items}\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </FormControl>\n </form>\n )\n}"
941
997
  },
942
998
  {
943
- "id": "components-autocomplete-features--custom-search-filter-fn"
999
+ "id": "components-autocomplete-features--custom-search-filter-fn",
1000
+ "code": "() => {\n const [filterVal, setFilterVal] = useState<string>('')\n const handleChange: ChangeEventHandler<HTMLInputElement> = (e) => {\n setFilterVal(e.currentTarget.value)\n }\n const customFilterFn = (item: Datum) => item.text.includes(filterVal)\n return (\n <form className={classes.FormPadding}>\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input onChange={handleChange} />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n items={items}\n selectedItemIds={[]}\n filterFn={customFilterFn}\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n <FormControl.Caption>\n Items in dropdown are filtered if their text has no part that matches\n the input value\n </FormControl.Caption>\n </FormControl>\n </form>\n )\n}"
944
1001
  },
945
1002
  {
946
- "id": "components-autocomplete-features--custom-sort-after-menu-close"
1003
+ "id": "components-autocomplete-features--custom-sort-after-menu-close",
1004
+ "code": "() => {\n const [selectedItemIds, setSelectedItemIds] = useState<Array<string>>([])\n const isItemSelected = (itemId: string) => selectedItemIds.includes(itemId)\n const onSelectedChange = (newlySelectedItems: Datum | Datum[]) => {\n if (!Array.isArray(newlySelectedItems)) {\n return\n }\n setSelectedItemIds(newlySelectedItems.map((item) => item.id))\n }\n const customSortFn = (itemIdA: string, itemIdB: string) =>\n isItemSelected(itemIdA) === isItemSelected(itemIdB)\n ? 0\n : isItemSelected(itemIdA)\n ? 1\n : -1\n return (\n <form className={classes.FormPadding}>\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n items={items}\n selectedItemIds={selectedItemIds}\n onSelectedChange={onSelectedChange}\n sortOnCloseFn={customSortFn}\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n <FormControl.Caption>\n When the dropdown closes, selected items are sorted to the end\n </FormControl.Caption>\n </FormControl>\n </form>\n )\n}"
947
1005
  },
948
1006
  {
949
- "id": "components-autocomplete-features--with-callback-when-overlay-open-state-changes"
1007
+ "id": "components-autocomplete-features--with-callback-when-overlay-open-state-changes",
1008
+ "code": "() => {\n const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false)\n const onOpenChange = (isOpen: boolean) => {\n setIsMenuOpen(isOpen)\n }\n return (\n <Stack as=\"form\" padding=\"normal\">\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n items={items}\n selectedItemIds={[]}\n onOpenChange={onOpenChange}\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </FormControl>\n <div>\n The menu is <strong>{isMenuOpen ? 'opened' : 'closed'}</strong>\n </div>\n </Stack>\n )\n}"
950
1009
  },
951
1010
  {
952
- "id": "components-autocomplete-features--async-loading-of-items"
1011
+ "id": "components-autocomplete-features--async-loading-of-items",
1012
+ "code": "(args: FormControlArgs<AutocompleteArgs>) => {\n const { parentArgs, labelArgs, captionArgs, validationArgs } =\n getFormControlArgsByChildComponent(args)\n const { menuArgs, overlayArgs, textInputArgs } = getArgsByChildComponent(args)\n const [loadedItems, setLoadedItems] = useState<Datum[]>([])\n const onOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n setTimeout(() => {\n setLoadedItems(items)\n }, 1500)\n }\n }\n return (\n <form className={classes.FormPadding}>\n <FormControl {...parentArgs}>\n <FormControl.Label id=\"autocompleteLabel\" {...labelArgs} />\n <Autocomplete>\n <Autocomplete.Input\n {...textInputArgs}\n size={textInputArgs.inputSize}\n />\n <Autocomplete.Overlay {...overlayArgs}>\n <Autocomplete.Menu\n items={loadedItems}\n selectedItemIds={[]}\n onOpenChange={onOpenChange}\n aria-labelledby=\"autocompleteLabel\"\n {...menuArgs}\n loading={loadedItems.length === 0}\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n {captionArgs.children && <FormControl.Caption {...captionArgs} />}\n {validationArgs.children && validationArgs.variant && (\n <FormControl.Validation\n {...validationArgs}\n variant={validationArgs.variant}\n />\n )}\n </FormControl>\n </form>\n )\n}"
953
1013
  },
954
1014
  {
955
- "id": "components-autocomplete-features--rendering-the-menu-outside-an-overlay"
1015
+ "id": "components-autocomplete-features--rendering-the-menu-outside-an-overlay",
1016
+ "code": "() => {\n return (\n <form className={classes.FormPadding}>\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input />\n <Autocomplete.Menu\n items={items}\n selectedItemIds={[]}\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete>\n </FormControl>\n </form>\n )\n}"
956
1017
  },
957
1018
  {
958
- "id": "components-autocomplete-features--custom-overlay-menu-anchor"
1019
+ "id": "components-autocomplete-features--custom-overlay-menu-anchor",
1020
+ "code": "() => {\n const menuAnchorRef = useRef<HTMLElement>(null)\n return (\n <form className={classes.FormPadding}>\n <FormControl>\n <FormControl.Label htmlFor=\"autocompleteInput\" id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <div\n ref={menuAnchorRef as React.RefObject<HTMLDivElement>}\n className={classes.AnchorContainer}\n >\n <Autocomplete>\n <Autocomplete.Input\n id=\"autocompleteInput\"\n aria-describedby=\"autocompleteCaption autocompleteValidation\"\n className={classes.AnchorInput}\n />\n <Autocomplete.Overlay menuAnchorRef={menuAnchorRef}>\n <Autocomplete.Menu\n items={items}\n selectedItemIds={[]}\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </div>\n <FormControl.Caption>\n The overlay menu position is anchored to the div with the black border\n instead of to the text input\n </FormControl.Caption>\n </FormControl>\n </form>\n )\n}"
959
1021
  },
960
1022
  {
961
- "id": "components-autocomplete-features--in-overlay-with-custom-scroll-container-ref"
1023
+ "id": "components-autocomplete-features--in-overlay-with-custom-scroll-container-ref",
1024
+ "code": "() => {\n const scrollContainerRef = useRef<HTMLElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const triggerRef = useRef<HTMLButtonElement>(null)\n const [isOpen, setIsOpen] = useState(false)\n const [selectedItem, setSelectedItem] = useState<Datum>()\n const handleOpen = () => {\n setIsOpen(true)\n inputRef.current && inputRef.current.focus()\n }\n const selectChange = (item: Datum[] | Datum) => {\n setIsOpen(false)\n if (Array.isArray(item) && item.length) setSelectedItem(item[0])\n triggerRef.current?.focus()\n }\n return (\n <form className={classes.FormPadding}>\n Selected item: {selectedItem ? selectedItem.text : 'none'}\n <AnchoredOverlay\n open={isOpen}\n onOpen={handleOpen}\n onClose={() => setIsOpen(false)}\n width=\"large\"\n focusTrapSettings={{\n initialFocusRef: inputRef,\n }}\n side=\"inside-top\"\n anchorRef={triggerRef}\n renderAnchor={(props) => <Button {...props}>open overlay</Button>}\n preventOverflow={false}\n >\n <Autocomplete>\n <div className={classes.OverlayFlexCol}>\n <div className={classes.OverlayInputBar}>\n <Autocomplete.Input\n ref={inputRef}\n className={classes.OverlayInput}\n block\n aria-label=\"Search\"\n />\n </div>\n <div\n ref={scrollContainerRef as RefObject<HTMLDivElement>}\n className={classes.OverlayScroll}\n >\n <Autocomplete.Menu\n items={items}\n selectedItemIds={[]}\n customScrollContainerRef={scrollContainerRef}\n aria-labelledby=\"autocompleteLabel\"\n onSelectedChange={selectChange}\n />\n </div>\n </div>\n </Autocomplete>\n </AnchoredOverlay>\n </form>\n )\n}"
962
1025
  },
963
1026
  {
964
- "id": "components-autocomplete-features--in-a-dialog"
1027
+ "id": "components-autocomplete-features--in-a-dialog",
1028
+ "code": "() => {\n const outerContainerRef = useRef<HTMLDivElement>(null)\n const [mounted, setMounted] = useState(false)\n const [isDialogOpen, setIsDialogOpen] = useState(false)\n useEffect(() => {\n if (outerContainerRef.current instanceof HTMLElement) {\n registerPortalRoot(outerContainerRef.current, 'outerContainer')\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setMounted(true)\n }\n }, [isDialogOpen])\n return (\n <>\n <Button onClick={() => setIsDialogOpen(true)}>Show dialog</Button>\n <Dialog\n aria-label=\"Dialog with autocomplete\"\n id=\"dialog-with-autocomplete\"\n isOpen={isDialogOpen}\n onDismiss={() => setIsDialogOpen(false)}\n >\n <div ref={outerContainerRef}>\n <form className={classes.FormPadding}>\n {mounted ? (\n <FormControl>\n <FormControl.Label id=\"autocompleteLabel\">\n Default label\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input data-testid=\"autocompleteInput\" />\n <Autocomplete.Overlay portalContainerName=\"outerContainer\">\n <Autocomplete.Menu\n items={items}\n selectedItemIds={[]}\n aria-labelledby=\"autocompleteLabel\"\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </FormControl>\n ) : null}\n </form>\n </div>\n </Dialog>\n <p>\n The Autocomplete.Overlay is portalled to a div inside the Dialog to\n ensure it appears above the dialog in the stacking context.\n </p>\n </>\n )\n}"
965
1029
  }
966
1030
  ],
967
1031
  "importPath": "@primer/react",
@@ -1099,16 +1163,20 @@
1099
1163
  "a11yReviewed": "2025-01-08",
1100
1164
  "stories": [
1101
1165
  {
1102
- "id": "components-avatar--default"
1166
+ "id": "components-avatar--default",
1167
+ "code": "() => <Avatar src=\"https://avatars.githubusercontent.com/u/7143434?v=4\" />"
1103
1168
  },
1104
1169
  {
1105
- "id": "components-avatar-features--square"
1170
+ "id": "components-avatar-features--square",
1171
+ "code": "() => (\n <Avatar\n square\n alt=\"primer\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n)"
1106
1172
  },
1107
1173
  {
1108
- "id": "components-avatar-features--size"
1174
+ "id": "components-avatar-features--size",
1175
+ "code": "() => (\n <div>\n <Avatar\n size={4}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={8}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={12}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={16}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={20}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={24}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={28}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={32}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={40}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={48}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={56}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={64}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n </div>\n)"
1109
1176
  },
1110
1177
  {
1111
- "id": "components-avatar-features--size-responsive"
1178
+ "id": "components-avatar-features--size-responsive",
1179
+ "code": "() => (\n <div>\n <Avatar\n size={{\n narrow: 4,\n regular: 8,\n wide: 12,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 8,\n regular: 12,\n wide: 16,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 12,\n regular: 16,\n wide: 20,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 16,\n regular: 20,\n wide: 24,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 20,\n regular: 24,\n wide: 28,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 24,\n regular: 28,\n wide: 32,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 28,\n regular: 32,\n wide: 40,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 32,\n regular: 40,\n wide: 48,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 40,\n regular: 48,\n wide: 56,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n <Avatar\n size={{\n narrow: 48,\n regular: 56,\n wide: 64,\n }}\n alt=\"mona\"\n src=\"https://avatars.githubusercontent.com/u/7143434?v=4\"\n />\n </div>\n)"
1112
1180
  }
1113
1181
  ],
1114
1182
  "importPath": "@primer/react",
@@ -1149,31 +1217,36 @@
1149
1217
  "a11yReviewed": "2025-01-08",
1150
1218
  "stories": [
1151
1219
  {
1152
- "id": "components-avatarstack--default"
1220
+ "id": "components-avatarstack-features--align-left",
1221
+ "code": "() => (\n <AvatarStack>\n <Avatar\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar alt=\"Atom logo\" src=\"https://avatars.githubusercontent.com/atom\" />\n <Avatar\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1153
1222
  },
1154
1223
  {
1155
- "id": "components-avatarstack-features--align-left"
1224
+ "id": "components-avatarstack-features--align-right",
1225
+ "code": "() => (\n <AvatarStack alignRight>\n <Avatar\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar alt=\"Atom logo\" src=\"https://avatars.githubusercontent.com/atom\" />\n <Avatar\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1156
1226
  },
1157
1227
  {
1158
- "id": "components-avatarstack-features--align-right"
1228
+ "id": "components-avatarstack-features--disable-expand-on-hover",
1229
+ "code": "() => (\n <AvatarStack disableExpand>\n <Avatar\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar alt=\"Atom logo\" src=\"https://avatars.githubusercontent.com/atom\" />\n <Avatar\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1159
1230
  },
1160
1231
  {
1161
- "id": "components-avatarstack-features--disable-expand-on-hover"
1232
+ "id": "components-avatarstack-features--custom-size-on-parent",
1233
+ "code": "() => (\n <AvatarStack size={32}>\n <Avatar\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar alt=\"Atom logo\" src=\"https://avatars.githubusercontent.com/atom\" />\n <Avatar\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1162
1234
  },
1163
1235
  {
1164
- "id": "components-avatarstack-features--custom-size-on-parent"
1236
+ "id": "components-avatarstack-features--custom-size-on-parent-responsive",
1237
+ "code": "() => (\n <AvatarStack\n size={{\n narrow: 32,\n regular: 48,\n wide: 64,\n }}\n >\n <Avatar\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar alt=\"Atom logo\" src=\"https://avatars.githubusercontent.com/atom\" />\n <Avatar\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1165
1238
  },
1166
1239
  {
1167
- "id": "components-avatarstack-features--custom-size-on-parent-responsive"
1240
+ "id": "components-avatarstack-features--custom-size-on-children",
1241
+ "code": "() => (\n <AvatarStack>\n <Avatar\n size={20}\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n size={32}\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar\n size={48}\n alt=\"Atom logo\"\n src=\"https://avatars.githubusercontent.com/atom\"\n />\n <Avatar\n size={64}\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1168
1242
  },
1169
1243
  {
1170
- "id": "components-avatarstack-features--custom-size-on-children"
1244
+ "id": "components-avatarstack-features--custom-size-on-children-responsive",
1245
+ "code": "() => (\n <AvatarStack>\n <Avatar\n size={{\n narrow: 16,\n regular: 32,\n wide: 48,\n }}\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n <Avatar\n size={{\n narrow: 32,\n regular: 48,\n wide: 64,\n }}\n alt=\"GitHub logo\"\n src=\"https://avatars.githubusercontent.com/github\"\n />\n <Avatar\n size={{\n narrow: 48,\n regular: 64,\n wide: 96,\n }}\n alt=\"Atom logo\"\n src=\"https://avatars.githubusercontent.com/atom\"\n />\n <Avatar\n size={{\n narrow: 64,\n regular: 96,\n wide: 120,\n }}\n alt=\"GitHub Desktop logo\"\n src=\"https://avatars.githubusercontent.com/desktop\"\n />\n </AvatarStack>\n)"
1171
1246
  },
1172
1247
  {
1173
- "id": "components-avatarstack-features--custom-size-on-children-responsive"
1174
- },
1175
- {
1176
- "id": "components-avatarstack-features--with-single-avatar"
1248
+ "id": "components-avatarstack-features--with-single-avatar",
1249
+ "code": "() => (\n <AvatarStack>\n <Avatar\n alt=\"Primer logo\"\n src=\"https://avatars.githubusercontent.com/primer\"\n />\n </AvatarStack>\n)"
1177
1250
  }
1178
1251
  ],
1179
1252
  "importPath": "@primer/react",
@@ -1220,49 +1293,64 @@
1220
1293
  "importPath": "@primer/react",
1221
1294
  "stories": [
1222
1295
  {
1223
- "id": "components-banner--default"
1296
+ "id": "components-banner--default",
1297
+ "code": "() => {\n return (\n <Banner\n onDismiss={action('onDismiss')}\n title=\"Info\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n primaryAction={<Banner.PrimaryAction>Button</Banner.PrimaryAction>}\n secondaryAction={<Banner.SecondaryAction>Button</Banner.SecondaryAction>}\n />\n )\n}"
1224
1298
  },
1225
1299
  {
1226
- "id": "components-banner-features--critical"
1300
+ "id": "components-banner-features--critical",
1301
+ "code": "() => {\n return (\n <Banner\n title=\"Critical\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n variant=\"critical\"\n />\n )\n}"
1227
1302
  },
1228
1303
  {
1229
- "id": "components-banner-features--info"
1304
+ "id": "components-banner-features--info",
1305
+ "code": "() => {\n return (\n <Banner\n title=\"Info\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n variant=\"info\"\n ></Banner>\n )\n}"
1230
1306
  },
1231
1307
  {
1232
- "id": "components-banner-features--success"
1308
+ "id": "components-banner-features--success",
1309
+ "code": "() => {\n return (\n <Banner\n title=\"Success\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n variant=\"success\"\n />\n )\n}"
1233
1310
  },
1234
1311
  {
1235
- "id": "components-banner-features--upsell"
1312
+ "id": "components-banner-features--upsell",
1313
+ "code": "() => {\n return (\n <Banner\n title=\"Upsell\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n variant=\"upsell\"\n />\n )\n}"
1236
1314
  },
1237
1315
  {
1238
- "id": "components-banner-features--warning"
1316
+ "id": "components-banner-features--warning",
1317
+ "code": "() => {\n return (\n <Banner\n title=\"Warning\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n variant=\"warning\"\n />\n )\n}"
1239
1318
  },
1240
1319
  {
1241
- "id": "components-banner-features--dismiss"
1320
+ "id": "components-banner-features--dismiss",
1321
+ "code": "() => {\n return (\n <Banner\n title=\"Notice\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n />\n )\n}"
1242
1322
  },
1243
1323
  {
1244
- "id": "components-banner-features--dismiss-with-actions"
1324
+ "id": "components-banner-features--dismiss-with-actions",
1325
+ "code": "() => {\n return (\n <Banner\n title=\"Notice\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n primaryAction={<Banner.PrimaryAction>Button</Banner.PrimaryAction>}\n secondaryAction={<Banner.SecondaryAction>Button</Banner.SecondaryAction>}\n />\n )\n}"
1245
1326
  },
1246
1327
  {
1247
- "id": "components-banner-features--with-hidden-title"
1328
+ "id": "components-banner-features--with-hidden-title",
1329
+ "code": "() => {\n return (\n <Banner\n title=\"Warning\"\n hideTitle\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n variant=\"warning\"\n />\n )\n}"
1248
1330
  },
1249
1331
  {
1250
- "id": "components-banner-features--with-hidden-title-and-actions"
1332
+ "id": "components-banner-features--with-hidden-title-and-actions",
1333
+ "code": "() => {\n return (\n <Banner\n title=\"Warning\"\n hideTitle\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n variant=\"warning\"\n primaryAction={<Banner.PrimaryAction>Button</Banner.PrimaryAction>}\n secondaryAction={<Banner.SecondaryAction>Button</Banner.SecondaryAction>}\n />\n )\n}"
1251
1334
  },
1252
1335
  {
1253
- "id": "components-banner-features--dismissible-with-hidden-title-and-actions"
1336
+ "id": "components-banner-features--dismissible-with-hidden-title-and-actions",
1337
+ "code": "() => {\n return (\n <Banner\n title=\"Warning\"\n hideTitle\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n variant=\"warning\"\n primaryAction={<Banner.PrimaryAction>Button</Banner.PrimaryAction>}\n secondaryAction={<Banner.SecondaryAction>Button</Banner.SecondaryAction>}\n />\n )\n}"
1254
1338
  },
1255
1339
  {
1256
- "id": "components-banner-features--dismissible-with-hidden-title-and-secondary-action"
1340
+ "id": "components-banner-features--dismissible-with-hidden-title-and-secondary-action",
1341
+ "code": "() => {\n return (\n <Banner\n title=\"Warning\"\n hideTitle\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n onDismiss={action('onDismiss')}\n variant=\"warning\"\n secondaryAction={\n <Banner.SecondaryAction leadingVisual={GitPullRequestIcon}>\n Button\n </Banner.SecondaryAction>\n }\n />\n )\n}"
1257
1342
  },
1258
1343
  {
1259
- "id": "components-banner-features--with-actions"
1344
+ "id": "components-banner-features--with-actions",
1345
+ "code": "() => {\n return (\n <Banner\n title=\"Warning\"\n description={\n <>\n GitHub users are{' '}\n <Link inline href=\"#\">\n now required\n </Link>{' '}\n to enable two-factor authentication as an additional security measure.\n </>\n }\n primaryAction={<Banner.PrimaryAction>Button</Banner.PrimaryAction>}\n secondaryAction={<Banner.SecondaryAction>Button</Banner.SecondaryAction>}\n variant=\"warning\"\n />\n )\n}"
1260
1346
  },
1261
1347
  {
1262
- "id": "components-banner-features--custom-icon"
1348
+ "id": "components-banner-features--custom-icon",
1349
+ "code": "() => {\n return (\n <Banner\n title=\"Upsell\"\n description=\"An example banner with a custom icon\"\n leadingVisual={<CopilotIcon />}\n onDismiss={action('onDismiss')}\n variant=\"upsell\"\n />\n )\n}"
1263
1350
  },
1264
1351
  {
1265
- "id": "components-banner-examples--with-announcement"
1352
+ "id": "components-banner-examples--with-announcement",
1353
+ "code": "() => {\n type Choice = 'one' | 'two' | 'three'\n const messages: Map<Choice, string> = new Map([\n ['one', 'This is a message for choice one'],\n ['two', 'This is a message for choice two'],\n ['three', 'This is a message for choice three'],\n ])\n const [selected, setSelected] = React.useState<Choice>('one')\n return (\n <>\n <Banner\n title=\"Info\"\n description={<AriaStatus>{messages.get(selected)}</AriaStatus>}\n onDismiss={action('onDismiss')}\n primaryAction={<Banner.PrimaryAction>Button</Banner.PrimaryAction>}\n secondaryAction={\n <Banner.SecondaryAction>Button</Banner.SecondaryAction>\n }\n />\n <RadioGroup\n name=\"options\"\n onChange={(selected) => {\n setSelected(selected as Choice)\n }}\n className={classes.RadioGroupWithTopMargin}\n >\n <RadioGroup.Label>Choices</RadioGroup.Label>\n <FormControl>\n <Radio value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </RadioGroup>\n </>\n )\n}"
1266
1354
  }
1267
1355
  ],
1268
1356
  "props": [
@@ -1386,28 +1474,36 @@
1386
1474
  "a11yReviewed": "2025-01-08",
1387
1475
  "stories": [
1388
1476
  {
1389
- "id": "experimental-components-blankslate--default"
1477
+ "id": "experimental-components-blankslate--default",
1478
+ "code": "() => (\n <Blankslate>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Welcome to the mona wiki!</Blankslate.Heading>\n <Blankslate.Description>\n Wikis provide a place in your repository to lay out the roadmap of your\n project, show the current status, and document software better, together.\n </Blankslate.Description>\n <Blankslate.PrimaryAction href=\"#\">\n Create the first page\n </Blankslate.PrimaryAction>\n <Blankslate.SecondaryAction href=\"#\">\n Learn more about wikis\n </Blankslate.SecondaryAction>\n </Blankslate>\n)"
1390
1479
  },
1391
1480
  {
1392
- "id": "experimental-components-blankslate-features--with-visual"
1481
+ "id": "experimental-components-blankslate-features--with-visual",
1482
+ "code": "() => (\n <Blankslate>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n </Blankslate>\n)"
1393
1483
  },
1394
1484
  {
1395
- "id": "experimental-components-blankslate-features--with-primary-action-as-link"
1485
+ "id": "experimental-components-blankslate-features--with-primary-action-as-link",
1486
+ "code": "() => (\n <Blankslate>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n <Blankslate.PrimaryAction href=\"#\">Primary action</Blankslate.PrimaryAction>\n </Blankslate>\n)"
1396
1487
  },
1397
1488
  {
1398
- "id": "experimental-components-blankslate-features--with-primary-action-as-button"
1489
+ "id": "experimental-components-blankslate-features--with-primary-action-as-button",
1490
+ "code": "() => {\n const [isOpen, setIsOpen] = React.useState(false)\n const onDialogClose = React.useCallback(() => setIsOpen(false), [])\n return (\n <>\n <Blankslate>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n <Blankslate.PrimaryAction onClick={() => setIsOpen(true)}>\n Primary action\n </Blankslate.PrimaryAction>\n </Blankslate>\n {isOpen ? (\n <ConfirmationDialog\n title=\"Delete universe?\"\n onClose={onDialogClose}\n confirmButtonContent=\"Delete it!\"\n confirmButtonType=\"danger\"\n >\n Deleting the universe could have disastrous effects, including but not\n limited to destroying all life on Earth.\n </ConfirmationDialog>\n ) : null}\n </>\n )\n}"
1399
1491
  },
1400
1492
  {
1401
- "id": "experimental-components-blankslate-features--with-secondary-action"
1493
+ "id": "experimental-components-blankslate-features--with-secondary-action",
1494
+ "code": "() => (\n <Blankslate>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n <Blankslate.SecondaryAction href=\"#\">\n Secondary action\n </Blankslate.SecondaryAction>\n </Blankslate>\n)"
1402
1495
  },
1403
1496
  {
1404
- "id": "experimental-components-blankslate-features--with-border"
1497
+ "id": "experimental-components-blankslate-features--with-border",
1498
+ "code": "() => (\n <Blankslate border>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n </Blankslate>\n)"
1405
1499
  },
1406
1500
  {
1407
- "id": "experimental-components-blankslate-features--narrow"
1501
+ "id": "experimental-components-blankslate-features--narrow",
1502
+ "code": "() => (\n <Blankslate border narrow>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n </Blankslate>\n)"
1408
1503
  },
1409
1504
  {
1410
- "id": "experimental-components-blankslate-features--spacious"
1505
+ "id": "experimental-components-blankslate-features--spacious",
1506
+ "code": "() => (\n <Blankslate spacious>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n </Blankslate>\n)"
1411
1507
  }
1412
1508
  ],
1413
1509
  "importPath": "@primer/react/experimental",
@@ -1489,13 +1585,16 @@
1489
1585
  "a11yReviewed": "2025-01-08",
1490
1586
  "stories": [
1491
1587
  {
1492
- "id": "components-branchname--default"
1588
+ "id": "components-branchname--default",
1589
+ "code": "() => <BranchName href=\"#\">branch_name</BranchName>"
1493
1590
  },
1494
1591
  {
1495
- "id": "components-branchname-features--with-branch-icon"
1592
+ "id": "components-branchname-features--with-branch-icon",
1593
+ "code": "() => (\n <BranchName href=\"#\">\n <Stack direction=\"horizontal\" gap=\"condensed\" align=\"center\">\n <Octicon icon={GitBranchIcon} />\n branch_name\n </Stack>\n </BranchName>\n)"
1496
1594
  },
1497
1595
  {
1498
- "id": "components-branchname-features--not-a-link"
1596
+ "id": "components-branchname-features--not-a-link",
1597
+ "code": "() => <BranchName as=\"span\">branch_name_as_span</BranchName>"
1499
1598
  }
1500
1599
  ],
1501
1600
  "importPath": "@primer/react",
@@ -1520,7 +1619,8 @@
1520
1619
  "a11yReviewed": "2025-01-08",
1521
1620
  "stories": [
1522
1621
  {
1523
- "id": "components-breadcrumbs--default"
1622
+ "id": "components-breadcrumbs--default",
1623
+ "code": "() => (\n <Breadcrumbs>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">About</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\" selected>\n Team\n </Breadcrumbs.Item>\n </Breadcrumbs>\n)"
1524
1624
  }
1525
1625
  ],
1526
1626
  "importPath": "@primer/react",
@@ -1600,82 +1700,108 @@
1600
1700
  "a11yReviewed": "2025-01-08",
1601
1701
  "stories": [
1602
1702
  {
1603
- "id": "components-button--default"
1703
+ "id": "components-button--default",
1704
+ "code": "() => <Button>Default</Button>"
1604
1705
  },
1605
1706
  {
1606
- "id": "components-button-features--primary"
1707
+ "id": "components-button-features--primary",
1708
+ "code": "() => <Button variant=\"primary\">Primary</Button>"
1607
1709
  },
1608
1710
  {
1609
- "id": "components-button-features--danger"
1711
+ "id": "components-button-features--danger",
1712
+ "code": "() => <Button variant=\"danger\">Danger</Button>"
1610
1713
  },
1611
1714
  {
1612
- "id": "components-button-features--invisible"
1715
+ "id": "components-button-features--invisible",
1716
+ "code": "() => <Button variant=\"invisible\">Invisible</Button>"
1613
1717
  },
1614
1718
  {
1615
- "id": "components-button-features--link"
1719
+ "id": "components-button-features--link",
1720
+ "code": "() => <Button variant=\"link\">Button that looks like a link</Button>"
1616
1721
  },
1617
1722
  {
1618
- "id": "components-button-features--leading-visual"
1723
+ "id": "components-button-features--leading-visual",
1724
+ "code": "() => <Button leadingVisual={HeartIcon}>Leading visual</Button>"
1619
1725
  },
1620
1726
  {
1621
- "id": "components-button-features--trailing-visual"
1727
+ "id": "components-button-features--trailing-visual",
1728
+ "code": "() => <Button trailingVisual={EyeIcon}>Trailing visual</Button>"
1622
1729
  },
1623
1730
  {
1624
- "id": "components-button-features--trailing-counter"
1731
+ "id": "components-button-features--trailing-counter",
1732
+ "code": "() => {\n const [count, setCount] = useState(0)\n const onClick = () => {\n setCount(count + 1)\n announce(`Watch ${count + 1}`)\n }\n return (\n <>\n <Button onClick={onClick} count={count}>\n Watch\n </Button>\n <AccessibilityNote />\n <p>\n In this example, a live region has been implemented to communicate the\n change.\n </p>\n </>\n )\n}"
1625
1733
  },
1626
1734
  {
1627
- "id": "components-button-features--trailing-counter-with-no-text"
1735
+ "id": "components-button-features--trailing-counter-with-no-text",
1736
+ "code": "() => <Button aria-label=\"Comments\" leadingVisual={CommentIcon} count={3} />"
1628
1737
  },
1629
1738
  {
1630
- "id": "components-button-features--trailing-counter-all-variants"
1739
+ "id": "components-button-features--trailing-counter-all-variants",
1740
+ "code": "() => {\n const [count, setCount] = useState(0)\n const onClick = () => {\n setCount(count + 1)\n announce(`Watch ${count + 1}`)\n }\n return (\n <>\n <Stack gap=\"normal\" wrap=\"wrap\" direction=\"horizontal\">\n <Button onClick={onClick} count={count}>\n Watch\n </Button>\n <Button onClick={onClick} count={count}>\n Watch\n </Button>\n <Button onClick={onClick} count={count}>\n Watch\n </Button>\n <Button onClick={onClick} variant=\"primary\" disabled count={count}>\n Watch\n </Button>\n <Button onClick={onClick} variant=\"danger\" count={count}>\n Watch\n </Button>\n <Button onClick={onClick} variant=\"danger\" disabled count={count}>\n Watch\n </Button>\n <Button onClick={onClick} variant=\"invisible\" count={count}>\n Watch\n </Button>\n <Button onClick={onClick} variant=\"invisible\" disabled count={count}>\n Watch\n </Button>\n </Stack>\n <AccessibilityNote />\n <p>\n In these examples, a live region has been implemented to communicate the\n change.\n </p>\n </>\n )\n}"
1631
1741
  },
1632
1742
  {
1633
- "id": "components-button-features--trailing-action"
1743
+ "id": "components-button-features--trailing-action",
1744
+ "code": "() => <Button trailingAction={TriangleDownIcon}>Trailing action</Button>"
1634
1745
  },
1635
1746
  {
1636
- "id": "components-button-features--block"
1747
+ "id": "components-button-features--block",
1748
+ "code": "() => <Button block>Default</Button>"
1637
1749
  },
1638
1750
  {
1639
- "id": "components-button-features--disabled"
1751
+ "id": "components-button-features--disabled",
1752
+ "code": "() => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n gap: '1rem',\n }}\n >\n <Button disabled>Default</Button>\n <Button variant=\"primary\" disabled>\n Primary\n </Button>\n <Button variant=\"danger\" disabled>\n Danger\n </Button>\n <Button variant=\"invisible\" disabled>\n Invisible\n </Button>\n </div>\n)"
1640
1753
  },
1641
1754
  {
1642
- "id": "components-button-features--inactive"
1755
+ "id": "components-button-features--inactive",
1756
+ "code": "() => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n gap: '1rem',\n }}\n >\n <Button inactive>Default</Button>\n <Button variant=\"primary\" inactive>\n Primary\n </Button>\n <Button variant=\"danger\" inactive>\n Danger\n </Button>\n <Button variant=\"invisible\" inactive>\n Invisible\n </Button>\n </div>\n)"
1643
1757
  },
1644
1758
  {
1645
- "id": "components-button-features--small"
1759
+ "id": "components-button-features--small",
1760
+ "code": "() => <Button size=\"small\">Default</Button>"
1646
1761
  },
1647
1762
  {
1648
- "id": "components-button-features--medium"
1763
+ "id": "components-button-features--medium",
1764
+ "code": "() => <Button size=\"medium\">Default</Button>"
1649
1765
  },
1650
1766
  {
1651
- "id": "components-button-features--large"
1767
+ "id": "components-button-features--large",
1768
+ "code": "() => <Button size=\"large\">Default</Button>"
1652
1769
  },
1653
1770
  {
1654
- "id": "components-button-features--loading"
1771
+ "id": "components-button-features--loading",
1772
+ "code": "() => <Button loading>Default</Button>"
1655
1773
  },
1656
1774
  {
1657
- "id": "components-button-features--loading-custom-announcement"
1775
+ "id": "components-button-features--loading-custom-announcement",
1776
+ "code": "() => (\n <Button loading loadingAnnouncement=\"This is a custom loading announcement\">\n Default\n </Button>\n)"
1658
1777
  },
1659
1778
  {
1660
- "id": "components-button-features--loading-with-leading-visual"
1779
+ "id": "components-button-features--loading-with-leading-visual",
1780
+ "code": "() => (\n <Button loading leadingVisual={DownloadIcon}>\n Export\n </Button>\n)"
1661
1781
  },
1662
1782
  {
1663
- "id": "components-button-features--loading-with-trailing-visual"
1783
+ "id": "components-button-features--loading-with-trailing-visual",
1784
+ "code": "() => (\n <Button loading trailingVisual={DownloadIcon}>\n Export\n </Button>\n)"
1664
1785
  },
1665
1786
  {
1666
- "id": "components-button-features--loading-with-trailing-action"
1787
+ "id": "components-button-features--loading-with-trailing-action",
1788
+ "code": "() => (\n <Button loading trailingAction={TriangleDownIcon}>\n Export dropdown\n </Button>\n)"
1667
1789
  },
1668
1790
  {
1669
- "id": "components-button-features--loading-trigger"
1791
+ "id": "components-button-features--loading-trigger",
1792
+ "code": "() => {\n const [isLoading, setIsLoading] = useState(false)\n const handleClick = () => {\n setIsLoading(true)\n }\n return (\n <Button\n loading={isLoading}\n onClick={handleClick}\n leadingVisual={DownloadIcon}\n >\n Export\n </Button>\n )\n}"
1670
1793
  },
1671
1794
  {
1672
- "id": "components-button-features--label-wrap"
1795
+ "id": "components-button-features--label-wrap",
1796
+ "code": "() => {\n return (\n <Stack\n style={{\n width: '200px',\n }}\n >\n <Button labelWrap>\n This button label will wrap if the label is too long\n </Button>\n <Button size=\"small\" labelWrap>\n This small button label will wrap if the label is too long\n </Button>\n <Button size=\"large\" labelWrap>\n This large button label will wrap if the label is too long\n </Button>\n <Button labelWrap leadingVisual={HeartIcon} trailingVisual={EyeIcon}>\n This button label will wrap if the label is too long\n </Button>\n </Stack>\n )\n}"
1673
1797
  },
1674
1798
  {
1675
- "id": "components-button-features--inactive-button-with-tooltip"
1799
+ "id": "components-button-features--inactive-button-with-tooltip",
1800
+ "code": "() => (\n <Tooltip\n text=\"Action unavailable: an error occurred while loading repository permissions\"\n direction=\"n\"\n >\n <Button inactive>Review changes</Button>\n </Tooltip>\n)"
1676
1801
  },
1677
1802
  {
1678
- "id": "components-button-features--expanded-button"
1803
+ "id": "components-button-features--expanded-button",
1804
+ "code": "() => (\n <Stack align=\"start\">\n <Button aria-expanded trailingAction={TriangleDownIcon}>\n Review changes\n </Button>\n <Button aria-expanded trailingAction={TriangleDownIcon} variant=\"primary\">\n Review changes\n </Button>\n <Button aria-expanded trailingAction={TriangleDownIcon} variant=\"invisible\">\n Review changes\n </Button>\n <Button aria-expanded trailingAction={TriangleDownIcon} variant=\"danger\">\n Review changes\n </Button>\n </Stack>\n)"
1679
1805
  }
1680
1806
  ],
1681
1807
  "importPath": "@primer/react",
@@ -1794,52 +1920,68 @@
1794
1920
  "a11yReviewed": "2025-01-08",
1795
1921
  "stories": [
1796
1922
  {
1797
- "id": "components-iconbutton--default"
1923
+ "id": "components-iconbutton--default",
1924
+ "code": "() => <IconButton icon={HeartIcon} aria-label=\"Favorite\" />"
1798
1925
  },
1799
1926
  {
1800
- "id": "components-iconbutton-features--primary"
1927
+ "id": "components-iconbutton-features--primary",
1928
+ "code": "() => <IconButton icon={HeartIcon} variant=\"primary\" aria-label=\"Favorite\" />"
1801
1929
  },
1802
1930
  {
1803
- "id": "components-iconbutton-features--danger"
1931
+ "id": "components-iconbutton-features--danger",
1932
+ "code": "() => <IconButton icon={HeartIcon} variant=\"danger\" aria-label=\"Favorite\" />"
1804
1933
  },
1805
1934
  {
1806
- "id": "components-iconbutton-features--invisible"
1935
+ "id": "components-iconbutton-features--invisible",
1936
+ "code": "() => <IconButton icon={HeartIcon} variant=\"invisible\" aria-label=\"Favorite\" />"
1807
1937
  },
1808
1938
  {
1809
- "id": "components-iconbutton-features--disabled"
1939
+ "id": "components-iconbutton-features--disabled",
1940
+ "code": "() => <IconButton disabled icon={HeartIcon} aria-label=\"Favorite\" />"
1810
1941
  },
1811
1942
  {
1812
- "id": "components-iconbutton-features--small"
1943
+ "id": "components-iconbutton-features--small",
1944
+ "code": "() => <IconButton size=\"small\" icon={HeartIcon} aria-label=\"Favorite\" />"
1813
1945
  },
1814
1946
  {
1815
- "id": "components-iconbutton-features--medium"
1947
+ "id": "components-iconbutton-features--medium",
1948
+ "code": "() => <IconButton size=\"medium\" icon={HeartIcon} aria-label=\"Favorite\" />"
1816
1949
  },
1817
1950
  {
1818
- "id": "components-iconbutton-features--large"
1951
+ "id": "components-iconbutton-features--large",
1952
+ "code": "() => <IconButton size=\"large\" icon={HeartIcon} aria-label=\"Favorite\" />"
1819
1953
  },
1820
1954
  {
1821
- "id": "components-iconbutton-features--with-description"
1955
+ "id": "components-iconbutton-features--with-description",
1956
+ "code": "() => (\n <IconButton\n icon={InboxIcon}\n aria-label=\"Notifications\"\n description=\"You have no unread notifications.\"\n />\n)"
1822
1957
  },
1823
1958
  {
1824
- "id": "components-iconbutton-features--external-tooltip"
1959
+ "id": "components-iconbutton-features--external-tooltip",
1960
+ "code": "() => (\n <Tooltip\n text=\"this is a supportive description for icon button\"\n direction=\"se\"\n >\n <IconButton icon={HeartIcon} aria-label=\"HeartIcon\" />\n </Tooltip>\n)"
1825
1961
  },
1826
1962
  {
1827
- "id": "components-iconbutton-features--external-tooltip-version-1"
1963
+ "id": "components-iconbutton-features--external-tooltip-version-1",
1964
+ "code": "() => (\n <TooltipV1\n text=\"this is a supportive description for icon button\"\n direction=\"se\"\n >\n <IconButton icon={HeartIcon} aria-label=\"HeartIcon\" />\n </TooltipV1>\n)"
1828
1965
  },
1829
1966
  {
1830
- "id": "components-iconbutton-features--as-a-menu-anchor"
1967
+ "id": "components-iconbutton-features--as-a-menu-anchor",
1968
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Anchor>\n <IconButton icon={ChevronDownIcon} aria-label=\"Something\" />\n </ActionMenu.Anchor>\n\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Copy link clicked')}>\n Copy link\n <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Quote reply clicked')}>\n Quote reply\n <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Edit comment clicked')}>\n Edit comment\n <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item\n variant=\"danger\"\n onSelect={() => alert('Delete file clicked')}\n >\n Delete file\n <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
1831
1969
  },
1832
1970
  {
1833
- "id": "components-iconbutton-features--loading"
1971
+ "id": "components-iconbutton-features--loading",
1972
+ "code": "() => (\n <IconButton loading icon={HeartIcon} variant=\"primary\" aria-label=\"Primary\" />\n)"
1834
1973
  },
1835
1974
  {
1836
- "id": "components-iconbutton-features--loading-trigger"
1975
+ "id": "components-iconbutton-features--loading-trigger",
1976
+ "code": "() => {\n const [isLoading, setIsLoading] = useState(false)\n const handleClick = () => {\n setIsLoading(true)\n setTimeout(() => {\n setIsLoading(false)\n }, 3000)\n }\n return (\n <IconButton\n loading={isLoading}\n onClick={handleClick}\n icon={DownloadIcon}\n aria-label=\"Download\"\n />\n )\n}"
1837
1977
  },
1838
1978
  {
1839
- "id": "components-iconbutton-features--keybinding-hint-on-description"
1979
+ "id": "components-iconbutton-features--keybinding-hint-on-description",
1980
+ "code": "() => (\n <IconButton\n icon={InboxIcon}\n aria-label=\"Notifications\"\n description=\"You have unread notifications\"\n keybindingHint=\"G+N\"\n />\n)"
1840
1981
  },
1841
1982
  {
1842
- "id": "components-iconbutton-features--keybinding-hint"
1983
+ "id": "components-iconbutton-features--keybinding-hint",
1984
+ "code": "() => <IconButton icon={BoldIcon} aria-label=\"Bold\" keybindingHint=\"Mod+B\" />"
1843
1985
  }
1844
1986
  ],
1845
1987
  "importPath": "@primer/react",
@@ -1927,19 +2069,24 @@
1927
2069
  "a11yReviewed": "2025-01-08",
1928
2070
  "stories": [
1929
2071
  {
1930
- "id": "components-buttongroup--default"
2072
+ "id": "components-buttongroup--default",
2073
+ "code": "() => (\n <ButtonGroup>\n <Button>Button 1</Button>\n <Button>Button 2</Button>\n <Button>Button 3</Button>\n </ButtonGroup>\n)"
1931
2074
  },
1932
2075
  {
1933
- "id": "components-buttongroup-features--icon-buttons"
2076
+ "id": "components-buttongroup-features--icon-buttons",
2077
+ "code": "() => (\n <ButtonGroup>\n {/* We can remove these unsafe props after we resolve https://github.com/primer/react/issues/4129 */}\n <IconButton icon={PlusIcon} aria-label=\"Add\" />\n <IconButton icon={DashIcon} aria-label=\"Subtract\" />\n </ButtonGroup>\n)"
1934
2078
  },
1935
2079
  {
1936
- "id": "components-buttongroup-features--loading-buttons"
2080
+ "id": "components-buttongroup-features--loading-buttons",
2081
+ "code": "() => {\n const handleClick = () => {}\n return (\n <ButtonGroup>\n <Button loading={true} onClick={handleClick}>\n Button 1\n </Button>\n <Button onClick={handleClick}>Button 2</Button>\n <Tooltip text=\"Additional info about the button\">\n <Button onClick={handleClick}>Button 3</Button>\n </Tooltip>\n </ButtonGroup>\n )\n}"
1937
2082
  },
1938
2083
  {
1939
- "id": "components-buttongroup-features--dropdown-split"
2084
+ "id": "components-buttongroup-features--dropdown-split",
2085
+ "code": "() => {\n const actions = ['Action one', 'Action two', 'Action three']\n const [selectedActionIndex, setSelectedActionIndex] =\n React.useState<number>(0)\n const selectedAction = actions[selectedActionIndex]\n return (\n <ButtonGroup>\n <Button\n onClick={() => {\n alert(`Activated ${selectedAction}`)\n }}\n >\n {selectedAction}\n </Button>\n <ActionMenu>\n <ActionMenu.Button aria-label=\"More options\" icon={TriangleDownIcon} />\n <ActionMenu.Overlay>\n <ActionList>\n {actions.map((action, index) => {\n return (\n <ActionList.Item\n key={action}\n onSelect={() => {\n setSelectedActionIndex(index)\n }}\n >\n {action}\n </ActionList.Item>\n )\n })}\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n </ButtonGroup>\n )\n}"
1940
2086
  },
1941
2087
  {
1942
- "id": "components-buttongroup-features--as-toolbar"
2088
+ "id": "components-buttongroup-features--as-toolbar",
2089
+ "code": "() => (\n <ButtonGroup role=\"toolbar\">\n <Button>Button 1</Button>\n <Button>Button 2</Button>\n <Button>Button 3</Button>\n </ButtonGroup>\n)"
1943
2090
  }
1944
2091
  ],
1945
2092
  "importPath": "@primer/react",
@@ -1959,19 +2106,24 @@
1959
2106
  "a11yReviewed": "2025-01-08",
1960
2107
  "stories": [
1961
2108
  {
1962
- "id": "components-checkbox--default"
2109
+ "id": "components-checkbox--default",
2110
+ "code": "() => (\n <form>\n <FormControl>\n <Checkbox value=\"default\" />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n </form>\n)"
1963
2111
  },
1964
2112
  {
1965
- "id": "components-checkbox-features--with-leading-visual"
2113
+ "id": "components-checkbox-features--with-leading-visual",
2114
+ "code": "() => {\n return (\n <form>\n <FormControl>\n <FormControl.LeadingVisual>\n <MarkGithubIcon />\n </FormControl.LeadingVisual>\n <Checkbox value=\"default\" />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n </form>\n )\n}"
1966
2115
  },
1967
2116
  {
1968
- "id": "components-checkbox-features--disabled"
2117
+ "id": "components-checkbox-features--disabled",
2118
+ "code": "() => {\n return (\n <form>\n <FormControl disabled>\n <Checkbox value=\"default\" />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n </form>\n )\n}"
1969
2119
  },
1970
2120
  {
1971
- "id": "components-checkbox-features--with-caption"
2121
+ "id": "components-checkbox-features--with-caption",
2122
+ "code": "() => {\n return (\n <form>\n <FormControl>\n <Checkbox value=\"default\" />\n <FormControl.Label>Default label</FormControl.Label>\n <FormControl.Caption>This is a caption</FormControl.Caption>\n </FormControl>\n </form>\n )\n}"
1972
2123
  },
1973
2124
  {
1974
- "id": "components-checkbox-features--indeterminate"
2125
+ "id": "components-checkbox-features--indeterminate",
2126
+ "code": "() => (\n <form>\n <FormControl>\n <Checkbox value=\"default\" indeterminate />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n </form>\n)"
1975
2127
  }
1976
2128
  ],
1977
2129
  "importPath": "@primer/react",
@@ -2038,22 +2190,28 @@
2038
2190
  "a11yReviewed": "2025-01-08",
2039
2191
  "stories": [
2040
2192
  {
2041
- "id": "components-checkboxgroup--default"
2193
+ "id": "components-checkboxgroup--default",
2194
+ "code": "() => (\n <CheckboxGroup>\n <CheckboxGroup.Label>Choices</CheckboxGroup.Label>\n <FormControl required>\n <Checkbox value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </CheckboxGroup>\n)"
2042
2195
  },
2043
2196
  {
2044
- "id": "components-checkboxgroup-features--visually-hidden-label"
2197
+ "id": "components-checkboxgroup-features--visually-hidden-label",
2198
+ "code": "() => (\n <CheckboxGroup>\n <CheckboxGroup.Label visuallyHidden>Choices</CheckboxGroup.Label>\n <FormControl>\n <Checkbox value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </CheckboxGroup>\n)"
2045
2199
  },
2046
2200
  {
2047
- "id": "components-checkboxgroup-features--with-external-label"
2201
+ "id": "components-checkboxgroup-features--with-external-label",
2202
+ "code": "() => (\n <>\n <div id=\"choiceHeading\" className={classes.ExternalLabel}>\n External label\n </div>\n <CheckboxGroup aria-labelledby=\"choiceHeading\">\n <FormControl>\n <Checkbox />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </CheckboxGroup>\n </>\n)"
2048
2203
  },
2049
2204
  {
2050
- "id": "components-checkboxgroup-features--error"
2205
+ "id": "components-checkboxgroup-features--error",
2206
+ "code": "() => (\n <CheckboxGroup>\n <CheckboxGroup.Label>Choices</CheckboxGroup.Label>\n <FormControl>\n <Checkbox value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n <CheckboxGroup.Validation variant=\"error\">\n Something went wrong\n </CheckboxGroup.Validation>\n </CheckboxGroup>\n)"
2051
2207
  },
2052
2208
  {
2053
- "id": "components-checkboxgroup-features--success"
2209
+ "id": "components-checkboxgroup-features--success",
2210
+ "code": "() => (\n <CheckboxGroup>\n <CheckboxGroup.Label>Choices</CheckboxGroup.Label>\n <FormControl>\n <Checkbox value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n <CheckboxGroup.Validation variant=\"success\">\n Great job!\n </CheckboxGroup.Validation>\n </CheckboxGroup>\n)"
2054
2211
  },
2055
2212
  {
2056
- "id": "components-checkboxgroup-features--caption"
2213
+ "id": "components-checkboxgroup-features--caption",
2214
+ "code": "() => (\n <CheckboxGroup>\n <CheckboxGroup.Label>Choices</CheckboxGroup.Label>\n <CheckboxGroup.Caption>Caption</CheckboxGroup.Caption>\n <FormControl>\n <Checkbox value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </CheckboxGroup>\n)"
2057
2215
  }
2058
2216
  ],
2059
2217
  "importPath": "@primer/react",
@@ -2147,7 +2305,8 @@
2147
2305
  "a11yReviewed": "2025-01-08",
2148
2306
  "stories": [
2149
2307
  {
2150
- "id": "deprecated-components-circlebadge--default"
2308
+ "id": "deprecated-components-circlebadge--default",
2309
+ "code": "() => (\n <CircleBadge>\n <CircleBadge.Icon icon={ZapIcon} aria-label=\"User badge\" />\n </CircleBadge>\n)"
2151
2310
  }
2152
2311
  ],
2153
2312
  "importPath": "@primer/react",
@@ -2207,16 +2366,20 @@
2207
2366
  "importPath": "@primer/react",
2208
2367
  "stories": [
2209
2368
  {
2210
- "id": "components-confirmationdialog--default"
2369
+ "id": "components-confirmationdialog--default",
2370
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(!isOpen)}>\n Show dialog\n </Button>\n {isOpen && (\n <ConfirmationDialog\n title=\"Delete universe?\"\n onClose={onDialogClose}\n confirmButtonContent=\"Delete it!\"\n confirmButtonType=\"danger\"\n >\n Deleting the universe could have disastrous effects, including but not\n limited to destroying all life on Earth.\n </ConfirmationDialog>\n )}\n </>\n )\n}"
2211
2371
  },
2212
2372
  {
2213
- "id": "components-confirmationdialog-features--shorthand-hook"
2373
+ "id": "components-confirmationdialog-features--shorthand-hook",
2374
+ "code": "() => {\n const confirm = useConfirm()\n const onButtonClick = useCallback(\n async (event: React.MouseEvent) => {\n if (\n (await confirm({\n title: 'Are you sure?',\n content: 'Do you really want to turn this button green?',\n })) &&\n event.target instanceof HTMLElement\n ) {\n event.target.style.color = 'var(--fgColor-success)'\n event.target.textContent = \"I'm green!\"\n }\n },\n [confirm],\n )\n return (\n <div className={classes.ButtonContainer}>\n <Button onClick={onButtonClick} className={classes.TurnGreenButton}>\n Turn me green!\n </Button>\n <Button onClick={onButtonClick} className={classes.TurnGreenButton}>\n Turn me green!\n </Button>\n <Button onClick={onButtonClick} className={classes.TurnGreenButton}>\n Turn me green!\n </Button>\n <Button onClick={onButtonClick} className={classes.TurnGreenButton}>\n Turn me green!\n </Button>\n </div>\n )\n}"
2214
2375
  },
2215
2376
  {
2216
- "id": "components-confirmationdialog-features--shorthand-hook-from-action-menu"
2377
+ "id": "components-confirmationdialog-features--shorthand-hook-from-action-menu",
2378
+ "code": "() => {\n const confirm = useConfirm()\n const [text, setText] = useState('open me')\n const onButtonClick = useCallback(async () => {\n if (\n await confirm({\n title: 'Are you sure?',\n content: 'Do you really want to do a trick?',\n })\n ) {\n setText('tada!')\n }\n }, [confirm])\n return (\n <div className={classes.ButtonContainer}>\n <ActionMenu>\n <ActionMenu.Button>{text}</ActionMenu.Button>\n <ActionMenu.Overlay>\n <ActionList>\n <ActionList.Item onSelect={onButtonClick}>\n Do a trick!\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n </div>\n )\n}"
2217
2379
  },
2218
2380
  {
2219
- "id": "components-confirmationdialog-features--loading-states"
2381
+ "id": "components-confirmationdialog-features--loading-states",
2382
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const [isConfirmLoading, setIsConfirmLoading] = useState(false)\n const [isCancelLoading, setIsCancelLoading] = useState(false)\n const handleConfirm = useCallback(() => {\n setIsConfirmLoading(true)\n // Simulate async operation\n setTimeout(() => {\n setIsConfirmLoading(false)\n setIsOpen(false)\n }, 2000)\n }, [])\n const handleCancel = useCallback(() => {\n setIsCancelLoading(true)\n // Simulate async operation\n setTimeout(() => {\n setIsCancelLoading(false)\n setIsOpen(false)\n }, 1500)\n }, [])\n const handleClose = useCallback(\n (gesture: 'confirm' | 'close-button' | 'cancel' | 'escape') => {\n if (gesture === 'confirm') {\n handleConfirm()\n } else if (gesture === 'cancel') {\n handleCancel()\n } else {\n setIsOpen(false)\n }\n },\n [handleConfirm, handleCancel],\n )\n return (\n <div className={classes.ButtonContainer}>\n <Button onClick={() => setIsOpen(true)}>Show Loading Dialog</Button>\n {isOpen && (\n <ConfirmationDialog\n title=\"Delete this file?\"\n confirmButtonType=\"danger\"\n confirmButtonContent=\"Delete\"\n confirmButtonLoading={isConfirmLoading}\n cancelButtonLoading={isCancelLoading}\n onClose={handleClose}\n >\n This action cannot be undone. The file will be permanently deleted\n from your repository.\n </ConfirmationDialog>\n )}\n </div>\n )\n}"
2220
2383
  }
2221
2384
  ],
2222
2385
  "props": [
@@ -2281,13 +2444,16 @@
2281
2444
  "a11yReviewed": "2025-01-08",
2282
2445
  "stories": [
2283
2446
  {
2284
- "id": "components-counterlabel--default"
2447
+ "id": "components-counterlabel--default",
2448
+ "code": "() => <CounterLabel>12</CounterLabel>"
2285
2449
  },
2286
2450
  {
2287
- "id": "components-counterlabel-features--primary-theme"
2451
+ "id": "components-counterlabel-features--primary-theme",
2452
+ "code": "() => <CounterLabel variant=\"primary\">12</CounterLabel>"
2288
2453
  },
2289
2454
  {
2290
- "id": "components-counterlabel-features--secondary-theme"
2455
+ "id": "components-counterlabel-features--secondary-theme",
2456
+ "code": "() => <CounterLabel variant=\"secondary\">12</CounterLabel>"
2291
2457
  }
2292
2458
  ],
2293
2459
  "importPath": "@primer/react",
@@ -2315,46 +2481,56 @@
2315
2481
  "a11yReviewed": "2025-01-08",
2316
2482
  "stories": [
2317
2483
  {
2318
- "id": "components-datatable--default"
2484
+ "id": "experimental-components-datatable--default",
2485
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n)"
2319
2486
  },
2320
2487
  {
2321
- "id": "experimental-components-datatable--default"
2488
+ "id": "experimental-components-datatable-features--with-title",
2489
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n)"
2322
2490
  },
2323
2491
  {
2324
- "id": "experimental-components-datatable-features--with-title"
2492
+ "id": "experimental-components-datatable-features--with-title-and-subtitle",
2493
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n)"
2325
2494
  },
2326
2495
  {
2327
- "id": "experimental-components-datatable-features--with-title-and-subtitle"
2496
+ "id": "experimental-components-datatable-features--with-sorting",
2497
+ "code": "() => {\n const rows = Array.from(data).sort((a, b) => {\n return b.updatedAt - a.updatedAt\n })\n return (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={rows}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n sortBy: 'alphanumeric',\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n sortBy: 'datetime',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n initialSortColumn=\"updatedAt\"\n initialSortDirection=\"DESC\"\n />\n </Table.Container>\n )\n}"
2328
2498
  },
2329
2499
  {
2330
- "id": "experimental-components-datatable-features--with-sorting"
2500
+ "id": "experimental-components-datatable-features--with-actions",
2501
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Actions>\n <IconButton\n aria-label=\"Download\"\n icon={DownloadIcon}\n variant=\"invisible\"\n />\n <IconButton aria-label=\"Add row\" icon={PlusIcon} variant=\"invisible\" />\n </Table.Actions>\n <Table.Divider />\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n)"
2331
2502
  },
2332
2503
  {
2333
- "id": "experimental-components-datatable-features--with-actions"
2504
+ "id": "experimental-components-datatable-features--with-action",
2505
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Actions>\n <Button>Action</Button>\n </Table.Actions>\n <Table.Divider />\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n)"
2334
2506
  },
2335
2507
  {
2336
- "id": "experimental-components-datatable-features--with-action"
2508
+ "id": "experimental-components-datatable-features--with-row-action",
2509
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n id: 'actions',\n header: () => <VisuallyHidden>Actions</VisuallyHidden>,\n renderCell: (row) => {\n return (\n <IconButton\n aria-label={`Download: ${row.name}`}\n title={`Download: ${row.name}`}\n icon={DownloadIcon}\n variant=\"invisible\"\n onClick={() => {\n action('Download')(row)\n }}\n />\n )\n },\n },\n ]}\n />\n </Table.Container>\n)"
2337
2510
  },
2338
2511
  {
2339
- "id": "experimental-components-datatable-features--with-row-action"
2512
+ "id": "experimental-components-datatable-features--with-row-actions",
2513
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n id: 'actions',\n header: () => <VisuallyHidden>Actions</VisuallyHidden>,\n renderCell: (row) => {\n return (\n <>\n <IconButton\n aria-label={`Edit: ${row.name}`}\n title={`Edit: ${row.name}`}\n icon={PencilIcon}\n variant=\"invisible\"\n onClick={() => {\n action('Edit')(row)\n }}\n />\n <IconButton\n aria-label={`Delete: ${row.name}`}\n title={`Delete: ${row.name}`}\n icon={TrashIcon}\n variant=\"invisible\"\n onClick={() => {\n action('Delete')(row)\n }}\n />\n </>\n )\n },\n },\n ]}\n />\n </Table.Container>\n)"
2340
2514
  },
2341
2515
  {
2342
- "id": "experimental-components-datatable-features--with-row-actions"
2516
+ "id": "experimental-components-datatable-features--with-row-action-menu",
2517
+ "code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n id: 'actions',\n header: () => <VisuallyHidden>Actions</VisuallyHidden>,\n renderCell: (row) => {\n return (\n <ActionMenu>\n <ActionMenu.Anchor>\n <IconButton\n aria-label={`Actions: ${row.name}`}\n title={`Actions: ${row.name}`}\n icon={KebabHorizontalIcon}\n variant=\"invisible\"\n />\n </ActionMenu.Anchor>\n <ActionMenu.Overlay>\n <ActionList>\n <ActionList.Item\n onSelect={() => {\n action('Copy')(row)\n }}\n >\n Copy row\n </ActionList.Item>\n <ActionList.Item>Edit row</ActionList.Item>\n <ActionList.Item>Export row as CSV</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">\n Delete row\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n )\n },\n },\n ]}\n />\n </Table.Container>\n)"
2343
2518
  },
2344
2519
  {
2345
- "id": "experimental-components-datatable-features--with-row-action-menu"
2520
+ "id": "experimental-components-datatable-features--with-custom-heading",
2521
+ "code": "() => (\n <>\n <Heading as=\"h2\" id=\"repositories\">\n Security coverage\n </Heading>\n <p id=\"repositories-subtitle\">\n Organization members can only see data for the most recently-updated\n repositories. To see all repositories, talk to your organization\n administrator about becoming a security manager.\n </p>\n <Table.Container>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n </>\n)"
2346
2522
  },
2347
2523
  {
2348
- "id": "experimental-components-datatable-features--with-custom-heading"
2524
+ "id": "experimental-components-datatable-features--with-no-content",
2525
+ "code": "() => {\n const exampleEmptyData: Array<Repo> = []\n return exampleEmptyData.length === 0 ? (\n <Blankslate border>\n <Blankslate.Visual>\n <BookIcon size=\"medium\" />\n </Blankslate.Visual>\n <Blankslate.Heading>Blankslate heading</Blankslate.Heading>\n <Blankslate.Description>\n Use it to provide information when no dynamic content exists.\n </Blankslate.Description>\n <Blankslate.PrimaryAction href=\"#\">\n Primary action\n </Blankslate.PrimaryAction>\n <Blankslate.SecondaryAction href=\"#\">\n Secondary action link\n </Blankslate.SecondaryAction>\n </Blankslate>\n ) : (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={exampleEmptyData}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n )\n}"
2349
2526
  },
2350
2527
  {
2351
- "id": "experimental-components-datatable-features--with-no-content"
2528
+ "id": "experimental-components-datatable-features--with-loading",
2529
+ "code": "() => {\n const [loading] = React.useState(true)\n return (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n {loading ? (\n <Table.Skeleton\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n columns={columns}\n rows={10}\n />\n ) : (\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={columns}\n />\n )}\n </Table.Container>\n )\n}"
2352
2530
  },
2353
2531
  {
2354
- "id": "experimental-components-datatable-features--with-loading"
2355
- },
2356
- {
2357
- "id": "experimental-components-datatable-features--with-pagination"
2532
+ "id": "experimental-components-datatable-features--with-pagination",
2533
+ "code": "() => {\n const pageSize = 10\n const [pageIndex, setPageIndex] = React.useState(0)\n const start = pageIndex * pageSize\n const end = start + pageSize\n const rows = repos.slice(start, end)\n return (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={rows}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n <Table.Pagination\n aria-label=\"Pagination for Repositories\"\n pageSize={pageSize}\n totalCount={repos.length}\n onChange={({ pageIndex }) => {\n setPageIndex(pageIndex)\n }}\n />\n </Table.Container>\n )\n}"
2358
2534
  }
2359
2535
  ],
2360
2536
  "importPath": "@primer/react/experimental",
@@ -2746,7 +2922,8 @@
2746
2922
  "a11yReviewed": "2025-01-08",
2747
2923
  "stories": [
2748
2924
  {
2749
- "id": "components-details--default"
2925
+ "id": "components-details--default",
2926
+ "code": "() => {\n const { getDetailsProps } = useDetails({\n closeOnOutsideClick: true,\n })\n return (\n <Details {...getDetailsProps()}>\n <Details.Summary as={Button}>See Details</Details.Summary>\n This is some content\n </Details>\n )\n}"
2750
2927
  }
2751
2928
  ],
2752
2929
  "importPath": "@primer/react",
@@ -2779,34 +2956,44 @@
2779
2956
  "a11yReviewed": "2025-01-08",
2780
2957
  "stories": [
2781
2958
  {
2782
- "id": "components-dialog--default"
2959
+ "id": "components-dialog--default",
2960
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const [secondOpen, setSecondOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n const onSecondDialogClose = useCallback(() => setSecondOpen(false), [])\n const openSecondDialog = useCallback(() => setSecondOpen(true), [])\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(!isOpen)}>\n Show dialog\n </Button>\n {isOpen && (\n <Dialog\n title=\"My Dialog\"\n onClose={onDialogClose}\n footerButtons={[\n {\n buttonType: 'default',\n content: 'Open Second Dialog',\n onClick: openSecondDialog,\n },\n {\n buttonType: 'danger',\n content: 'Delete the universe',\n onClick: onDialogClose,\n },\n {\n buttonType: 'primary',\n content: 'Proceed',\n onClick: openSecondDialog,\n },\n ]}\n >\n {lipsum}\n {secondOpen && (\n <Dialog\n title=\"Inner dialog!\"\n onClose={onSecondDialogClose}\n width=\"small\"\n >\n Hello world\n </Dialog>\n )}\n </Dialog>\n )}\n </>\n )\n}"
2783
2961
  },
2784
2962
  {
2785
- "id": "components-dialog-features--with-custom-renderers"
2963
+ "id": "components-dialog-features--with-custom-renderers",
2964
+ "code": "({ width, height, subtitle }: DialogStoryProps) => {\n const [isOpen, setIsOpen] = useState(false)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n return (\n <>\n <Button onClick={() => setIsOpen(!isOpen)}>Show dialog</Button>\n {isOpen && (\n <Dialog\n title=\"My Dialog\"\n subtitle={subtitle ? 'This is a subtitle!' : undefined}\n width={width}\n height={height}\n renderHeader={CustomHeader}\n renderBody={CustomBody}\n renderFooter={CustomFooter}\n onClose={onDialogClose}\n footerButtons={[\n {\n buttonType: 'danger',\n content: 'Delete the universe',\n onClick: onDialogClose,\n },\n {\n buttonType: 'primary',\n content: 'Proceed',\n },\n ]}\n >\n {lipsum}\n </Dialog>\n )}\n </>\n )\n}"
2786
2965
  },
2787
2966
  {
2788
- "id": "components-dialog-features--stress-test"
2967
+ "id": "components-dialog-features--stress-test",
2968
+ "code": "({ width, height, subtitle }: DialogStoryProps) => {\n const [isOpen, setIsOpen] = useState(false)\n const [secondOpen, setSecondOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n const onSecondDialogClose = useCallback(() => setSecondOpen(false), [])\n const openSecondDialog = useCallback(() => setSecondOpen(true), [])\n const manyButtons = new Array(7).fill(undefined).map((_, i) => ({\n content: `Button ${i}`,\n }))\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(!isOpen)}>\n Show dialog\n </Button>\n {isOpen && (\n <Dialog\n title=\"This dialog has a really long title. So long, in fact, that it should cause wrapping, going to multiple lines!.\"\n subtitle={\n subtitle\n ? \"It's not a common scenario, sure, but what if the subtitle is generated from a really long value? Do we just break the dialog? Or do we handle it because we are pros?\"\n : undefined\n }\n onClose={onDialogClose}\n width={width}\n height={height}\n footerButtons={[\n ...manyButtons,\n {\n buttonType: 'danger',\n content: 'Delete the universe',\n onClick: onDialogClose,\n },\n {\n buttonType: 'primary',\n content: 'Proceed',\n onClick: openSecondDialog,\n },\n ]}\n position={{\n narrow: 'fullscreen',\n regular: 'center',\n }}\n >\n {lipsum}\n {secondOpen && (\n <Dialog\n title=\"Inner dialog!\"\n onClose={onSecondDialogClose}\n width=\"small\"\n >\n Hello world\n </Dialog>\n )}\n </Dialog>\n )}\n </>\n )\n}"
2789
2969
  },
2790
2970
  {
2791
- "id": "components-dialog-features--repro-multistep-dialog-with-conditional-footer"
2971
+ "id": "components-dialog-features--repro-multistep-dialog-with-conditional-footer",
2972
+ "code": "({ width, height }: DialogStoryProps) => {\n const [isOpen, setIsOpen] = useState(false)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n const [step, setStep] = React.useState(1)\n const [inputText, setInputText] = React.useState('')\n const dialogRef = useRef<HTMLDivElement>(null)\n const renderFooterConditionally = () => {\n if (step === 1) return null\n return (\n <Dialog.Footer>\n <Button variant=\"primary\">Submit</Button>\n </Dialog.Footer>\n )\n }\n React.useEffect(() => {\n // focus the close button when the step changes\n const focusTarget = dialogRef.current?.querySelector(\n 'button[aria-label=\"Close\"]',\n ) as HTMLButtonElement\n if (step === 2) {\n focusTarget.focus()\n }\n }, [step])\n return (\n <>\n <Button onClick={() => setIsOpen(!isOpen)}>Show dialog</Button>\n {isOpen && (\n <Dialog\n title={`Step ${step}`}\n width={width}\n height={height}\n renderFooter={renderFooterConditionally}\n onClose={onDialogClose}\n footerButtons={[\n {\n buttonType: 'primary',\n content: 'Proceed',\n },\n ]}\n ref={dialogRef}\n >\n {step === 1 ? (\n <Stack gap=\"spacious\" direction=\"vertical\">\n <Stack direction=\"horizontal\" justify=\"space-between\">\n Bug Report <Button onClick={() => setStep(2)}>Choose</Button>\n </Stack>\n <Stack direction=\"horizontal\" justify=\"space-between\">\n Feature request{' '}\n <Button onClick={() => setStep(2)}>Choose</Button>\n </Stack>\n </Stack>\n ) : (\n <div>\n <Stack gap=\"condensed\" direction=\"vertical\">\n <label htmlFor=\"description\">Description</label>\n <TextInput\n id=\"description\"\n placeholder=\"Write the description here\"\n value={inputText}\n onChange={(event) => setInputText(event.target.value)}\n />\n </Stack>\n </div>\n )}\n </Dialog>\n )}\n </>\n )\n}"
2792
2973
  },
2793
2974
  {
2794
- "id": "components-dialog-features--bottom-sheet-narrow"
2975
+ "id": "components-dialog-features--bottom-sheet-narrow",
2976
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(true)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(true)}>\n Show dialog\n </Button>\n {isOpen && (\n <Dialog\n title=\"My Dialog\"\n onClose={onDialogClose}\n position={{\n narrow: 'bottom',\n regular: 'center',\n }}\n >\n {bodyContent}\n </Dialog>\n )}\n </>\n )\n}"
2795
2977
  },
2796
2978
  {
2797
- "id": "components-dialog-features--full-screen-narrow"
2979
+ "id": "components-dialog-features--full-screen-narrow",
2980
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(true)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(true)}>\n Show dialog\n </Button>\n {isOpen && (\n <Dialog\n title=\"My Dialog\"\n onClose={onDialogClose}\n position={{\n narrow: 'fullscreen',\n regular: 'center',\n }}\n >\n {bodyContent}\n </Dialog>\n )}\n </>\n )\n}"
2798
2981
  },
2799
2982
  {
2800
- "id": "components-dialog-features--side-sheet"
2983
+ "id": "components-dialog-features--side-sheet",
2984
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(true)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(true)}>\n Show dialog\n </Button>\n {isOpen && (\n <Dialog title=\"My Dialog\" onClose={onDialogClose} position=\"right\">\n {bodyContent}\n </Dialog>\n )}\n </>\n )\n}"
2801
2985
  },
2802
2986
  {
2803
- "id": "components-dialog-features--return-focus-ref"
2987
+ "id": "components-dialog-features--return-focus-ref",
2988
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n const triggerRef = React.useRef<HTMLButtonElement>(null)\n const triggerButton = (\n <Button ref={triggerRef} variant=\"primary\" onClick={() => setIsOpen(true)}>\n Show dialog\n </Button>\n )\n if (!isOpen) return triggerButton\n return (\n <React.Suspense fallback={<Button>Show Dialog</Button>}>\n {triggerButton}\n <Dialog title=\"title\" onClose={onDialogClose} returnFocusRef={triggerRef}>\n body\n </Dialog>\n </React.Suspense>\n )\n}"
2804
2989
  },
2805
2990
  {
2806
- "id": "components-dialog-features--new-issues"
2991
+ "id": "components-dialog-features--new-issues",
2992
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n const initialFocusRef = useRef(null)\n return (\n <>\n <Button onClick={() => setIsOpen(true)}>Show dialog</Button>\n {isOpen ? (\n <Dialog\n initialFocusRef={initialFocusRef}\n onClose={onDialogClose}\n title=\"New issue\"\n renderBody={() => (\n <ActionList>\n <ActionList.LinkItem\n ref={initialFocusRef}\n href=\"https://github.com\"\n >\n Item 1\n </ActionList.LinkItem>\n <ActionList.LinkItem href=\"https://github.com\">\n Link\n </ActionList.LinkItem>\n </ActionList>\n )}\n ></Dialog>\n ) : null}\n </>\n )\n}"
2807
2993
  },
2808
2994
  {
2809
- "id": "components-dialog-features--retains-focus-trap-with-dynamic-content"
2995
+ "id": "components-dialog-features--retains-focus-trap-with-dynamic-content",
2996
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const [secondOpen, setSecondOpen] = useState(false)\n const [expandContent, setExpandContent] = useState(false)\n const [changeBodyContent, setChangeBodyContent] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const onDialogClose = useCallback(() => setIsOpen(false), [])\n const onSecondDialogClose = useCallback(() => setSecondOpen(false), [])\n const openSecondDialog = useCallback(() => setSecondOpen(true), [])\n const renderFooterConditionally = () => {\n if (!changeBodyContent) return null\n return (\n <Dialog.Footer>\n <Button variant=\"primary\">Submit</Button>\n </Dialog.Footer>\n )\n }\n return (\n <>\n <Button ref={buttonRef} onClick={() => setIsOpen(!isOpen)}>\n Show dialog\n </Button>\n {isOpen && (\n <Dialog\n title=\"My Dialog\"\n onClose={onDialogClose}\n renderFooter={renderFooterConditionally}\n >\n <Button onClick={() => setExpandContent(!expandContent)}>\n Click me to dynamically {expandContent ? 'remove' : 'render'}{' '}\n content\n </Button>\n <Button onClick={() => setChangeBodyContent(!changeBodyContent)}>\n Click me to {changeBodyContent ? 'remove' : 'add'} a footer\n </Button>\n <Button onClick={openSecondDialog}>\n Click me to open a new dialog\n </Button>\n {expandContent && (\n <Stack gap=\"normal\" direction=\"vertical\">\n {lipsum}\n <Button>Dialog Button Example 1</Button>\n <Button>Dialog Button Example 2</Button>\n </Stack>\n )}\n {secondOpen && (\n <Dialog\n title=\"Inner dialog!\"\n onClose={onSecondDialogClose}\n width=\"small\"\n >\n Hello world\n </Dialog>\n )}\n </Dialog>\n )}\n </>\n )\n}"
2810
2997
  }
2811
2998
  ],
2812
2999
  "importPath": "@primer/react",
@@ -2978,25 +3165,32 @@
2978
3165
  "a11yReviewed": "2025-01-08",
2979
3166
  "stories": [
2980
3167
  {
2981
- "id": "components-flash--default"
3168
+ "id": "components-flash--default",
3169
+ "code": "() => <Flash>Default</Flash>"
2982
3170
  },
2983
3171
  {
2984
- "id": "components-flash-features--success"
3172
+ "id": "components-flash-features--success",
3173
+ "code": "() => (\n <Flash\n variant=\"success\"\n style={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <CheckCircleIcon aria-label=\"Success\" />\n </div>\n <div className={classes.Message}>Success</div>\n </Flash>\n)"
2985
3174
  },
2986
3175
  {
2987
- "id": "components-flash-features--danger"
3176
+ "id": "components-flash-features--danger",
3177
+ "code": "() => (\n <Flash\n variant=\"danger\"\n style={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <InfoIcon aria-label=\"Danger\" />\n </div>\n <div className={classes.Message}>Danger</div>\n </Flash>\n)"
2988
3178
  },
2989
3179
  {
2990
- "id": "components-flash-features--warning"
3180
+ "id": "components-flash-features--warning",
3181
+ "code": "() => (\n <Flash\n variant=\"warning\"\n style={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <AlertIcon aria-label=\"Warning\" />\n </div>\n <div className={classes.Message}>Warning</div>\n </Flash>\n)"
2991
3182
  },
2992
3183
  {
2993
- "id": "components-flash-features--full"
3184
+ "id": "components-flash-features--full",
3185
+ "code": "() => (\n <Flash\n full\n style={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <InfoIcon aria-label=\"Info\" />\n </div>\n <div className={classes.Message}>Full</div>\n </Flash>\n)"
2994
3186
  },
2995
3187
  {
2996
- "id": "components-flash-features--with-icon-and-action"
3188
+ "id": "components-flash-features--with-icon-and-action",
3189
+ "code": "() => (\n <Flash className={classes.WithIconAndAction}>\n <div className={classes.Visual}>\n <InfoIcon aria-label=\"Info\" />\n </div>\n <div className={classes.Message}>\n This is a flash message with an icon and an action.\n <Link href=\"/\"> Learn more.</Link>\n </div>\n <div className={classes.ActionsResponsive}>\n <Button>Join waitlist</Button>\n </div>\n </Flash>\n)"
2997
3190
  },
2998
3191
  {
2999
- "id": "components-flash-features--with-icon-action-dismiss"
3192
+ "id": "components-flash-features--with-icon-action-dismiss",
3193
+ "code": "() => (\n <Flash className={classes.WithIconActionDismiss}>\n <div className={classes.Visual}>\n <InfoIcon aria-label=\"Info\" />\n </div>\n <div className={classes.Message}>\n This is a flash message with an icon and an action.\n <Link href=\"/\"> Learn more.</Link>\n </div>\n <div className={classes.ActionsResponsive}>\n <Button>Join waitlist</Button>\n </div>\n <div className={classes.Close}>\n <IconButton variant=\"invisible\" icon={XIcon} aria-label=\"Dismiss\" />\n </div>\n </Flash>\n)"
3000
3194
  }
3001
3195
  ],
3002
3196
  "importPath": "@primer/react",
@@ -3033,52 +3227,68 @@
3033
3227
  "a11yReviewed": "2025-01-08",
3034
3228
  "stories": [
3035
3229
  {
3036
- "id": "components-formcontrol--default"
3230
+ "id": "components-formcontrol--default",
3231
+ "code": "() => (\n <FormControl required={true}>\n <FormControl.Label>Form Input Label</FormControl.Label>\n <FormControl.Caption>This is a caption</FormControl.Caption>\n <Checkbox />\n </FormControl>\n)"
3037
3232
  },
3038
3233
  {
3039
- "id": "components-formcontrol-features--with-complex-inputs"
3234
+ "id": "components-formcontrol-features--with-complex-inputs",
3235
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens])\n const onTokenRemove = (tokenId: string | number) => {\n setTokens(\n tokens.filter((token: { id: string | number }) => token.id !== tokenId),\n )\n }\n return (\n <div className={classes.GridContainer}>\n <FormControl>\n <FormControl.Label id=\"form-label\">\n TextInputWithTokens\n </FormControl.Label>\n <TextInputWithTokens onTokenRemove={onTokenRemove} tokens={tokens} />\n </FormControl>\n <FormControl>\n <FormControl.Label id=\"autocomplete-label\">\n Autocomplete\n </FormControl.Label>\n <Autocomplete>\n <Autocomplete.Input block />\n <Autocomplete.Overlay>\n <Autocomplete.Menu\n aria-labelledby=\"autocomplete-label\"\n items={[\n {\n text: 'css',\n id: '0',\n },\n {\n text: 'css-in-js',\n id: '1',\n },\n {\n text: 'styled-system',\n id: '2',\n },\n {\n text: 'javascript',\n id: '3',\n },\n {\n text: 'typescript',\n id: '4',\n },\n {\n text: 'react',\n id: '5',\n },\n {\n text: 'design-systems',\n id: '6',\n },\n ]}\n selectedItemIds={[]}\n />\n </Autocomplete.Overlay>\n </Autocomplete>\n </FormControl>\n <FormControl>\n <FormControl.Label>Select</FormControl.Label>\n <Select>\n <Select.Option value=\"figma\">Figma</Select.Option>\n <Select.Option value=\"css\">Primer CSS</Select.Option>\n <Select.Option value=\"prc\">Primer React components</Select.Option>\n <Select.Option value=\"pvc\">Primer ViewComponents</Select.Option>\n </Select>\n </FormControl>\n <FormControl>\n <FormControl.Label>Textarea</FormControl.Label>\n <Textarea />\n </FormControl>\n </div>\n )\n}"
3040
3236
  },
3041
3237
  {
3042
- "id": "components-formcontrol-features--form-control-with-custom-input"
3238
+ "id": "components-formcontrol-features--form-control-with-custom-input",
3239
+ "code": "() => {\n const [value, setValue] = React.useState('mona lisa')\n const [validationResult, setValidationResult] = React.useState('')\n const doesValueContainSpaces = (inputValue: string) => /\\s/g.test(inputValue)\n const handleInputChange = (e: {\n currentTarget: {\n value: React.SetStateAction<string>\n }\n }) => {\n setValue(e.currentTarget.value)\n }\n React.useEffect(() => {\n if (doesValueContainSpaces(value)) {\n setValidationResult('noSpaces')\n } else if (value) {\n setValidationResult('validName')\n }\n }, [value])\n return (\n <div className={classes.GridContainer}>\n <FormControl>\n <FormControl.Label htmlFor=\"custom-input\">\n GitHub handle\n </FormControl.Label>\n <CustomTextInput\n id=\"custom-input\"\n aria-describedby=\"custom-input-caption custom-input-validation\"\n aria-invalid={validationResult === 'noSpaces'}\n onChange={handleInputChange}\n />\n {validationResult === 'noSpaces' && (\n <FormControl.Validation id=\"custom-input-validation\" variant=\"error\">\n GitHub handles cannot contain spaces\n </FormControl.Validation>\n )}\n {validationResult === 'validName' && (\n <FormControl.Validation\n id=\"custom-input-validation\"\n variant=\"success\"\n >\n Valid name\n </FormControl.Validation>\n )}\n <FormControl.Caption id=\"custom-input-caption\">\n With or without &quot;@&quot;. For example &quot;monalisa&quot; or\n &quot;@monalisa&quot;\n </FormControl.Caption>\n </FormControl>\n\n <CheckboxGroup>\n <CheckboxGroup.Label>Checkboxes</CheckboxGroup.Label>\n <FormControl layout=\"horizontal\">\n <CustomCheckboxInput\n id=\"custom-checkbox-one\"\n aria-describedby=\"custom-checkbox-one-caption\"\n value=\"checkOne\"\n />\n <FormControl.Label htmlFor=\"custom-checkbox-one\">\n Checkbox one\n </FormControl.Label>\n <FormControl.Caption id=\"custom-checkbox-one-caption\">\n Hint text for checkbox one\n </FormControl.Caption>\n </FormControl>\n <FormControl layout=\"horizontal\">\n <CustomCheckboxInput\n id=\"custom-checkbox-two\"\n aria-describedby=\"custom-checkbox-two-caption\"\n value=\"checkTwo\"\n />\n <FormControl.Label htmlFor=\"custom-checkbox-two\">\n Checkbox two\n </FormControl.Label>\n <FormControl.Caption id=\"custom-checkbox-two-caption\">\n Hint text for checkbox two\n </FormControl.Caption>\n </FormControl>\n </CheckboxGroup>\n </div>\n )\n}"
3043
3240
  },
3044
3241
  {
3045
- "id": "components-formcontrol-features--with-checkbox-and-radio-inputs"
3242
+ "id": "components-formcontrol-features--with-checkbox-and-radio-inputs",
3243
+ "code": "() => {\n return (\n <div className={classes.GapContainer}>\n <CheckboxGroup>\n <CheckboxGroup.Label>Checkboxes</CheckboxGroup.Label>\n <FormControl>\n <Checkbox value=\"checkOne\" />\n <FormControl.Label>Checkbox one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"checkTwo\" />\n <FormControl.Label>Checkbox two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Checkbox value=\"checkThree\" />\n <FormControl.Label>Checkbox three</FormControl.Label>\n </FormControl>\n </CheckboxGroup>\n\n <RadioGroup name={''}>\n <RadioGroup.Label>Radios</RadioGroup.Label>\n <FormControl>\n <Radio name=\"radioChoices\" value=\"radioOne\" />\n <FormControl.Label>Radio one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio name=\"radioChoices\" value=\"radioTwo\" />\n <FormControl.Label>Radio two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio name=\"radioChoices\" value=\"radioThree\" />\n <FormControl.Label>Radio three</FormControl.Label>\n </FormControl>\n </RadioGroup>\n </div>\n )\n}"
3046
3244
  },
3047
3245
  {
3048
- "id": "components-formcontrol-features--single-input"
3246
+ "id": "components-formcontrol-features--single-input",
3247
+ "code": "({\n label = 'Input',\n caption = '',\n required = false,\n disabled = false,\n}: ArgTypes) => (\n <FormControl required={required} disabled={disabled}>\n <FormControl.Label>{label}</FormControl.Label>\n <TextInput />\n {caption && <FormControl.Caption>{caption}</FormControl.Caption>}\n </FormControl>\n)"
3049
3248
  },
3050
3249
  {
3051
- "id": "components-formcontrol-features--validation-example"
3250
+ "id": "components-formcontrol-features--validation-example",
3251
+ "code": "() => {\n const [value, setValue] = React.useState('mona lisa')\n const [validationResult, setValidationResult] = React.useState('')\n const doesValueContainSpaces = (inputValue: string) => /\\s/g.test(inputValue)\n const handleInputChange = (e: {\n currentTarget: {\n value: React.SetStateAction<string>\n }\n }) => {\n setValue(e.currentTarget.value)\n }\n React.useEffect(() => {\n if (doesValueContainSpaces(value)) {\n setValidationResult('noSpaces')\n } else if (value) {\n setValidationResult('validName')\n }\n }, [value])\n return (\n <FormControl>\n <FormControl.Label>GitHub handle</FormControl.Label>\n <TextInput block value={value} onChange={handleInputChange} />\n {validationResult === 'noSpaces' && (\n <FormControl.Validation variant=\"error\">\n GitHub handles cannot contain spaces\n </FormControl.Validation>\n )}\n {validationResult === 'validName' && (\n <FormControl.Validation variant=\"success\">\n Valid name\n </FormControl.Validation>\n )}\n <FormControl.Caption>\n With or without &quot;@&quot;. For example &quot;monalisa&quot; or\n &quot;@monalisa&quot;\n </FormControl.Caption>\n </FormControl>\n )\n}"
3052
3252
  },
3053
3253
  {
3054
- "id": "components-formcontrol-features--with-select-panel"
3254
+ "id": "components-formcontrol-features--with-select-panel",
3255
+ "code": "() => {\n const [selected, setSelected] = React.useState<ItemInput[]>([\n items[0],\n items[1],\n ])\n const [filter, setFilter] = React.useState('')\n const filteredItems = items.filter((item) =>\n item.text?.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl required>\n <FormControl.Label id=\"select_panel_label\">\n Select Labels\n </FormControl.Label>\n <SelectPanel\n title=\"Select labels\"\n subtitle=\"Use labels to organize issues and pull requests\"\n renderAnchor={({ children, id, ...anchorProps }) => (\n <Button\n trailingAction={TriangleDownIcon}\n aria-labelledby={`select_panel_label selectpanel_wrapper`}\n id={id}\n {...anchorProps}\n aria-haspopup=\"dialog\"\n >\n <span id=\"selectpanel_wrapper\">{children ?? 'Select Labels'}</span>\n </Button>\n )}\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n />\n </FormControl>\n )\n}"
3055
3256
  },
3056
3257
  {
3057
- "id": "components-formcontrol-features--with-leading-visual"
3258
+ "id": "components-formcontrol-features--with-leading-visual",
3259
+ "code": "() => (\n <Stack gap=\"none\">\n <FormControl>\n <FormControl.Label>Option one</FormControl.Label>\n <FormControl.LeadingVisual>\n <MarkGithubIcon />\n </FormControl.LeadingVisual>\n <Checkbox />\n </FormControl>\n\n <FormControl>\n <FormControl.Label>Option two</FormControl.Label>\n <FormControl.LeadingVisual>\n <MarkGithubIcon />\n </FormControl.LeadingVisual>\n <Checkbox />\n <FormControl.Caption>This one has a caption</FormControl.Caption>\n </FormControl>\n\n <FormControl disabled>\n <FormControl.Label>Option three</FormControl.Label>\n <FormControl.LeadingVisual>\n <MarkGithubIcon />\n </FormControl.LeadingVisual>\n <Checkbox />\n </FormControl>\n\n <FormControl disabled>\n <FormControl.Label>Option four</FormControl.Label>\n <FormControl.LeadingVisual>\n <MarkGithubIcon />\n </FormControl.LeadingVisual>\n <Checkbox />\n <FormControl.Caption>This one has a caption</FormControl.Caption>\n </FormControl>\n </Stack>\n)"
3058
3260
  },
3059
3261
  {
3060
- "id": "components-formcontrol-features--disabled-inputs"
3262
+ "id": "components-formcontrol-features--disabled-inputs",
3263
+ "code": "() => (\n <div className={classes.FlexColumnGapContainer}>\n <FormControl disabled>\n <FormControl.Label>Disabled checkbox</FormControl.Label>\n <Checkbox />\n </FormControl>\n <FormControl disabled>\n <FormControl.Label>Disabled input</FormControl.Label>\n <TextInput />\n </FormControl>\n <FormControl disabled>\n <FormControl.Label>Disabled select</FormControl.Label>\n <Select>\n <Select.Option value=\"figma\">Figma</Select.Option>\n <Select.Option value=\"css\">Primer CSS</Select.Option>\n <Select.Option value=\"prc\">Primer React components</Select.Option>\n <Select.Option value=\"pvc\">Primer ViewComponents</Select.Option>\n </Select>\n </FormControl>\n </div>\n)"
3061
3264
  },
3062
3265
  {
3063
- "id": "components-formcontrol-features--custom-required"
3266
+ "id": "components-formcontrol-features--custom-required",
3267
+ "code": "() => (\n <div className={classes.FlexColumnGapContainer}>\n <FormControl required={true}>\n <FormControl.Label requiredText=\"(required)\">\n Form Input Label\n </FormControl.Label>\n <FormControl.Caption>\n This is a form field with a custom required indicator\n </FormControl.Caption>\n <TextInput />\n </FormControl>\n\n <Text className={classes.RequiredFieldsNote}>\n Required fields are marked with an asterisk (*)\n </Text>\n <FormControl required={true}>\n <FormControl.Label requiredIndicator={false}>\n Form Input Label\n </FormControl.Label>\n <FormControl.Caption>\n This is a form field with a required indicator that is hidden in the\n accessibility tree\n </FormControl.Caption>\n <TextInput />\n </FormControl>\n\n <FormControl required={false}>\n <FormControl.Label requiredText=\"(optional)\" requiredIndicator={false}>\n Form Input Label\n </FormControl.Label>\n <FormControl.Caption>\n This is a form field that is marked as optional, it is not required\n </FormControl.Caption>\n <TextInput />\n </FormControl>\n </div>\n)"
3064
3268
  },
3065
3269
  {
3066
- "id": "components-formcontrol-features--with-caption"
3270
+ "id": "components-formcontrol-features--with-caption",
3271
+ "code": "() => (\n <FormControl>\n <FormControl.Label>Example label</FormControl.Label>\n <TextInput />\n <FormControl.Caption>Example caption</FormControl.Caption>\n </FormControl>\n)"
3067
3272
  },
3068
3273
  {
3069
- "id": "components-formcontrol-features--with-caption-and-disabled"
3274
+ "id": "components-formcontrol-features--with-caption-and-disabled",
3275
+ "code": "() => (\n <FormControl disabled>\n <FormControl.Label>Example label</FormControl.Label>\n <TextInput />\n <FormControl.Caption>Example caption</FormControl.Caption>\n </FormControl>\n)"
3070
3276
  },
3071
3277
  {
3072
- "id": "components-formcontrol-features--with-hidden-label"
3278
+ "id": "components-formcontrol-features--with-hidden-label",
3279
+ "code": "() => (\n <FormControl>\n <FormControl.Label visuallyHidden>Example label</FormControl.Label>\n <TextInput />\n </FormControl>\n)"
3073
3280
  },
3074
3281
  {
3075
- "id": "components-formcontrol-features--with-required-indicator"
3282
+ "id": "components-formcontrol-features--with-required-indicator",
3283
+ "code": "() => (\n <FormControl required>\n <FormControl.Label requiredIndicator>Example label</FormControl.Label>\n <TextInput />\n </FormControl>\n)"
3076
3284
  },
3077
3285
  {
3078
- "id": "components-formcontrol-features--with-success-validation"
3286
+ "id": "components-formcontrol-features--with-success-validation",
3287
+ "code": "() => (\n <FormControl required>\n <FormControl.Label requiredIndicator>Example label</FormControl.Label>\n <TextInput defaultValue=\"Input value\" />\n <FormControl.Validation variant=\"success\">\n Example success validation message\n </FormControl.Validation>\n </FormControl>\n)"
3079
3288
  },
3080
3289
  {
3081
- "id": "components-formcontrol-features--with-error-validation"
3290
+ "id": "components-formcontrol-features--with-error-validation",
3291
+ "code": "() => (\n <FormControl required>\n <FormControl.Label requiredIndicator>Example label</FormControl.Label>\n <TextInput defaultValue=\"Input value\" />\n <FormControl.Validation variant=\"error\">\n Example error validation message\n </FormControl.Validation>\n </FormControl>\n)"
3082
3292
  }
3083
3293
  ],
3084
3294
  "importPath": "@primer/react",
@@ -3240,16 +3450,20 @@
3240
3450
  "a11yReviewed": "2025-01-08",
3241
3451
  "stories": [
3242
3452
  {
3243
- "id": "components-header--default"
3453
+ "id": "components-header--default",
3454
+ "code": "() => (\n <Header>\n <Header.Item>\n <Header.Link href=\"#\" className={classes.HeaderLink}>\n <MarkGithubIcon className={classes.Icon} size={32} />\n <span>GitHub</span>\n </Header.Link>\n </Header.Item>\n <Header.Item full>Menu</Header.Item>\n <Header.Item className={classes.AvatarContainer}>\n <Avatar\n src=\"https://github.com/octocat.png\"\n size={20}\n square\n alt=\"@octocat\"\n />\n </Header.Item>\n </Header>\n)"
3244
3455
  },
3245
3456
  {
3246
- "id": "components-header-features--with-full-size-item"
3457
+ "id": "components-header-features--with-full-size-item",
3458
+ "code": "() => (\n <Header>\n <Header.Item>Item 1</Header.Item>\n <Header.Item full>Item 2</Header.Item>\n <Header.Item className={classes.LastItem}>Item 3</Header.Item>\n </Header>\n)"
3247
3459
  },
3248
3460
  {
3249
- "id": "components-header-features--with-links"
3461
+ "id": "components-header-features--with-links",
3462
+ "code": "() => (\n <Header>\n <Header.Item>\n <Header.Link href=\"#\">About</Header.Link>\n </Header.Item>\n <Header.Item>\n <Header.Link href=\"#\">Releases</Header.Link>\n </Header.Item>\n <Header.Item>\n <Header.Link href=\"#\">Team</Header.Link>\n </Header.Item>\n </Header>\n)"
3250
3463
  },
3251
3464
  {
3252
- "id": "components-header-features--with-many-items"
3465
+ "id": "components-header-features--with-many-items",
3466
+ "code": "() => (\n <Header>\n <Header.Item>\n <Header.Link className={classes.Logo} href=\"#\">\n <MarkGithubIcon className={classes.Icon} size={32} />\n <span>GitHub</span>\n </Header.Link>\n </Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item>Item</Header.Item>\n <Header.Item className={classes.LastItem}>\n <Avatar\n src=\"https://github.com/octocat.png\"\n size={20}\n square\n alt=\"@octocat\"\n />\n </Header.Item>\n </Header>\n)"
3253
3467
  }
3254
3468
  ],
3255
3469
  "importPath": "@primer/react",
@@ -3296,16 +3510,20 @@
3296
3510
  "a11yReviewed": "2025-01-08",
3297
3511
  "stories": [
3298
3512
  {
3299
- "id": "components-heading--default"
3513
+ "id": "components-heading--default",
3514
+ "code": "() => <Heading>Default H2 Heading</Heading>"
3300
3515
  },
3301
3516
  {
3302
- "id": "components-heading-features--small"
3517
+ "id": "components-heading-features--small",
3518
+ "code": "() => <Heading variant=\"small\">Small heading</Heading>"
3303
3519
  },
3304
3520
  {
3305
- "id": "components-heading-features--medium"
3521
+ "id": "components-heading-features--medium",
3522
+ "code": "() => <Heading variant=\"medium\">Medium heading</Heading>"
3306
3523
  },
3307
3524
  {
3308
- "id": "components-heading-features--large"
3525
+ "id": "components-heading-features--large",
3526
+ "code": "() => <Heading variant=\"large\">Large heading</Heading>"
3309
3527
  }
3310
3528
  ],
3311
3529
  "importPath": "@primer/react",
@@ -3329,13 +3547,16 @@
3329
3547
  "a11yReviewed": "2025-01-08",
3330
3548
  "stories": [
3331
3549
  {
3332
- "id": "experimental-components-hidden--default"
3550
+ "id": "experimental-components-hidden--default",
3551
+ "code": "() => (\n <>\n <Text>\n The below content is visible when the viewport is regular or wide but\n hidden when narrow:\n </Text>\n <Hidden when=\"narrow\">\n This is the said content and it is visible when the viewport is regular or\n wide but hidden when narrow\n </Hidden>\n </>\n)"
3333
3552
  },
3334
3553
  {
3335
- "id": "experimental-components-hidden-features--hide-content"
3554
+ "id": "experimental-components-hidden-features--hide-content",
3555
+ "code": "() => (\n <div>\n <Hidden when=\"narrow\">\n {' '}\n This value is shown in regular and wide viewports\n </Hidden>\n <Hidden when=\"regular\">\n {' '}\n This value is shown in narrow and wide viewports\n </Hidden>\n <Hidden when=\"wide\">\n {' '}\n This value is shown in narrow and regular viewports\n </Hidden>\n </div>\n)"
3336
3556
  },
3337
3557
  {
3338
- "id": "experimental-components-hidden-features--render-content-responsively"
3558
+ "id": "experimental-components-hidden-features--render-content-responsively",
3559
+ "code": "() => (\n <div>\n <Hidden when=\"narrow\">\n <Button variant=\"primary\">\n I am visible when the viewport is regular or wide viewport\n </Button>\n </Hidden>\n\n <Hidden when={['regular', 'wide']}>\n <Button variant=\"primary\">\n I am visible when the viewport is narrow\n </Button>\n </Hidden>\n </div>\n)"
3339
3560
  }
3340
3561
  ],
3341
3562
  "importPath": "@primer/react/experimental",
@@ -3358,25 +3579,28 @@
3358
3579
  "importPath": "@primer/react/experimental",
3359
3580
  "stories": [
3360
3581
  {
3361
- "id": "components-inlinemessage--default"
3362
- },
3363
- {
3364
- "id": "experimental-components-inlinemessage--default"
3582
+ "id": "experimental-components-inlinemessage--default",
3583
+ "code": "() => {\n return (\n <InlineMessage variant=\"unavailable\">\n An example inline message\n </InlineMessage>\n )\n}"
3365
3584
  },
3366
3585
  {
3367
- "id": "experimental-components-inlinemessage-features--critical"
3586
+ "id": "experimental-components-inlinemessage-features--critical",
3587
+ "code": "() => {\n return (\n <InlineMessage variant=\"critical\">An example inline message</InlineMessage>\n )\n}"
3368
3588
  },
3369
3589
  {
3370
- "id": "experimental-components-inlinemessage-features--success"
3590
+ "id": "experimental-components-inlinemessage-features--success",
3591
+ "code": "() => {\n return (\n <InlineMessage variant=\"success\">An example inline message</InlineMessage>\n )\n}"
3371
3592
  },
3372
3593
  {
3373
- "id": "experimental-components-inlinemessage-features--unavailable"
3594
+ "id": "experimental-components-inlinemessage-features--unavailable",
3595
+ "code": "() => {\n return (\n <InlineMessage variant=\"unavailable\">\n An example inline message\n </InlineMessage>\n )\n}"
3374
3596
  },
3375
3597
  {
3376
- "id": "experimental-components-inlinemessage-features--warning"
3598
+ "id": "experimental-components-inlinemessage-features--warning",
3599
+ "code": "() => {\n return (\n <InlineMessage variant=\"warning\">An example inline message</InlineMessage>\n )\n}"
3377
3600
  },
3378
3601
  {
3379
- "id": "experimental-components-inlinemessage-features--multiline"
3602
+ "id": "experimental-components-inlinemessage-features--multiline",
3603
+ "code": "() => {\n return (\n <div\n style={{\n maxWidth: '30ch',\n }}\n >\n <InlineMessage variant=\"success\">\n An example inline message that spans multiple lines\n </InlineMessage>\n </div>\n )\n}"
3380
3604
  }
3381
3605
  ],
3382
3606
  "props": [
@@ -3392,6 +3616,12 @@
3392
3616
  "description": "Specify the type of the inline message",
3393
3617
  "type": "'critical' | 'success' | 'unvailable' | 'warning'",
3394
3618
  "required": true
3619
+ },
3620
+ {
3621
+ "name": "leadingVisual",
3622
+ "description": "A custom leading visual to display instead of the default variant icon.",
3623
+ "type": "React.ElementType | React.ReactNode",
3624
+ "required": false
3395
3625
  }
3396
3626
  ]
3397
3627
  },
@@ -3403,10 +3633,12 @@
3403
3633
  "a11yReviewed": "2025-01-08",
3404
3634
  "stories": [
3405
3635
  {
3406
- "id": "experimental-components-keybindinghint-features--on-emphasis"
3636
+ "id": "experimental-components-keybindinghint-features--on-emphasis",
3637
+ "code": "(args) => (\n <div className={classes.EmphasisBackground}>\n <KeybindingHint {...args} />\n </div>\n)"
3407
3638
  },
3408
3639
  {
3409
- "id": "experimental-components-keybindinghint-features--on-primary"
3640
+ "id": "experimental-components-keybindinghint-features--on-primary",
3641
+ "code": "(args) => (\n <div className={classes.PrimaryBackground}>\n <KeybindingHint {...args} />\n </div>\n)"
3410
3642
  }
3411
3643
  ],
3412
3644
  "importPath": "@primer/react",
@@ -3445,40 +3677,52 @@
3445
3677
  "a11yReviewed": "2025-01-08",
3446
3678
  "stories": [
3447
3679
  {
3448
- "id": "components-label--default"
3680
+ "id": "components-label--default",
3681
+ "code": "() => <Label>Default</Label>"
3449
3682
  },
3450
3683
  {
3451
- "id": "components-label-features--primary"
3684
+ "id": "components-label-features--primary",
3685
+ "code": "() => <Label variant=\"primary\">Primary</Label>"
3452
3686
  },
3453
3687
  {
3454
- "id": "components-label-features--secondary"
3688
+ "id": "components-label-features--secondary",
3689
+ "code": "() => <Label variant=\"secondary\">Secondary</Label>"
3455
3690
  },
3456
3691
  {
3457
- "id": "components-label-features--accent"
3692
+ "id": "components-label-features--accent",
3693
+ "code": "() => <Label variant=\"accent\">Accent</Label>"
3458
3694
  },
3459
3695
  {
3460
- "id": "components-label-features--success"
3696
+ "id": "components-label-features--success",
3697
+ "code": "() => <Label variant=\"success\">Success</Label>"
3461
3698
  },
3462
3699
  {
3463
- "id": "components-label-features--attention"
3700
+ "id": "components-label-features--attention",
3701
+ "code": "() => <Label variant=\"attention\">Attention</Label>"
3464
3702
  },
3465
3703
  {
3466
- "id": "components-label-features--severe"
3704
+ "id": "components-label-features--severe",
3705
+ "code": "() => <Label variant=\"severe\">Primary</Label>"
3467
3706
  },
3468
3707
  {
3469
- "id": "components-label-features--danger"
3708
+ "id": "components-label-features--danger",
3709
+ "code": "() => <Label variant=\"danger\">Danger</Label>"
3470
3710
  },
3471
3711
  {
3472
- "id": "components-label-features--done"
3712
+ "id": "components-label-features--done",
3713
+ "code": "() => <Label variant=\"done\">Done</Label>"
3473
3714
  },
3474
3715
  {
3475
- "id": "components-label-features--sponsors"
3716
+ "id": "components-label-features--sponsors",
3717
+ "code": "() => <Label variant=\"sponsors\">Sponsors</Label>"
3476
3718
  },
3477
3719
  {
3478
- "id": "components-label-features--size-large"
3720
+ "id": "components-label-features--size-large",
3721
+ "code": "() => <Label size=\"large\">Default</Label>"
3479
3722
  },
3480
3723
  {
3481
- "id": "components-label-features--size-small"
3724
+ "id": "components-label-features--size-small",
3725
+ "code": "() => <Label size=\"small\">Default</Label>"
3482
3726
  }
3483
3727
  ],
3484
3728
  "importPath": "@primer/react",
@@ -3506,22 +3750,28 @@
3506
3750
  "a11yReviewed": "2025-01-08",
3507
3751
  "stories": [
3508
3752
  {
3509
- "id": "components-labelgroup--default"
3753
+ "id": "components-labelgroup--default",
3754
+ "code": "() => (\n <LabelGroup>\n <Label>One</Label>\n <Label>Two</Label>\n <Label>Three</Label>\n <Label>Four</Label>\n <Label>Five</Label>\n <Label>Six</Label>\n <Label>Seven</Label>\n <Label>Eight</Label>\n <Label>Nine</Label>\n <Label>Ten</Label>\n <Label>Eleven</Label>\n <Label>Twelve</Label>\n <Label>Thirteen</Label>\n <Label>Fourteen</Label>\n <Label>Fifteen</Label>\n <Label>Sixteen</Label>\n </LabelGroup>\n)"
3510
3755
  },
3511
3756
  {
3512
- "id": "components-labelgroup-features--truncate-auto"
3757
+ "id": "components-labelgroup-features--truncate-auto",
3758
+ "code": "() => (\n <ResizableContainer>\n <LabelGroup visibleChildCount=\"auto\">\n <Label>One</Label>\n <Label>Two</Label>\n <Label>Three</Label>\n <Label>Four</Label>\n <Label>Five</Label>\n <Label>Six</Label>\n <Label>Seven</Label>\n <Label>Eight</Label>\n <Label>Nine</Label>\n <Label>Ten</Label>\n <Label>Eleven</Label>\n <Label>Twelve</Label>\n <Label>Thirteen</Label>\n <Label>Fourteen</Label>\n <Label>Fifteen</Label>\n <Label>Sixteen</Label>\n </LabelGroup>\n </ResizableContainer>\n)"
3513
3759
  },
3514
3760
  {
3515
- "id": "components-labelgroup-features--truncate-auto-with-interactive-tokens"
3761
+ "id": "components-labelgroup-features--truncate-auto-with-interactive-tokens",
3762
+ "code": "() => (\n <ResizableContainer>\n <LabelGroup visibleChildCount=\"auto\">\n <Token as=\"button\" text=\"One\" />\n <Token as=\"button\" text=\"Two\" />\n <Token as=\"button\" text=\"Three\" />\n <Token as=\"button\" text=\"Four\" />\n <Token as=\"button\" text=\"Five\" />\n <Token as=\"button\" text=\"Six\" />\n <Token as=\"button\" text=\"Seven\" />\n <Token as=\"button\" text=\"Eight\" />\n <Token as=\"button\" text=\"Nine\" />\n <Token as=\"button\" text=\"Ten\" />\n <Token as=\"button\" text=\"Eleven\" />\n <Token as=\"button\" text=\"Twelve\" />\n <Token as=\"button\" text=\"Thirteen\" />\n <Token as=\"button\" text=\"Fourteen\" />\n <Token as=\"button\" text=\"Fifteen\" />\n <Token as=\"button\" text=\"Sixteen\" />\n </LabelGroup>\n </ResizableContainer>\n)"
3516
3763
  },
3517
3764
  {
3518
- "id": "components-labelgroup-features--truncate-after-five"
3765
+ "id": "components-labelgroup-features--truncate-after-five",
3766
+ "code": "() => (\n <LabelGroup visibleChildCount={5}>\n <Label>One</Label>\n <Label>Two</Label>\n <Label>Three</Label>\n <Label>Four</Label>\n <Label>Five</Label>\n <Label>Six</Label>\n <Label>Seven</Label>\n <Label>Eight</Label>\n <Label>Nine</Label>\n <Label>Ten</Label>\n <Label>Eleven</Label>\n <Label>Twelve</Label>\n <Label>Thirteen</Label>\n <Label>Fourteen</Label>\n <Label>Fifteen</Label>\n <Label>Sixteen</Label>\n </LabelGroup>\n)"
3519
3767
  },
3520
3768
  {
3521
- "id": "components-labelgroup-features--truncate-auto-expand-inline"
3769
+ "id": "components-labelgroup-features--truncate-auto-expand-inline",
3770
+ "code": "() => (\n <ResizableContainer>\n <LabelGroup visibleChildCount=\"auto\" overflowStyle=\"inline\">\n <Label>One</Label>\n <Label>Two</Label>\n <Label>Three</Label>\n <Label>Four</Label>\n <Label>Five</Label>\n <Label>Six</Label>\n <Label>Seven</Label>\n <Label>Eight</Label>\n <Label>Nine</Label>\n <Label>Ten</Label>\n <Label>Eleven</Label>\n <Label>Twelve</Label>\n <Label>Thirteen</Label>\n <Label>Fourteen</Label>\n <Label>Fifteen</Label>\n <Label>Sixteen</Label>\n </LabelGroup>\n </ResizableContainer>\n)"
3522
3771
  },
3523
3772
  {
3524
- "id": "components-labelgroup-features--truncate-auto-expand-inline-with-interactive-tokens"
3773
+ "id": "components-labelgroup-features--truncate-auto-expand-inline-with-interactive-tokens",
3774
+ "code": "() => (\n <ResizableContainer>\n <LabelGroup visibleChildCount=\"auto\" overflowStyle=\"inline\">\n <Token as=\"button\" text=\"One\" />\n <Token as=\"button\" text=\"Two\" />\n <Token as=\"button\" text=\"Three\" />\n <Token as=\"button\" text=\"Four\" />\n <Token as=\"button\" text=\"Five\" />\n <Token as=\"button\" text=\"Six\" />\n <Token as=\"button\" text=\"Seven\" />\n <Token as=\"button\" text=\"Eight\" />\n <Token as=\"button\" text=\"Nine\" />\n <Token as=\"button\" text=\"Ten\" />\n <Token as=\"button\" text=\"Eleven\" />\n <Token as=\"button\" text=\"Twelve\" />\n <Token as=\"button\" text=\"Thirteen\" />\n <Token as=\"button\" text=\"Fourteen\" />\n <Token as=\"button\" text=\"Fifteen\" />\n <Token as=\"button\" text=\"Sixteen\" />\n </LabelGroup>\n </ResizableContainer>\n)"
3525
3775
  }
3526
3776
  ],
3527
3777
  "importPath": "@primer/react",
@@ -3555,13 +3805,16 @@
3555
3805
  "a11yReviewed": "2025-01-08",
3556
3806
  "stories": [
3557
3807
  {
3558
- "id": "components-link--default"
3808
+ "id": "components-link--default",
3809
+ "code": "() => <Link href=\"#\">Links are great</Link>"
3559
3810
  },
3560
3811
  {
3561
- "id": "components-link-features--muted"
3812
+ "id": "components-link-features--muted",
3813
+ "code": "() => (\n <Link href=\"#\" muted>\n Link\n </Link>\n)"
3562
3814
  },
3563
3815
  {
3564
- "id": "components-link-features--inline"
3816
+ "id": "components-link-features--inline",
3817
+ "code": "() => (\n <div data-a11y-link-underlines=\"true\">\n <Link inline={true} href=\"#\">\n Link\n </Link>\n </div>\n)"
3565
3818
  }
3566
3819
  ],
3567
3820
  "importPath": "@primer/react",
@@ -3617,58 +3870,76 @@
3617
3870
  "a11yReviewed": "2025-01-08",
3618
3871
  "stories": [
3619
3872
  {
3620
- "id": "components-navlist--default"
3873
+ "id": "components-navlist--default",
3874
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Item 1\n </NavList.Item>\n <NavList.Item href=\"#\">Item 2</NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3621
3875
  },
3622
3876
  {
3623
- "id": "components-navlist-features--expand-with-custom-items"
3877
+ "id": "components-navlist-features--expand-with-custom-items",
3878
+ "code": "() => {\n const items: {\n href: string\n text: string\n 'aria-current'?: 'page'\n }[] = [\n {\n href: '#',\n text: 'Item 4',\n 'aria-current': 'page',\n },\n {\n href: '#',\n text: 'Item 5',\n },\n {\n href: '#',\n text: 'Item 6',\n },\n {\n href: '#',\n text: 'Item 7',\n },\n {\n href: '#',\n text: 'Item 8',\n },\n {\n href: '#',\n text: 'Item 9',\n },\n ]\n const Item = ({\n leadingVisual,\n text,\n trailingVisual,\n ...rest\n }: CustomItemProps) => {\n return (\n <NavList.Item key={text} onClick={() => {}} href=\"#\" {...rest}>\n {leadingVisual ? (\n <NavList.LeadingVisual>\n <Octicon icon={leadingVisual} />\n </NavList.LeadingVisual>\n ) : null}\n {text}\n\n {trailingVisual ? (\n <NavList.TrailingVisual>\n {typeof trailingVisual === 'string' ? (\n trailingVisual\n ) : (\n <Octicon icon={trailingVisual as React.ElementType} />\n )}\n <VisuallyHidden>results</VisuallyHidden>\n </NavList.TrailingVisual>\n ) : null}\n </NavList.Item>\n )\n }\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\">Item 1</NavList.Item>\n <NavList.Item href=\"#\">Item 2</NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n <NavList.GroupExpand\n label=\"Show more\"\n items={items}\n renderItem={Item}\n />\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n )\n}"
3624
3879
  },
3625
3880
  {
3626
- "id": "components-navlist-features--expand-with-pages"
3881
+ "id": "components-navlist-features--expand-with-pages",
3882
+ "code": "() => {\n const items = [\n {\n href: '#',\n text: 'Item 4',\n },\n {\n href: '#',\n text: 'Item 5',\n },\n {\n href: '#',\n text: 'Item 6',\n },\n {\n href: '#',\n text: 'Item 7',\n },\n {\n href: '#',\n text: 'Item 8',\n },\n {\n href: '#',\n text: 'Item 9',\n },\n ]\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Item 1\n </NavList.Item>\n <NavList.Item href=\"#\">Item 2</NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n <NavList.GroupExpand pages={2} label=\"Show more\" items={items} />\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n )\n}"
3627
3883
  },
3628
3884
  {
3629
- "id": "components-navlist-features--group-with-expand-and-custom-items"
3885
+ "id": "components-navlist-features--group-with-expand-and-custom-items",
3886
+ "code": "() => {\n const Item = ({\n leadingVisual: LeadingVisual,\n text,\n trailingVisual: TrailingVisual,\n ...rest\n }: CustomItemProps) => {\n return (\n <NavList.Item onClick={() => {}} href=\"#\" {...rest} key={text}>\n {LeadingVisual ? (\n <NavList.LeadingVisual>\n <LeadingVisual />\n </NavList.LeadingVisual>\n ) : null}\n {text}\n\n {TrailingVisual ? (\n <NavList.TrailingVisual>\n {typeof TrailingVisual === 'string' ? (\n TrailingVisual\n ) : (\n <TrailingVisual />\n )}\n <VisuallyHidden>results</VisuallyHidden>\n </NavList.TrailingVisual>\n ) : null}\n </NavList.Item>\n )\n }\n const items = [\n {\n href: '#',\n text: 'Commits',\n leadingVisual: GitCommitIcon,\n trailingVisual: '32k',\n },\n {\n href: '#',\n text: 'Packages',\n leadingVisual: PackageIcon,\n trailingVisual: '1k',\n },\n {\n href: '#',\n text: 'Wikis',\n leadingVisual: BookIcon,\n trailingVisual: '121',\n },\n {\n href: '#',\n text: 'Topics',\n leadingVisual: MilestoneIcon,\n trailingVisual: '12k',\n },\n {\n href: '#',\n text: 'Marketplace',\n leadingVisual: TelescopeIcon,\n trailingVisual: ArrowRightIcon,\n },\n ]\n return (\n <NavList>\n <NavList.Group>\n <NavList.Item aria-current=\"page\">\n <NavList.LeadingVisual>\n <CodeIcon />\n </NavList.LeadingVisual>\n Code\n <NavList.TrailingVisual>3k</NavList.TrailingVisual>\n </NavList.Item>\n <NavList.Item>\n <NavList.LeadingVisual>\n <RepoIcon />\n </NavList.LeadingVisual>\n Repositories\n <NavList.TrailingVisual>713</NavList.TrailingVisual>\n </NavList.Item>\n <NavList.Item>\n <NavList.LeadingVisual>\n <IssueOpenedIcon />\n </NavList.LeadingVisual>\n Issues\n <NavList.TrailingVisual>6k</NavList.TrailingVisual>\n </NavList.Item>\n <NavList.Item>\n <NavList.LeadingVisual>\n <GitPullRequestIcon />\n </NavList.LeadingVisual>\n Pull requests\n <NavList.TrailingVisual>4k</NavList.TrailingVisual>\n </NavList.Item>\n <NavList.Item>\n <NavList.LeadingVisual>\n <CommentDiscussionIcon />\n </NavList.LeadingVisual>\n Discussions\n <NavList.TrailingVisual>236</NavList.TrailingVisual>\n </NavList.Item>\n <NavList.Item>\n <NavList.LeadingVisual>\n <PeopleIcon />\n </NavList.LeadingVisual>\n Users\n <NavList.TrailingVisual>10k</NavList.TrailingVisual>\n </NavList.Item>\n <NavList.GroupExpand items={items} renderItem={Item} />\n </NavList.Group>\n </NavList>\n )\n}"
3630
3887
  },
3631
3888
  {
3632
- "id": "components-navlist-features--with-description"
3889
+ "id": "components-navlist-features--with-description",
3890
+ "code": "() => (\n <NavList>\n <NavList.Item href=\"#\" aria-current=\"page\">\n <NavList.LeadingVisual>\n <RepoIcon />\n </NavList.LeadingVisual>\n Main Repository\n <NavList.Description>Primary project repository</NavList.Description>\n </NavList.Item>\n <NavList.Item href=\"#\">\n <NavList.LeadingVisual>\n <BookIcon />\n </NavList.LeadingVisual>\n Documentation\n <NavList.Description>\n User guides and API documentation\n </NavList.Description>\n </NavList.Item>\n <NavList.Item href=\"#\">\n <NavList.LeadingVisual>\n <IssueOpenedIcon />\n </NavList.LeadingVisual>\n Bug Reports\n <NavList.Description variant=\"block\">\n Submit and track bug reports for the project. Include detailed steps to\n reproduce, expected behavior, and system information.\n </NavList.Description>\n </NavList.Item>\n <NavList.Item href=\"#\">\n <NavList.LeadingVisual>\n <PeopleIcon />\n </NavList.LeadingVisual>\n Community\n <NavList.Description variant=\"block\">\n Connect with other developers, share ideas, and collaborate on features\n and improvements.\n </NavList.Description>\n </NavList.Item>\n <NavList.Item href=\"#\">\n <NavList.LeadingVisual>\n <GitCommitIcon />\n </NavList.LeadingVisual>\n Recent Changes\n <NavList.Description>Latest commits and releases</NavList.Description>\n </NavList.Item>\n </NavList>\n)"
3633
3891
  },
3634
3892
  {
3635
- "id": "components-navlist-features--with-expand"
3893
+ "id": "components-navlist-features--with-expand",
3894
+ "code": "() => {\n const items = [\n {\n href: '#',\n text: 'Item 4',\n },\n {\n href: '#',\n text: 'Item 5',\n },\n {\n href: '#',\n text: 'Item 6',\n },\n {\n href: '#',\n text: 'Item 7',\n },\n {\n href: '#',\n text: 'Item 8',\n },\n {\n href: '#',\n text: 'Item 9',\n },\n ]\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Item 1\n </NavList.Item>\n <NavList.Item href=\"#\">Item 2</NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n <NavList.GroupExpand label=\"Show more\" items={items} />\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n )\n}"
3636
3895
  },
3637
3896
  {
3638
- "id": "components-navlist-features--with-expand-and-icons"
3897
+ "id": "components-navlist-features--with-expand-and-icons",
3898
+ "code": "() => {\n const items = [\n {\n href: '#',\n text: 'Item 4',\n },\n {\n href: '#',\n text: 'Item 5',\n },\n {\n href: '#',\n text: 'Item 6',\n },\n {\n href: '#',\n text: 'Item 7',\n },\n {\n href: '#',\n text: 'Item 8',\n },\n {\n href: '#',\n text: 'Item 9',\n },\n ]\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Item 1\n </NavList.Item>\n <NavList.Item href=\"#\">Item 2</NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n <NavList.GroupExpand label=\"Show more\" items={items} />\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n )\n}"
3639
3899
  },
3640
3900
  {
3641
- "id": "components-navlist-features--with-group"
3901
+ "id": "components-navlist-features--with-group",
3902
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Group title=\"Group 1\">\n <NavList.Item aria-current=\"true\" href=\"#\">\n Item 1A\n </NavList.Item>\n <NavList.Item href=\"#\">Item 1B</NavList.Item>\n <NavList.Item href=\"#\">Item 1C</NavList.Item>\n </NavList.Group>\n <NavList.Group title=\"Group 2\">\n <NavList.Item href=\"#\">Item 2A</NavList.Item>\n <NavList.Item href=\"#\">Item 2B</NavList.Item>\n <NavList.Item href=\"#\">Item 2C</NavList.Item>\n </NavList.Group>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3642
3903
  },
3643
3904
  {
3644
- "id": "components-navlist-features--with-group-expand"
3905
+ "id": "components-navlist-features--with-group-expand",
3906
+ "code": "() => {\n const items1 = [\n {\n href: '#',\n text: 'Item 1D',\n },\n {\n href: '#',\n text: 'Item 1E',\n trailingAction: {\n label: 'Some action',\n icon: ArrowRightIcon,\n },\n },\n ]\n const items2 = [\n {\n href: '#',\n text: 'Item 2D',\n trailingVisual: BookIcon,\n },\n {\n href: '#',\n text: 'Item 2E',\n trailingVisual: FileDirectoryIcon,\n },\n ]\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Group title=\"Group 1\">\n <NavList.Item aria-current=\"true\" href=\"#\">\n Item 1A\n </NavList.Item>\n <NavList.Item href=\"#\">Item 1B</NavList.Item>\n <NavList.Item href=\"#\">Item 1C</NavList.Item>\n <NavList.GroupExpand label=\"More\" items={items1} />\n </NavList.Group>\n <NavList.Group title=\"Group 2\">\n <NavList.Item href=\"#\">Item 2A</NavList.Item>\n <NavList.Item href=\"#\">Item 2B</NavList.Item>\n <NavList.Item href=\"#\">Item 2C</NavList.Item>\n <NavList.GroupExpand label=\"Show\" items={items2} />\n </NavList.Group>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n )\n}"
3645
3907
  },
3646
3908
  {
3647
- "id": "components-navlist-features--with-group-heading-links"
3909
+ "id": "components-navlist-features--with-group-heading-links",
3910
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Group>\n <NavList.GroupHeading>\n <a href=\"#group-1\">Group 1</a>\n </NavList.GroupHeading>\n <NavList.Item aria-current=\"true\" href=\"#\">\n Item 1A\n </NavList.Item>\n <NavList.Item href=\"#\">Item 1B</NavList.Item>\n <NavList.Item href=\"#\">Item 1C</NavList.Item>\n </NavList.Group>\n <NavList.Group>\n <NavList.GroupHeading>\n <a href=\"#group-2\">Group 2</a>\n </NavList.GroupHeading>\n <NavList.Item href=\"#\">Item 2A</NavList.Item>\n <NavList.Item href=\"#\">Item 2B</NavList.Item>\n <NavList.Item href=\"#\">Item 2C</NavList.Item>\n </NavList.Group>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3648
3911
  },
3649
3912
  {
3650
- "id": "components-navlist-features--with-inactive-items"
3913
+ "id": "components-navlist-features--with-inactive-items",
3914
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\" inactiveText=\"Unavailable due to an outage\">\n Item 1\n </NavList.Item>\n <NavList.Item>\n Item 2\n <NavList.SubNav>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Sub item 1\n </NavList.Item>\n <NavList.Item href=\"#\" inactiveText=\"Unavailable due to an outage\">\n Sub item 2\n </NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3651
3915
  },
3652
3916
  {
3653
- "id": "components-navlist-features--with-nested-sub-items"
3917
+ "id": "components-navlist-features--with-nested-sub-items",
3918
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item defaultOpen={true} href=\"#\">\n Item 1\n <NavList.SubNav>\n <NavList.Item href=\"#\">Sub item 1</NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item href=\"#\">\n Item 2{/* NOTE: Don't nest SubNavs. For testing purposes only */}\n <NavList.SubNav>\n <NavList.Item href=\"#\">\n Sub item 1\n <NavList.SubNav>\n <NavList.Item href=\"#\">\n Sub item 1.1\n <NavList.SubNav>\n <NavList.Item href=\"#\">Sub item 1.1.1</NavList.Item>\n <NavList.Item href=\"#\">\n Sub item 1.1.2\n <NavList.SubNav>\n <NavList.Item href=\"#\">Sub item 1.1.2.1</NavList.Item>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Sub item 1.1.2.2\n </NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item href=\"#\">Sub item 1.2</NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item href=\"#\">Sub item 2</NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3654
3919
  },
3655
3920
  {
3656
- "id": "components-navlist-features--with-next-js-link"
3921
+ "id": "components-navlist-features--with-next-js-link",
3922
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NextJSLikeLink href=\"#\">\n <NavList.Item aria-current=\"page\">Item 1</NavList.Item>\n </NextJSLikeLink>\n <NextJSLikeLink href=\"#\">\n <NavList.Item>Item 2</NavList.Item>\n </NextJSLikeLink>\n <NextJSLikeLink href=\"#\">\n <NavList.Item>Item 3</NavList.Item>\n </NextJSLikeLink>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3657
3923
  },
3658
3924
  {
3659
- "id": "components-navlist-features--with-react-router-link"
3925
+ "id": "components-navlist-features--with-react-router-link",
3926
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item as={ReactRouterLikeLink} to=\"#\" aria-current=\"page\">\n Item 1\n </NavList.Item>\n <NavList.Item as={ReactRouterLikeLink} to=\"#\">\n Item 2\n </NavList.Item>\n <NavList.Item as={ReactRouterLikeLink} to=\"#\">\n Item 3\n </NavList.Item>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3660
3927
  },
3661
3928
  {
3662
- "id": "components-navlist-features--with-reloads"
3929
+ "id": "components-navlist-features--with-reloads",
3930
+ "code": "() => {\n // eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc\n const location = window.location\n const storyId = new URLSearchParams(location.search).get('id')\n const urlBase = `${location.origin + location.pathname}?id=${storyId}`\n const itemId = new URLSearchParams(location.search).get('itemId')\n return (\n <>\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item\n href={`${urlBase}&itemId=1`}\n aria-current={itemId === '1' ? 'page' : 'false'}\n >\n Item 1\n </NavList.Item>\n <NavList.Item>\n Item 2\n <NavList.SubNav>\n <NavList.Item\n href={`${urlBase}&itemId=2.1`}\n aria-current={itemId === '2.1' ? 'page' : 'false'}\n >\n Sub item 2.1\n </NavList.Item>\n <NavList.Item\n href={`${urlBase}&itemId=2.2`}\n aria-current={itemId === '2.2' ? 'page' : 'false'}\n >\n Sub item 2.2\n </NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item>\n Item 3\n <NavList.SubNav>\n <NavList.Item\n href={`${urlBase}&itemId=3.1`}\n aria-current={itemId === '3.1' ? 'page' : 'false'}\n >\n Sub item 3.1\n </NavList.Item>\n <NavList.Item\n href={`${urlBase}&itemId=3.2`}\n aria-current={itemId === '3.2' ? 'page' : 'false'}\n >\n Sub item 3.2\n </NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n </>\n )\n}"
3663
3931
  },
3664
3932
  {
3665
- "id": "components-navlist-features--with-sub-items"
3933
+ "id": "components-navlist-features--with-sub-items",
3934
+ "code": "() => (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item href=\"#\">Item 1</NavList.Item>\n <NavList.Item>\n Item 2\n <NavList.SubNav>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Sub item 1\n </NavList.Item>\n <NavList.Item href=\"#\">Sub item 2</NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n <NavList.Item href=\"#\">Item 3</NavList.Item>\n </NavList>\n </PageLayout.Pane>\n <PageLayout.Content></PageLayout.Content>\n </PageLayout>\n)"
3666
3935
  },
3667
3936
  {
3668
- "id": "components-navlist-features--with-trailing-action"
3937
+ "id": "components-navlist-features--with-trailing-action",
3938
+ "code": "() => {\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item>\n <NavList.LeadingVisual>\n <FileDirectoryIcon />\n </NavList.LeadingVisual>\n Item 1\n <NavList.TrailingAction\n label=\"Expand sidebar\"\n icon={ArrowLeftIcon}\n />\n </NavList.Item>\n <NavList.Item>\n Item 2\n <NavList.TrailingAction\n as=\"a\"\n href=\"#\"\n label=\"Some action\"\n icon={ArrowRightIcon}\n />\n </NavList.Item>\n </NavList>\n </PageLayout.Pane>\n </PageLayout>\n )\n}"
3669
3939
  },
3670
3940
  {
3671
- "id": "components-navlist-features--with-trailing-action-in-sub-item"
3941
+ "id": "components-navlist-features--with-trailing-action-in-sub-item",
3942
+ "code": "() => {\n return (\n <PageLayout>\n <PageLayout.Pane position=\"start\">\n <NavList>\n <NavList.Item>\n <NavList.LeadingVisual>\n <FileDirectoryIcon />\n </NavList.LeadingVisual>\n Item 1\n <NavList.TrailingAction\n label=\"Expand sidebar\"\n icon={ArrowLeftIcon}\n />\n </NavList.Item>\n <NavList.Item>\n Item 2\n <NavList.TrailingAction\n as=\"a\"\n href=\"#\"\n label=\"Some action\"\n icon={ArrowRightIcon}\n />\n </NavList.Item>\n <NavList.Item>\n Item 3\n <NavList.SubNav>\n <NavList.Item href=\"#\">\n Sub item 1\n <NavList.TrailingAction\n label=\"Another action\"\n icon={BookIcon}\n />\n </NavList.Item>\n </NavList.SubNav>\n </NavList.Item>\n </NavList>\n </PageLayout.Pane>\n </PageLayout>\n )\n}"
3672
3943
  }
3673
3944
  ],
3674
3945
  "importPath": "@primer/react",
@@ -3934,7 +4205,8 @@
3934
4205
  "a11yReviewed": false,
3935
4206
  "stories": [
3936
4207
  {
3937
- "id": "deprecated-components-octicon--default"
4208
+ "id": "deprecated-components-octicon--default",
4209
+ "code": "() => <Octicon icon={HeartFillIcon} aria-label=\"Like\" size={32} />"
3938
4210
  }
3939
4211
  ],
3940
4212
  "importPath": "@primer/react/deprecated",
@@ -3980,16 +4252,16 @@
3980
4252
  "a11yReviewed": "2025-01-08",
3981
4253
  "stories": [
3982
4254
  {
3983
- "id": "components-overlay--default"
3984
- },
3985
- {
3986
- "id": "private-components-overlay--default"
4255
+ "id": "private-components-overlay--default",
4256
+ "code": "(args: Args) => {\n const [isOpen, setIsOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const confirmButtonRef = useRef<HTMLButtonElement>(null)\n const anchorRef = useRef<HTMLDivElement>(null)\n const closeOverlay = () => setIsOpen(false)\n const containerRef = useRef<HTMLDivElement>(null)\n useFocusTrap({\n containerRef,\n disabled: !isOpen,\n })\n return (\n <div ref={anchorRef}>\n <Button\n ref={buttonRef}\n onClick={() => {\n setIsOpen(!isOpen)\n }}\n >\n Open overlay\n </Button>\n {isOpen || args.open ? (\n <Overlay\n initialFocusRef={confirmButtonRef}\n returnFocusRef={buttonRef}\n ignoreClickRefs={[buttonRef]}\n onEscape={closeOverlay}\n onClickOutside={closeOverlay}\n width=\"large\"\n anchorSide=\"inside-right\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Sample overlay\"\n ref={containerRef}\n >\n <div className={classes.FullHeightContent}>\n <IconButton\n aria-label=\"Close\"\n onClick={closeOverlay}\n icon={XIcon}\n variant=\"invisible\"\n className={classes.CloseButtonOverlay}\n />\n <Text>Look! an overlay</Text>\n </div>\n </Overlay>\n ) : null}\n </div>\n )\n}"
3987
4257
  },
3988
4258
  {
3989
- "id": "private-components-overlay-features--dialog-overlay"
4259
+ "id": "private-components-overlay-features--dialog-overlay",
4260
+ "code": "({ anchorSide, role, open }: Args) => {\n const [isOpen, setIsOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const confirmButtonRef = useRef<HTMLButtonElement>(null)\n const anchorRef = useRef<HTMLDivElement>(null)\n const closeOverlay = () => setIsOpen(false)\n useFocusTrap({\n containerRef,\n disabled: !isOpen,\n initialFocusRef: confirmButtonRef,\n returnFocusRef: buttonRef,\n })\n return (\n <div ref={anchorRef}>\n <Button ref={buttonRef} onClick={() => setIsOpen(!isOpen)}>\n open overlay\n </Button>\n {isOpen || open ? (\n <Overlay\n initialFocusRef={confirmButtonRef}\n returnFocusRef={buttonRef}\n ignoreClickRefs={[buttonRef]}\n onEscape={closeOverlay}\n onClickOutside={closeOverlay}\n width=\"small\"\n anchorSide={anchorSide}\n role={role}\n aria-modal={role === 'dialog' ? 'true' : undefined}\n aria-label={role === 'dialog' ? 'Confirmation screen' : undefined}\n ref={containerRef}\n >\n <div className={classes.DialogContent}>\n <Text>Are you sure?</Text>\n <Button variant=\"danger\" onClick={closeOverlay}>\n Cancel\n </Button>\n <Button onClick={closeOverlay} ref={confirmButtonRef}>\n Confirm\n </Button>\n </div>\n </Overlay>\n ) : null}\n </div>\n )\n}"
3990
4261
  },
3991
4262
  {
3992
- "id": "private-components-overlay-features--positioned-overlays"
4263
+ "id": "private-components-overlay-features--positioned-overlays",
4264
+ "code": "({ right, role, open }: Args) => {\n const [isOpen, setIsOpen] = useState(false)\n const [direction, setDirection] = useState<'left' | 'right'>(\n right ? 'right' : 'left',\n )\n const buttonRef = useRef<HTMLButtonElement>(null)\n const confirmButtonRef = useRef<HTMLButtonElement>(null)\n const anchorRef = useRef<HTMLDivElement>(null)\n const closeOverlay = () => setIsOpen(false)\n const containerRef = useRef<HTMLDivElement>(null)\n useFocusTrap({\n containerRef,\n disabled: !isOpen,\n })\n return (\n <div ref={anchorRef}>\n <Button\n ref={buttonRef}\n onClick={() => {\n setIsOpen(!isOpen)\n setDirection('left')\n }}\n >\n Open left overlay\n </Button>\n <Button\n ref={buttonRef}\n onClick={() => {\n setIsOpen(!isOpen)\n setDirection('right')\n }}\n style={{\n marginTop: '8px',\n }}\n >\n Open right overlay\n </Button>\n {isOpen || open ? (\n direction === 'left' ? (\n <Overlay\n initialFocusRef={confirmButtonRef}\n returnFocusRef={buttonRef}\n ignoreClickRefs={[buttonRef]}\n onEscape={closeOverlay}\n onClickOutside={closeOverlay}\n width=\"auto\"\n anchorSide=\"inside-right\"\n role={role}\n aria-modal={role === 'dialog' ? 'true' : undefined}\n aria-label={role === 'dialog' ? 'Left aligned overlay' : undefined}\n ref={containerRef}\n >\n <div className={classes.ResponsiveWidthContainer}>\n <div className={classes.OverlayFullHeight}>\n <IconButton\n aria-label=\"Close\"\n onClick={closeOverlay}\n icon={XIcon}\n variant=\"invisible\"\n className={classes.CloseButtonLeft}\n />\n <Text>Look! left aligned</Text>\n </div>\n </div>\n </Overlay>\n ) : (\n <Overlay\n initialFocusRef={confirmButtonRef}\n returnFocusRef={buttonRef}\n ignoreClickRefs={[buttonRef]}\n onEscape={closeOverlay}\n onClickOutside={closeOverlay}\n width=\"auto\"\n anchorSide={'inside-left'}\n right={0}\n position=\"fixed\"\n role={role}\n aria-modal={role === 'dialog' ? 'true' : undefined}\n aria-label={role === 'dialog' ? 'Right aligned overlay' : undefined}\n ref={containerRef}\n >\n <div className={classes.ResponsiveWidthContainer}>\n <div className={classes.OverlayFullHeight}>\n <IconButton\n aria-label=\"Close\"\n onClick={closeOverlay}\n icon={XIcon}\n variant=\"invisible\"\n className={classes.CloseButtonRight}\n />\n <Text>Look! right aligned</Text>\n </div>\n </div>\n </Overlay>\n )\n ) : null}\n </div>\n )\n}"
3993
4265
  }
3994
4266
  ],
3995
4267
  "importPath": "@primer/react",
@@ -4142,43 +4414,52 @@
4142
4414
  "a11yReviewed": "2025-01-08",
4143
4415
  "stories": [
4144
4416
  {
4145
- "id": "components-pageheader--default"
4146
- },
4147
- {
4148
- "id": "components-pageheader-features--has-title-only"
4417
+ "id": "components-pageheader-features--has-title-only",
4418
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Title</PageHeader.Title>\n </PageHeader.TitleArea>\n </PageHeader>\n </div>\n)"
4149
4419
  },
4150
4420
  {
4151
- "id": "components-pageheader-features--has-large-title"
4421
+ "id": "components-pageheader-features--has-large-title",
4422
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea variant=\"large\">\n <PageHeader.Title>Title</PageHeader.Title>\n </PageHeader.TitleArea>\n </PageHeader>\n </div>\n)"
4152
4423
  },
4153
4424
  {
4154
- "id": "components-pageheader-features--with-leading-and-trailing-visuals"
4425
+ "id": "components-pageheader-features--with-leading-and-trailing-visuals",
4426
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.LeadingVisual>\n <GitPullRequestIcon />\n </PageHeader.LeadingVisual>\n <PageHeader.Title>Title</PageHeader.Title>\n <PageHeader.TrailingVisual>\n <Label>Beta</Label>\n </PageHeader.TrailingVisual>\n </PageHeader.TitleArea>\n </PageHeader>\n </div>\n)"
4155
4427
  },
4156
4428
  {
4157
- "id": "components-pageheader-features--with-leading-visual-hidden-on-regular-viewport"
4429
+ "id": "components-pageheader-features--with-leading-visual-hidden-on-regular-viewport",
4430
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.LeadingVisual\n hidden={{\n regular: true,\n }}\n >\n <GitPullRequestIcon />\n </PageHeader.LeadingVisual>\n <PageHeader.Title>Title</PageHeader.Title>\n <PageHeader.TrailingVisual>\n <Label>Beta</Label>\n </PageHeader.TrailingVisual>\n </PageHeader.TitleArea>\n </PageHeader>\n </div>\n)"
4158
4431
  },
4159
4432
  {
4160
- "id": "components-pageheader-features--with-actions"
4433
+ "id": "components-pageheader-features--with-actions",
4434
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Title</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.Actions>\n <IconButton aria-label=\"Workflows\" icon={WorkflowIcon} />\n <IconButton aria-label=\"Insights\" icon={GraphIcon} />\n <Button variant=\"primary\" trailingVisual={TriangleDownIcon}>\n Add Item\n </Button>\n <IconButton aria-label=\"Settings\" icon={GearIcon} />\n </PageHeader.Actions>\n </PageHeader>\n </div>\n)"
4161
4435
  },
4162
4436
  {
4163
- "id": "components-pageheader-features--with-description-slot"
4437
+ "id": "components-pageheader-features--with-description-slot",
4438
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Add-pageheader-docs\">\n <PageHeader.TitleArea>\n <PageHeader.Title>add-pageheader-docs</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.Description>\n <Text className={classes.DescriptionText}>\n <Link\n href=\"https://github.com/broccolinisoup\"\n className={classes.BoldLink}\n >\n broccolinisoup\n </Link>{' '}\n created this branch 5 days ago · 14 commits · updated today\n </Text>\n </PageHeader.Description>\n </PageHeader>\n </div>\n)"
4164
4439
  },
4165
4440
  {
4166
- "id": "components-pageheader-features--with-navigation-slot"
4441
+ "id": "components-pageheader-features--with-navigation-slot",
4442
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Pull request title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Pull request title</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.Navigation>\n <UnderlineNav aria-label=\"Pull Request\">\n <UnderlineNav.Item\n icon={CommentDiscussionIcon}\n counter=\"12\"\n aria-current=\"page\"\n >\n Conversation\n </UnderlineNav.Item>\n <UnderlineNav.Item counter={3} icon={GitCommitIcon}>\n Commits\n </UnderlineNav.Item>\n <UnderlineNav.Item counter={7} icon={ChecklistIcon}>\n Checks\n </UnderlineNav.Item>\n <UnderlineNav.Item counter={4} icon={FileDiffIcon}>\n Files Changes\n </UnderlineNav.Item>\n </UnderlineNav>\n </PageHeader.Navigation>\n </PageHeader>\n </div>\n)"
4167
4443
  },
4168
4444
  {
4169
- "id": "components-pageheader-features--with-custom-navigation"
4445
+ "id": "components-pageheader-features--with-custom-navigation",
4446
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Pull request title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Pull request title</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.Navigation as=\"nav\" aria-label=\"Item list\">\n <ul className={classes.CustomNavigationList}>\n <li>\n <Link href=\"https://github.com/primer/react\" aria-current=\"page\">\n Item 1\n </Link>\n </li>\n <li>\n <Link href=\"https://github.com/primer/react/pulls\">Item 2</Link>\n </li>\n </ul>\n </PageHeader.Navigation>\n </PageHeader>\n </div>\n)"
4170
4447
  },
4171
4448
  {
4172
- "id": "components-pageheader-features--with-leading-and-trailing-actions"
4449
+ "id": "components-pageheader-features--with-leading-and-trailing-actions",
4450
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Title</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.LeadingAction>\n <IconButton\n aria-label=\"Expand\"\n icon={SidebarExpandIcon}\n variant=\"invisible\"\n />\n </PageHeader.LeadingAction>\n <PageHeader.TrailingAction>\n <IconButton aria-label=\"Edit\" icon={PencilIcon} variant=\"invisible\" />\n </PageHeader.TrailingAction>\n </PageHeader>\n </div>\n)"
4173
4451
  },
4174
4452
  {
4175
- "id": "components-pageheader-features--with-parent-link-and-actions-of-context-area"
4453
+ "id": "components-pageheader-features--with-parent-link-and-actions-of-context-area",
4454
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Title</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.ContextArea>\n <PageHeader.ParentLink href=\"http://github.com\">\n Parent Link\n </PageHeader.ParentLink>\n\n <PageHeader.ContextAreaActions>\n <Button size=\"small\" trailingAction={TriangleDownIcon}>\n Add File\n </Button>\n <IconButton\n size=\"small\"\n aria-label=\"More Options\"\n icon={KebabHorizontalIcon}\n />\n </PageHeader.ContextAreaActions>\n </PageHeader.ContextArea>\n </PageHeader>\n </div>\n)"
4176
4455
  },
4177
4456
  {
4178
- "id": "components-pageheader-features--with-context-bar-and-actions-of-context-area"
4457
+ "id": "components-pageheader-features--with-context-bar-and-actions-of-context-area",
4458
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Title\">\n <PageHeader.TitleArea>\n <PageHeader.Title>Title</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.ContextArea>\n <PageHeader.ContextBar>\n <Breadcrumbs>\n <Breadcrumbs.Item href=\"https://github.com/primer/react/tree/main\">\n react\n </Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"https://github.com/primer/react/tree/main/src\">\n src\n </Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"https://github.com/primer/react/tree/main/src/PageHeader\">\n PageHeader\n </Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"https://github.com/primer/react/blob/main/src/PageHeader/PageHeader.tsx\">\n PageHeader.tsx\n </Breadcrumbs.Item>\n </Breadcrumbs>\n </PageHeader.ContextBar>\n <PageHeader.ContextAreaActions>\n <Button size=\"small\" leadingVisual={GitBranchIcon}>\n Main\n </Button>\n <IconButton\n size=\"small\"\n aria-label=\"More Options\"\n icon={KebabHorizontalIcon}\n />\n </PageHeader.ContextAreaActions>\n </PageHeader.ContextArea>\n </PageHeader>\n </div>\n)"
4179
4459
  },
4180
4460
  {
4181
- "id": "components-pageheader-features--with-actions-that-have-responsive-content"
4461
+ "id": "components-pageheader-features--with-actions-that-have-responsive-content",
4462
+ "code": "() => (\n <div className={classes.PaddingContainer}>\n <PageHeader role=\"banner\" aria-label=\"Webhooks\">\n <PageHeader.TitleArea>\n <PageHeader.Title as=\"h2\">Webhooks</PageHeader.Title>\n </PageHeader.TitleArea>\n <PageHeader.Actions>\n <Hidden when={['narrow']}>\n <Button variant=\"primary\">New webhook</Button>\n </Hidden>\n <Hidden when={['regular', 'wide']}>\n <Button variant=\"primary\">New</Button>\n </Hidden>\n </PageHeader.Actions>\n </PageHeader>\n </div>\n)"
4182
4463
  }
4183
4464
  ],
4184
4465
  "importPath": "@primer/react",
@@ -4505,31 +4786,40 @@
4505
4786
  "a11yReviewed": "2025-01-08",
4506
4787
  "stories": [
4507
4788
  {
4508
- "id": "components-pagelayout--default"
4789
+ "id": "components-pagelayout--default",
4790
+ "code": "(args) => (\n <PageLayout\n containerWidth={args.containerWidth}\n padding={args.padding}\n rowGap={args.rowGap}\n columnGap={args.columnGap}\n >\n {args['Render header?'] ? (\n <PageLayout.Header\n padding={args['Header.padding']}\n divider={{\n narrow: args['Header.divider.narrow'],\n regular: args['Header.divider.regular'],\n wide: args['Header.divider.wide'],\n }}\n hidden={{\n narrow: args['Header.hidden.narrow'],\n regular: args['Header.hidden.regular'],\n wide: args['Header.hidden.wide'],\n }}\n >\n <Placeholder\n height={args['Header placeholder height']}\n label=\"Header\"\n />\n </PageLayout.Header>\n ) : null}\n <PageLayout.Content\n width={args['Content.width']}\n padding={args['Content.padding']}\n hidden={{\n narrow: args['Content.hidden.narrow'],\n regular: args['Content.hidden.regular'],\n wide: args['Content.hidden.wide'],\n }}\n >\n <Placeholder\n height={args['Content placeholder height']}\n label=\"Content\"\n />\n </PageLayout.Content>\n {args['Render pane?'] ? (\n <PageLayout.Pane\n position={{\n narrow: args['Pane.position.narrow'],\n regular: args['Pane.position.regular'],\n wide: args['Pane.position.wide'],\n }}\n width={args['Pane.width']}\n minWidth={args['Pane.minWidth']}\n sticky={args['Pane.sticky']}\n resizable={args['Pane.resizable']}\n padding={args['Pane.padding']}\n divider={{\n narrow: args['Pane.divider.narrow'],\n regular: args['Pane.divider.regular'],\n wide: args['Pane.divider.wide'],\n }}\n hidden={{\n narrow: args['Pane.hidden.narrow'],\n regular: args['Pane.hidden.regular'],\n wide: args['Pane.hidden.wide'],\n }}\n >\n <Placeholder height={args['Pane placeholder height']} label=\"Pane\" />\n </PageLayout.Pane>\n ) : null}\n {args['Render footer?'] ? (\n <PageLayout.Footer\n padding={args['Footer.padding']}\n divider={{\n narrow: args['Footer.divider.narrow'],\n regular: args['Footer.divider.regular'],\n wide: args['Footer.divider.wide'],\n }}\n hidden={{\n narrow: args['Footer.hidden.narrow'],\n regular: args['Footer.hidden.regular'],\n wide: args['Footer.hidden.wide'],\n }}\n >\n <Placeholder\n height={args['Footer placeholder height']}\n label=\"Footer\"\n />\n </PageLayout.Footer>\n ) : null}\n </PageLayout>\n)"
4509
4791
  },
4510
4792
  {
4511
- "id": "components-pagelayout-features--pull-request-page"
4793
+ "id": "components-pagelayout-features--pull-request-page",
4794
+ "code": "() => (\n <PageLayout>\n <PageLayout.Header>\n <div className={classes.HeaderStack}>\n <div>\n <Heading as=\"h1\" className={classes.TitleHeading}>\n Input validation styles{' '}\n <Text className={classes.TitleSubdued}>#1831</Text>\n </Heading>\n <div className={classes.StatusRow}>\n <StateLabel status=\"pullOpened\">Open</StateLabel>\n <Text className={classes.StatusMeta}>\n <Link href=\"#\" muted className={classes.BoldMetaLink}>\n mperrotti\n </Link>{' '}\n wants to merge 3 commits into{' '}\n <BranchName href=\"#\">main</BranchName> from{' '}\n <BranchName href=\"#\">mp/validation-styles</BranchName>\n </Text>\n </div>\n </div>\n <TabNav>\n <TabNav.Link href=\"#\" selected>\n Conversation\n </TabNav.Link>\n <TabNav.Link href=\"#\">Commits</TabNav.Link>\n <TabNav.Link href=\"#\">Checks</TabNav.Link>\n <TabNav.Link href=\"#\">Files changed</TabNav.Link>\n </TabNav>\n </div>\n </PageLayout.Header>\n <PageLayout.Content>\n <div className={classes.ContentBox}></div>\n <div className={classes.ScrollBox} tabIndex={0}>\n This box has really long content. If it is too long, it will cause x\n overflow and should show a scrollbar. When this overflows, it should not\n break to overall page layout!\n </div>\n </PageLayout.Content>\n <PageLayout.Pane aria-label=\"Side pane\">\n <div className={classes.PaneStack}>\n <div>\n <Text className={classes.PaneSectionHeading}>Assignees</Text>\n <Text className={classes.PaneMetaText}>\n No one –{' '}\n <Link href=\"#\" muted>\n assign yourself\n </Link>\n </Text>\n </div>\n <div role=\"separator\" className={classes.PaneSeparator}></div>\n <div>\n <Text className={classes.PaneSectionHeading}>Labels</Text>\n <Text className={classes.PaneMetaText}>None yet</Text>\n </div>\n </div>\n </PageLayout.Pane>\n </PageLayout>\n)"
4512
4795
  },
4513
4796
  {
4514
- "id": "components-pagelayout-features--sticky-pane"
4797
+ "id": "components-pagelayout-features--sticky-pane",
4798
+ "code": "(args) => (\n <PageLayout\n rowGap=\"none\"\n columnGap=\"none\"\n padding=\"none\"\n containerWidth=\"full\"\n >\n <PageLayout.Header padding=\"normal\" divider=\"line\">\n <Placeholder label=\"Header\" height={64} />\n </PageLayout.Header>\n <PageLayout.Content padding=\"normal\" width=\"large\">\n <div className={classes.ContentGrid}>\n {Array.from({\n length: args.numParagraphsInContent,\n }).map((_, i) => {\n const testId = `content${i}`\n return (\n <p key={i} className={classes.Paragraph}>\n <span data-testid={testId}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at\n enim id lorem tempus egestas a non ipsum. Maecenas imperdiet\n ante quam, at varius lorem molestie vel. Sed at eros consequat,\n varius tellus et, auctor felis. Donec pulvinar lacinia urna nec\n commodo. Phasellus at imperdiet risus. Donec sit amet massa\n purus. Nunc sem lectus, bibendum a sapien nec, tristique tempus\n felis. Ut porttitor auctor tellus in imperdiet. Ut blandit\n tincidunt augue, quis fringilla nunc tincidunt sed. Vestibulum\n auctor euismod nisi. Nullam tincidunt est in mi tincidunt\n dictum. Sed consectetur aliquet velit ut ornare.\n </span>\n </p>\n )\n })}\n </div>\n </PageLayout.Content>\n <PageLayout.Pane\n position=\"start\"\n resizable\n padding=\"normal\"\n divider=\"line\"\n sticky={args.sticky}\n aria-label=\"Side pane\"\n >\n <div className={classes.ContentGrid}>\n {Array.from({\n length: args.numParagraphsInPane,\n }).map((_, i) => {\n const testId = `paragraph${i}`\n return (\n <p key={i} className={classes.Paragraph}>\n <span data-testid={testId}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at\n enim id lorem tempus egestas a non ipsum. Maecenas imperdiet\n ante quam, at varius lorem molestie vel. Sed at eros consequat,\n varius tellus et, auctor felis. Donec pulvinar lacinia urna nec\n commodo. Phasellus at imperdiet risus. Donec sit amet massa\n purus.\n </span>\n </p>\n )\n })}\n <p>\n Donec sit amet massa purus.{' '}\n <Link inline href=\"#foo\">\n Plura de lorem Ispum.\n </Link>\n </p>\n </div>\n </PageLayout.Pane>\n <PageLayout.Footer padding=\"normal\" divider=\"line\">\n <Placeholder label=\"Footer\" height={64} />\n </PageLayout.Footer>\n </PageLayout>\n)"
4515
4799
  },
4516
4800
  {
4517
- "id": "components-pagelayout-features--nested-scroll-container"
4801
+ "id": "components-pagelayout-features--nested-scroll-container",
4802
+ "code": "(args) => (\n <div className={classes.NestedScrollContainer}>\n <Placeholder label=\"Above scroll container\" height={120} />\n <div className={classes.OverflowAuto}>\n <PageLayout\n rowGap=\"none\"\n columnGap=\"none\"\n padding=\"none\"\n containerWidth=\"full\"\n >\n <PageLayout.Header padding=\"normal\" divider=\"line\">\n <Placeholder label=\"Header\" height={64} />\n </PageLayout.Header>\n <PageLayout.Content padding=\"normal\" width=\"large\">\n <div\n className={classes.ContentGrid}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Page content\"\n >\n {Array.from({\n length: args.numParagraphsInContent,\n }).map((_, i) => (\n <p key={i} className={classes.Paragraph}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at\n enim id lorem tempus egestas a non ipsum. Maecenas imperdiet\n ante quam, at varius lorem molestie vel. Sed at eros consequat,\n varius tellus et, auctor felis. Donec pulvinar lacinia urna nec\n commodo. Phasellus at imperdiet risus. Donec sit amet massa\n purus. Nunc sem lectus, bibendum a sapien nec, tristique tempus\n felis. Ut porttitor auctor tellus in imperdiet. Ut blandit\n tincidunt augue, quis fringilla nunc tincidunt sed. Vestibulum\n auctor euismod nisi. Nullam tincidunt est in mi tincidunt\n dictum. Sed consectetur aliquet velit ut ornare.\n </p>\n ))}\n </div>\n </PageLayout.Content>\n <PageLayout.Pane\n position=\"start\"\n padding=\"normal\"\n divider=\"line\"\n sticky\n aria-label=\"Side pane\"\n >\n <div className={classes.ContentGrid}>\n {Array.from({\n length: args.numParagraphsInPane,\n }).map((_, i) => (\n <p key={i} className={classes.Paragraph}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam at\n enim id lorem tempus egestas a non ipsum. Maecenas imperdiet\n ante quam, at varius lorem molestie vel. Sed at eros consequat,\n varius tellus et, auctor felis. Donec pulvinar lacinia urna nec\n commodo. Phasellus at imperdiet risus. Donec sit amet massa\n purus.\n </p>\n ))}\n </div>\n </PageLayout.Pane>\n <PageLayout.Footer padding=\"normal\" divider=\"line\">\n <Placeholder label=\"Footer\" height={64} />\n </PageLayout.Footer>\n </PageLayout>\n </div>\n <Placeholder label=\"Below scroll container\" height={120} />\n </div>\n)"
4518
4803
  },
4519
4804
  {
4520
- "id": "components-pagelayout-features--custom-sticky-header"
4805
+ "id": "components-pagelayout-features--custom-sticky-header",
4806
+ "code": "(args) => (\n // a box to create a sticky top element that will be on the consumer side and outside of the PageLayout component\n <div data-testid=\"story-window\">\n <header\n data-testid=\"sticky-header\"\n className={classes.StickyHeader}\n style={{\n height: args.offsetHeader,\n }}\n >\n Custom sticky header\n </header>\n <PageLayout\n rowGap=\"none\"\n columnGap=\"none\"\n padding=\"none\"\n containerWidth=\"full\"\n >\n <PageLayout.Content padding=\"normal\" width=\"large\">\n <div className={classes.ContentGrid} data-testid=\"scrollContainer\">\n {Array.from({\n length: args.numParagraphsInContent,\n }).map((_, i) => {\n const testId = `content${i}`\n return (\n <p key={i} className={classes.Paragraph}>\n <span data-testid={testId}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin\n vitae orci et magna consectetur ullamcorper eget ac purus. Nam\n at enim id lorem tempus egestas a non ipsum. Maecenas\n imperdiet ante quam, at varius lorem molestie vel. Sed at eros\n consequat, varius tellus et, auctor felis. Donec pulvinar\n lacinia urna nec commodo. Phasellus at imperdiet risus. Donec\n sit amet massa purus. Nunc sem lectus, bibendum a sapien nec,\n tristique tempus felis. Ut porttitor auctor tellus in\n imperdiet. Ut blandit tincidunt augue, quis fringilla nunc\n tincidunt sed. Vestibulum auctor euismod nisi. Nullam\n tincidunt est in mi tincidunt dictum. Sed consectetur aliquet\n velit ut ornare.\n </span>\n </p>\n )\n })}\n </div>\n </PageLayout.Content>\n <PageLayout.Pane\n position=\"start\"\n padding=\"normal\"\n divider=\"line\"\n aria-label=\"Aside pane\"\n sticky\n offsetHeader={args.offsetHeader}\n >\n <div className={classes.ContentGrid}>\n {Array.from({\n length: args.numParagraphsInPane,\n }).map((_, i) => {\n const testId = `paragraph${i}`\n return (\n <p key={i} className={classes.Paragraph}>\n <span data-testid={testId}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam\n at enim id lorem tempus egestas a non ipsum. Maecenas\n imperdiet ante quam, at varius lorem molestie vel. Sed at eros\n consequat, varius tellus et, auctor felis. Donec pulvinar\n lacinia urna nec commodo. Phasellus at imperdiet risus. Donec\n sit amet massa purus.\n </span>\n </p>\n )\n })}\n </div>\n </PageLayout.Pane>\n <PageLayout.Footer padding=\"normal\" divider=\"line\">\n <Placeholder label=\"Footer\" height={64} />\n </PageLayout.Footer>\n </PageLayout>\n </div>\n)"
4521
4807
  },
4522
4808
  {
4523
- "id": "components-pagelayout-features--resizable-pane"
4809
+ "id": "components-pagelayout-features--resizable-pane",
4810
+ "code": "() => (\n <PageLayout containerWidth=\"full\">\n <PageLayout.Header>\n <Placeholder height={64} label=\"Header\" />\n </PageLayout.Header>\n <PageLayout.Pane resizable position=\"start\" aria-label=\"Side pane\">\n <Placeholder height={320} label=\"Pane\" />\n </PageLayout.Pane>\n <PageLayout.Content>\n <Placeholder height={640} label=\"Content\" />\n </PageLayout.Content>\n <PageLayout.Footer>\n <Placeholder height={64} label=\"Footer\" />\n </PageLayout.Footer>\n </PageLayout>\n)"
4524
4811
  },
4525
4812
  {
4526
- "id": "components-pagelayout-features--scroll-container-within-page-layout-pane"
4813
+ "id": "components-pagelayout-features--scroll-container-within-page-layout-pane",
4814
+ "code": "() => (\n <div className={classes.NestedScrollContainer}>\n <div className={classes.OverflowAuto}>\n <Placeholder label=\"Above inner scroll container\" height={120} />\n <PageLayout\n rowGap=\"none\"\n columnGap=\"none\"\n padding=\"none\"\n containerWidth=\"full\"\n >\n <PageLayout.Pane\n position=\"start\"\n padding=\"normal\"\n divider=\"line\"\n sticky\n aria-label=\"Sticky pane\"\n >\n <div className={classes.OverflowAuto}>\n <PageLayout.Pane padding=\"normal\" aria-label=\"Side pane\">\n <Placeholder label=\"Inner scroll container\" height={800} />\n </PageLayout.Pane>\n </div>\n </PageLayout.Pane>\n <PageLayout.Content padding=\"normal\" width=\"large\">\n <div\n className={classes.ContentGrid}\n tabIndex={0}\n role=\"region\"\n aria-label=\"Page content\"\n >\n <Placeholder label=\"Page content\" height={1600} />\n </div>\n </PageLayout.Content>\n </PageLayout>\n <Placeholder label=\"Beneath inner scroll container\" height={120} />\n </div>\n </div>\n)"
4527
4815
  },
4528
4816
  {
4529
- "id": "components-pagelayout-features--custom-pane-widths"
4817
+ "id": "components-pagelayout-features--custom-pane-widths",
4818
+ "code": "() => (\n <PageLayout containerWidth=\"full\">\n <PageLayout.Header>\n <Placeholder height={64} label=\"Header\" />\n </PageLayout.Header>\n <PageLayout.Pane\n resizable\n width={{\n min: '200px',\n default: '300px',\n max: '400px',\n }}\n aria-label=\"Side pane\"\n >\n <Placeholder height={320} label=\"Pane\" />\n </PageLayout.Pane>\n <PageLayout.Content>\n <Placeholder height={640} label=\"Content\" />\n </PageLayout.Content>\n <PageLayout.Footer>\n <Placeholder height={64} label=\"Footer\" />\n </PageLayout.Footer>\n </PageLayout>\n)"
4530
4819
  },
4531
4820
  {
4532
- "id": "components-pagelayout-features--with-custom-pane-heading"
4821
+ "id": "components-pagelayout-features--with-custom-pane-heading",
4822
+ "code": "() => (\n <PageLayout containerWidth=\"full\">\n <PageLayout.Header>\n <Placeholder height={64} label=\"Header\" />\n </PageLayout.Header>\n <PageLayout.Pane resizable position=\"start\" aria-label=\"Side pane\">\n <Heading as=\"h2\" className={classes.PaneHeading} id=\"pane-heading\">\n Pane Heading\n </Heading>\n <Placeholder height={320} label=\"Pane\" />\n </PageLayout.Pane>\n <PageLayout.Content>\n <Placeholder height={640} label=\"Content\" />\n </PageLayout.Content>\n <PageLayout.Footer>\n <Placeholder height={64} label=\"Footer\" />\n </PageLayout.Footer>\n </PageLayout>\n)"
4533
4823
  }
4534
4824
  ],
4535
4825
  "importPath": "@primer/react",
@@ -4781,7 +5071,8 @@
4781
5071
  "a11yReviewed": false,
4782
5072
  "stories": [
4783
5073
  {
4784
- "id": "deprecated-components-pagehead--default"
5074
+ "id": "deprecated-components-pagehead--default",
5075
+ "code": "() => (\n <Pagehead>\n <Heading as=\"h2\" variant=\"small\">\n Pagehead\n </Heading>\n </Pagehead>\n)"
4785
5076
  }
4786
5077
  ],
4787
5078
  "importPath": "@primer/react/deprecated",
@@ -4803,19 +5094,24 @@
4803
5094
  "a11yReviewed": "2025-01-08",
4804
5095
  "stories": [
4805
5096
  {
4806
- "id": "components-pagination--default"
5097
+ "id": "components-pagination--default",
5098
+ "code": "() => {\n const [page, setPage] = useState(2)\n return (\n <Pagination\n pageCount={15}\n currentPage={page}\n onPageChange={(e, n) => {\n e.preventDefault()\n setPage(n)\n }}\n showPages={{\n narrow: false,\n }}\n />\n )\n}"
4807
5099
  },
4808
5100
  {
4809
- "id": "components-pagination-features--larger-page-count-margin"
5101
+ "id": "components-pagination-features--larger-page-count-margin",
5102
+ "code": "() => (\n <Pagination\n pageCount={15}\n currentPage={5}\n marginPageCount={4}\n onPageChange={(e) => e.preventDefault()}\n />\n)"
4810
5103
  },
4811
5104
  {
4812
- "id": "components-pagination-features--hide-page-numbers"
5105
+ "id": "components-pagination-features--hide-page-numbers",
5106
+ "code": "() => (\n <Pagination\n pageCount={15}\n currentPage={5}\n showPages={false}\n onPageChange={(e) => e.preventDefault()}\n />\n)"
4813
5107
  },
4814
5108
  {
4815
- "id": "components-pagination-features--hide-page-numbers-by-viewport"
5109
+ "id": "components-pagination-features--hide-page-numbers-by-viewport",
5110
+ "code": "() => (\n <>\n <Pagination\n pageCount={15}\n currentPage={5}\n showPages={{\n narrow: false,\n }}\n onPageChange={(e) => e.preventDefault()}\n />\n <p>Page numbers are hidden on narrow viewports.</p>\n </>\n)"
4816
5111
  },
4817
5112
  {
4818
- "id": "components-pagination-features--higher-surrounding-page-count"
5113
+ "id": "components-pagination-features--higher-surrounding-page-count",
5114
+ "code": "() => (\n <Pagination\n pageCount={15}\n currentPage={5}\n surroundingPageCount={4}\n onPageChange={(e) => e.preventDefault()}\n />\n)"
4819
5115
  }
4820
5116
  ],
4821
5117
  "importPath": "@primer/react",
@@ -4881,7 +5177,8 @@
4881
5177
  "a11yReviewed": "2025-01-08",
4882
5178
  "stories": [
4883
5179
  {
4884
- "id": "components-popover--default"
5180
+ "id": "components-popover--default",
5181
+ "code": "() => (\n <Popover relative open={true} caret=\"top\">\n <Popover.Content\n style={{\n marginTop: 'var(--base-size-8)',\n }}\n >\n <Heading\n style={{\n fontSize: 'var(--text-title-size-small)',\n }}\n >\n Popover heading\n </Heading>\n <Text as=\"p\">Message about popovers</Text>\n <Button>Got it!</Button>\n </Popover.Content>\n </Popover>\n)"
4885
5182
  }
4886
5183
  ],
4887
5184
  "importPath": "@primer/react",
@@ -4961,19 +5258,20 @@
4961
5258
  "a11yReviewed": false,
4962
5259
  "stories": [
4963
5260
  {
4964
- "id": "components-portal--default"
4965
- },
4966
- {
4967
- "id": "behaviors-portal--default"
5261
+ "id": "behaviors-portal--default",
5262
+ "code": "() => (\n <>\n Root position\n <div className={clsx(classes.PortalContainer, classes.OuterContainer)}>\n Outer container\n <div className={clsx(classes.PortalContainer, classes.InnerContainer)}>\n Inner container\n <Portal>\n Portaled content rendered at <code>&lt;BaseStyles&gt;</code> root.\n </Portal>\n </div>\n </div>\n </>\n)"
4968
5263
  },
4969
5264
  {
4970
- "id": "behaviors-portal-features--custom-portal-root-by-id"
5265
+ "id": "behaviors-portal-features--custom-portal-root-by-id",
5266
+ "code": "() => (\n <>\n Root position\n <div\n className={clsx(classes.PortalContainer, classes.OuterContainer)}\n id=\"__primerPortalRoot__\"\n >\n Outer container\n <div className={clsx(classes.PortalContainer, classes.InnerContainer)}>\n Inner container\n <Portal>Portaled content rendered at the outer container.</Portal>\n </div>\n </div>\n </>\n)"
4971
5267
  },
4972
5268
  {
4973
- "id": "behaviors-portal-features--custom-portal-root-by-registration"
5269
+ "id": "behaviors-portal-features--custom-portal-root-by-registration",
5270
+ "code": "() => {\n const outerContainerRef = React.useRef<HTMLDivElement>(null)\n const [mounted, setMounted] = React.useState(false)\n React.useEffect(() => {\n if (outerContainerRef.current instanceof HTMLElement) {\n registerPortalRoot(outerContainerRef.current)\n setMounted(true)\n }\n }, [])\n return (\n <>\n Root position\n <div\n className={clsx(classes.PortalContainer, classes.OuterContainer)}\n ref={outerContainerRef}\n >\n {mounted ? (\n <>\n Outer container\n <div\n className={clsx(classes.PortalContainer, classes.InnerContainer)}\n >\n Inner container\n <Portal>Portaled content rendered at the outer container.</Portal>\n </div>\n </>\n ) : null}\n </div>\n </>\n )\n}"
4974
5271
  },
4975
5272
  {
4976
- "id": "behaviors-portal-features--multiple-portal-roots"
5273
+ "id": "behaviors-portal-features--multiple-portal-roots",
5274
+ "code": "() => {\n const outerContainerRef = React.useRef<HTMLDivElement>(null)\n const innerContainerRef = React.useRef<HTMLDivElement>(null)\n const [mounted, setMounted] = React.useState(false)\n React.useEffect(() => {\n if (\n outerContainerRef.current instanceof HTMLElement &&\n innerContainerRef.current instanceof HTMLElement\n ) {\n registerPortalRoot(outerContainerRef.current, 'outer')\n registerPortalRoot(innerContainerRef.current, 'inner')\n setMounted(true)\n }\n }, [outerContainerRef])\n return (\n <>\n Root position\n <div\n className={clsx(classes.PortalContainer, classes.OuterContainer)}\n ref={outerContainerRef}\n >\n Outer container\n <div\n className={clsx(classes.PortalContainer, classes.InnerContainer)}\n ref={innerContainerRef}\n >\n {mounted ? (\n <>\n <Portal containerName=\"outer\">\n Portaled content rendered at the outer container.\n </Portal>\n <Portal containerName=\"inner\">\n Portaled content rendered at the end of the inner container.\n </Portal>\n <Portal>\n Portaled content rendered at <code>&lt;BaseStyles&gt;</code>{' '}\n root.\n </Portal>\n </>\n ) : null}\n Inner container\n </div>\n </div>\n </>\n )\n}"
4977
5275
  }
4978
5276
  ],
4979
5277
  "importPath": "@primer/react",
@@ -5001,34 +5299,44 @@
5001
5299
  "a11yReviewed": "2025-01-08",
5002
5300
  "stories": [
5003
5301
  {
5004
- "id": "components-progressbar--default"
5302
+ "id": "components-progressbar--default",
5303
+ "code": "() => <ProgressBar aria-label=\"Upload test.png\" />"
5005
5304
  },
5006
5305
  {
5007
- "id": "components-progressbar-features--progress-zero"
5306
+ "id": "components-progressbar-features--progress-zero",
5307
+ "code": "() => <ProgressBar progress=\"0\" aria-label=\"Upload test.png\" />"
5008
5308
  },
5009
5309
  {
5010
- "id": "components-progressbar-features--progress-half"
5310
+ "id": "components-progressbar-features--progress-half",
5311
+ "code": "() => <ProgressBar progress=\"50\" aria-label=\"Upload test.png\" />"
5011
5312
  },
5012
5313
  {
5013
- "id": "components-progressbar-features--progress-done"
5314
+ "id": "components-progressbar-features--progress-done",
5315
+ "code": "() => <ProgressBar progress=\"100\" aria-label=\"Upload test.png\" />"
5014
5316
  },
5015
5317
  {
5016
- "id": "components-progressbar-features--size-small"
5318
+ "id": "components-progressbar-features--size-small",
5319
+ "code": "() => (\n <ProgressBar progress=\"66\" barSize=\"small\" aria-label=\"Upload test.png\" />\n)"
5017
5320
  },
5018
5321
  {
5019
- "id": "components-progressbar-features--size-large"
5322
+ "id": "components-progressbar-features--size-large",
5323
+ "code": "() => (\n <ProgressBar progress=\"66\" barSize=\"large\" aria-label=\"Upload test.png\" />\n)"
5020
5324
  },
5021
5325
  {
5022
- "id": "components-progressbar-features--inline"
5326
+ "id": "components-progressbar-features--inline",
5327
+ "code": "() => (\n <ProgressBar\n inline\n progress=\"66\"\n style={{\n width: '100px',\n }}\n aria-label=\"Upload test.png\"\n />\n)"
5023
5328
  },
5024
5329
  {
5025
- "id": "components-progressbar-features--all-colors"
5330
+ "id": "components-progressbar-features--all-colors",
5331
+ "code": "() => (\n <ProgressBar aria-label=\"Upload test.png\">\n <ProgressBar.Item\n progress={20}\n aria-label=\"Photo Usage\"\n bg=\"accent.emphasis\"\n />\n <ProgressBar.Item\n progress={15}\n aria-label=\"Application Usage\"\n bg=\"danger.emphasis\"\n />\n <ProgressBar.Item\n progress={12}\n aria-label=\"Music Usage\"\n bg=\"severe.emphasis\"\n />\n <ProgressBar.Item\n progress={11}\n aria-label=\"Music Usage\"\n bg=\"done.emphasis\"\n />\n <ProgressBar.Item\n progress={8}\n aria-label=\"Music Usage\"\n bg=\"sponsors.emphasis\"\n />\n <ProgressBar.Item\n progress={7}\n aria-label=\"Music Usage\"\n bg=\"neutral.emphasis\"\n />\n <ProgressBar.Item\n progress={7}\n aria-label=\"Music Usage\"\n bg=\"attention.emphasis\"\n />\n </ProgressBar>\n)"
5026
5332
  },
5027
5333
  {
5028
- "id": "components-progressbar-features--multiple-items"
5334
+ "id": "components-progressbar-features--multiple-items",
5335
+ "code": "() => (\n <ProgressBar>\n <ProgressBar.Item\n progress={33}\n aria-label=\"Photo Usage\"\n bg=\"accent.emphasis\"\n />\n <ProgressBar.Item\n progress={23}\n aria-label=\"Application Usage\"\n bg={'danger.emphasis'}\n />\n <ProgressBar.Item\n progress={14}\n aria-label=\"Music Usage\"\n bg={'severe.emphasis'}\n />\n </ProgressBar>\n)"
5029
5336
  },
5030
5337
  {
5031
- "id": "components-progressbar-features--animated"
5338
+ "id": "components-progressbar-features--animated",
5339
+ "code": "() => <ProgressBar progress=\"50\" aria-label=\"Upload test.png\" animated />"
5032
5340
  }
5033
5341
  ],
5034
5342
  "importPath": "@primer/react",
@@ -5097,16 +5405,20 @@
5097
5405
  "a11yReviewed": "2025-01-08",
5098
5406
  "stories": [
5099
5407
  {
5100
- "id": "components-radio--default"
5408
+ "id": "components-radio--default",
5409
+ "code": "() => (\n <form>\n <FormControl>\n <Radio name=\"default-radio-name\" value=\"default\" />\n <FormControl.Label>Label</FormControl.Label>\n </FormControl>\n </form>\n)"
5101
5410
  },
5102
5411
  {
5103
- "id": "components-radio-features--with-leading-visual"
5412
+ "id": "components-radio-features--with-leading-visual",
5413
+ "code": "() => {\n return (\n <form>\n <FormControl>\n <FormControl.LeadingVisual>\n <MarkGithubIcon />\n </FormControl.LeadingVisual>\n <Radio value=\"default\" name=\"default-radio-name\" />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n <FormControl>\n <FormControl.LeadingVisual>\n <Avatar src={`https://github.com/lukasoppermann.png`} />\n </FormControl.LeadingVisual>\n <Radio value=\"default\" name=\"default-radio-name\" />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n </form>\n )\n}"
5104
5414
  },
5105
5415
  {
5106
- "id": "components-radio-features--disabled"
5416
+ "id": "components-radio-features--disabled",
5417
+ "code": "() => {\n return (\n <form>\n <FormControl disabled>\n <Radio value=\"default\" name=\"default-radio-name\" />\n <FormControl.Label>Default label</FormControl.Label>\n </FormControl>\n </form>\n )\n}"
5107
5418
  },
5108
5419
  {
5109
- "id": "components-radio-features--with-caption"
5420
+ "id": "components-radio-features--with-caption",
5421
+ "code": "() => {\n return (\n <form>\n <FormControl>\n <Radio value=\"default\" name=\"default-radio-name\" />\n <FormControl.Label>Default label</FormControl.Label>\n <FormControl.Caption>This is a caption</FormControl.Caption>\n </FormControl>\n </form>\n )\n}"
5110
5422
  }
5111
5423
  ],
5112
5424
  "importPath": "@primer/react",
@@ -5163,22 +5475,28 @@
5163
5475
  "a11yReviewed": "2025-01-08",
5164
5476
  "stories": [
5165
5477
  {
5166
- "id": "components-radiogroup--default"
5478
+ "id": "components-radiogroup--default",
5479
+ "code": "() => (\n <RadioGroup name=\"defaultRadioGroup\">\n <RadioGroup.Label>Choices</RadioGroup.Label>\n <FormControl>\n <Radio value=\"one\" />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </RadioGroup>\n)"
5167
5480
  },
5168
5481
  {
5169
- "id": "components-radiogroup-features--visually-hidden-label"
5482
+ "id": "components-radiogroup-features--visually-hidden-label",
5483
+ "code": "() => (\n <RadioGroup name=\"defaultRadioGroup\">\n <RadioGroup.Label visuallyHidden>Choices</RadioGroup.Label>\n <FormControl>\n <Radio value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </RadioGroup>\n)"
5170
5484
  },
5171
5485
  {
5172
- "id": "components-radiogroup-features--with-external-label"
5486
+ "id": "components-radiogroup-features--with-external-label",
5487
+ "code": "() => (\n <>\n <div id=\"choiceHeading\" className={classes.ExternalLabel}>\n External label\n </div>\n <RadioGroup aria-labelledby=\"choiceHeading\" name=\"defaultRadioGroup\">\n <FormControl>\n <Radio value=\"one\" />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </RadioGroup>\n </>\n)"
5173
5488
  },
5174
5489
  {
5175
- "id": "components-radiogroup-features--error"
5490
+ "id": "components-radiogroup-features--error",
5491
+ "code": "() => (\n <RadioGroup name=\"defaultRadioGroup\">\n <RadioGroup.Label>Choices</RadioGroup.Label>\n <FormControl>\n <Radio value=\"one\" defaultChecked />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n <RadioGroup.Validation variant=\"error\">\n Something went wrong\n </RadioGroup.Validation>\n </RadioGroup>\n)"
5176
5492
  },
5177
5493
  {
5178
- "id": "components-radiogroup-features--success"
5494
+ "id": "components-radiogroup-features--success",
5495
+ "code": "() => (\n <RadioGroup name=\"defaultRadioGroup\">\n <RadioGroup.Label>Choices</RadioGroup.Label>\n <FormControl>\n <Radio value=\"one\" />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n <RadioGroup.Validation variant=\"success\">Great job!</RadioGroup.Validation>\n </RadioGroup>\n)"
5179
5496
  },
5180
5497
  {
5181
- "id": "components-radiogroup-features--caption"
5498
+ "id": "components-radiogroup-features--caption",
5499
+ "code": "() => (\n <RadioGroup name=\"defaultRadioGroup\">\n <RadioGroup.Label>Choices</RadioGroup.Label>\n <RadioGroup.Caption>Caption</RadioGroup.Caption>\n <FormControl>\n <Radio value=\"one\" />\n <FormControl.Label>Choice one</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"two\" defaultChecked />\n <FormControl.Label>Choice two</FormControl.Label>\n </FormControl>\n <FormControl>\n <Radio value=\"three\" />\n <FormControl.Label>Choice three</FormControl.Label>\n </FormControl>\n </RadioGroup>\n)"
5182
5500
  }
5183
5501
  ],
5184
5502
  "importPath": "@primer/react",
@@ -5279,16 +5597,20 @@
5279
5597
  "a11yReviewed": "2025-01-08",
5280
5598
  "stories": [
5281
5599
  {
5282
- "id": "components-relativetime--default"
5600
+ "id": "components-relativetime--default",
5601
+ "code": "() => <RelativeTime date={new Date('2020-01-01T00:00:00Z')} noTitle={true} />"
5283
5602
  },
5284
5603
  {
5285
- "id": "components-relativetime-features--micro-format"
5604
+ "id": "components-relativetime-features--micro-format",
5605
+ "code": "(args) => {\n const { date, ...rest } = args\n return (\n <RelativeTime\n noTitle={true}\n {...rest}\n date={new Date(date)}\n format=\"micro\"\n />\n )\n}"
5286
5606
  },
5287
5607
  {
5288
- "id": "components-relativetime-features--recent-time"
5608
+ "id": "components-relativetime-features--recent-time",
5609
+ "code": "(args) => {\n const { ...rest } = args\n return <RelativeTime noTitle={true} {...rest} date={new Date()} />\n}"
5289
5610
  },
5290
5611
  {
5291
- "id": "components-relativetime-features--count-down-timer"
5612
+ "id": "components-relativetime-features--count-down-timer",
5613
+ "code": "(args) => {\n const { ...rest } = args\n return <RelativeTime noTitle={true} {...rest} />\n}"
5292
5614
  }
5293
5615
  ],
5294
5616
  "importPath": "@primer/react",
@@ -5434,34 +5756,44 @@
5434
5756
  "a11yReviewed": "2025-01-08",
5435
5757
  "stories": [
5436
5758
  {
5437
- "id": "components-segmentedcontrol--default"
5759
+ "id": "components-segmentedcontrol--default",
5760
+ "code": "() => (\n <SegmentedControl aria-label=\"File view\">\n <SegmentedControl.Button defaultSelected>Preview</SegmentedControl.Button>\n <SegmentedControl.Button>Raw</SegmentedControl.Button>\n <SegmentedControl.Button>Blame</SegmentedControl.Button>\n </SegmentedControl>\n)"
5438
5761
  },
5439
5762
  {
5440
- "id": "components-segmentedcontrol-features--with-icons"
5763
+ "id": "components-segmentedcontrol-features--with-icons",
5764
+ "code": "() => (\n <SegmentedControl aria-label=\"File view\">\n <SegmentedControl.Button\n defaultSelected\n aria-label={'Preview'}\n leadingVisual={EyeIcon}\n >\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Raw'} leadingVisual={FileCodeIcon}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Blame'} leadingVisual={PeopleIcon}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n)"
5441
5765
  },
5442
5766
  {
5443
- "id": "components-segmentedcontrol-features--controlled"
5767
+ "id": "components-segmentedcontrol-features--controlled",
5768
+ "code": "() => {\n const [selectedIndex, setSelectedIndex] = useState(0)\n const handleChange = (i: number) => {\n setSelectedIndex(i)\n }\n return (\n <SegmentedControl aria-label=\"File view\" onChange={handleChange}>\n <SegmentedControl.Button selected={selectedIndex === 0}>\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button selected={selectedIndex === 1}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button selected={selectedIndex === 2}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n )\n}"
5444
5769
  },
5445
5770
  {
5446
- "id": "components-segmentedcontrol-features--variant-narrow-hide-labels"
5771
+ "id": "components-segmentedcontrol-features--variant-narrow-hide-labels",
5772
+ "code": "() => (\n <SegmentedControl\n aria-label=\"File view\"\n variant={{\n narrow: 'hideLabels',\n regular: 'default',\n wide: 'default',\n }}\n >\n <SegmentedControl.Button\n defaultSelected\n aria-label={'Preview'}\n leadingVisual={EyeIcon}\n >\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Raw'} leadingVisual={FileCodeIcon}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Blame'} leadingVisual={PeopleIcon}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n)"
5447
5773
  },
5448
5774
  {
5449
- "id": "components-segmentedcontrol-features--variant-narrow-action-menu"
5775
+ "id": "components-segmentedcontrol-features--variant-narrow-action-menu",
5776
+ "code": "() => (\n <SegmentedControl\n aria-label=\"File view\"\n variant={{\n narrow: 'dropdown',\n regular: 'default',\n wide: 'default',\n }}\n >\n <SegmentedControl.Button\n defaultSelected\n aria-label={'Preview'}\n leadingVisual={EyeIcon}\n >\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Raw'} leadingVisual={FileCodeIcon}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Blame'} leadingVisual={PeopleIcon}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n)"
5450
5777
  },
5451
5778
  {
5452
- "id": "components-segmentedcontrol-features--fullwidth-narrow"
5779
+ "id": "components-segmentedcontrol-features--fullwidth-narrow",
5780
+ "code": "() => (\n <SegmentedControl\n aria-label=\"File view\"\n fullWidth={{\n narrow: true,\n regular: false,\n wide: false,\n }}\n >\n <SegmentedControl.Button\n defaultSelected\n aria-label={'Preview'}\n leadingVisual={EyeIcon}\n >\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Raw'} leadingVisual={FileCodeIcon}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Blame'} leadingVisual={PeopleIcon}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n)"
5453
5781
  },
5454
5782
  {
5455
- "id": "components-segmentedcontrol-features--fullwidth-regular"
5783
+ "id": "components-segmentedcontrol-features--fullwidth-regular",
5784
+ "code": "() => (\n <SegmentedControl\n aria-label=\"File view\"\n fullWidth={{\n narrow: false,\n regular: true,\n wide: false,\n }}\n >\n <SegmentedControl.Button\n defaultSelected\n aria-label={'Preview'}\n leadingVisual={EyeIcon}\n >\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Raw'} leadingVisual={FileCodeIcon}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Blame'} leadingVisual={PeopleIcon}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n)"
5456
5785
  },
5457
5786
  {
5458
- "id": "components-segmentedcontrol-features--fullwidth-all"
5787
+ "id": "components-segmentedcontrol-features--fullwidth-all",
5788
+ "code": "() => (\n <SegmentedControl aria-label=\"File view\" fullWidth>\n <SegmentedControl.Button\n defaultSelected\n aria-label={'Preview'}\n leadingVisual={EyeIcon}\n >\n Preview\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Raw'} leadingVisual={FileCodeIcon}>\n Raw\n </SegmentedControl.Button>\n <SegmentedControl.Button aria-label={'Blame'} leadingVisual={PeopleIcon}>\n Blame\n </SegmentedControl.Button>\n </SegmentedControl>\n)"
5459
5789
  },
5460
5790
  {
5461
- "id": "components-segmentedcontrol-features--icon-only"
5791
+ "id": "components-segmentedcontrol-features--icon-only",
5792
+ "code": "() => (\n <SegmentedControl aria-label=\"File view\">\n <SegmentedControl.IconButton\n defaultSelected\n aria-label={'Preview'}\n icon={EyeIcon}\n />\n <SegmentedControl.IconButton aria-label={'Raw'} icon={FileCodeIcon} />\n <SegmentedControl.IconButton aria-label={'Blame'} icon={PeopleIcon} />\n </SegmentedControl>\n)"
5462
5793
  },
5463
5794
  {
5464
- "id": "components-segmentedcontrol-features--associated-with-a-label-and-caption"
5795
+ "id": "components-segmentedcontrol-features--associated-with-a-label-and-caption",
5796
+ "code": "() => (\n <div className={classes.LabelAndCaptionContainer}>\n <div className={classes.LabelAndCaption}>\n <Text\n className={classes.TextLargeBold}\n id=\"scLabel-vert\"\n style={{\n display: 'block',\n }}\n >\n File view\n </Text>\n <Text\n className={classes.TextMediumSubtle}\n id=\"scCaption-vert\"\n style={{\n display: 'block',\n }}\n >\n Change the way the file is viewed\n </Text>\n </div>\n <SegmentedControl\n aria-labelledby=\"scLabel-vert\"\n aria-describedby=\"scCaption-vert\"\n >\n <SegmentedControl.Button defaultSelected>Preview</SegmentedControl.Button>\n <SegmentedControl.Button>Raw</SegmentedControl.Button>\n <SegmentedControl.Button>Blame</SegmentedControl.Button>\n </SegmentedControl>\n </div>\n)"
5465
5797
  }
5466
5798
  ],
5467
5799
  "importPath": "@primer/react",
@@ -5617,40 +5949,52 @@
5617
5949
  "a11yReviewed": "2025-01-08",
5618
5950
  "stories": [
5619
5951
  {
5620
- "id": "components-select--default"
5952
+ "id": "components-select--default",
5953
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5621
5954
  },
5622
5955
  {
5623
- "id": "components-select-features--with-option-groups"
5956
+ "id": "components-select-features--with-option-groups",
5957
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select>\n <Select.OptGroup label=\"Group one\">\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n </Select.OptGroup>\n <Select.OptGroup disabled label=\"Group two\">\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select.OptGroup>\n </Select>\n </FormControl>\n </form>\n)"
5624
5958
  },
5625
5959
  {
5626
- "id": "components-select-features--disabled"
5960
+ "id": "components-select-features--disabled",
5961
+ "code": "() => (\n <form>\n <FormControl disabled>\n <FormControl.Label>Default label</FormControl.Label>\n <Select>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5627
5962
  },
5628
5963
  {
5629
- "id": "components-select-features--with-caption"
5964
+ "id": "components-select-features--with-caption",
5965
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <FormControl.Caption>This is a caption</FormControl.Caption>\n <Select>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5630
5966
  },
5631
5967
  {
5632
- "id": "components-select-features--visually-hidden-label"
5968
+ "id": "components-select-features--visually-hidden-label",
5969
+ "code": "() => (\n <form>\n <Heading as=\"h2\" variant=\"small\">\n Primer form title\n </Heading>\n <FormControl>\n <FormControl.Label visuallyHidden>Primer form label</FormControl.Label>\n <Select>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n <FormControl.Caption>\n Label is visually hidden; the title describes the purpose visually\n </FormControl.Caption>\n </FormControl>\n </form>\n)"
5633
5970
  },
5634
5971
  {
5635
- "id": "components-select-features--error"
5972
+ "id": "components-select-features--error",
5973
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n <FormControl.Validation variant=\"error\">\n Something went wrong\n </FormControl.Validation>\n </FormControl>\n </form>\n)"
5636
5974
  },
5637
5975
  {
5638
- "id": "components-select-features--success"
5976
+ "id": "components-select-features--success",
5977
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n <FormControl.Validation variant=\"success\">Success</FormControl.Validation>\n </FormControl>\n </form>\n)"
5639
5978
  },
5640
5979
  {
5641
- "id": "components-select-features--block"
5980
+ "id": "components-select-features--block",
5981
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select block>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5642
5982
  },
5643
5983
  {
5644
- "id": "components-select-features--small"
5984
+ "id": "components-select-features--small",
5985
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select size=\"small\">\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5645
5986
  },
5646
5987
  {
5647
- "id": "components-select-features--large"
5988
+ "id": "components-select-features--large",
5989
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select size=\"large\">\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5648
5990
  },
5649
5991
  {
5650
- "id": "components-select-features--with-custom-styling"
5992
+ "id": "components-select-features--with-custom-styling",
5993
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select className={classes.CustomSelect}>\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5651
5994
  },
5652
5995
  {
5653
- "id": "components-select-features--with-placeholder-option"
5996
+ "id": "components-select-features--with-placeholder-option",
5997
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Select placeholder=\"No choice selected\">\n <Select.Option value=\"one\">Choice one</Select.Option>\n <Select.Option value=\"two\">Choice two</Select.Option>\n <Select.Option value=\"three\">Choice three</Select.Option>\n <Select.Option value=\"four\">Choice four</Select.Option>\n <Select.Option value=\"five\">Choice five</Select.Option>\n <Select.Option value=\"six\">Choice six</Select.Option>\n </Select>\n </FormControl>\n </form>\n)"
5654
5998
  }
5655
5999
  ],
5656
6000
  "importPath": "@primer/react",
@@ -5697,31 +6041,40 @@
5697
6041
  "a11yReviewed": "2025-01-08",
5698
6042
  "stories": [
5699
6043
  {
5700
- "id": "components-selectpanel--default"
6044
+ "id": "components-selectpanel--default",
6045
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text?.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <SelectPanel\n title=\"Select labels\"\n placeholder=\"Select labels\" // button text when no items are selected\n subtitle=\"Use labels to organize issues and pull requests\"\n renderAnchor={({ children, ...anchorProps }) => (\n <Button\n trailingAction={TriangleDownIcon}\n {...anchorProps}\n aria-haspopup=\"dialog\"\n >\n {children}\n </Button>\n )}\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n width=\"medium\"\n message={\n filteredItems.length === 0\n ? {\n variant: 'empty',\n title: 'No items available',\n body: '',\n }\n : undefined\n }\n />\n </FormControl>\n )\n}"
5701
6046
  },
5702
6047
  {
5703
- "id": "components-selectpanel-features--with-item-dividers"
6048
+ "id": "components-selectpanel-features--with-item-dividers",
6049
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <SelectPanel\n title=\"Select labels\"\n placeholder=\"Select labels\" // button text when no items are selected\n subtitle=\"Use labels to organize issues and pull requests\"\n renderAnchor={({ children, ...anchorProps }) => (\n <Button\n trailingAction={TriangleDownIcon}\n {...anchorProps}\n aria-haspopup=\"dialog\"\n >\n {children}\n </Button>\n )}\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n showItemDividers={true}\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5704
6050
  },
5705
6051
  {
5706
- "id": "components-selectpanel-features--with-placeholder-for-search-input"
6052
+ "id": "components-selectpanel-features--with-placeholder-for-search-input",
6053
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <SelectPanel\n title=\"Select labels\"\n placeholder=\"Select labels\" // button text when no items are selected\n subtitle=\"Use labels to organize issues and pull requests\"\n renderAnchor={({ children, ...anchorProps }) => (\n <Button\n trailingAction={TriangleDownIcon}\n {...anchorProps}\n aria-haspopup=\"dialog\"\n >\n {children}\n </Button>\n )}\n placeholderText=\"Filter labels\"\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5707
6054
  },
5708
6055
  {
5709
- "id": "components-selectpanel-features--single-select"
6056
+ "id": "components-selectpanel-features--single-select",
6057
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput | undefined>(items[0])\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Label</FormControl.Label>\n <SelectPanel\n renderAnchor={({ children, ...anchorProps }) => (\n <Button trailingAction={TriangleDownIcon} {...anchorProps}>\n {children ?? 'Select Labels'}\n </Button>\n )}\n placeholder=\"Select labels\" // button text when no items are selected\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5710
6058
  },
5711
6059
  {
5712
- "id": "components-selectpanel-features--multi-select"
6060
+ "id": "components-selectpanel-features--multi-select",
6061
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <SelectPanel\n title=\"Select labels\"\n placeholder=\"Select labels\"\n subtitle=\"Use labels to organize issues and pull requests\"\n renderAnchor={({ children, ...anchorProps }) => (\n <Button\n trailingAction={TriangleDownIcon}\n {...anchorProps}\n aria-haspopup=\"dialog\"\n >\n {children}\n </Button>\n )}\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5713
6062
  },
5714
6063
  {
5715
- "id": "components-selectpanel-features--with-external-anchor"
6064
+ "id": "components-selectpanel-features--with-external-anchor",
6065
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n const buttonRef = useRef<HTMLButtonElement>(null)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <Button\n trailingAction={TriangleDownIcon}\n ref={buttonRef}\n onClick={() => setOpen(!open)}\n >\n {selected.map((selectedItem) => selectedItem.text).join(', ') ||\n 'Select labels'}\n </Button>\n <SelectPanel\n renderAnchor={null}\n anchorRef={buttonRef}\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={filteredItems}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5716
6066
  },
5717
6067
  {
5718
- "id": "components-selectpanel-features--with-secondary-action-button"
6068
+ "id": "components-selectpanel-features--with-secondary-action-button",
6069
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <SelectPanel\n renderAnchor={({ children, ...anchorProps }) => (\n <Button trailingAction={TriangleDownIcon} {...anchorProps}>\n {children}\n </Button>\n )}\n placeholder=\"Select labels\" // button text when no items are selected\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n overlayProps={{\n width: 'small',\n height: 'medium',\n }}\n secondaryAction={\n <SelectPanel.SecondaryActionButton>\n Edit labels\n </SelectPanel.SecondaryActionButton>\n }\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5719
6070
  },
5720
6071
  {
5721
- "id": "components-selectpanel-features--with-secondary-action-link"
6072
+ "id": "components-selectpanel-features--with-secondary-action-link",
6073
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))\n const [filter, setFilter] = useState('')\n const filteredItems = items.filter((item) =>\n item.text.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Labels</FormControl.Label>\n <SelectPanel\n renderAnchor={({ children, ...anchorProps }) => (\n <Button trailingAction={TriangleDownIcon} {...anchorProps}>\n {children}\n </Button>\n )}\n placeholder=\"Select labels\" // button text when no items are selected\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n overlayProps={{\n width: 'small',\n height: 'medium',\n }}\n secondaryAction={\n <SelectPanel.SecondaryActionLink href=\"#\">\n Edit labels\n </SelectPanel.SecondaryActionLink>\n }\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5722
6074
  },
5723
6075
  {
5724
- "id": "components-selectpanel-features--with-groups"
6076
+ "id": "components-selectpanel-features--with-groups",
6077
+ "code": "() => {\n const [selected, setSelected] = useState<ItemInput[]>([])\n const [filter, setFilter] = useState('')\n const filteredItems = listOfItems.filter((item) =>\n item.text?.toLowerCase().startsWith(filter.toLowerCase()),\n )\n const [open, setOpen] = useState(false)\n return (\n <FormControl>\n <FormControl.Label>Options</FormControl.Label>\n <SelectPanel\n title=\"Attach files and symbols\"\n subtitle=\"Choose which files and symbols you want to chat about. Use fewer references for more accurate responses.\"\n renderAnchor={({ children, ...anchorProps }) => (\n <Button trailingAction={TriangleDownIcon} {...anchorProps}>\n {children}\n </Button>\n )}\n placeholder=\"Select options\" // button text when no items are selected\n groupMetadata={groupMetadata}\n open={open}\n onOpenChange={setOpen}\n items={filteredItems}\n selected={selected}\n onSelectedChange={setSelected}\n onFilterChange={setFilter}\n overlayProps={{\n width: 'large',\n height: 'xlarge',\n }}\n width=\"medium\"\n message={\n filteredItems.length === 0 ? NoResultsMessage(filter) : undefined\n }\n />\n </FormControl>\n )\n}"
5725
6078
  }
5726
6079
  ],
5727
6080
  "importPath": "@primer/react",
@@ -5928,16 +6281,16 @@
5928
6281
  "a11yReviewed": "2025-01-08",
5929
6282
  "stories": [
5930
6283
  {
5931
- "id": "components-skeletonbox--default"
5932
- },
5933
- {
5934
- "id": "components-skeleton-skeletonbox--default"
6284
+ "id": "components-skeleton-skeletonbox--default",
6285
+ "code": "() => <SkeletonBox />"
5935
6286
  },
5936
6287
  {
5937
- "id": "components-skeleton-skeletonbox-features--custom-height"
6288
+ "id": "components-skeleton-skeletonbox-features--custom-height",
6289
+ "code": "() => <SkeletonBox height=\"4rem\" />"
5938
6290
  },
5939
6291
  {
5940
- "id": "components-skeleton-skeletonbox-features--custom-width"
6292
+ "id": "components-skeleton-skeletonbox-features--custom-width",
6293
+ "code": "() => <SkeletonBox width=\"300px\" />"
5941
6294
  }
5942
6295
  ],
5943
6296
  "importPath": "@primer/react",
@@ -5970,22 +6323,24 @@
5970
6323
  "a11yReviewed": "2025-01-08",
5971
6324
  "stories": [
5972
6325
  {
5973
- "id": "components-skeletonavatar--default"
5974
- },
5975
- {
5976
- "id": "components-skeleton-skeletonavatar--default"
6326
+ "id": "components-skeleton-skeletonavatar--default",
6327
+ "code": "() => <SkeletonAvatar />"
5977
6328
  },
5978
6329
  {
5979
- "id": "components-skeleton-skeletonavatar-features--square"
6330
+ "id": "components-skeleton-skeletonavatar-features--square",
6331
+ "code": "() => <SkeletonAvatar square />"
5980
6332
  },
5981
6333
  {
5982
- "id": "components-skeleton-skeletonavatar-features--size"
6334
+ "id": "components-skeleton-skeletonavatar-features--size",
6335
+ "code": "() => (\n <div>\n <SkeletonAvatar size={4} />\n <SkeletonAvatar size={8} />\n <SkeletonAvatar size={12} />\n <SkeletonAvatar size={16} />\n <SkeletonAvatar size={20} />\n <SkeletonAvatar size={24} />\n <SkeletonAvatar size={28} />\n <SkeletonAvatar size={32} />\n <SkeletonAvatar size={40} />\n <SkeletonAvatar size={48} />\n <SkeletonAvatar size={56} />\n <SkeletonAvatar size={64} />\n </div>\n)"
5983
6336
  },
5984
6337
  {
5985
- "id": "components-skeleton-skeletonavatar-features--size-responsive"
6338
+ "id": "components-skeleton-skeletonavatar-features--size-responsive",
6339
+ "code": "() => (\n <div>\n <SkeletonAvatar\n size={{\n narrow: 4,\n regular: 8,\n wide: 12,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 8,\n regular: 12,\n wide: 16,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 12,\n regular: 16,\n wide: 20,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 16,\n regular: 20,\n wide: 24,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 20,\n regular: 24,\n wide: 28,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 24,\n regular: 28,\n wide: 32,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 28,\n regular: 32,\n wide: 40,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 32,\n regular: 40,\n wide: 48,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 40,\n regular: 48,\n wide: 56,\n }}\n />\n <SkeletonAvatar\n size={{\n narrow: 48,\n regular: 56,\n wide: 64,\n }}\n />\n </div>\n)"
5986
6340
  },
5987
6341
  {
5988
- "id": "components-skeleton-skeletonavatar-features--in-a-stack"
6342
+ "id": "components-skeleton-skeletonavatar-features--in-a-stack",
6343
+ "code": "() => (\n <AvatarStack>\n <SkeletonAvatar />\n <SkeletonAvatar />\n <SkeletonAvatar />\n <SkeletonAvatar />\n </AvatarStack>\n)"
5989
6344
  }
5990
6345
  ],
5991
6346
  "importPath": "@primer/react/experimental",
@@ -6018,40 +6373,48 @@
6018
6373
  "a11yReviewed": "2025-01-08",
6019
6374
  "stories": [
6020
6375
  {
6021
- "id": "components-skeletontext--default"
6376
+ "id": "components-skeleton-skeletontext--default",
6377
+ "code": "() => <SkeletonText />"
6022
6378
  },
6023
6379
  {
6024
- "id": "components-skeleton-skeletontext--default"
6380
+ "id": "components-skeleton-skeletontext-features--with-max-width",
6381
+ "code": "() => <SkeletonText maxWidth={200} />"
6025
6382
  },
6026
6383
  {
6027
- "id": "components-skeleton-skeletontext-features--with-max-width"
6384
+ "id": "components-skeleton-skeletontext-features--with-multiple-lines",
6385
+ "code": "() => <SkeletonText lines={3} />"
6028
6386
  },
6029
6387
  {
6030
- "id": "components-skeleton-skeletontext-features--with-multiple-lines"
6388
+ "id": "components-skeleton-skeletontext-features--display",
6389
+ "code": "() => <SkeletonText size=\"display\" />"
6031
6390
  },
6032
6391
  {
6033
- "id": "components-skeleton-skeletontext-features--display"
6392
+ "id": "components-skeleton-skeletontext-features--subtitle",
6393
+ "code": "() => <SkeletonText size=\"subtitle\" />"
6034
6394
  },
6035
6395
  {
6036
- "id": "components-skeleton-skeletontext-features--subtitle"
6396
+ "id": "components-skeleton-skeletontext-features--title-large",
6397
+ "code": "() => <SkeletonText size=\"titleLarge\" />"
6037
6398
  },
6038
6399
  {
6039
- "id": "components-skeleton-skeletontext-features--title-large"
6400
+ "id": "components-skeleton-skeletontext-features--title-medium",
6401
+ "code": "() => <SkeletonText size=\"titleMedium\" />"
6040
6402
  },
6041
6403
  {
6042
- "id": "components-skeleton-skeletontext-features--title-medium"
6404
+ "id": "components-skeleton-skeletontext-features--title-small",
6405
+ "code": "() => <SkeletonText size=\"titleSmall\" />"
6043
6406
  },
6044
6407
  {
6045
- "id": "components-skeleton-skeletontext-features--title-small"
6408
+ "id": "components-skeleton-skeletontext-features--body-large",
6409
+ "code": "() => <SkeletonText size=\"bodyLarge\" />"
6046
6410
  },
6047
6411
  {
6048
- "id": "components-skeleton-skeletontext-features--body-large"
6412
+ "id": "components-skeleton-skeletontext-features--body-medium",
6413
+ "code": "() => <SkeletonText size=\"bodyMedium\" />"
6049
6414
  },
6050
6415
  {
6051
- "id": "components-skeleton-skeletontext-features--body-medium"
6052
- },
6053
- {
6054
- "id": "components-skeleton-skeletontext-features--body-small"
6416
+ "id": "components-skeleton-skeletontext-features--body-small",
6417
+ "code": "() => <SkeletonText size=\"bodySmall\" />"
6055
6418
  }
6056
6419
  ],
6057
6420
  "importPath": "@primer/react/experimental",
@@ -6125,19 +6488,24 @@
6125
6488
  "status": "alpha",
6126
6489
  "stories": [
6127
6490
  {
6128
- "id": "components-spinner--default"
6491
+ "id": "components-spinner--default",
6492
+ "code": "() => <Spinner />"
6129
6493
  },
6130
6494
  {
6131
- "id": "components-spinner-features--small"
6495
+ "id": "components-spinner-features--small",
6496
+ "code": "() => <Spinner size=\"small\" />"
6132
6497
  },
6133
6498
  {
6134
- "id": "components-spinner-features--large"
6499
+ "id": "components-spinner-features--large",
6500
+ "code": "() => <Spinner size=\"large\" />"
6135
6501
  },
6136
6502
  {
6137
- "id": "components-spinner-features--suppress-screen-reader-text"
6503
+ "id": "components-spinner-features--suppress-screen-reader-text",
6504
+ "code": "() => (\n <Stack direction=\"horizontal\" className={classes.SuppressScreenReaderText}>\n <Spinner size=\"small\" srText={null} />\n <AriaStatus>Loading...</AriaStatus>\n </Stack>\n)"
6138
6505
  },
6139
6506
  {
6140
- "id": "components-spinner-features--with-delay"
6507
+ "id": "components-spinner-features--with-delay",
6508
+ "code": "() => <Spinner delay />"
6141
6509
  }
6142
6510
  ],
6143
6511
  "subcomponents": []
@@ -6150,10 +6518,12 @@
6150
6518
  "a11yReviewed": "2025-01-08",
6151
6519
  "stories": [
6152
6520
  {
6153
- "id": "components-splitpagelayout--default"
6521
+ "id": "components-splitpagelayout--default",
6522
+ "code": "() => (\n <SplitPageLayout>\n <SplitPageLayout.Header>\n <Placeholder label=\"Header\" height={100} />\n </SplitPageLayout.Header>\n <SplitPageLayout.Pane position=\"start\" aria-label=\"Pane\">\n <Placeholder label=\"Pane\" height={400} />\n </SplitPageLayout.Pane>\n <SplitPageLayout.Content>\n <Placeholder label=\"Content\" height={600} />\n </SplitPageLayout.Content>\n <SplitPageLayout.Footer>\n <Placeholder label=\"Footer\" height={100} />\n </SplitPageLayout.Footer>\n </SplitPageLayout>\n)"
6154
6523
  },
6155
6524
  {
6156
- "id": "components-splitpagelayout-features--settings-page"
6525
+ "id": "components-splitpagelayout-features--settings-page",
6526
+ "code": "() => (\n <SplitPageLayout>\n <SplitPageLayout.Pane position=\"start\" aria-label=\"Navigation Pane\">\n <NavList aria-label=\"Main navigation\">\n <NavList.Item href=\"#\">Profile</NavList.Item>\n <NavList.Item href=\"#\" aria-current=\"page\">\n Account\n </NavList.Item>\n <NavList.Item href=\"#\">Emails</NavList.Item>\n <NavList.Item href=\"#\">Notifications</NavList.Item>\n </NavList>\n </SplitPageLayout.Pane>\n <SplitPageLayout.Content>\n <Heading as=\"h2\" className={classes.SectionHeading}>\n Danger zone\n </Heading>\n <div className={classes.DeleteAccountContainer}>\n <div className={classes.DeleteAccountTextContainer}>\n <Text className={classes.DeleteAccountTitle}>Delete account</Text>\n <Text className={classes.DeleteAccountDescription}>\n Are you sure you don&apos;t want to just downgrade your account to a\n free account? We won&apos;t charge your credit card anymore.\n </Text>\n </div>\n <Button variant=\"danger\">Delete account</Button>\n </div>\n </SplitPageLayout.Content>\n </SplitPageLayout>\n)"
6157
6527
  }
6158
6528
  ],
6159
6529
  "importPath": "@primer/react",
@@ -6360,10 +6730,12 @@
6360
6730
  "a11yReviewed": "2025-01-08",
6361
6731
  "stories": [
6362
6732
  {
6363
- "id": "components-stack--default"
6733
+ "id": "components-stack--default",
6734
+ "code": "() => (\n <Stack>\n <div\n style={{\n background: 'var(--display-lemon-bgColor-muted)',\n borderRadius: 'var(--borderRadius-medium)',\n padding: 'var(--base-size-8)',\n }}\n >\n First\n </div>\n <div\n style={{\n background: 'var(--display-olive-bgColor-muted)',\n borderRadius: 'var(--borderRadius-medium)',\n padding: 'var(--base-size-8)',\n }}\n >\n Second\n </div>\n <div\n style={{\n background: 'var(--display-lime-bgColor-muted)',\n borderRadius: 'var(--borderRadius-medium)',\n padding: 'var(--base-size-8)',\n }}\n >\n Third\n </div>\n </Stack>\n)"
6364
6735
  },
6365
6736
  {
6366
- "id": "components-stack-features--shrinking-stack-items"
6737
+ "id": "components-stack-features--shrinking-stack-items",
6738
+ "code": "() => (\n <div\n style={{\n maxWidth: '200px',\n padding: 'var(--base-size-8)',\n }}\n >\n <Stack direction=\"horizontal\" gap=\"condensed\">\n <Stack.Item shrink={false}>\n <ShieldLockIcon size=\"small\" />\n </Stack.Item>\n <Stack.Item>\n This stack has the leading icon set to prevent shrinking\n </Stack.Item>\n </Stack>\n <Stack direction=\"horizontal\" gap=\"condensed\">\n <Stack.Item shrink={true}>\n <ShieldLockIcon size=\"small\" />\n </Stack.Item>\n <Stack.Item>\n This stack item does not have the icon set to prevent shrinking\n </Stack.Item>\n </Stack>\n </div>\n)"
6367
6739
  }
6368
6740
  ],
6369
6741
  "importPath": "@primer/react",
@@ -6433,46 +6805,56 @@
6433
6805
  "a11yReviewed": "2025-01-08",
6434
6806
  "stories": [
6435
6807
  {
6436
- "id": "components-statelabel--default"
6437
- },
6438
- {
6439
- "id": "components-statelabel-features--issue-opened"
6808
+ "id": "components-statelabel-features--issue-opened",
6809
+ "code": "() => <StateLabel status=\"issueOpened\">Open</StateLabel>"
6440
6810
  },
6441
6811
  {
6442
- "id": "components-statelabel-features--issue-closed"
6812
+ "id": "components-statelabel-features--issue-closed",
6813
+ "code": "() => <StateLabel status=\"issueClosed\">Closed</StateLabel>"
6443
6814
  },
6444
6815
  {
6445
- "id": "components-statelabel-features--issue-closed-not-planned"
6816
+ "id": "components-statelabel-features--issue-closed-not-planned",
6817
+ "code": "() => <StateLabel status=\"issueClosedNotPlanned\">Closed</StateLabel>"
6446
6818
  },
6447
6819
  {
6448
- "id": "components-statelabel-features--issue-draft"
6820
+ "id": "components-statelabel-features--issue-draft",
6821
+ "code": "() => <StateLabel status=\"issueDraft\">Draft</StateLabel>"
6449
6822
  },
6450
6823
  {
6451
- "id": "components-statelabel-features--pull-opened"
6824
+ "id": "components-statelabel-features--pull-opened",
6825
+ "code": "() => <StateLabel status=\"pullOpened\">Open</StateLabel>"
6452
6826
  },
6453
6827
  {
6454
- "id": "components-statelabel-features--pull-closed"
6828
+ "id": "components-statelabel-features--pull-closed",
6829
+ "code": "() => <StateLabel status=\"pullClosed\">Closed</StateLabel>"
6455
6830
  },
6456
6831
  {
6457
- "id": "components-statelabel-features--pull-merged"
6832
+ "id": "components-statelabel-features--pull-merged",
6833
+ "code": "() => <StateLabel status=\"pullMerged\">Merged</StateLabel>"
6458
6834
  },
6459
6835
  {
6460
- "id": "components-statelabel-features--queued"
6836
+ "id": "components-statelabel-features--queued",
6837
+ "code": "() => <StateLabel status=\"pullQueued\">Queued</StateLabel>"
6461
6838
  },
6462
6839
  {
6463
- "id": "components-statelabel-features--draft"
6840
+ "id": "components-statelabel-features--draft",
6841
+ "code": "() => <StateLabel status=\"draft\">Draft</StateLabel>"
6464
6842
  },
6465
6843
  {
6466
- "id": "components-statelabel-features--unavailable"
6844
+ "id": "components-statelabel-features--unavailable",
6845
+ "code": "() => <StateLabel status=\"unavailable\">Unavailable</StateLabel>"
6467
6846
  },
6468
6847
  {
6469
- "id": "components-statelabel-features--small"
6848
+ "id": "components-statelabel-features--small",
6849
+ "code": "() => (\n <StateLabel status=\"issueOpened\" size=\"small\">\n Open\n </StateLabel>\n)"
6470
6850
  },
6471
6851
  {
6472
- "id": "components-statelabel-features--open"
6852
+ "id": "components-statelabel-features--open",
6853
+ "code": "() => (\n <StateLabel status=\"open\">\n {/* Because open is a generic status, a visually hidden text could be added to specify the type of the artifact */}\n <VisuallyHidden>Milestone</VisuallyHidden>\n Open\n </StateLabel>\n)"
6473
6854
  },
6474
6855
  {
6475
- "id": "components-statelabel-features--closed"
6856
+ "id": "components-statelabel-features--closed",
6857
+ "code": "() => <StateLabel status=\"closed\">Closed</StateLabel>"
6476
6858
  }
6477
6859
  ],
6478
6860
  "importPath": "@primer/react",
@@ -6498,10 +6880,8 @@
6498
6880
  "a11yReviewed": "2025-01-08",
6499
6881
  "stories": [
6500
6882
  {
6501
- "id": "components-subnav--default"
6502
- },
6503
- {
6504
- "id": "components-subnav-features--selected"
6883
+ "id": "components-subnav-features--selected",
6884
+ "code": "() => (\n <SubNav aria-label=\"Main\">\n <SubNav.Links>\n <SubNav.Link href=\"#home\" selected>\n Home\n </SubNav.Link>\n <SubNav.Link href=\"#documentation\">Documentation</SubNav.Link>\n <SubNav.Link href=\"#support\">Support</SubNav.Link>\n </SubNav.Links>\n </SubNav>\n)"
6505
6885
  }
6506
6886
  ],
6507
6887
  "importPath": "@primer/react",
@@ -6572,10 +6952,12 @@
6572
6952
  "a11yReviewed": false,
6573
6953
  "stories": [
6574
6954
  {
6575
- "id": "deprecated-components-tabnav--default"
6955
+ "id": "deprecated-components-tabnav--default",
6956
+ "code": "() => (\n <TabNav aria-label=\"Main\">\n <TabNav.Link href=\"#\" selected>\n Home\n </TabNav.Link>\n <TabNav.Link href=\"#\">Documentation</TabNav.Link>\n <TabNav.Link href=\"#\">Support</TabNav.Link>\n </TabNav>\n)"
6576
6957
  },
6577
6958
  {
6578
- "id": "deprecated-components-tabnav-features--selected"
6959
+ "id": "deprecated-components-tabnav-features--selected",
6960
+ "code": "() => (\n <TabNav aria-label=\"Main\">\n <TabNav.Link href=\"#\">Home</TabNav.Link>\n <TabNav.Link href=\"#\" selected>\n Documentation\n </TabNav.Link>\n <TabNav.Link href=\"#\">Support</TabNav.Link>\n </TabNav>\n)"
6579
6961
  }
6580
6962
  ],
6581
6963
  "importPath": "@primer/react/deprecated",
@@ -6620,34 +7002,44 @@
6620
7002
  "a11yReviewed": "2025-01-08",
6621
7003
  "stories": [
6622
7004
  {
6623
- "id": "components-text--default"
7005
+ "id": "components-text--default",
7006
+ "code": "() => <Text>Default Text</Text>"
6624
7007
  },
6625
7008
  {
6626
- "id": "components-text-features--polymorphism"
7009
+ "id": "components-text-features--polymorphism",
7010
+ "code": "() => (\n <div className={classes.PolymorphismContainer}>\n <Text as=\"em\">Emphasized text</Text>\n <Text as=\"i\">Italicized text</Text>\n <Text as=\"strong\">Strong text</Text>\n <Text as=\"small\">Small text</Text>\n <Text as=\"u\">Text with underline</Text>\n </div>\n)"
6627
7011
  },
6628
7012
  {
6629
- "id": "components-text-features--styled-text"
7013
+ "id": "components-text-features--styled-text",
7014
+ "code": "() => (\n <Text as=\"p\" className={classes.StyledText} size=\"small\">\n Stylized text\n </Text>\n)"
6630
7015
  },
6631
7016
  {
6632
- "id": "components-text-features--size-small"
7017
+ "id": "components-text-features--size-small",
7018
+ "code": "() => (\n <Text as=\"span\" size=\"small\">\n Stylized text\n </Text>\n)"
6633
7019
  },
6634
7020
  {
6635
- "id": "components-text-features--size-medium"
7021
+ "id": "components-text-features--size-medium",
7022
+ "code": "() => (\n <Text as=\"span\" size=\"medium\">\n Stylized text\n </Text>\n)"
6636
7023
  },
6637
7024
  {
6638
- "id": "components-text-features--size-large"
7025
+ "id": "components-text-features--size-large",
7026
+ "code": "() => (\n <Text as=\"span\" size=\"large\">\n Stylized text\n </Text>\n)"
6639
7027
  },
6640
7028
  {
6641
- "id": "components-text-features--light-weight"
7029
+ "id": "components-text-features--light-weight",
7030
+ "code": "() => (\n <Text as=\"span\" weight=\"light\">\n Stylized text\n </Text>\n)"
6642
7031
  },
6643
7032
  {
6644
- "id": "components-text-features--normal-weight"
7033
+ "id": "components-text-features--normal-weight",
7034
+ "code": "() => (\n <Text as=\"span\" weight=\"normal\">\n Stylized text\n </Text>\n)"
6645
7035
  },
6646
7036
  {
6647
- "id": "components-text-features--medium-weight"
7037
+ "id": "components-text-features--medium-weight",
7038
+ "code": "() => (\n <Text as=\"span\" weight=\"medium\">\n Stylized text\n </Text>\n)"
6648
7039
  },
6649
7040
  {
6650
- "id": "components-text-features--semibold-weight"
7041
+ "id": "components-text-features--semibold-weight",
7042
+ "code": "() => (\n <Text as=\"span\" weight=\"semibold\">\n Stylized text\n </Text>\n)"
6651
7043
  }
6652
7044
  ],
6653
7045
  "importPath": "@primer/react",
@@ -6680,52 +7072,68 @@
6680
7072
  "a11yReviewed": "2025-01-08",
6681
7073
  "stories": [
6682
7074
  {
6683
- "id": "components-textinput--default"
7075
+ "id": "components-textinput--default",
7076
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput />\n </FormControl>\n </form>\n)"
6684
7077
  },
6685
7078
  {
6686
- "id": "components-textinput-features--disabled"
7079
+ "id": "components-textinput-features--disabled",
7080
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput disabled />\n </FormControl>\n </form>\n)"
6687
7081
  },
6688
7082
  {
6689
- "id": "components-textinput-features--with-caption"
7083
+ "id": "components-textinput-features--with-caption",
7084
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <FormControl.Caption>This is a caption</FormControl.Caption>\n <TextInput />\n </FormControl>\n </form>\n)"
6690
7085
  },
6691
7086
  {
6692
- "id": "components-textinput-features--visually-hidden-label"
7087
+ "id": "components-textinput-features--visually-hidden-label",
7088
+ "code": "() => (\n <form>\n <Heading as=\"h2\" variant=\"small\">\n Primer form title\n </Heading>\n <FormControl>\n <FormControl.Label visuallyHidden>Primer form label</FormControl.Label>\n <TextInput />\n <FormControl.Caption>\n Label is visually hidden; the title describes the purpose visually\n </FormControl.Caption>\n </FormControl>\n </form>\n)"
6693
7089
  },
6694
7090
  {
6695
- "id": "components-textinput-features--error"
7091
+ "id": "components-textinput-features--error",
7092
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput />\n <FormControl.Validation variant=\"error\">\n Something went wrong\n </FormControl.Validation>\n </FormControl>\n </form>\n)"
6696
7093
  },
6697
7094
  {
6698
- "id": "components-textinput-features--success"
7095
+ "id": "components-textinput-features--success",
7096
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput />\n <FormControl.Validation variant=\"success\">\n Something went wrong\n </FormControl.Validation>\n </FormControl>\n </form>\n)"
6699
7097
  },
6700
7098
  {
6701
- "id": "components-textinput-features--block"
7099
+ "id": "components-textinput-features--block",
7100
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput block />\n </FormControl>\n </form>\n)"
6702
7101
  },
6703
7102
  {
6704
- "id": "components-textinput-features--small"
7103
+ "id": "components-textinput-features--small",
7104
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput size=\"small\" />\n </FormControl>\n </form>\n)"
6705
7105
  },
6706
7106
  {
6707
- "id": "components-textinput-features--large"
7107
+ "id": "components-textinput-features--large",
7108
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput size=\"large\" />\n </FormControl>\n </form>\n)"
6708
7109
  },
6709
7110
  {
6710
- "id": "components-textinput-features--required"
7111
+ "id": "components-textinput-features--required",
7112
+ "code": "() => (\n <form>\n <FormControl required>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput size=\"large\" />\n </FormControl>\n </form>\n)"
6711
7113
  },
6712
7114
  {
6713
- "id": "components-textinput-features--with-leading-visual"
7115
+ "id": "components-textinput-features--with-leading-visual",
7116
+ "code": "() => {\n const Checkmark = () => <CheckIcon aria-label=\"Checkmark\" />\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput leadingVisual={Checkmark} />\n </FormControl>\n <FormControl>\n <FormControl.Label>Enter monies</FormControl.Label>\n <TextInput leadingVisual=\"$\" />\n </FormControl>\n </form>\n )\n}"
6714
7117
  },
6715
7118
  {
6716
- "id": "components-textinput-features--with-trailing-icon"
7119
+ "id": "components-textinput-features--with-trailing-icon",
7120
+ "code": "() => {\n const Checkmark = () => <CheckIcon aria-label=\"Checkmark\" />\n return (\n <div>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput trailingVisual={Checkmark} />\n </FormControl>\n <FormControl>\n <FormControl.Label>Enter monies</FormControl.Label>\n <TextInput trailingVisual=\"minutes\" placeholder=\"200\" />\n </FormControl>\n </div>\n )\n}"
6717
7121
  },
6718
7122
  {
6719
- "id": "components-textinput-features--with-trailing-action"
7123
+ "id": "components-textinput-features--with-trailing-action",
7124
+ "code": "() => {\n const [value, setValue] = useState('sample text')\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setValue(event.target.value)\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n value={value}\n onChange={handleChange}\n trailingAction={\n <Stack\n justify=\"center\"\n style={{\n minWidth: '34px',\n }}\n >\n {value.length ? (\n <TextInput.Action\n onClick={() => setValue('')}\n icon={XCircleFillIcon}\n aria-label=\"Clear input\"\n />\n ) : undefined}\n </Stack>\n }\n />\n </FormControl>\n </form>\n )\n}"
6720
7125
  },
6721
7126
  {
6722
- "id": "components-textinput-features--with-tooltip-direction"
7127
+ "id": "components-textinput-features--with-tooltip-direction",
7128
+ "code": "() => {\n const [value, setValue] = useState('sample text')\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setValue(event.target.value)\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n value={value}\n onChange={handleChange}\n trailingAction={\n <Stack\n justify=\"center\"\n style={{\n minWidth: '34px',\n }}\n >\n {value.length ? (\n <TextInput.Action\n onClick={() => setValue('')}\n icon={XCircleFillIcon}\n aria-label=\"Clear input\"\n tooltipDirection=\"nw\"\n />\n ) : undefined}\n </Stack>\n }\n />\n </FormControl>\n </form>\n )\n}"
6723
7129
  },
6724
7130
  {
6725
- "id": "components-textinput-features--with-loading-indicator"
7131
+ "id": "components-textinput-features--with-loading-indicator",
7132
+ "code": "(args: FormControlArgs<TextInputProps>) => {\n return (\n <div>\n <h3>No visual</h3>\n\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput value=\"auto\" {...args} />\n </FormControl>\n </div>\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput value=\"leading\" {...args} loaderPosition=\"leading\" />\n </FormControl>\n </div>\n <div className={classes.MarginBottomLarge}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput value=\"trailing\" {...args} loaderPosition=\"trailing\" />\n </FormControl>\n </div>\n\n <h3>Leading visual</h3>\n\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput leadingVisual={Calendar} {...args} value=\"auto\" />\n </FormControl>\n </div>\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n leadingVisual={Calendar}\n {...args}\n loaderPosition=\"leading\"\n value=\"leading\"\n />\n </FormControl>\n </div>\n <div className={classes.MarginBottomLarge}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n leadingVisual={Calendar}\n {...args}\n loaderPosition=\"trailing\"\n value=\"trailing\"\n />\n </FormControl>\n </div>\n\n <h3>Trailing visual</h3>\n <FormControl>\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput trailingVisual={Calendar} {...args} value=\"auto\" />\n </FormControl>\n </div>\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n trailingVisual={Calendar}\n {...args}\n loaderPosition=\"leading\"\n value=\"leading\"\n />\n </FormControl>\n </div>\n <div className={classes.MarginBottomLarge}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n trailingVisual={Calendar}\n {...args}\n loaderPosition=\"trailing\"\n value=\"trailing\"\n />\n </FormControl>\n </div>\n </FormControl>\n\n <h3>Both visuals</h3>\n\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n size=\"small\"\n leadingVisual={Calendar}\n trailingVisual={Calendar}\n {...args}\n value=\"auto\"\n />\n </FormControl>\n </div>\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n leadingVisual={Calendar}\n trailingVisual={Calendar}\n {...args}\n loaderPosition=\"leading\"\n value=\"leading\"\n />\n </FormControl>\n </div>\n <div className={classes.MarginBottom}>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInput\n size=\"large\"\n leadingVisual={Calendar}\n trailingVisual={Calendar}\n {...args}\n loaderPosition=\"trailing\"\n value=\"trailing\"\n />\n </FormControl>\n </div>\n </div>\n )\n}"
6726
7133
  },
6727
7134
  {
6728
- "id": "components-textinput-features--with-autocomplete-attribute"
7135
+ "id": "components-textinput-features--with-autocomplete-attribute",
7136
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>First name</FormControl.Label>\n <TextInput autoComplete=\"given-name\" />\n </FormControl>\n <FormControl>\n <FormControl.Label>Last name</FormControl.Label>\n <TextInput autoComplete=\"family-name\" />\n </FormControl>\n </form>\n)"
6729
7137
  }
6730
7138
  ],
6731
7139
  "importPath": "@primer/react",
@@ -6902,34 +7310,44 @@
6902
7310
  "a11yReviewed": "2025-01-08",
6903
7311
  "stories": [
6904
7312
  {
6905
- "id": "deprecated-components-textinputwithtokens--default"
7313
+ "id": "deprecated-components-textinputwithtokens--default",
7314
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 3))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens tokens={tokens} onTokenRemove={onTokenRemove} />\n </FormControl>\n )\n}"
6906
7315
  },
6907
7316
  {
6908
- "id": "deprecated-components-textinputwithtokens-features--with-leading-visual"
7317
+ "id": "deprecated-components-textinputwithtokens-features--with-leading-visual",
7318
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 3))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n leadingVisual={NumberIcon}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n />\n </FormControl>\n )\n}"
6909
7319
  },
6910
7320
  {
6911
- "id": "deprecated-components-textinputwithtokens-features--with-trailing-visual"
7321
+ "id": "deprecated-components-textinputwithtokens-features--with-trailing-visual",
7322
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 3))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n trailingVisual={CheckIcon}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n />\n </FormControl>\n )\n}"
6912
7323
  },
6913
7324
  {
6914
- "id": "deprecated-components-textinputwithtokens-features--with-loading-indicator"
7325
+ "id": "deprecated-components-textinputwithtokens-features--with-loading-indicator",
7326
+ "code": "(args: FormControlArgs<TextInputWithTokensProps>) => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 3))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <form className={classes.Grid}>\n <FormControl>\n <FormControl.Label>No visual</FormControl.Label>\n <TextInputWithTokens\n {...args}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n />\n </FormControl>\n\n <FormControl>\n <FormControl.Label>Leading visual</FormControl.Label>\n <TextInputWithTokens\n {...args}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n leadingVisual={NumberIcon}\n />\n </FormControl>\n\n <FormControl>\n <FormControl.Label>Both visuals</FormControl.Label>\n <TextInputWithTokens\n {...args}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n leadingVisual={NumberIcon}\n trailingVisual={CheckIcon}\n />\n </FormControl>\n </form>\n )\n}"
6915
7327
  },
6916
7328
  {
6917
- "id": "deprecated-components-textinputwithtokens-features--using-issue-label-tokens"
7329
+ "id": "deprecated-components-textinputwithtokens-features--using-issue-label-tokens",
7330
+ "code": "() => {\n const [tokens, setTokens] = useState([\n {\n text: 'enhancement',\n id: 1,\n fillColor: '#a2eeef',\n },\n {\n text: 'bug',\n id: 2,\n fillColor: '#d73a4a',\n },\n {\n text: 'good first issue',\n id: 3,\n fillColor: '#0cf478',\n },\n ])\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n tokenComponent={IssueLabelToken}\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n />\n </FormControl>\n </form>\n )\n}"
6918
7331
  },
6919
7332
  {
6920
- "id": "deprecated-components-textinputwithtokens-features--unstyled"
7333
+ "id": "deprecated-components-textinputwithtokens-features--unstyled",
7334
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 2))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label visuallyHidden>Default label</FormControl.Label>\n <TextInputWithTokens\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n className={classes.Unstyled}\n />\n </FormControl>\n </form>\n )\n}"
6921
7335
  },
6922
7336
  {
6923
- "id": "deprecated-components-textinputwithtokens-features--prevent-tokens-from-wrapping"
7337
+ "id": "deprecated-components-textinputwithtokens-features--prevent-tokens-from-wrapping",
7338
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 3))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n preventTokenWrapping\n />\n </FormControl>\n </form>\n )\n}"
6924
7339
  },
6925
7340
  {
6926
- "id": "deprecated-components-textinputwithtokens-features--max-height"
7341
+ "id": "deprecated-components-textinputwithtokens-features--max-height",
7342
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 7))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <div className={classes.MaxWidth}>\n {/* Setting max-width to force tokens to wrap and demo `maxHeight` behavior */}\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n maxHeight={70}\n block // `block` only needed to fill parent width without overflowing\n />\n </FormControl>\n </div>\n )\n}"
6927
7343
  },
6928
7344
  {
6929
- "id": "deprecated-components-textinputwithtokens-features--size"
7345
+ "id": "deprecated-components-textinputwithtokens-features--size",
7346
+ "code": "() => {\n const [tokens, setTokens] = useState([...mockTokens].slice(0, 3))\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n size=\"small\"\n />\n </FormControl>\n </form>\n )\n}"
6930
7347
  },
6931
7348
  {
6932
- "id": "deprecated-components-textinputwithtokens-features--truncated"
7349
+ "id": "deprecated-components-textinputwithtokens-features--truncated",
7350
+ "code": "() => {\n const [tokens, setTokens] = useState(mockTokens)\n const onTokenRemove: (tokenId: string | number) => void = (tokenId) => {\n setTokens(tokens.filter((token) => token.id !== tokenId))\n }\n return (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <TextInputWithTokens\n tokens={tokens}\n onTokenRemove={onTokenRemove}\n visibleTokenCount={5}\n />\n </FormControl>\n </form>\n )\n}"
6933
7351
  }
6934
7352
  ],
6935
7353
  "importPath": "@primer/react",
@@ -7005,34 +7423,44 @@
7005
7423
  "a11yReviewed": "2025-01-08",
7006
7424
  "stories": [
7007
7425
  {
7008
- "id": "components-textarea--default"
7426
+ "id": "components-textarea--default",
7427
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea />\n </FormControl>\n </form>\n)"
7009
7428
  },
7010
7429
  {
7011
- "id": "components-textarea-features--disabled"
7430
+ "id": "components-textarea-features--disabled",
7431
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea disabled />\n </FormControl>\n </form>\n)"
7012
7432
  },
7013
7433
  {
7014
- "id": "components-textarea-features--with-caption"
7434
+ "id": "components-textarea-features--with-caption",
7435
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <FormControl.Caption>This is a caption</FormControl.Caption>\n <Textarea />\n </FormControl>\n </form>\n)"
7015
7436
  },
7016
7437
  {
7017
- "id": "components-textarea-features--visually-hidden-label"
7438
+ "id": "components-textarea-features--visually-hidden-label",
7439
+ "code": "() => (\n <form>\n <Heading as=\"h2\" variant=\"small\">\n Primer form title\n </Heading>\n <FormControl>\n <FormControl.Label visuallyHidden>Primer form label</FormControl.Label>\n <Textarea />\n <FormControl.Caption>\n Label is visually hidden; the title describes the purpose visually\n </FormControl.Caption>\n </FormControl>\n </form>\n)"
7018
7440
  },
7019
7441
  {
7020
- "id": "components-textarea-features--error"
7442
+ "id": "components-textarea-features--error",
7443
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea />\n <FormControl.Validation variant=\"error\">\n Something went wrong\n </FormControl.Validation>\n </FormControl>\n </form>\n)"
7021
7444
  },
7022
7445
  {
7023
- "id": "components-textarea-features--success"
7446
+ "id": "components-textarea-features--success",
7447
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea />\n <FormControl.Validation variant=\"success\">Success</FormControl.Validation>\n </FormControl>\n </form>\n)"
7024
7448
  },
7025
7449
  {
7026
- "id": "components-textarea-features--block"
7450
+ "id": "components-textarea-features--block",
7451
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea block />\n </FormControl>\n </form>\n)"
7027
7452
  },
7028
7453
  {
7029
- "id": "components-textarea-features--custom-height"
7454
+ "id": "components-textarea-features--custom-height",
7455
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea rows={3} />\n </FormControl>\n </form>\n)"
7030
7456
  },
7031
7457
  {
7032
- "id": "components-textarea-features--custom-width"
7458
+ "id": "components-textarea-features--custom-width",
7459
+ "code": "() => (\n <form>\n <FormControl>\n <FormControl.Label>Default label</FormControl.Label>\n <Textarea cols={60} />\n </FormControl>\n </form>\n)"
7033
7460
  },
7034
7461
  {
7035
- "id": "components-textarea-features--custom-resize-behavior"
7462
+ "id": "components-textarea-features--custom-resize-behavior",
7463
+ "code": "() => (\n <Stack as=\"form\">\n <FormControl>\n <FormControl.Label>\n Resize in either direction (default)\n </FormControl.Label>\n <Textarea resize=\"both\" />\n </FormControl>\n <FormControl>\n <FormControl.Label>No resize</FormControl.Label>\n <Textarea resize=\"none\" />\n </FormControl>\n <FormControl>\n <FormControl.Label>Horizontal resize</FormControl.Label>\n <Textarea resize=\"horizontal\" />\n </FormControl>\n <FormControl>\n <FormControl.Label>Vertical resize</FormControl.Label>\n <Textarea resize=\"vertical\" />\n </FormControl>\n </Stack>\n)"
7036
7464
  }
7037
7465
  ],
7038
7466
  "importPath": "@primer/react",
@@ -7114,19 +7542,24 @@
7114
7542
  "a11yReviewed": "2025-01-08",
7115
7543
  "stories": [
7116
7544
  {
7117
- "id": "components-timeline--default"
7545
+ "id": "components-timeline--default",
7546
+ "code": "() => (\n <Timeline>\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n </Timeline>\n)"
7118
7547
  },
7119
7548
  {
7120
- "id": "components-timeline-features--clip-sidebar"
7549
+ "id": "components-timeline-features--clip-sidebar",
7550
+ "code": "() => (\n <Timeline clipSidebar>\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n </Timeline>\n)"
7121
7551
  },
7122
7552
  {
7123
- "id": "components-timeline-features--condensed-items"
7553
+ "id": "components-timeline-features--condensed-items",
7554
+ "code": "() => (\n <Timeline>\n <Timeline.Item condensed>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Item condensed>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Break />\n <Timeline.Item condensed>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Item condensed>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n </Timeline>\n)"
7124
7555
  },
7125
7556
  {
7126
- "id": "components-timeline-features--timeline-break"
7557
+ "id": "components-timeline-features--timeline-break",
7558
+ "code": "() => (\n <Timeline>\n <Timeline.Item>\n <Timeline.Badge className={classes.BadgeWithDoneBackground}>\n <Octicon\n icon={GitMergeIcon}\n className={classes.GitMergeIcon}\n aria-label=\"Merged\"\n />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n <Timeline.Break />\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitBranchIcon} aria-label=\"Branch\" />\n </Timeline.Badge>\n <Timeline.Body>This is a message</Timeline.Body>\n </Timeline.Item>\n </Timeline>\n)"
7127
7559
  },
7128
7560
  {
7129
- "id": "components-timeline-features--with-inline-links"
7561
+ "id": "components-timeline-features--with-inline-links",
7562
+ "code": "() => (\n <Timeline>\n <Timeline.Item>\n <Timeline.Badge>\n <Octicon icon={GitCommitIcon} aria-label=\"Commit\" />\n </Timeline.Badge>\n <Timeline.Body>\n <Link href=\"#\" className={classes.LinkWithBoldStyle} muted>\n Monalisa\n </Link>\n enabled auto-merge (squash)\n </Timeline.Body>\n </Timeline.Item>\n </Timeline>\n)"
7130
7563
  }
7131
7564
  ],
7132
7565
  "importPath": "@primer/react",
@@ -7170,34 +7603,44 @@
7170
7603
  "a11yReviewed": "2025-01-08",
7171
7604
  "stories": [
7172
7605
  {
7173
- "id": "components-toggleswitch--default"
7606
+ "id": "components-toggleswitch--default",
7607
+ "code": "() => (\n <>\n <Text id=\"toggle\" className={classes.TextMediumBold}>\n Toggle label\n </Text>\n <ToggleSwitch aria-labelledby=\"toggle\" />\n </>\n)"
7174
7608
  },
7175
7609
  {
7176
- "id": "components-toggleswitch-features--small"
7610
+ "id": "components-toggleswitch-features--small",
7611
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch size=\"small\" aria-labelledby=\"toggle\" />\n </ToggleSwitchStoryWrapper>\n)"
7177
7612
  },
7178
7613
  {
7179
- "id": "components-toggleswitch-features--with-caption"
7614
+ "id": "components-toggleswitch-features--with-caption",
7615
+ "code": "() => (\n <div className={styles.Row}>\n <div className={styles.ColGrow}>\n <span className={styles.SwitchLabel} id=\"switchLabel\">\n Notifications\n </span>\n <span className={styles.SwitchCaption} id=\"switchCaption\">\n Notifications will be delivered via email and the GitHub notification\n center\n </span>\n </div>\n <ToggleSwitch\n aria-labelledby=\"switchLabel\"\n aria-describedby=\"switchCaption\"\n />\n </div>\n)"
7180
7616
  },
7181
7617
  {
7182
- "id": "components-toggleswitch-features--disabled"
7618
+ "id": "components-toggleswitch-features--disabled",
7619
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch disabled aria-labelledby=\"toggle\" />\n </ToggleSwitchStoryWrapper>\n)"
7183
7620
  },
7184
7621
  {
7185
- "id": "components-toggleswitch-features--checked"
7622
+ "id": "components-toggleswitch-features--checked",
7623
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch checked aria-labelledby=\"toggle\" />\n </ToggleSwitchStoryWrapper>\n)"
7186
7624
  },
7187
7625
  {
7188
- "id": "components-toggleswitch-features--checked-disabled"
7626
+ "id": "components-toggleswitch-features--checked-disabled",
7627
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch checked disabled aria-labelledby=\"toggle\" />\n </ToggleSwitchStoryWrapper>\n)"
7189
7628
  },
7190
7629
  {
7191
- "id": "components-toggleswitch-features--loading"
7630
+ "id": "components-toggleswitch-features--loading",
7631
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch loading aria-labelledby=\"toggle\" />\n </ToggleSwitchStoryWrapper>\n)"
7192
7632
  },
7193
7633
  {
7194
- "id": "components-toggleswitch-features--label-end"
7634
+ "id": "components-toggleswitch-features--label-end",
7635
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch statusLabelPosition=\"end\" aria-labelledby=\"toggle\" />\n </ToggleSwitchStoryWrapper>\n)"
7195
7636
  },
7196
7637
  {
7197
- "id": "components-toggleswitch-features--controlled"
7638
+ "id": "components-toggleswitch-features--controlled",
7639
+ "code": "() => {\n const [isOn, setIsOn] = React.useState(false)\n const onClick = React.useCallback(() => {\n setIsOn(!isOn)\n }, [setIsOn, isOn])\n const handleSwitchChange = (on: boolean) => {\n action(`new switch \"on\" state: ${on}`)\n }\n return (\n <>\n <div\n className={styles.Row}\n style={{\n maxWidth: '300px',\n }}\n >\n <span\n className={clsx(styles.ColGrow, styles.SwitchLabel)}\n id=\"switchLabel\"\n >\n Notifications\n </span>\n <ToggleSwitch\n onClick={onClick}\n onChange={handleSwitchChange}\n checked={isOn}\n aria-labelledby=\"switchLabel\"\n />\n </div>\n <p>The switch is {isOn ? 'on' : 'off'}</p>\n </>\n )\n}"
7198
7640
  },
7199
7641
  {
7200
- "id": "components-toggleswitch-features--with-custom-labels"
7642
+ "id": "components-toggleswitch-features--with-custom-labels",
7643
+ "code": "() => (\n <ToggleSwitchStoryWrapper>\n <span id=\"toggle\" className={styles.ToggleLabel}>\n Toggle label\n </span>\n <ToggleSwitch\n buttonLabelOn=\"Active\"\n buttonLabelOff=\"Inactive\"\n aria-labelledby=\"toggle\"\n />\n </ToggleSwitchStoryWrapper>\n)"
7201
7644
  }
7202
7645
  ],
7203
7646
  "importPath": "@primer/react",
@@ -7304,37 +7747,48 @@
7304
7747
  "a11yReviewed": "2025-01-08",
7305
7748
  "stories": [
7306
7749
  {
7307
- "id": "components-token--default"
7750
+ "id": "components-token--default",
7751
+ "code": "() => <Token text=\"token\" />"
7308
7752
  },
7309
7753
  {
7310
- "id": "components-token-features--interactive-token"
7754
+ "id": "components-token-features--interactive-token",
7755
+ "code": "() => {\n return (\n <div className={classes.TokenRow}>\n <Token\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Link\"\n />\n <Token as=\"button\" onClick={action('clicked')} text=\"Button\" />\n </div>\n )\n}"
7311
7756
  },
7312
7757
  {
7313
- "id": "components-token-features--token-with-leading-visual"
7758
+ "id": "components-token-features--token-with-leading-visual",
7759
+ "code": "() => {\n return <Token text=\"token\" leadingVisual={GitBranchIcon} />\n}"
7314
7760
  },
7315
7761
  {
7316
- "id": "components-token-features--token-with-on-remove-fn"
7762
+ "id": "components-token-features--token-with-on-remove-fn",
7763
+ "code": "({ ...args }) => {\n return (\n <div className={classes.TokenRow}>\n <Token text=\"token\" onRemove={action('remove me')} {...args} />\n <Token\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n onRemove={action('remove me')}\n text=\"Link\"\n {...args}\n />\n <Token\n as=\"button\"\n onClick={action('clicked')}\n onRemove={action('remove me')}\n text=\"Button\"\n {...args}\n />\n </div>\n )\n}"
7317
7764
  },
7318
7765
  {
7319
- "id": "components-token-features--default-issue-label-token"
7766
+ "id": "components-token-features--default-issue-label-token",
7767
+ "code": "() => {\n return <IssueLabelToken text=\"good first issue\" />\n}"
7320
7768
  },
7321
7769
  {
7322
- "id": "components-token-features--interactive-issue-label-token"
7770
+ "id": "components-token-features--interactive-issue-label-token",
7771
+ "code": "() => {\n return (\n <div className={classes.TokenRow}>\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Link\"\n />\n <IssueLabelToken as=\"button\" onClick={action('clicked')} text=\"Button\" />\n </div>\n )\n}"
7323
7772
  },
7324
7773
  {
7325
- "id": "components-token-features--issue-label-token-with-on-remove-fn"
7774
+ "id": "components-token-features--issue-label-token-with-on-remove-fn",
7775
+ "code": "() => {\n return (\n <div className={classes.TokenRow}>\n <IssueLabelToken text=\"token\" onRemove={action('remove me')} />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n onRemove={action('remove me')}\n text=\"Link\"\n />\n <IssueLabelToken\n as=\"button\"\n onClick={action('clicked')}\n onRemove={action('remove me')}\n text=\"Button\"\n />\n </div>\n )\n}"
7326
7776
  },
7327
7777
  {
7328
- "id": "components-token-features--small-token"
7778
+ "id": "components-token-features--small-token",
7779
+ "code": "() => <Token text=\"token\" size=\"small\" />"
7329
7780
  },
7330
7781
  {
7331
- "id": "components-token-features--large-token"
7782
+ "id": "components-token-features--large-token",
7783
+ "code": "() => <Token text=\"token\" size=\"xlarge\" />"
7332
7784
  },
7333
7785
  {
7334
- "id": "components-token-features--x-large-token"
7786
+ "id": "components-token-features--x-large-token",
7787
+ "code": "() => <Token text=\"token\" size=\"xlarge\" />"
7335
7788
  },
7336
7789
  {
7337
- "id": "components-token-features--issue-label-token-custom-colors"
7790
+ "id": "components-token-features--issue-label-token-custom-colors",
7791
+ "code": "() => {\n return (\n <div className={classes.TokenColumn}>\n <div className={classes.TokenRow}>\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Link\"\n fillColor=\"#0366d6\"\n />\n <IssueLabelToken\n as=\"button\"\n onClick={action('clicked')}\n text=\"Button\"\n fillColor=\"lightpink\"\n />\n </div>\n <h3>Color examples</h3>\n <div className={classes.TokenWrapRow}>\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"😀 Link\"\n fillColor=\"#8c50c8\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Token\"\n fillColor=\"#a9d3bc\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"🚨 Problem\"\n fillColor=\"#98afa7\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"📥 Inbox\"\n fillColor=\"#573807\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"deeppink\"\n fillColor=\"#b7b41e\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"👹 Link\"\n fillColor=\"#0f65b1\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Tiger\"\n fillColor=\"#e7bc68\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"🐛 coral\"\n fillColor=\"#D6F2DE\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Long label\"\n fillColor=\"#161E37\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"✅ Done\"\n fillColor=\"#232323\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Hello\"\n fillColor=\"#E0E0E0\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Lorem\"\n fillColor=\"#aed531\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Lorem\"\n fillColor=\"#d980fc\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Lorem\"\n fillColor=\"#e7f922\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"🚀 Lorem\"\n fillColor=\"#ef70e9\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Lorem\"\n fillColor=\"#72ea84\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"Lorem\"\n fillColor=\"#87e50b\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"🤷 Lorem\"\n fillColor=\"#fcf646\"\n />\n <IssueLabelToken\n as=\"a\"\n href=\"/?path=/story/components-token-features--issue-label-token-custom-colors\"\n text=\"💡 Light\"\n fillColor=\"#E40C74\"\n />\n </div>\n </div>\n )\n}"
7338
7792
  }
7339
7793
  ],
7340
7794
  "importPath": "@primer/react",
@@ -7439,13 +7893,16 @@
7439
7893
  "a11yReviewed": false,
7440
7894
  "stories": [
7441
7895
  {
7442
- "id": "deprecated-components-tooltip--default"
7896
+ "id": "deprecated-components-tooltip--default",
7897
+ "code": "() => (\n <>\n <div className={classes.BannerContainer}>\n <Banner\n title=\"Planned for deprecation\"\n description={\n <div data-a11y-link-underlines=\"true\">\n There are plans to deprecate this component in a future release. We\n recommend using{' '}\n <Link\n inline={true}\n href=\"/react/storybook/?path=/story/components-tooltipv2--default\"\n >\n Tooltip\n </Link>{' '}\n instead.\n </div>\n }\n variant=\"warning\"\n />\n </div>\n <div className={classes.PaddedContainer}>\n <Tooltip aria-label=\"Hello, Tooltip!\">\n <Button>Hover me</Button>\n </Tooltip>\n </div>\n </>\n)"
7443
7898
  },
7444
7899
  {
7445
- "id": "deprecated-components-tooltip-features--all-directions"
7900
+ "id": "deprecated-components-tooltip-features--all-directions",
7901
+ "code": "() => (\n <div className={classes.AllDirectionsRow}>\n <Tooltip direction=\"n\" aria-label=\"Supplementary text\">\n <Button>North</Button>\n </Tooltip>\n <Tooltip direction=\"s\" aria-label=\"Supplementary text\">\n <Button>South</Button>\n </Tooltip>\n <Tooltip direction=\"e\" aria-label=\"Supplementary text\">\n <Button>East</Button>\n </Tooltip>\n <Tooltip direction=\"w\" aria-label=\"Supplementary text\">\n <Button>West</Button>\n </Tooltip>\n <Tooltip direction=\"ne\" aria-label=\"Supplementary text\">\n <Button>North East</Button>\n </Tooltip>\n <Tooltip direction=\"nw\" aria-label=\"Supplementary text\">\n <Button>North West</Button>\n </Tooltip>\n <Tooltip direction=\"se\" aria-label=\"Supplementary text\">\n <Button>Southeast</Button>\n </Tooltip>\n <Tooltip direction=\"sw\" aria-label=\"Supplementary text\">\n <Button>Southwest</Button>\n </Tooltip>\n </div>\n)"
7446
7902
  },
7447
7903
  {
7448
- "id": "deprecated-components-tooltip-features--icon-button-tooltip"
7904
+ "id": "deprecated-components-tooltip-features--icon-button-tooltip",
7905
+ "code": "() => (\n <div className={classes.PaddedContainer}>\n <Tooltip aria-label=\"Search\">\n <IconButton icon={SearchIcon} aria-label=\"Search\" />\n </Tooltip>\n </div>\n)"
7449
7906
  }
7450
7907
  ],
7451
7908
  "importPath": "@primer/react/deprecated",
@@ -7488,31 +7945,40 @@
7488
7945
  "importPath": "@primer/react/next",
7489
7946
  "stories": [
7490
7947
  {
7491
- "id": "components-tooltipv2--default"
7948
+ "id": "components-tooltipv2--default",
7949
+ "code": "() => (\n <div className={classes.PaddedContainer}>\n <Tooltip text=\"This change can't be undone.\">\n <Button>Delete</Button>\n </Tooltip>\n </div>\n)"
7492
7950
  },
7493
7951
  {
7494
- "id": "components-tooltipv2-features--anchor-has-margin"
7952
+ "id": "components-tooltipv2-features--anchor-has-margin",
7953
+ "code": "() => (\n <div className={classes.PaddedContainer}>\n <Tooltip text=\"Tooltip is still centered\">\n <Button className={classes.MarginLeftButton}>\n Button has 16px margin Left\n </Button>\n </Tooltip>\n </div>\n)"
7495
7954
  },
7496
7955
  {
7497
- "id": "components-tooltipv2-features--label-type"
7956
+ "id": "components-tooltipv2-features--label-type",
7957
+ "code": "() => (\n <div>\n <Tooltip text=\"Contribution Documentation for 'Primer React'\" type=\"label\">\n <Link\n href=\"https://github.com/primer/react/contributor-docs/CONTRIBUTING.md\"\n className={classes.LabelLink}\n >\n <Octicon icon={BookIcon} className={classes.LabelIcon} />\n </Link>\n </Tooltip>\n </div>\n)"
7498
7958
  },
7499
7959
  {
7500
- "id": "components-tooltipv2-features--description-type"
7960
+ "id": "components-tooltipv2-features--description-type",
7961
+ "code": "() => (\n <div className={classes.PaddedContainer}>\n <Tooltip text=\"Supplementary text\" direction=\"n\">\n <Button>Save</Button>\n </Tooltip>\n </div>\n)"
7501
7962
  },
7502
7963
  {
7503
- "id": "components-tooltipv2-features--icon-button-with-description"
7964
+ "id": "components-tooltipv2-features--icon-button-with-description",
7965
+ "code": "() => (\n <div className={classes.PaddedContainer}>\n <Tooltip text=\"Supplementary text for icon button\" direction=\"e\">\n <IconButton icon={SearchIcon} aria-label=\"Search\" />\n </Tooltip>\n </div>\n)"
7504
7966
  },
7505
7967
  {
7506
- "id": "components-tooltipv2-features--all-directions"
7968
+ "id": "components-tooltipv2-features--all-directions",
7969
+ "code": "() => (\n <div className={classes.AllDirectionsRow}>\n <Tooltip direction=\"n\" text=\"Supplementary text\">\n <Button>North</Button>\n </Tooltip>\n <Tooltip direction=\"s\" text=\"Supplementary text\">\n <Button>South</Button>\n </Tooltip>\n <Tooltip direction=\"e\" text=\"Supplementary text\">\n <Button>East</Button>\n </Tooltip>\n <Tooltip direction=\"w\" text=\"Supplementary text\">\n <Button>West</Button>\n </Tooltip>\n <Tooltip direction=\"ne\" text=\"Supplementary text\">\n <Button>North East</Button>\n </Tooltip>\n <Tooltip direction=\"nw\" text=\"Supplementary text\">\n <Button>North West</Button>\n </Tooltip>\n <Tooltip direction=\"se\" text=\"Supplementary text\">\n <Button>Southeast</Button>\n </Tooltip>\n <Tooltip direction=\"sw\" text=\"Supplementary text\">\n <Button>Southwest</Button>\n </Tooltip>\n </div>\n)"
7507
7970
  },
7508
7971
  {
7509
- "id": "components-tooltipv2-features--multiline-text"
7972
+ "id": "components-tooltipv2-features--multiline-text",
7973
+ "code": "() => (\n <div>\n <Tooltip\n direction=\"e\"\n text=\"Random long text that needs to be wrapped and be multipline and have some paddings around\"\n >\n <Button>Multiline East</Button>\n </Tooltip>\n </div>\n)"
7510
7974
  },
7511
7975
  {
7512
- "id": "components-tooltipv2-features--calculated-direction"
7976
+ "id": "components-tooltipv2-features--calculated-direction",
7977
+ "code": "() => (\n <div className={classes.AllDirectionsRow}>\n <Tooltip\n direction=\"w\"\n text=\"But appears in the east direction due to not having enough space in the west\"\n >\n <Button>West</Button>\n </Tooltip>\n\n <Tooltip text=\"The direction here is north by default but there is not enough space in the north therefore the tooltip appears in the south\">\n <Button>North</Button>\n </Tooltip>\n </div>\n)"
7513
7978
  },
7514
7979
  {
7515
- "id": "components-tooltipv2-features--on-action-menu-anchor"
7980
+ "id": "components-tooltipv2-features--on-action-menu-anchor",
7981
+ "code": "() => (\n <div className={classes.ActionMenuRow}>\n <ActionMenu>\n <ActionMenu.Anchor>\n <Tooltip text=\"Supplementary text to add here\" direction=\"n\">\n <Button\n leadingVisual={GitBranchIcon}\n trailingAction={TriangleDownIcon}\n >\n ActionMenu.Anchor w/ t\n </Button>\n </Tooltip>\n </ActionMenu.Anchor>\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Main')}>\n <ActionList.LeadingVisual>\n <CheckIcon />\n </ActionList.LeadingVisual>\n main <ActionList.TrailingVisual>default</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 1')}>\n branch-1\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 2')}>\n branch-2\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n <ActionMenu>\n <Tooltip text=\"Supplementary text to add here\" direction=\"n\">\n <ActionMenu.Button leadingVisual={GitBranchIcon}>\n ActionMenu.Button w/ t\n </ActionMenu.Button>\n </Tooltip>\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Main')}>\n <ActionList.LeadingVisual>\n <CheckIcon />\n </ActionList.LeadingVisual>\n main <ActionList.TrailingVisual>default</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 1')}>\n branch-1\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 2')}>\n branch-2\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n <ActionMenu>\n <ActionMenu.Anchor>\n <Button leadingVisual={GitBranchIcon} trailingAction={TriangleDownIcon}>\n ActionMenu.Anchor\n </Button>\n </ActionMenu.Anchor>\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Main')}>\n <ActionList.LeadingVisual>\n <CheckIcon />\n </ActionList.LeadingVisual>\n main <ActionList.TrailingVisual>default</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 1')}>\n branch-1\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 2')}>\n branch-2\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n <ActionMenu>\n <ActionMenu.Button leadingVisual={GitBranchIcon}>\n ActionMenu.Button\n </ActionMenu.Button>\n\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Main')}>\n <ActionList.LeadingVisual>\n <CheckIcon />\n </ActionList.LeadingVisual>\n main <ActionList.TrailingVisual>default</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 1')}>\n branch-1\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Branch 2')}>\n branch-2\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n </div>\n)"
7516
7982
  }
7517
7983
  ],
7518
7984
  "props": [
@@ -7556,13 +8022,16 @@
7556
8022
  "a11yReviewed": false,
7557
8023
  "stories": [
7558
8024
  {
7559
- "id": "experimental-components-topictag--default"
8025
+ "id": "experimental-components-topictag--default",
8026
+ "code": "() => <TopicTag>react</TopicTag>"
7560
8027
  },
7561
8028
  {
7562
- "id": "experimental-components-topictag-features--as-button"
8029
+ "id": "experimental-components-topictag-features--as-button",
8030
+ "code": "() => <TopicTag as=\"button\">react</TopicTag>"
7563
8031
  },
7564
8032
  {
7565
- "id": "experimental-components-topictag-features--as-group"
8033
+ "id": "experimental-components-topictag-features--as-group",
8034
+ "code": "() => {\n const tags = [\n 'react',\n 'nodejs',\n 'javascript',\n 'd3',\n 'teachers',\n 'community',\n 'education',\n 'programming',\n 'curriculum',\n 'math',\n ]\n return (\n <TopicTagGroup>\n {tags.map((tag) => (\n <TopicTag key={tag} href={`/topics/${tag}`}>\n {tag}\n </TopicTag>\n ))}\n </TopicTagGroup>\n )\n}"
7566
8035
  }
7567
8036
  ],
7568
8037
  "importPath": "@primer/react/experimental",
@@ -7599,25 +8068,32 @@
7599
8068
  "a11yReviewed": "2025-01-08",
7600
8069
  "stories": [
7601
8070
  {
7602
- "id": "components-treeview--default"
8071
+ "id": "components-treeview--default",
8072
+ "code": "() => (\n <nav aria-label=\"Files changed\">\n <TreeView aria-label=\"Files changed\">\n <TreeView.Item id=\"src\" defaultExpanded>\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n src\n <TreeView.SubTree>\n <TreeView.Item id=\"src/Avatar.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Avatar.tsx\n <TreeView.TrailingVisual label=\"Added\">\n <Octicon icon={DiffAddedIcon} className={classes.SuccessIcon} />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n <TreeView.Item id=\"src/Button.tsx\" current>\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Button.tsx\n <TreeView.TrailingVisual label=\"Modified\">\n <Octicon\n icon={DiffModifiedIcon}\n className={classes.AttentionIcon}\n />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"package.json\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n package.json\n <TreeView.TrailingVisual label=\"Modified\">\n <Octicon icon={DiffModifiedIcon} className={classes.AttentionIcon} />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n </TreeView>\n </nav>\n)"
7603
8073
  },
7604
8074
  {
7605
- "id": "components-treeview-features--files"
8075
+ "id": "components-treeview-features--files",
8076
+ "code": "() => (\n <nav aria-label=\"Files\">\n <TreeView aria-label=\"Files\" truncate={false}>\n <TreeView.Item id=\"src\" defaultExpanded>\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n src\n <TreeView.SubTree>\n <TreeView.Item id=\"src/Avatar.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Avatar.tsx\n </TreeView.Item>\n <TreeView.Item id=\"src/Button\" current>\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n Button\n <TreeView.SubTree>\n <TreeView.Item id=\"src/Button/Button.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Button.tsx\n </TreeView.Item>\n <TreeView.Item id=\"src/Button/Button.test.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Button.test.tsx\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"src/ReallyLongFileNameThatShouldBeTruncated.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n ReallyLongFileNameThatShouldBeTruncated.tsx\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item\n id=\"public\"\n // eslint-disable-next-line no-console\n onExpandedChange={(isExpanded) =>\n console.log(\n `${isExpanded ? 'Expanded' : 'Collapsed'} \"public\" folder `,\n )\n }\n >\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n public\n <TreeView.SubTree>\n <TreeView.Item id=\"public/index.html\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n index.html\n </TreeView.Item>\n <TreeView.Item id=\"public/favicon.ico\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n favicon.ico\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"package.json\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n package.json\n </TreeView.Item>\n </TreeView>\n </nav>\n)"
7606
8077
  },
7607
8078
  {
7608
- "id": "components-treeview-features--files-changed"
8079
+ "id": "components-treeview-features--files-changed",
8080
+ "code": "() => {\n return (\n <nav aria-label=\"Files\">\n <TreeView aria-label=\"Files\" truncate={false}>\n <TreeView.Item id=\"src\" defaultExpanded>\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n src\n <TreeView.SubTree>\n <TreeView.Item id=\"src/Avatar.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Avatar.tsx\n <TreeView.TrailingVisual label=\"added\">\n <Octicon icon={DiffAddedIcon} className={classes.SuccessIcon} />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n <TreeView.Item id=\"src/Button\" defaultExpanded>\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n Button\n <TreeView.SubTree>\n <TreeView.Item id=\"src/Button/Button.tsx\" current>\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Button.tsx\n <TreeView.TrailingVisual label=\"modified\">\n <Octicon\n icon={DiffModifiedIcon}\n className={classes.AttentionIcon}\n />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n <TreeView.Item id=\"src/Button/Button.test.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Button.test.tsx\n <TreeView.TrailingVisual label=\"modified\">\n <Octicon\n icon={DiffModifiedIcon}\n className={classes.AttentionIcon}\n />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"src/ReallyLongFileNameThatShouldBeTruncated.tsx\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n ReallyLongFileNameThatShouldBeTruncated.tsx\n <TreeView.TrailingVisual label=\"modified\">\n <Octicon\n icon={DiffModifiedIcon}\n className={classes.AttentionIcon}\n />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"public\" defaultExpanded>\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n public\n <TreeView.SubTree>\n <TreeView.Item id=\"public/index.html\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n index.html\n <TreeView.TrailingVisual label=\"renamed\">\n <Octicon icon={DiffRenamedIcon} />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n <TreeView.Item id=\"public/favicon.ico\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n favicon.ico\n <TreeView.TrailingVisual label=\"removed\">\n <Octicon\n icon={DiffRemovedIcon}\n className={classes.DangerIcon}\n />\n </TreeView.TrailingVisual>\n </TreeView.Item>\n </TreeView.SubTree>\n </TreeView.Item>\n </TreeView>\n </nav>\n )\n}"
7609
8081
  },
7610
8082
  {
7611
- "id": "components-treeview-features--async-success"
8083
+ "id": "components-treeview-features--async-success",
8084
+ "code": "(args) => {\n const [isLoading, setIsLoading] = React.useState(false)\n const [asyncItems, setAsyncItems] = React.useState<string[]>([])\n let state: SubTreeState = 'initial'\n if (isLoading) {\n state = 'loading'\n } else if (asyncItems.length > 0) {\n state = 'done'\n }\n return (\n <nav aria-label=\"Files\">\n <TreeView aria-label=\"Files\">\n <TreeView.Item id=\"file-1\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Some file\n </TreeView.Item>\n <TreeView.Item\n id=\"async-directory\"\n onExpandedChange={async (isExpanded) => {\n if (asyncItems.length === 0 && isExpanded) {\n setIsLoading(true)\n\n // Load items\n const items = await loadItems(args.responseTime)\n setIsLoading(false)\n setAsyncItems(items)\n }\n }}\n >\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n Directory with async items\n <TreeView.SubTree state={state}>\n {asyncItems.map((item) => (\n <TreeView.Item id={`item-${item}`} key={item}>\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n {item}\n </TreeView.Item>\n ))}\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"another-file\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Another file\n </TreeView.Item>\n </TreeView>\n </nav>\n )\n}"
7612
8085
  },
7613
8086
  {
7614
- "id": "components-treeview-features--async-error"
8087
+ "id": "components-treeview-features--async-error",
8088
+ "code": "(args) => {\n const [isLoading, setIsLoading] = React.useState(false)\n const [asyncItems, setAsyncItems] = React.useState<string[]>([])\n const [error, setError] = React.useState<Error | null>(null)\n let state: SubTreeState = 'initial'\n if (isLoading) {\n state = 'loading'\n } else if (error) {\n state = 'error'\n } else if (asyncItems.length > 0) {\n state = 'done'\n }\n async function loadItems() {\n if (asyncItems.length === 0) {\n setIsLoading(true)\n try {\n // Try to load items\n const items = await alwaysFails(args.responseTime)\n setAsyncItems(items)\n } catch (error) {\n setError(error as Error)\n } finally {\n setIsLoading(false)\n }\n }\n }\n return (\n <TreeView aria-label=\"Files\">\n <TreeView.Item id=\"some-file\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Some file\n </TreeView.Item>\n <TreeView.Item\n id=\"async-directory\"\n onExpandedChange={(isExpanded) => {\n if (isExpanded) {\n loadItems()\n }\n }}\n >\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n Directory with async items\n <TreeView.SubTree state={state}>\n {error ? (\n <TreeView.ErrorDialog\n onRetry={() => {\n setError(null)\n loadItems()\n }}\n onDismiss={() => {\n setError(null)\n }}\n >\n {error.message}\n </TreeView.ErrorDialog>\n ) : null}\n {asyncItems.map((item) => (\n <TreeView.Item key={item} id={`item-${item}`}>\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n {item}\n </TreeView.Item>\n ))}\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"another-file\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Another file\n </TreeView.Item>\n </TreeView>\n )\n}"
7615
8089
  },
7616
8090
  {
7617
- "id": "components-treeview-features--async-with-count"
8091
+ "id": "components-treeview-features--async-with-count",
8092
+ "code": "(args) => {\n const [isLoading, setIsLoading] = React.useState(false)\n const [asyncItems, setAsyncItems] = React.useState<string[]>([])\n let state: SubTreeState = 'initial'\n if (isLoading) {\n state = 'loading'\n } else if (asyncItems.length > 0) {\n state = 'done'\n }\n return (\n <nav aria-label=\"Files\">\n <TreeView aria-label=\"Files\">\n <TreeView.Item id=\"some-file\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Some file\n </TreeView.Item>\n <TreeView.Item\n id=\"async-directory\"\n onExpandedChange={async (isExpanded) => {\n if (asyncItems.length === 0 && isExpanded) {\n setIsLoading(true)\n\n // Load items\n const items = await loadItems(args.responseTime)\n setIsLoading(false)\n setAsyncItems(items)\n }\n }}\n >\n <TreeView.LeadingVisual>\n <TreeView.DirectoryIcon />\n </TreeView.LeadingVisual>\n Directory with async items\n <TreeView.SubTree state={state} count={args.count}>\n {asyncItems.map((item) => (\n <TreeView.Item key={item} id={`item-${item}`}>\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n {item}\n </TreeView.Item>\n ))}\n </TreeView.SubTree>\n </TreeView.Item>\n <TreeView.Item id=\"another-file\">\n <TreeView.LeadingVisual>\n <FileIcon />\n </TreeView.LeadingVisual>\n Another file\n </TreeView.Item>\n </TreeView>\n </nav>\n )\n}"
7618
8093
  },
7619
8094
  {
7620
- "id": "components-treeview-features--controlled"
8095
+ "id": "components-treeview-features--controlled",
8096
+ "code": "() => {\n const [currentPath, setCurrentPath] = React.useState<string[]>([\n 'src',\n 'Avatar.tsx',\n ])\n const [tree, setTree] = React.useState<TreeItem[]>(initialTree)\n return (\n <div className={classes.ControlledContainer}>\n <div className={classes.ButtonContainer}>\n <Button onClick={() => setTree(collapseAll)}>Collapse all</Button>\n <Button onClick={() => setTree(expandAll)}>Expand all</Button>\n </div>\n <nav aria-label=\"Files\">\n <CurrentPathContext.Provider\n value={{\n currentPath,\n setCurrentPath,\n }}\n >\n <TreeView aria-label=\"Files\">\n {tree.map((item) => (\n <TreeItem\n key={item.data.name}\n item={item}\n path={[item.data.name]}\n onExpandedChange={(path, expanded) =>\n setTree((tree) => setExpanded(tree, path, expanded))\n }\n />\n ))}\n </TreeView>\n </CurrentPathContext.Provider>\n </nav>\n </div>\n )\n}"
7621
8097
  }
7622
8098
  ],
7623
8099
  "importPath": "@primer/react",
@@ -7832,16 +8308,20 @@
7832
8308
  "a11yReviewed": "2025-01-08",
7833
8309
  "stories": [
7834
8310
  {
7835
- "id": "components-truncate--default"
8311
+ "id": "components-truncate--default",
8312
+ "code": "() => <Truncate title=\"Some example text\">Some example text</Truncate>"
7836
8313
  },
7837
8314
  {
7838
- "id": "components-truncate-features--expandable"
8315
+ "id": "components-truncate-features--expandable",
8316
+ "code": "() => (\n <Truncate title=\"Hover this example text\" expandable>\n Hover this example text\n </Truncate>\n)"
7839
8317
  },
7840
8318
  {
7841
- "id": "components-truncate-features--inline"
8319
+ "id": "components-truncate-features--inline",
8320
+ "code": "() => (\n <>\n <ArrowRightIcon />\n <Truncate title=\"Inline example text\" inline>\n Inline example text\n </Truncate>\n <ArrowLeftIcon />\n </>\n)"
7842
8321
  },
7843
8322
  {
7844
- "id": "components-truncate-features--max-width"
8323
+ "id": "components-truncate-features--max-width",
8324
+ "code": "() => (\n <Truncate title=\"Some example text with a max width\" maxWidth={200}>\n Some example text with a max width\n </Truncate>\n)"
7845
8325
  }
7846
8326
  ],
7847
8327
  "importPath": "@primer/react",
@@ -7880,28 +8360,32 @@
7880
8360
  "a11yReviewed": "2025-01-08",
7881
8361
  "stories": [
7882
8362
  {
7883
- "id": "components-underlinenav--default"
7884
- },
7885
- {
7886
- "id": "components-underlinenav-features--default"
8363
+ "id": "components-underlinenav-features--default",
8364
+ "code": "() => {\n const children = ['Code', 'Pull requests', 'Actions', 'Projects', 'Wiki']\n return (\n <UnderlineNav aria-label=\"Repository\">\n {children.map((child: string, index: number) => (\n <UnderlineNavItem\n key={index}\n href=\"#\"\n aria-current={index === 0 ? 'page' : undefined}\n >\n {child}\n </UnderlineNavItem>\n ))}\n </UnderlineNav>\n )\n}"
7887
8365
  },
7888
8366
  {
7889
- "id": "components-underlinenav-features--with-icons"
8367
+ "id": "components-underlinenav-features--with-icons",
8368
+ "code": "() => {\n return (\n <UnderlineNav aria-label=\"Repository with icons\">\n <UnderlineNav.Item leadingVisual={<CodeIcon />}>Code</UnderlineNav.Item>\n <UnderlineNav.Item leadingVisual={<EyeIcon />} counter={6}>\n Issues\n </UnderlineNav.Item>\n <UnderlineNav.Item\n aria-current=\"page\"\n leadingVisual={<GitPullRequestIcon />}\n >\n Pull Requests\n </UnderlineNav.Item>\n <UnderlineNav.Item leadingVisual={<CommentDiscussionIcon />} counter={7}>\n Discussions\n </UnderlineNav.Item>\n <UnderlineNav.Item leadingVisual={<ProjectIcon />}>\n Projects\n </UnderlineNav.Item>\n </UnderlineNav>\n )\n}"
7890
8369
  },
7891
8370
  {
7892
- "id": "components-underlinenav-features--with-counter-labels"
8371
+ "id": "components-underlinenav-features--with-counter-labels",
8372
+ "code": "() => {\n return (\n <UnderlineNav aria-label=\"Repository with counters\">\n <UnderlineNav.Item\n aria-current=\"page\"\n leadingVisual={<CodeIcon />}\n counter=\"11K\"\n >\n Code\n </UnderlineNav.Item>\n <UnderlineNav.Item leadingVisual={<IssueOpenedIcon />} counter={12}>\n Issues\n </UnderlineNav.Item>\n </UnderlineNav>\n )\n}"
7893
8373
  },
7894
8374
  {
7895
- "id": "components-underlinenav-features--overflow-template"
8375
+ "id": "components-underlinenav-features--overflow-template",
8376
+ "code": "({ initialSelectedIndex = 1 }: { initialSelectedIndex?: number }) => {\n const [selectedIndex, setSelectedIndex] = React.useState<number | null>(\n initialSelectedIndex,\n )\n return (\n <UnderlineNav\n aria-label=\"Repository\"\n // @ts-ignore UnderlineNav does not take selectionVariant prop, but we need to pass it to the underlying ActionList so it doesn't show Selections.\n selectionVariant={undefined}\n >\n {items.map((item, index) => (\n <UnderlineNav.Item\n key={item.navigation}\n leadingVisual={item.icon}\n aria-current={index === selectedIndex ? 'page' : undefined}\n // Set so that navigation in interaction tests does not cause the\n // page to load the storybook iframe URL and instead keeps the test in\n // the local preview\n target=\"_self\"\n onSelect={(event) => {\n event.preventDefault()\n setSelectedIndex(index)\n }}\n counter={item.counter}\n href={item.href}\n >\n {item.navigation}\n </UnderlineNav.Item>\n ))}\n </UnderlineNav>\n )\n}"
7896
8377
  },
7897
8378
  {
7898
- "id": "components-underlinenav-features--overflow-on-narrow-screen"
8379
+ "id": "components-underlinenav-features--overflow-on-narrow-screen",
8380
+ "code": "() => {\n return <OverflowTemplate initialSelectedIndex={1} />\n}"
7899
8381
  },
7900
8382
  {
7901
- "id": "components-underlinenav-features--counters-loading-state"
8383
+ "id": "components-underlinenav-features--counters-loading-state",
8384
+ "code": "() => {\n const [selectedIndex, setSelectedIndex] = React.useState<number | null>(1)\n return (\n <UnderlineNav\n aria-label=\"Repository with loading counters\"\n loadingCounters={true}\n >\n {items.map((item, index) => (\n <UnderlineNav.Item\n key={item.navigation}\n leadingVisual={item.icon}\n aria-current={index === selectedIndex ? 'page' : undefined}\n onSelect={() => setSelectedIndex(index)}\n counter={item.counter}\n >\n {item.navigation}\n </UnderlineNav.Item>\n ))}\n </UnderlineNav>\n )\n}"
7902
8385
  },
7903
8386
  {
7904
- "id": "components-underlinenav-features--variant-flush"
8387
+ "id": "components-underlinenav-features--variant-flush",
8388
+ "code": "() => {\n return (\n <UnderlineNav aria-label=\"Repository\" variant=\"flush\">\n <UnderlineNav.Item aria-current=\"page\">Code</UnderlineNav.Item>\n <UnderlineNav.Item>Issues</UnderlineNav.Item>\n <UnderlineNav.Item>Pull Requests</UnderlineNav.Item>\n </UnderlineNav>\n )\n}"
7905
8389
  }
7906
8390
  ],
7907
8391
  "importPath": "@primer/react",
@@ -7995,10 +8479,8 @@
7995
8479
  "a11yReviewed": false,
7996
8480
  "stories": [
7997
8481
  {
7998
- "id": "deprecated-components-dialog--default"
7999
- },
8000
- {
8001
- "id": "components-dialog--default"
8482
+ "id": "components-dialog--default",
8483
+ "code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const returnFocusRef = useRef(null)\n return (\n <div>\n <div\n style={{\n marginBottom: 'var(--stack-gap-normal)',\n }}\n >\n <Banner\n title=\"This component is deprecated\"\n description=\"We recommend using Dialog instead.\"\n variant=\"warning\"\n />\n </div>\n <Button\n data-testid=\"trigger-button\"\n ref={returnFocusRef}\n onClick={() => setIsOpen(true)}\n >\n Show Dialog\n </Button>\n <Dialog\n returnFocusRef={returnFocusRef}\n isOpen={isOpen}\n onDismiss={() => setIsOpen(false)}\n aria-labelledby=\"header\"\n >\n <div data-testid=\"inner\">\n <Dialog.Header id=\"header\">Title</Dialog.Header>\n <div\n style={{\n padding: 'var(--stack-gap-normal)',\n }}\n >\n <Text>Some content</Text>\n </div>\n </div>\n </Dialog>\n </div>\n )\n}"
8002
8484
  }
8003
8485
  ],
8004
8486
  "importPath": "@primer/react/deprecated",
@@ -8057,7 +8539,8 @@
8057
8539
  "a11yReviewed": false,
8058
8540
  "stories": [
8059
8541
  {
8060
- "id": "deprecated-components-filteredsearch--default"
8542
+ "id": "deprecated-components-filteredsearch--default",
8543
+ "code": "() => (\n <FilteredSearch>\n <ActionMenu>\n <ActionMenu.Button as=\"summary\">Filter</ActionMenu.Button>\n <ActionMenu.Overlay>\n <ActionList>\n <ActionList.Item>Item 1</ActionList.Item>\n <ActionList.Item>Item 2</ActionList.Item>\n <ActionList.Item>Item 3</ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n <TextInput aria-label=\"Filtered search\" leadingVisual={SearchIcon} />\n </FilteredSearch>\n)"
8061
8544
  }
8062
8545
  ],
8063
8546
  "importPath": "@primer/react/deprecated",
@@ -8078,10 +8561,12 @@
8078
8561
  "a11yReviewed": "2025-01-08",
8079
8562
  "stories": [
8080
8563
  {
8081
- "id": "deprecated-components-underlinenav--default"
8564
+ "id": "deprecated-components-underlinenav--default",
8565
+ "code": "() => (\n <UnderlineNav aria-label=\"Main\">\n <UnderlineNav.Link href=\"#home\" selected>\n Home\n </UnderlineNav.Link>\n <UnderlineNav.Link href=\"#documentation\">Documentation</UnderlineNav.Link>\n <UnderlineNav.Link href=\"#support\">Support</UnderlineNav.Link>\n </UnderlineNav>\n)"
8082
8566
  },
8083
8567
  {
8084
- "id": "deprecated-components-underlinenav-features--actions"
8568
+ "id": "deprecated-components-underlinenav-features--actions",
8569
+ "code": "() => (\n <UnderlineNav aria-label=\"Main\" actions={<Button>Click me</Button>}>\n <UnderlineNav.Link href=\"#home\" selected>\n Home\n </UnderlineNav.Link>\n <UnderlineNav.Link href=\"#documentation\">Documentation</UnderlineNav.Link>\n <UnderlineNav.Link href=\"#support\">Support</UnderlineNav.Link>\n </UnderlineNav>\n)"
8085
8570
  }
8086
8571
  ],
8087
8572
  "importPath": "@primer/react/deprecated",
@@ -8136,16 +8621,16 @@
8136
8621
  "a11yReviewed": "2025-01-08",
8137
8622
  "stories": [
8138
8623
  {
8139
- "id": "components-issuelabel--default"
8140
- },
8141
- {
8142
- "id": "experimental-components-issuelabel--default"
8624
+ "id": "experimental-components-issuelabel--default",
8625
+ "code": "() => <IssueLabel>Issue label</IssueLabel>"
8143
8626
  },
8144
8627
  {
8145
- "id": "experimental-components-issuelabel-features--group-of-labels"
8628
+ "id": "experimental-components-issuelabel-features--group-of-labels",
8629
+ "code": "() => (\n <Stack direction=\"horizontal\" gap=\"condensed\" wrap=\"wrap\">\n <IssueLabel variant=\"blue\">Issue label</IssueLabel>\n <IssueLabel variant=\"purple\">Another label</IssueLabel>\n <IssueLabel variant=\"green\">A third label</IssueLabel>\n <IssueLabel variant=\"orange\">Issue label</IssueLabel>\n <IssueLabel variant=\"yellow\">Another label</IssueLabel>\n <IssueLabel variant=\"brown\">A third label</IssueLabel>\n </Stack>\n)"
8146
8630
  },
8147
8631
  {
8148
- "id": "experimental-components-issuelabel-features--hex-color"
8632
+ "id": "experimental-components-issuelabel-features--hex-color",
8633
+ "code": "(args: { fillColor: `#${string}` }) => {\n return <IssueLabel fillColor={args.fillColor}>Issue label</IssueLabel>\n}"
8149
8634
  }
8150
8635
  ],
8151
8636
  "importPath": "@primer/react/experimental",
@@ -8183,34 +8668,44 @@
8183
8668
  "a11yReviewed": false,
8184
8669
  "stories": [
8185
8670
  {
8186
- "id": "deprecated-components-selectpanel--default"
8671
+ "id": "deprecated-components-selectpanel--default",
8672
+ "code": "() => {\n const initialSelectedLabels = data.issue.labelIds // mock initial state: has selected labels\n const [selectedLabelIds, setSelectedLabelIds] = React.useState<string[]>(\n initialSelectedLabels,\n )\n\n /* Selection */\n const onLabelSelect = (labelId: string) => {\n if (!selectedLabelIds.includes(labelId))\n setSelectedLabelIds([...selectedLabelIds, labelId])\n else setSelectedLabelIds(selectedLabelIds.filter((id) => id !== labelId))\n }\n const onClearSelection = () => {\n setSelectedLabelIds([])\n }\n const onSubmit = () => {\n data.issue.labelIds = selectedLabelIds // pretending to persist changes\n }\n const onCancel = () => {\n setSelectedLabelIds(initialSelectedLabels)\n }\n\n /* Filtering */\n const [filteredLabels, setFilteredLabels] = React.useState(data.labels)\n const [query, setQuery] = React.useState('')\n const onSearchInputChange: React.ChangeEventHandler<HTMLInputElement> = (\n event,\n ) => {\n const query = event.currentTarget.value\n setQuery(query)\n if (query === '') setFilteredLabels(data.labels)\n else {\n setFilteredLabels(\n data.labels\n .map((label) => {\n if (label.name.toLowerCase().startsWith(query))\n return {\n priority: 1,\n label,\n }\n else if (label.name.toLowerCase().includes(query))\n return {\n priority: 2,\n label,\n }\n else if (label.description?.toLowerCase().includes(query))\n return {\n priority: 3,\n label,\n }\n else\n return {\n priority: -1,\n label,\n }\n })\n .filter((result) => result.priority > 0)\n .map((result) => result.label),\n )\n }\n }\n const sortingFn = (\n itemA: {\n id: string\n },\n itemB: {\n id: string\n },\n ) => {\n const initialSelectedIds = data.issue.labelIds\n if (\n initialSelectedIds.includes(itemA.id) &&\n initialSelectedIds.includes(itemB.id)\n )\n return 1\n else if (initialSelectedIds.includes(itemA.id)) return -1\n else if (initialSelectedIds.includes(itemB.id)) return 1\n else return 1\n }\n const itemsToShow = query ? filteredLabels : data.labels.sort(sortingFn)\n return (\n <>\n <SelectPanel\n title=\"Select labels\"\n onSubmit={onSubmit}\n onCancel={onCancel}\n onClearSelection={onClearSelection}\n >\n <SelectPanel.Button>Assign label</SelectPanel.Button>\n\n <SelectPanel.Header>\n <SelectPanel.SearchInput\n aria-label=\"Search\"\n onChange={onSearchInputChange}\n />\n </SelectPanel.Header>\n\n {itemsToShow.length === 0 ? (\n <SelectPanel.Message\n variant=\"empty\"\n title={`No labels found for \"${query}\"`}\n >\n Try a different search term\n </SelectPanel.Message>\n ) : (\n <ActionList>\n {itemsToShow.map((label) => (\n <ActionList.Item\n key={label.id}\n onSelect={() => onLabelSelect(label.id)}\n selected={selectedLabelIds.includes(label.id)}\n >\n <ActionList.LeadingVisual>\n <div\n className={sharedClasses.Circle}\n style={{\n backgroundColor: `#${label.color}`,\n }}\n />\n </ActionList.LeadingVisual>\n {label.name}\n <ActionList.Description variant=\"block\">\n {label.description}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )}\n\n <SelectPanel.Footer>\n <SelectPanel.SecondaryAction variant=\"button\">\n Edit labels\n </SelectPanel.SecondaryAction>\n </SelectPanel.Footer>\n </SelectPanel>\n </>\n )\n}"
8187
8673
  },
8188
8674
  {
8189
- "id": "deprecated-components-selectpanel-examples--minimal"
8675
+ "id": "deprecated-components-selectpanel-examples--minimal",
8676
+ "code": "() => {\n const initialSelectedLabels = data.issue.labelIds // mock initial state: has selected labels\n const [selectedLabelIds, setSelectedLabelIds] = React.useState<string[]>(\n initialSelectedLabels,\n )\n\n /* Selection */\n const onLabelSelect = (labelId: string) => {\n if (!selectedLabelIds.includes(labelId))\n setSelectedLabelIds([...selectedLabelIds, labelId])\n else setSelectedLabelIds(selectedLabelIds.filter((id) => id !== labelId))\n }\n const onSubmit = () => {\n data.issue.labelIds = selectedLabelIds // pretending to persist changes\n\n // eslint-disable-next-line no-console\n console.log('form submitted')\n }\n const onCancel = () => {\n setSelectedLabelIds(initialSelectedLabels)\n }\n const sortingFn = (\n itemA: {\n id: string\n },\n itemB: {\n id: string\n },\n ) => {\n const initialSelectedIds = data.issue.labelIds\n if (\n initialSelectedIds.includes(itemA.id) &&\n initialSelectedIds.includes(itemB.id)\n )\n return 1\n else if (initialSelectedIds.includes(itemA.id)) return -1\n else if (initialSelectedIds.includes(itemB.id)) return 1\n else return 1\n }\n const itemsToShow = data.labels.sort(sortingFn)\n return (\n <>\n <h1>Minimal SelectPanel</h1>\n\n <SelectPanel\n title=\"Select labels\"\n onSubmit={onSubmit}\n onCancel={onCancel}\n >\n <SelectPanel.Button>Assign label</SelectPanel.Button>\n\n <ActionList>\n {itemsToShow.map((label) => (\n <ActionList.Item\n key={label.id}\n onSelect={() => onLabelSelect(label.id)}\n selected={selectedLabelIds.includes(label.id)}\n >\n <ActionList.LeadingVisual>\n {getCircle(label.color)}\n </ActionList.LeadingVisual>\n {label.name}\n <ActionList.Description variant=\"block\">\n {label.description}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
8190
8677
  },
8191
8678
  {
8192
- "id": "deprecated-components-selectpanel-examples--short-select-panel"
8679
+ "id": "deprecated-components-selectpanel-examples--short-select-panel",
8680
+ "code": "() => {\n const initialChannels = {\n GitHub: false,\n Email: false,\n }\n const [channels, setChannels] = React.useState(initialChannels)\n const [onlyFailures, setOnlyFailures] = React.useState(false)\n const onSubmit = () => {\n // eslint-disable-next-line no-console\n console.log('form submitted')\n }\n const onCancel = () => {\n setChannels(initialChannels)\n }\n const toggleChannel = (channel: keyof typeof channels) => {\n setChannels({\n ...channels,\n [channel]: !channels[channel],\n })\n }\n const channelsEnabled = channels.GitHub || channels.Email\n return (\n <>\n <h1>Short SelectPanel</h1>\n <p>\n Use <code>height=fit-content</code> to match height of contents\n </p>\n <SelectPanel\n title=\"Select notification channels\"\n onSubmit={onSubmit}\n onCancel={onCancel}\n >\n <SelectPanel.Button>\n <Text className={classes.TextMuted}>Notify me:</Text>{' '}\n {Object.keys(channels)\n .filter((channel) => channels[channel as keyof typeof channels])\n .join(', ') || 'Never'}\n {onlyFailures && channelsEnabled && ' (Failed workflows only)'}\n </SelectPanel.Button>\n\n <ActionList>\n <ActionList.Item\n selected={channels.GitHub}\n onSelect={() => toggleChannel('GitHub')}\n >\n On GitHub\n </ActionList.Item>\n <ActionList.Item\n selected={channels.Email}\n onSelect={() => toggleChannel('Email')}\n >\n Email\n </ActionList.Item>\n <div\n role=\"none\"\n className={`${classes.TransitionBox} ${channelsEnabled ? classes.TransitionBoxVisible : classes.TransitionBoxHidden}`}\n >\n <ActionList.Divider />\n <ActionList.Item\n selected={onlyFailures}\n onSelect={() => setOnlyFailures(!onlyFailures)}\n >\n Only notify for failed workflows\n </ActionList.Item>\n </div>\n </ActionList>\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
8193
8681
  },
8194
8682
  {
8195
- "id": "deprecated-components-selectpanel-features--instant-selection-variant"
8683
+ "id": "deprecated-components-selectpanel-features--instant-selection-variant",
8684
+ "code": "() => {\n const [selectedTag, setSelectedTag] = React.useState<string>()\n const onSubmit = () => {\n if (!selectedTag) return\n data.ref = selectedTag // pretending to persist changes\n }\n const itemsToShow = data.tags\n return (\n <>\n <h1>Instant selection variant</h1>\n\n <SelectPanel\n title=\"Choose a tag\"\n selectionVariant=\"instant\"\n onSubmit={onSubmit}\n >\n <SelectPanel.Button leadingVisual={TagIcon}>\n {selectedTag || 'Choose a tag'}\n </SelectPanel.Button>\n\n <ActionList>\n {itemsToShow.map((tag) => (\n <ActionList.Item\n key={tag.id}\n onSelect={() => setSelectedTag(tag.id)}\n selected={selectedTag === tag.id}\n >\n {tag.name}\n </ActionList.Item>\n ))}\n </ActionList>\n <SelectPanel.Footer>\n <SelectPanel.SecondaryAction variant=\"button\">\n Edit tags\n </SelectPanel.SecondaryAction>\n </SelectPanel.Footer>\n </SelectPanel>\n </>\n )\n}"
8196
8685
  },
8197
8686
  {
8198
- "id": "deprecated-components-selectpanel-features--with-warning"
8687
+ "id": "deprecated-components-selectpanel-features--with-warning",
8688
+ "code": "() => {\n /* Selection */\n\n const initialAssigneeIds = data.issue.assigneeIds // mock initial state\n const [selectedAssigneeIds, setSelectedAssigneeIds] =\n React.useState<string[]>(initialAssigneeIds)\n const MAX_LIMIT = 3\n const onCollaboratorSelect = (colloratorId: string) => {\n if (!selectedAssigneeIds.includes(colloratorId))\n setSelectedAssigneeIds([...selectedAssigneeIds, colloratorId])\n else\n setSelectedAssigneeIds(\n selectedAssigneeIds.filter((id) => id !== colloratorId),\n )\n }\n const onClearSelection = () => setSelectedAssigneeIds([])\n const onSubmit = () => {\n data.issue.assigneeIds = selectedAssigneeIds // pretending to persist changes\n }\n const onCancel = () => {\n setSelectedAssigneeIds(initialAssigneeIds)\n }\n\n /* Filtering */\n const [filteredUsers, setFilteredUsers] = React.useState(data.collaborators)\n const [query, setQuery] = React.useState('')\n const onSearchInputChange: React.ChangeEventHandler<HTMLInputElement> = (\n event,\n ) => {\n const query = event.currentTarget.value\n setQuery(query)\n if (query === '') setFilteredUsers(data.collaborators)\n else {\n setFilteredUsers(\n data.collaborators\n .map((collaborator) => {\n if (collaborator.login.toLowerCase().startsWith(query))\n return {\n priority: 1,\n collaborator,\n }\n else if (collaborator.name.startsWith(query))\n return {\n priority: 2,\n collaborator,\n }\n else if (collaborator.login.toLowerCase().includes(query))\n return {\n priority: 3,\n collaborator,\n }\n else if (collaborator.name.toLowerCase().includes(query))\n return {\n priority: 4,\n collaborator,\n }\n else\n return {\n priority: -1,\n collaborator,\n }\n })\n .filter((result) => result.priority > 0)\n .map((result) => result.collaborator),\n )\n }\n }\n const sortingFn = (\n itemA: {\n id: string\n },\n itemB: {\n id: string\n },\n ) => {\n const initialSelectedIds = data.issue.assigneeIds\n if (\n initialSelectedIds.includes(itemA.id) &&\n initialSelectedIds.includes(itemB.id)\n )\n return 1\n else if (initialSelectedIds.includes(itemA.id)) return -1\n else if (initialSelectedIds.includes(itemB.id)) return 1\n else return 1\n }\n const itemsToShow = query ? filteredUsers : data.collaborators.sort(sortingFn)\n return (\n <>\n <h1>SelectPanel with warning</h1>\n\n <SelectPanel\n title=\"Set assignees\"\n description={`Select up to ${MAX_LIMIT} people`}\n onSubmit={onSubmit}\n onCancel={onCancel}\n onClearSelection={onClearSelection}\n >\n <SelectPanel.Button\n variant=\"invisible\"\n trailingAction={GearIcon}\n className={classes.ButtonCustom}\n >\n Assignees\n </SelectPanel.Button>\n <SelectPanel.Header>\n <SelectPanel.SearchInput\n onChange={onSearchInputChange}\n aria-label=\"Search\"\n />\n </SelectPanel.Header>\n\n {selectedAssigneeIds.length >= MAX_LIMIT ? (\n <SelectPanel.Message variant=\"warning\" size=\"inline\">\n You have reached the limit of {MAX_LIMIT} assignees on your free\n account. <Link href=\"/upgrade\">Upgrade your account.</Link>\n </SelectPanel.Message>\n ) : null}\n\n {itemsToShow.length === 0 ? (\n <SelectPanel.Message\n variant=\"empty\"\n title={`No labels found for \"${query}\"`}\n >\n Try a different search term\n </SelectPanel.Message>\n ) : (\n <ActionList>\n {itemsToShow.map((collaborator) => (\n <ActionList.Item\n key={collaborator.id}\n onSelect={() => onCollaboratorSelect(collaborator.id)}\n selected={selectedAssigneeIds.includes(collaborator.id)}\n disabled={\n selectedAssigneeIds.length >= MAX_LIMIT &&\n !selectedAssigneeIds.includes(collaborator.id)\n }\n >\n <ActionList.LeadingVisual>\n <Avatar\n src={`https://github.com/${collaborator.login}.png`}\n />\n </ActionList.LeadingVisual>\n {collaborator.login}\n <ActionList.Description>\n {collaborator.login}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList>\n )}\n\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
8199
8689
  },
8200
8690
  {
8201
- "id": "deprecated-components-selectpanel-examples--open-from-menu"
8691
+ "id": "deprecated-components-selectpanel-examples--open-from-menu",
8692
+ "code": "() => {\n /* Open state */\n const [menuOpen, setMenuOpen] = React.useState(false)\n const [selectPanelOpen, setSelectPanelOpen] = React.useState(false)\n\n /* Selection */\n const [selectedSetting, setSelectedSetting] =\n React.useState<string>('All activity')\n const initialCustomEvents: string[] = []\n const [selectedCustomEvents, setSelectedCustomEvents] =\n React.useState<string[]>(initialCustomEvents)\n const onEventSelect = (event: string) => {\n if (!selectedCustomEvents.includes(event))\n setSelectedCustomEvents([...selectedCustomEvents, event])\n else\n setSelectedCustomEvents(\n selectedCustomEvents.filter((name) => name !== event),\n )\n }\n const itemsToShow = [\n 'Issues',\n 'Pull requests',\n 'Releases',\n 'Discussions',\n 'Security alerts',\n ]\n return (\n <>\n <h1>Open in modal from ActionMenu</h1>\n\n <ActionMenu open={menuOpen} onOpenChange={(value) => setMenuOpen(value)}>\n <ActionMenu.Button leadingVisual={EyeIcon}>\n {selectedSetting === 'Ignore' ? 'Watch' : 'Unwatch'}\n </ActionMenu.Button>\n <ActionMenu.Overlay width=\"medium\">\n <ActionList selectionVariant=\"single\">\n <ActionList.Item\n selected={selectedSetting === 'Participating and @mentions'}\n onSelect={() => setSelectedSetting('Participating and @mentions')}\n >\n Participating and @mentions\n <ActionList.Description variant=\"block\">\n Only receive notifications from this repository when\n participating or @mentioned.\n </ActionList.Description>\n </ActionList.Item>\n <ActionList.Item\n selected={selectedSetting === 'All activity'}\n onSelect={() => setSelectedSetting('All activity')}\n >\n All activity\n <ActionList.Description variant=\"block\">\n Notified of all notifications on this repository.\n </ActionList.Description>\n </ActionList.Item>\n <ActionList.Item\n selected={selectedSetting === 'Ignore'}\n onSelect={() => setSelectedSetting('Ignore')}\n >\n Ignore\n <ActionList.Description variant=\"block\">\n Never be notified.\n </ActionList.Description>\n </ActionList.Item>\n <ActionList.Item\n selected={selectedSetting === 'Custom'}\n onSelect={() => {\n setMenuOpen(false)\n setSelectPanelOpen(true)\n }}\n >\n Custom\n <ActionList.TrailingVisual>\n <ArrowRightIcon />\n </ActionList.TrailingVisual>\n <ActionList.Description variant=\"block\">\n Select events you want to be notified of in addition to\n participating and @mentions.\n </ActionList.Description>\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n <SelectPanel\n variant=\"modal\"\n title=\"Custom\"\n open={selectPanelOpen}\n onSubmit={() => {\n setSelectedSetting('Custom')\n setSelectPanelOpen(false)\n setMenuOpen(false)\n }}\n onCancel={() => {\n setSelectedCustomEvents(initialCustomEvents)\n setSelectPanelOpen(false)\n setMenuOpen(true)\n }}\n >\n <ActionList>\n {itemsToShow.map((item) => (\n <ActionList.Item\n key={item}\n onSelect={() => onEventSelect(item)}\n selected={selectedCustomEvents.includes(item)}\n >\n {item}\n </ActionList.Item>\n ))}\n </ActionList>\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
8202
8693
  },
8203
8694
  {
8204
- "id": "deprecated-components-selectpanel-examples--with-groups"
8695
+ "id": "deprecated-components-selectpanel-examples--with-groups",
8696
+ "code": "() => {\n /* Selection */\n const initialAssigneeIds = data.issue.assigneeIds // mock initial state\n const [selectedAssigneeIds, setSelectedAssigneeIds] =\n React.useState<string[]>(initialAssigneeIds)\n const onCollaboratorSelect = (collaboratorId: string) => {\n if (!selectedAssigneeIds.includes(collaboratorId))\n setSelectedAssigneeIds([...selectedAssigneeIds, collaboratorId])\n else\n setSelectedAssigneeIds(\n selectedAssigneeIds.filter((id) => id !== collaboratorId),\n )\n }\n const onClearSelection = () => setSelectedAssigneeIds([])\n const onSubmit = () => {\n data.issue.assigneeIds = selectedAssigneeIds // pretending to persist changes\n }\n const onCancel = () => {\n setSelectedAssigneeIds(initialAssigneeIds)\n }\n\n /* Filtering */\n const [filteredUsers, setFilteredUsers] = React.useState(data.collaborators)\n const [query, setQuery] = React.useState('')\n const onSearchInputChange: React.ChangeEventHandler<HTMLInputElement> = (\n event,\n ) => {\n const query = event.currentTarget.value\n setQuery(query)\n if (query === '') setFilteredUsers(data.collaborators)\n else {\n setFilteredUsers(\n data.collaborators\n .map((collaborator) => {\n if (collaborator.login.toLowerCase().startsWith(query))\n return {\n priority: 1,\n collaborator,\n }\n else if (collaborator.name.startsWith(query))\n return {\n priority: 2,\n collaborator,\n }\n else if (collaborator.login.toLowerCase().includes(query))\n return {\n priority: 3,\n collaborator,\n }\n else if (collaborator.name.toLowerCase().includes(query))\n return {\n priority: 4,\n collaborator,\n }\n else\n return {\n priority: -1,\n collaborator,\n }\n })\n .filter((result) => result.priority > 0)\n .map((result) => result.collaborator),\n )\n }\n }\n const sortingFn = (\n itemA: {\n id: string\n },\n itemB: {\n id: string\n },\n ) => {\n const initialSelectedIds = data.issue.assigneeIds\n if (\n initialSelectedIds.includes(itemA.id) &&\n initialSelectedIds.includes(itemB.id)\n )\n return 1\n else if (initialSelectedIds.includes(itemA.id)) return -1\n else if (initialSelectedIds.includes(itemB.id)) return 1\n else return 1\n }\n const itemsToShow = query ? filteredUsers : data.collaborators.sort(sortingFn)\n return (\n <>\n <h1>SelectPanel with groups</h1>\n\n <SelectPanel\n title=\"Request up to 100 reviewers\"\n onSubmit={onSubmit}\n onCancel={onCancel}\n onClearSelection={onClearSelection}\n >\n <SelectPanel.Button\n variant=\"invisible\"\n trailingAction={GearIcon}\n style={{\n width: '200px',\n }}\n className={classes.ButtonContentStartJustify}\n >\n Reviewers\n </SelectPanel.Button>\n <SelectPanel.Header>\n <SelectPanel.SearchInput onChange={onSearchInputChange} />\n </SelectPanel.Header>\n\n {itemsToShow.length === 0 ? (\n <SelectPanel.Message\n variant=\"empty\"\n title={`No labels found for \"${query}\"`}\n >\n Try a different search term\n </SelectPanel.Message>\n ) : (\n <ActionList>\n <ActionList.Group>\n <ActionList.GroupHeading variant=\"filled\">\n Suggestions\n </ActionList.GroupHeading>\n {itemsToShow\n .filter((collaborator) => collaborator.recommended)\n .map((collaborator) => (\n <ActionList.Item\n key={collaborator.id}\n onSelect={() => onCollaboratorSelect(collaborator.id)}\n selected={selectedAssigneeIds.includes(collaborator.id)}\n >\n <ActionList.LeadingVisual>\n <Avatar\n src={`https://github.com/${collaborator.login}.png`}\n />\n </ActionList.LeadingVisual>\n {collaborator.login}\n <ActionList.Description>\n {collaborator.login}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList.Group>\n <ActionList.Group>\n <ActionList.GroupHeading variant=\"filled\">\n Everyone else\n </ActionList.GroupHeading>\n {itemsToShow\n .filter((collaborator) => !collaborator.recommended)\n .map((collaborator) => (\n <ActionList.Item\n key={collaborator.id}\n onSelect={() => onCollaboratorSelect(collaborator.id)}\n selected={selectedAssigneeIds.includes(collaborator.id)}\n >\n <ActionList.LeadingVisual>\n <Avatar\n src={`https://github.com/${collaborator.login}.png`}\n />\n </ActionList.LeadingVisual>\n {collaborator.login}\n <ActionList.Description>\n {collaborator.login}\n </ActionList.Description>\n </ActionList.Item>\n ))}\n </ActionList.Group>\n </ActionList>\n )}\n\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
8205
8697
  },
8206
8698
  {
8207
- "id": "deprecated-components-selectpanel-examples--async-search-with-use-transition"
8699
+ "id": "deprecated-components-selectpanel-examples--async-search-with-use-transition",
8700
+ "code": "() => {\n const [isPending, startTransition] = React.useTransition()\n const [query, setQuery] = React.useState('')\n const onSearchInputChange: React.ChangeEventHandler<HTMLInputElement> = (\n event,\n ) => {\n const query = event.currentTarget.value\n startTransition(() => setQuery(query))\n }\n\n /* Selection */\n const initialAssigneeIds: string[] = data.issue.assigneeIds\n const [selectedUserIds, setSelectedUserIds] =\n React.useState<string[]>(initialAssigneeIds)\n const onUserSelect = (userId: string) => {\n if (!selectedUserIds.includes(userId))\n setSelectedUserIds([...selectedUserIds, userId])\n else setSelectedUserIds(selectedUserIds.filter((id) => id !== userId))\n }\n const onSubmit = () => {\n data.issue.assigneeIds = selectedUserIds // pretending to persist changes\n // eslint-disable-next-line no-console\n console.log('form submitted')\n }\n const onCancel = () => {\n setSelectedUserIds(initialAssigneeIds)\n }\n return (\n <>\n <h1>Async: search with useTransition</h1>\n <p>Fetching items on every keystroke search (like github users)</p>\n\n <SelectPanel\n title=\"Select collaborators\"\n onSubmit={onSubmit}\n onCancel={onCancel}\n >\n <SelectPanel.Button>Select assignees</SelectPanel.Button>\n <SelectPanel.Header>\n <SelectPanel.SearchInput\n loading={isPending}\n onChange={onSearchInputChange}\n />\n </SelectPanel.Header>\n\n <SearchableUserList\n query={query}\n initialAssigneeIds={initialAssigneeIds}\n selectedUserIds={selectedUserIds}\n onUserSelect={onUserSelect}\n />\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
8208
8701
  },
8209
8702
  {
8210
- "id": "deprecated-components-selectpanel-examples--async-with-suspended-list"
8703
+ "id": "deprecated-components-selectpanel-examples--async-with-suspended-list",
8704
+ "code": "() => {\n const [query, setQuery] = React.useState('')\n const onSearchInputChange: React.ChangeEventHandler<HTMLInputElement> = (\n event,\n ) => {\n const query = event.currentTarget.value\n setQuery(query)\n }\n return (\n <>\n <h1>Async: Suspended list</h1>\n <p>\n Fetching items once when the panel is opened (like repo labels)\n <br />\n Note: Save and Cancel is not implemented in this demo\n </p>\n\n <SelectPanel title=\"Select labels\">\n <SelectPanel.Button>Assign label</SelectPanel.Button>\n\n <SelectPanel.Header>\n <SelectPanel.SearchInput onChange={onSearchInputChange} />\n </SelectPanel.Header>\n\n <React.Suspense\n fallback={\n <SelectPanel.Loading>Fetching labels...</SelectPanel.Loading>\n }\n >\n <SuspendedActionList query={query} />\n <SelectPanel.Footer>\n <SelectPanel.SecondaryAction variant=\"link\" href=\"/settings\">\n Edit labels\n </SelectPanel.SecondaryAction>\n </SelectPanel.Footer>\n </React.Suspense>\n </SelectPanel>\n </>\n )\n}"
8211
8705
  },
8212
8706
  {
8213
- "id": "deprecated-components-selectpanel-examples--with-filter-buttons"
8707
+ "id": "deprecated-components-selectpanel-examples--with-filter-buttons",
8708
+ "code": "() => {\n const [selectedFilter, setSelectedFilter] = React.useState<\n 'branches' | 'tags'\n >('branches')\n\n /* Selection */\n const [savedInitialRef, setSavedInitialRef] = React.useState(data.ref)\n const [selectedRef, setSelectedRef] = React.useState(savedInitialRef)\n const onSubmit = () => {\n setSavedInitialRef(selectedRef)\n data.ref = selectedRef // pretending to persist changes\n\n // eslint-disable-next-line no-console\n console.log('form submitted')\n }\n const onCancel = () => {\n setSelectedRef(savedInitialRef)\n }\n\n /* Filter */\n const [query, setQuery] = React.useState('')\n const onSearchInputChange: React.ChangeEventHandler<HTMLInputElement> = (\n event,\n ) => {\n const query = event.currentTarget.value\n setQuery(query)\n }\n const [filteredRefs, setFilteredRefs] = React.useState(data.branches)\n const setSearchResults = (\n query: string,\n selectedFilter: 'branches' | 'tags',\n ) => {\n if (query === '') setFilteredRefs(data[selectedFilter])\n else {\n setFilteredRefs(\n data[selectedFilter]\n .map((item) => {\n if (item.name.toLowerCase().startsWith(query))\n return {\n priority: 1,\n item,\n }\n else if (item.name.toLowerCase().includes(query))\n return {\n priority: 2,\n item,\n }\n else\n return {\n priority: -1,\n item,\n }\n })\n .filter((result) => result.priority > 0)\n .map((result) => result.item),\n )\n }\n }\n React.useEffect(\n function updateSearchResults() {\n setSearchResults(query, selectedFilter)\n },\n [query, selectedFilter],\n )\n const sortingFn = (ref: { id: string }) => {\n if (ref.id === savedInitialRef) return -1\n else return 1\n }\n const itemsToShow = query\n ? filteredRefs\n : data[selectedFilter].sort(sortingFn)\n return (\n <>\n <h1>With Filter Buttons {savedInitialRef}</h1>\n\n <SelectPanel\n title=\"Switch branches/tags\"\n onSubmit={onSubmit}\n onCancel={onCancel}\n >\n <SelectPanel.Button\n leadingVisual={GitBranchIcon}\n trailingVisual={TriangleDownIcon}\n >\n {savedInitialRef}\n </SelectPanel.Button>\n\n <SelectPanel.Header>\n <SelectPanel.SearchInput onChange={onSearchInputChange} />\n\n <div id=\"filters\" className={classes.FilterButtons}>\n <Button\n variant=\"invisible\"\n style={{\n fontWeight:\n selectedFilter === 'branches'\n ? 'var(--base-text-weight-medium)'\n : 'var(--base-text-weight-normal)',\n color: 'var(--fgColor-default)',\n }}\n onClick={() => setSelectedFilter('branches')}\n count={20}\n >\n Branches\n </Button>\n <Button\n variant=\"invisible\"\n style={{\n fontWeight:\n selectedFilter === 'tags'\n ? 'var(--base-text-weight-medium)'\n : 'var(--base-text-weight-normal)',\n color: 'var(--fgColor-default)',\n }}\n onClick={() => setSelectedFilter('tags')}\n count={8}\n >\n Tags\n </Button>\n </div>\n </SelectPanel.Header>\n\n {itemsToShow.length === 0 ? (\n <SelectPanel.Message\n variant=\"empty\"\n title={`No labels found for \"${query}\"`}\n >\n Try a different search term\n </SelectPanel.Message>\n ) : (\n <ActionList>\n {itemsToShow.map((item) => (\n <ActionList.Item\n key={item.id}\n selected={selectedRef === item.id}\n onSelect={() => setSelectedRef(item.id)}\n >\n {item.name}\n <ActionList.TrailingVisual>\n {item.trailingInfo}\n </ActionList.TrailingVisual>\n </ActionList.Item>\n ))}\n </ActionList>\n )}\n\n <SelectPanel.Footer>\n <SelectPanel.SecondaryAction\n variant=\"link\"\n href={`/${selectedFilter}`}\n >\n View all {selectedFilter}\n </SelectPanel.SecondaryAction>\n </SelectPanel.Footer>\n </SelectPanel>\n </>\n )\n}"
8214
8709
  }
8215
8710
  ],
8216
8711
  "importPath": "@primer/react/experimental",
@@ -8403,25 +8898,32 @@
8403
8898
  "a11yReviewed": "2025-01-08",
8404
8899
  "stories": [
8405
8900
  {
8406
- "id": "experimental-components-underlinepanels--default"
8901
+ "id": "experimental-components-underlinepanels--default",
8902
+ "code": "() => {\n const tabs = ['Tab 1', 'Tab 2', 'Tab 3']\n const panels = ['Panel 1', 'Panel 2', 'Panel 3']\n return (\n <UnderlinePanels aria-label=\"Select a tab\">\n {tabs.map((tab: string, index: number) => (\n <UnderlinePanels.Tab\n key={index}\n aria-selected={index === 0 ? true : undefined}\n >\n {tab}\n </UnderlinePanels.Tab>\n ))}\n {panels.map((panel: string, index: number) => (\n <UnderlinePanels.Panel key={index}>{panel}</UnderlinePanels.Panel>\n ))}\n </UnderlinePanels>\n )\n}"
8407
8903
  },
8408
8904
  {
8409
- "id": "experimental-components-underlinepanels-features--labelled-by-external-element"
8905
+ "id": "experimental-components-underlinepanels-features--labelled-by-external-element",
8906
+ "code": "() => (\n <>\n <h2 id=\"my-heading\">UnderlinePanels example</h2>\n <UnderlinePanels aria-labelledby=\"my-heading\">\n <UnderlinePanels.Tab>Tab 1</UnderlinePanels.Tab>\n <UnderlinePanels.Tab>Tab 2</UnderlinePanels.Tab>\n <UnderlinePanels.Tab>Tab 3</UnderlinePanels.Tab>\n <UnderlinePanels.Panel>Panel 1</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 2</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 3</UnderlinePanels.Panel>\n </UnderlinePanels>\n </>\n)"
8410
8907
  },
8411
8908
  {
8412
- "id": "experimental-components-underlinepanels-features--selected-tab"
8909
+ "id": "experimental-components-underlinepanels-features--selected-tab",
8910
+ "code": "() => (\n <UnderlinePanels aria-label=\"Select a tab\" id=\"tab-panels\">\n <UnderlinePanels.Tab>Tab 1</UnderlinePanels.Tab>\n <UnderlinePanels.Tab aria-selected={true}>Tab 2</UnderlinePanels.Tab>\n <UnderlinePanels.Tab>Tab 3</UnderlinePanels.Tab>\n <UnderlinePanels.Panel>Panel 1</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 2</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 3</UnderlinePanels.Panel>\n </UnderlinePanels>\n)"
8413
8911
  },
8414
8912
  {
8415
- "id": "experimental-components-underlinepanels-features--with-counters"
8913
+ "id": "experimental-components-underlinepanels-features--with-counters",
8914
+ "code": "() => {\n return (\n <UnderlinePanels aria-label=\"Tabs with counters\">\n <UnderlinePanels.Tab counter=\"11K\">Tab 1</UnderlinePanels.Tab>\n <UnderlinePanels.Tab counter={12}>Tab 2</UnderlinePanels.Tab>\n <UnderlinePanels.Panel>Panel 1</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 2</UnderlinePanels.Panel>\n </UnderlinePanels>\n )\n}"
8416
8915
  },
8417
8916
  {
8418
- "id": "experimental-components-underlinepanels-features--with-counters-in-loading-state"
8917
+ "id": "experimental-components-underlinepanels-features--with-counters-in-loading-state",
8918
+ "code": "() => {\n return (\n <UnderlinePanels aria-label=\"Tabs with counters\" loadingCounters>\n <UnderlinePanels.Tab counter=\"11K\">Tab 1</UnderlinePanels.Tab>\n <UnderlinePanels.Tab counter={12}>Tab 2</UnderlinePanels.Tab>\n <UnderlinePanels.Panel>Panel 1</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 2</UnderlinePanels.Panel>\n </UnderlinePanels>\n )\n}"
8419
8919
  },
8420
8920
  {
8421
- "id": "experimental-components-underlinepanels-features--with-icons"
8921
+ "id": "experimental-components-underlinepanels-features--with-icons",
8922
+ "code": "() => (\n <UnderlinePanels aria-label=\"Tabs with icons\">\n <UnderlinePanels.Tab icon={CodeIcon}>Tab 1</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={EyeIcon}>Tab 2</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={GitPullRequestIcon}>Tab 3</UnderlinePanels.Tab>\n <UnderlinePanels.Panel>Panel 1</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 2</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 3</UnderlinePanels.Panel>\n </UnderlinePanels>\n)"
8422
8923
  },
8423
8924
  {
8424
- "id": "experimental-components-underlinepanels-features--with-icons-hidden-on-narrow-screen"
8925
+ "id": "experimental-components-underlinepanels-features--with-icons-hidden-on-narrow-screen",
8926
+ "code": "() => (\n <UnderlinePanels aria-label=\"Tabs with icons\">\n <UnderlinePanels.Tab icon={CodeIcon}>Tab 1</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={EyeIcon}>Tab 2</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={GitPullRequestIcon}>Tab 3</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={CommentDiscussionIcon}>\n Tab 4\n </UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={PlayIcon}>Tab 5</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={ProjectIcon}>Tab 6</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={GraphIcon}>Tab 7</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={GearIcon}>Tab 8</UnderlinePanels.Tab>\n <UnderlinePanels.Tab icon={ShieldLockIcon}>Tab 9</UnderlinePanels.Tab>\n <UnderlinePanels.Panel>Panel 1</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 2</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 3</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 4</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 5</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 6</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 7</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 8</UnderlinePanels.Panel>\n <UnderlinePanels.Panel>Panel 9</UnderlinePanels.Panel>\n </UnderlinePanels>\n)"
8425
8927
  }
8426
8928
  ],
8427
8929
  "importPath": "@primer/react/experimental",