@primer/react 37.0.0 → 37.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @primer/react
2
2
 
3
+ ## 37.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5162](https://github.com/primer/react/pull/5162) [`a5feea7`](https://github.com/primer/react/commit/a5feea7e8425a9f32fd23eb69aaad8126b8e0216) Thanks [@joshblack](https://github.com/joshblack)! - Update generated docs for draft components to use experimental instead
8
+
3
9
  ## 37.0.0
4
10
 
5
11
  ### Major Changes
@@ -2220,51 +2220,51 @@
2220
2220
  "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)"
2221
2221
  },
2222
2222
  {
2223
- "id": "drafts-components-datatable-features--with-title",
2223
+ "id": "experimental-components-datatable-features--with-title",
2224
2224
  "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)"
2225
2225
  },
2226
2226
  {
2227
- "id": "drafts-components-datatable-features--with-title-and-subtitle",
2227
+ "id": "experimental-components-datatable-features--with-title-and-subtitle",
2228
2228
  "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)"
2229
2229
  },
2230
2230
  {
2231
- "id": "drafts-components-datatable-features--with-sorting",
2231
+ "id": "experimental-components-datatable-features--with-sorting",
2232
2232
  "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}"
2233
2233
  },
2234
2234
  {
2235
- "id": "drafts-components-datatable-features--with-actions",
2235
+ "id": "experimental-components-datatable-features--with-actions",
2236
2236
  "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)"
2237
2237
  },
2238
2238
  {
2239
- "id": "drafts-components-datatable-features--with-action",
2239
+ "id": "experimental-components-datatable-features--with-action",
2240
2240
  "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)"
2241
2241
  },
2242
2242
  {
2243
- "id": "drafts-components-datatable-features--with-row-action",
2243
+ "id": "experimental-components-datatable-features--with-row-action",
2244
2244
  "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)"
2245
2245
  },
2246
2246
  {
2247
- "id": "drafts-components-datatable-features--with-row-actions",
2247
+ "id": "experimental-components-datatable-features--with-row-actions",
2248
2248
  "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)"
2249
2249
  },
2250
2250
  {
2251
- "id": "drafts-components-datatable-features--with-row-action-menu",
2251
+ "id": "experimental-components-datatable-features--with-row-action-menu",
2252
2252
  "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)"
2253
2253
  },
2254
2254
  {
2255
- "id": "drafts-components-datatable-features--with-custom-heading",
2255
+ "id": "experimental-components-datatable-features--with-custom-heading",
2256
2256
  "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)"
2257
2257
  },
2258
2258
  {
2259
- "id": "drafts-components-datatable-features--with-no-content",
2259
+ "id": "experimental-components-datatable-features--with-no-content",
2260
2260
  "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}"
2261
2261
  },
2262
2262
  {
2263
- "id": "drafts-components-datatable-features--with-loading",
2263
+ "id": "experimental-components-datatable-features--with-loading",
2264
2264
  "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}"
2265
2265
  },
2266
2266
  {
2267
- "id": "drafts-components-datatable-features--with-pagination",
2267
+ "id": "experimental-components-datatable-features--with-pagination",
2268
2268
  "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}"
2269
2269
  }
2270
2270
  ],
@@ -3127,19 +3127,19 @@
3127
3127
  "code": "() => {\n return (\n <InlineMessage variant=\"unavailable\">\n An example inline message\n </InlineMessage>\n )\n}"
3128
3128
  },
3129
3129
  {
3130
- "id": "drafts-components-inlinemessage-features--critical",
3130
+ "id": "experimental-components-inlinemessage-features--critical",
3131
3131
  "code": "() => {\n return (\n <InlineMessage variant=\"critical\">An example inline message</InlineMessage>\n )\n}"
3132
3132
  },
3133
3133
  {
3134
- "id": "drafts-components-inlinemessage-features--success",
3134
+ "id": "experimental-components-inlinemessage-features--success",
3135
3135
  "code": "() => {\n return (\n <InlineMessage variant=\"success\">An example inline message</InlineMessage>\n )\n}"
3136
3136
  },
3137
3137
  {
3138
- "id": "drafts-components-inlinemessage-features--unavailable",
3138
+ "id": "experimental-components-inlinemessage-features--unavailable",
3139
3139
  "code": "() => {\n return (\n <InlineMessage variant=\"unavailable\">\n An example inline message\n </InlineMessage>\n )\n}"
3140
3140
  },
3141
3141
  {
3142
- "id": "drafts-components-inlinemessage-features--warning",
3142
+ "id": "experimental-components-inlinemessage-features--warning",
3143
3143
  "code": "() => {\n return (\n <InlineMessage variant=\"warning\">An example inline message</InlineMessage>\n )\n}"
3144
3144
  }
3145
3145
  ],
@@ -7595,39 +7595,39 @@
7595
7595
  "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 <Box\n sx={{\n width: 14,\n height: 14,\n borderRadius: '100%',\n }}\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}"
7596
7596
  },
7597
7597
  {
7598
- "id": "drafts-components-selectpanel-examples--minimal",
7598
+ "id": "experimental-components-selectpanel-examples--minimal",
7599
7599
  "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}"
7600
7600
  },
7601
7601
  {
7602
- "id": "drafts-components-selectpanel-examples--short-select-panel",
7602
+ "id": "experimental-components-selectpanel-examples--short-select-panel",
7603
7603
  "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\n sx={{\n color: 'fg.muted',\n }}\n >\n Notify me:\n </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 <Box\n role=\"none\"\n sx={{\n transition: 'max-height 100ms ease-out, opacity 100ms ease-out',\n opacity: channelsEnabled ? 1 : 0,\n maxHeight: channelsEnabled ? '100px' : 0,\n overflow: channelsEnabled ? 'visible' : 'hidden',\n }}\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 </Box>\n </ActionList>\n <SelectPanel.Footer />\n </SelectPanel>\n </>\n )\n}"
7604
7604
  },
7605
7605
  {
7606
- "id": "drafts-components-selectpanel-features--instant-selection-variant",
7606
+ "id": "experimental-components-selectpanel-features--instant-selection-variant",
7607
7607
  "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}"
7608
7608
  },
7609
7609
  {
7610
- "id": "drafts-components-selectpanel-features--with-warning",
7610
+ "id": "experimental-components-selectpanel-features--with-warning",
7611
7611
  "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 sx={{\n width: '200px',\n '[data-component=buttonContent]': {\n justifyContent: 'start',\n },\n }}\n >\n Assignees\n </SelectPanel.Button>\n <SelectPanel.Header>\n <SelectPanel.SearchInput onChange={onSearchInputChange} />\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}"
7612
7612
  },
7613
7613
  {
7614
- "id": "drafts-components-selectpanel-examples--open-from-menu",
7614
+ "id": "experimental-components-selectpanel-examples--open-from-menu",
7615
7615
  "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}"
7616
7616
  },
7617
7617
  {
7618
- "id": "drafts-components-selectpanel-examples--with-groups",
7618
+ "id": "experimental-components-selectpanel-examples--with-groups",
7619
7619
  "code": "() => {\n /* Selection */\n const initialAssigneeIds = data.issue.assigneeIds // mock initial state\n const [selectedAssigneeIds, setSelectedAssigneeIds] =\n React.useState<string[]>(initialAssigneeIds)\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 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 sx={{\n width: '200px',\n '[data-component=buttonContent]': {\n justifyContent: 'start',\n },\n }}\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}"
7620
7620
  },
7621
7621
  {
7622
- "id": "drafts-components-selectpanel-examples--async-search-with-use-transition",
7622
+ "id": "experimental-components-selectpanel-examples--async-search-with-use-transition",
7623
7623
  "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}"
7624
7624
  },
7625
7625
  {
7626
- "id": "drafts-components-selectpanel-examples--async-with-suspended-list",
7626
+ "id": "experimental-components-selectpanel-examples--async-with-suspended-list",
7627
7627
  "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}"
7628
7628
  },
7629
7629
  {
7630
- "id": "drafts-components-selectpanel-examples--with-filter-buttons",
7630
+ "id": "experimental-components-selectpanel-examples--with-filter-buttons",
7631
7631
  "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 <Box\n id=\"filters\"\n sx={{\n display: 'flex',\n marginTop: 1,\n }}\n >\n <Button\n variant=\"invisible\"\n sx={{\n fontWeight:\n selectedFilter === 'branches' ? 'semibold' : 'normal',\n color: 'fg.default',\n }}\n onClick={() => setSelectedFilter('branches')}\n count={20}\n >\n Branches\n </Button>\n <Button\n variant=\"invisible\"\n sx={{\n fontWeight: selectedFilter === 'tags' ? 'semibold' : 'normal',\n color: 'fg.default',\n }}\n onClick={() => setSelectedFilter('tags')}\n count={8}\n >\n Tags\n </Button>\n </Box>\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}"
7632
7632
  }
7633
7633
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/react",
3
- "version": "37.0.0",
3
+ "version": "37.0.1",
4
4
  "description": "An implementation of GitHub's Primer Design System using React",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",