@primer/react 38.0.0-rc.1 → 38.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/dist/browser.esm.js +3 -3
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +3 -3
- package/dist/browser.umd.js.map +1 -1
- package/dist/components.css +660 -23
- package/generated/components.json +58 -121
- package/lib/AvatarStack/AvatarStack.d.ts +2 -3
- package/lib/AvatarStack/AvatarStack.d.ts.map +1 -1
- package/lib/AvatarStack/AvatarStack.js +1 -3
- package/lib/Banner/Banner.d.ts.map +1 -1
- package/lib/Banner/Banner.js +3 -1
- package/lib/Blankslate/Blankslate.js +38 -40
- package/lib/BranchName/BranchName.d.ts +6 -3
- package/lib/BranchName/BranchName.d.ts.map +1 -1
- package/lib/BranchName/BranchName.js +1 -3
- package/lib/Button/ButtonBase.js +2 -2
- package/lib/Checkbox/Checkbox.js +187 -56
- package/lib/CircleBadge/CircleBadge.d.ts +4 -0
- package/lib/CircleBadge/CircleBadge.d.ts.map +1 -1
- package/lib/CircleBadge/CircleBadge.js +4 -0
- package/lib/DataTable/useTable.js +63 -82
- package/lib/Details/Details.d.ts +2 -3
- package/lib/Details/Details.d.ts.map +1 -1
- package/lib/Details/Details.js +1 -3
- package/lib/FeatureFlags/FeatureFlags.js +10 -12
- package/lib/FilteredActionList/useAnnouncements.js +31 -40
- package/lib/LabelGroup/LabelGroup.d.ts +1 -2
- package/lib/LabelGroup/LabelGroup.d.ts.map +1 -1
- package/lib/LabelGroup/LabelGroup.js +13 -16
- package/lib/NavList/NavList.js +219 -53
- package/lib/PageLayout/PageLayout.js +53 -55
- package/lib/PointerBox/PointerBox.d.ts +8 -0
- package/lib/PointerBox/PointerBox.d.ts.map +1 -1
- package/lib/PointerBox/PointerBox.js +4 -0
- package/{lib-esm/ProgressBar/ProgressBar-a0957632.css → lib/ProgressBar/ProgressBar-36f689cb.css} +2 -2
- package/lib/ProgressBar/ProgressBar-36f689cb.css.map +1 -0
- package/lib/ProgressBar/ProgressBar.d.ts +3 -4
- package/lib/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/lib/ProgressBar/ProgressBar.module.css.js +1 -1
- package/lib/ProgressBar/index.d.ts +2 -2
- package/lib/ProgressBar/index.d.ts.map +1 -1
- package/lib/Select/Select.d.ts +1 -1
- package/lib/Select/Select.d.ts.map +1 -1
- package/lib/Select/Select.js +53 -65
- package/lib/SelectPanel/{SelectPanel-06900070.css → SelectPanel-e11ce210.css} +2 -2
- package/lib/SelectPanel/SelectPanel-e11ce210.css.map +1 -0
- package/lib/SelectPanel/SelectPanel.d.ts +1 -1
- package/lib/SelectPanel/SelectPanel.d.ts.map +1 -1
- package/lib/SelectPanel/SelectPanel.js +2 -9
- package/lib/SelectPanel/SelectPanel.module.css.js +2 -2
- package/lib/SideNav.d.ts +2 -3
- package/lib/SideNav.d.ts.map +1 -1
- package/lib/SideNav.js +4 -10
- package/lib/StateLabel/StateLabel-50420ff5.css +2 -0
- package/lib/StateLabel/StateLabel-50420ff5.css.map +1 -0
- package/lib/StateLabel/StateLabel.d.ts +6 -5
- package/lib/StateLabel/StateLabel.d.ts.map +1 -1
- package/lib/StateLabel/StateLabel.js +54 -126
- package/lib/StateLabel/StateLabel.module.css.js +2 -2
- package/lib/TextInputWithTokens/TextInputWithTokens.d.ts +6 -0
- package/lib/TextInputWithTokens/TextInputWithTokens.d.ts.map +1 -1
- package/lib/TextInputWithTokens/TextInputWithTokens.js +343 -331
- package/lib/ToggleSwitch/ToggleSwitch-4b23d166.css +2 -0
- package/lib/ToggleSwitch/ToggleSwitch-4b23d166.css.map +1 -0
- package/lib/ToggleSwitch/ToggleSwitch.d.ts +1 -3
- package/lib/ToggleSwitch/ToggleSwitch.d.ts.map +1 -1
- package/lib/ToggleSwitch/ToggleSwitch.js +120 -152
- package/lib/ToggleSwitch/ToggleSwitch.module.css.js +2 -2
- package/lib/Token/IssueLabelToken-0dbbbcdf.css +2 -0
- package/lib/Token/IssueLabelToken-0dbbbcdf.css.map +1 -0
- package/lib/Token/IssueLabelToken.d.ts.map +1 -1
- package/lib/Token/IssueLabelToken.js +7 -65
- package/lib/Token/IssueLabelToken.module.css.js +1 -1
- package/lib/Token/TokenBase.js +73 -82
- package/lib/Token/_RemoveTokenButton.js +106 -26
- package/lib/Tooltip/Tooltip.js +15 -17
- package/lib/TreeView/TreeView.js +18 -20
- package/lib/deprecated/ActionList/List.d.ts.map +1 -1
- package/lib/deprecated/ActionList/List.js +115 -138
- package/lib/deprecated/ActionMenu.js +19 -21
- package/lib/deprecated/index.d.ts +2 -0
- package/lib/deprecated/index.d.ts.map +1 -1
- package/lib/deprecated/index.js +2 -0
- package/lib/hooks/useMenuKeyboardNavigation.js +23 -43
- package/lib/hooks/useMnemonics.js +37 -76
- package/lib/hooks/useOpenAndCloseFocus.js +7 -14
- package/lib/hooks/useOverflow.js +7 -11
- package/lib/hooks/useScrollFlash.js +25 -14
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -10
- package/lib/internal/components/BoxWithFallback.js +40 -35
- package/lib/internal/components/Caret-e686f04c.css +2 -0
- package/lib/internal/components/Caret-e686f04c.css.map +1 -0
- package/lib/internal/components/Caret.d.ts +1 -3
- package/lib/internal/components/Caret.d.ts.map +1 -1
- package/lib/internal/components/Caret.js +14 -48
- package/lib/internal/components/Caret.module.css.js +7 -0
- package/lib/internal/components/LiveRegion.js +8 -10
- package/lib/internal/utils/getGlobalFocusStyles.js +1 -1
- package/lib-esm/AvatarStack/AvatarStack.d.ts +2 -3
- package/lib-esm/AvatarStack/AvatarStack.js +1 -3
- package/lib-esm/Banner/Banner.js +3 -1
- package/lib-esm/Blankslate/Blankslate.js +38 -40
- package/lib-esm/BranchName/BranchName.d.ts +6 -3
- package/lib-esm/BranchName/BranchName.js +1 -3
- package/lib-esm/Button/ButtonBase.js +2 -2
- package/lib-esm/Checkbox/Checkbox.js +187 -56
- package/lib-esm/CircleBadge/CircleBadge.d.ts +4 -0
- package/lib-esm/CircleBadge/CircleBadge.js +4 -0
- package/lib-esm/DataTable/useTable.js +64 -83
- package/lib-esm/Details/Details.d.ts +2 -3
- package/lib-esm/Details/Details.js +1 -3
- package/lib-esm/FeatureFlags/FeatureFlags.js +10 -12
- package/lib-esm/FilteredActionList/useAnnouncements.js +31 -40
- package/lib-esm/LabelGroup/LabelGroup.d.ts +1 -2
- package/lib-esm/LabelGroup/LabelGroup.js +13 -16
- package/lib-esm/NavList/NavList.js +219 -53
- package/lib-esm/PageLayout/PageLayout.js +53 -55
- package/lib-esm/PointerBox/PointerBox.d.ts +8 -0
- package/lib-esm/PointerBox/PointerBox.js +4 -0
- package/{lib/ProgressBar/ProgressBar-a0957632.css → lib-esm/ProgressBar/ProgressBar-36f689cb.css} +2 -2
- package/lib-esm/ProgressBar/ProgressBar-36f689cb.css.map +1 -0
- package/lib-esm/ProgressBar/ProgressBar.d.ts +3 -4
- package/lib-esm/ProgressBar/ProgressBar.module.css.js +1 -1
- package/lib-esm/ProgressBar/index.d.ts +2 -2
- package/lib-esm/Select/Select.d.ts +1 -1
- package/lib-esm/Select/Select.js +53 -65
- package/lib-esm/SelectPanel/{SelectPanel-06900070.css → SelectPanel-e11ce210.css} +2 -2
- package/lib-esm/SelectPanel/SelectPanel-e11ce210.css.map +1 -0
- package/lib-esm/SelectPanel/SelectPanel.d.ts +1 -1
- package/lib-esm/SelectPanel/SelectPanel.js +2 -9
- package/lib-esm/SelectPanel/SelectPanel.module.css.js +2 -2
- package/lib-esm/SideNav.d.ts +2 -3
- package/lib-esm/SideNav.js +4 -10
- package/lib-esm/StateLabel/StateLabel-50420ff5.css +2 -0
- package/lib-esm/StateLabel/StateLabel-50420ff5.css.map +1 -0
- package/lib-esm/StateLabel/StateLabel.d.ts +6 -5
- package/lib-esm/StateLabel/StateLabel.js +55 -123
- package/lib-esm/StateLabel/StateLabel.module.css.js +2 -2
- package/lib-esm/TextInputWithTokens/TextInputWithTokens.d.ts +6 -0
- package/lib-esm/TextInputWithTokens/TextInputWithTokens.js +343 -331
- package/lib-esm/ToggleSwitch/ToggleSwitch-4b23d166.css +2 -0
- package/lib-esm/ToggleSwitch/ToggleSwitch-4b23d166.css.map +1 -0
- package/lib-esm/ToggleSwitch/ToggleSwitch.d.ts +1 -3
- package/lib-esm/ToggleSwitch/ToggleSwitch.js +120 -151
- package/lib-esm/ToggleSwitch/ToggleSwitch.module.css.js +2 -2
- package/lib-esm/Token/IssueLabelToken-0dbbbcdf.css +2 -0
- package/lib-esm/Token/IssueLabelToken-0dbbbcdf.css.map +1 -0
- package/lib-esm/Token/IssueLabelToken.js +7 -65
- package/lib-esm/Token/IssueLabelToken.module.css.js +1 -1
- package/lib-esm/Token/TokenBase.js +73 -82
- package/lib-esm/Token/_RemoveTokenButton.js +106 -26
- package/lib-esm/Tooltip/Tooltip.js +15 -17
- package/lib-esm/TreeView/TreeView.js +18 -20
- package/lib-esm/deprecated/ActionList/List.js +116 -138
- package/lib-esm/deprecated/ActionMenu.js +19 -21
- package/lib-esm/deprecated/index.d.ts +2 -0
- package/lib-esm/deprecated/index.js +1 -0
- package/lib-esm/hooks/useMenuKeyboardNavigation.js +23 -43
- package/lib-esm/hooks/useMnemonics.js +37 -76
- package/lib-esm/hooks/useOpenAndCloseFocus.js +7 -14
- package/lib-esm/hooks/useOverflow.js +7 -11
- package/lib-esm/hooks/useScrollFlash.js +25 -14
- package/lib-esm/index.d.ts +4 -3
- package/lib-esm/index.js +1 -1
- package/lib-esm/internal/components/BoxWithFallback.js +40 -35
- package/lib-esm/internal/components/Caret-e686f04c.css +2 -0
- package/lib-esm/internal/components/Caret-e686f04c.css.map +1 -0
- package/lib-esm/internal/components/Caret.d.ts +1 -3
- package/lib-esm/internal/components/Caret.js +14 -44
- package/lib-esm/internal/components/Caret.module.css.js +5 -0
- package/lib-esm/internal/components/LiveRegion.js +8 -10
- package/lib-esm/internal/utils/getGlobalFocusStyles.js +1 -1
- package/package.json +10 -10
- package/lib/CircleOcticon/CircleOcticon.d.ts +0 -16
- package/lib/CircleOcticon/CircleOcticon.d.ts.map +0 -1
- package/lib/CircleOcticon/CircleOcticon.js +0 -99
- package/lib/CircleOcticon/index.d.ts +0 -3
- package/lib/CircleOcticon/index.d.ts.map +0 -1
- package/lib/ProgressBar/ProgressBar-a0957632.css.map +0 -1
- package/lib/SelectPanel/SelectPanel-06900070.css.map +0 -1
- package/lib/StateLabel/StateLabel-cd27f475.css +0 -2
- package/lib/StateLabel/StateLabel-cd27f475.css.map +0 -1
- package/lib/ToggleSwitch/ToggleSwitch-65936b4b.css +0 -4
- package/lib/ToggleSwitch/ToggleSwitch-65936b4b.css.map +0 -1
- package/lib/Token/IssueLabelToken-99c9b914.css +0 -2
- package/lib/Token/IssueLabelToken-99c9b914.css.map +0 -1
- package/lib-esm/CircleOcticon/CircleOcticon.d.ts +0 -16
- package/lib-esm/CircleOcticon/CircleOcticon.js +0 -97
- package/lib-esm/CircleOcticon/index.d.ts +0 -3
- package/lib-esm/ProgressBar/ProgressBar-a0957632.css.map +0 -1
- package/lib-esm/SelectPanel/SelectPanel-06900070.css.map +0 -1
- package/lib-esm/StateLabel/StateLabel-cd27f475.css +0 -2
- package/lib-esm/StateLabel/StateLabel-cd27f475.css.map +0 -1
- package/lib-esm/ToggleSwitch/ToggleSwitch-65936b4b.css +0 -4
- package/lib-esm/ToggleSwitch/ToggleSwitch-65936b4b.css.map +0 -1
- package/lib-esm/Token/IssueLabelToken-99c9b914.css +0 -2
- package/lib-esm/Token/IssueLabelToken-99c9b914.css.map +0 -1
|
@@ -1289,11 +1289,6 @@
|
|
|
1289
1289
|
"type": "string",
|
|
1290
1290
|
"description": "Class name for custom styling.",
|
|
1291
1291
|
"defaultValue": ""
|
|
1292
|
-
},
|
|
1293
|
-
{
|
|
1294
|
-
"name": "sx",
|
|
1295
|
-
"type": "SystemStyleObject",
|
|
1296
|
-
"deprecated": true
|
|
1297
1292
|
}
|
|
1298
1293
|
],
|
|
1299
1294
|
"subcomponents": []
|
|
@@ -1304,66 +1299,66 @@
|
|
|
1304
1299
|
"name": "Banner",
|
|
1305
1300
|
"status": "alpha",
|
|
1306
1301
|
"a11yReviewed": "2025-01-08",
|
|
1307
|
-
"importPath": "@primer/react
|
|
1302
|
+
"importPath": "@primer/react",
|
|
1308
1303
|
"stories": [
|
|
1309
1304
|
{
|
|
1310
|
-
"id": "
|
|
1305
|
+
"id": "components-banner--default",
|
|
1311
1306
|
"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}"
|
|
1312
1307
|
},
|
|
1313
1308
|
{
|
|
1314
|
-
"id": "
|
|
1309
|
+
"id": "components-banner-features--critical",
|
|
1315
1310
|
"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}"
|
|
1316
1311
|
},
|
|
1317
1312
|
{
|
|
1318
|
-
"id": "
|
|
1313
|
+
"id": "components-banner-features--info",
|
|
1319
1314
|
"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}"
|
|
1320
1315
|
},
|
|
1321
1316
|
{
|
|
1322
|
-
"id": "
|
|
1317
|
+
"id": "components-banner-features--success",
|
|
1323
1318
|
"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}"
|
|
1324
1319
|
},
|
|
1325
1320
|
{
|
|
1326
|
-
"id": "
|
|
1321
|
+
"id": "components-banner-features--upsell",
|
|
1327
1322
|
"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}"
|
|
1328
1323
|
},
|
|
1329
1324
|
{
|
|
1330
|
-
"id": "
|
|
1325
|
+
"id": "components-banner-features--warning",
|
|
1331
1326
|
"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}"
|
|
1332
1327
|
},
|
|
1333
1328
|
{
|
|
1334
|
-
"id": "
|
|
1329
|
+
"id": "components-banner-features--dismiss",
|
|
1335
1330
|
"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}"
|
|
1336
1331
|
},
|
|
1337
1332
|
{
|
|
1338
|
-
"id": "
|
|
1333
|
+
"id": "components-banner-features--dismiss-with-actions",
|
|
1339
1334
|
"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}"
|
|
1340
1335
|
},
|
|
1341
1336
|
{
|
|
1342
|
-
"id": "
|
|
1337
|
+
"id": "components-banner-features--with-hidden-title",
|
|
1343
1338
|
"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}"
|
|
1344
1339
|
},
|
|
1345
1340
|
{
|
|
1346
|
-
"id": "
|
|
1341
|
+
"id": "components-banner-features--with-hidden-title-and-actions",
|
|
1347
1342
|
"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}"
|
|
1348
1343
|
},
|
|
1349
1344
|
{
|
|
1350
|
-
"id": "
|
|
1345
|
+
"id": "components-banner-features--dismissible-with-hidden-title-and-actions",
|
|
1351
1346
|
"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}"
|
|
1352
1347
|
},
|
|
1353
1348
|
{
|
|
1354
|
-
"id": "
|
|
1349
|
+
"id": "components-banner-features--dismissible-with-hidden-title-and-secondary-action",
|
|
1355
1350
|
"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}"
|
|
1356
1351
|
},
|
|
1357
1352
|
{
|
|
1358
|
-
"id": "
|
|
1353
|
+
"id": "components-banner-features--with-actions",
|
|
1359
1354
|
"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}"
|
|
1360
1355
|
},
|
|
1361
1356
|
{
|
|
1362
|
-
"id": "
|
|
1357
|
+
"id": "components-banner-features--custom-icon",
|
|
1363
1358
|
"code": "() => {\n return (\n <Banner\n title=\"Upsell\"\n description=\"An example banner with a custom icon\"\n icon={<CopilotIcon />}\n onDismiss={action('onDismiss')}\n variant=\"upsell\"\n />\n )\n}"
|
|
1364
1359
|
},
|
|
1365
1360
|
{
|
|
1366
|
-
"id": "
|
|
1361
|
+
"id": "components-banner-examples--with-announcement",
|
|
1367
1362
|
"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 sx={{\n marginTop: 4,\n }}\n name=\"options\"\n onChange={(selected) => {\n setSelected(selected as Choice)\n }}\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}"
|
|
1368
1363
|
}
|
|
1369
1364
|
],
|
|
@@ -1646,11 +1641,6 @@
|
|
|
1646
1641
|
"name": "as",
|
|
1647
1642
|
"type": "React.ElementType",
|
|
1648
1643
|
"defaultValue": "\"a\""
|
|
1649
|
-
},
|
|
1650
|
-
{
|
|
1651
|
-
"name": "sx",
|
|
1652
|
-
"type": "SystemStyleObject",
|
|
1653
|
-
"deprecated": true
|
|
1654
1644
|
}
|
|
1655
1645
|
],
|
|
1656
1646
|
"subcomponents": []
|
|
@@ -1832,7 +1822,7 @@
|
|
|
1832
1822
|
},
|
|
1833
1823
|
{
|
|
1834
1824
|
"id": "components-button-features--inactive-button-with-tooltip",
|
|
1835
|
-
"code": "() => (\n <Tooltip\n text=\"Action unavailable: an error occurred while loading
|
|
1825
|
+
"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)"
|
|
1836
1826
|
},
|
|
1837
1827
|
{
|
|
1838
1828
|
"id": "components-button-features--expanded-button",
|
|
@@ -2376,11 +2366,11 @@
|
|
|
2376
2366
|
"source": "https://github.com/primer/react/tree/main/packages/react/src/CircleBadge",
|
|
2377
2367
|
"id": "circle_badge",
|
|
2378
2368
|
"name": "CircleBadge",
|
|
2379
|
-
"status": "
|
|
2369
|
+
"status": "deprecated",
|
|
2380
2370
|
"a11yReviewed": "2025-01-08",
|
|
2381
2371
|
"stories": [
|
|
2382
2372
|
{
|
|
2383
|
-
"id": "components-circlebadge--default",
|
|
2373
|
+
"id": "deprecated-components-circlebadge--default",
|
|
2384
2374
|
"code": "() => (\n <CircleBadge>\n <CircleBadge.Icon icon={ZapIcon} aria-label=\"User badge\" />\n </CircleBadge>\n)"
|
|
2385
2375
|
}
|
|
2386
2376
|
],
|
|
@@ -2436,38 +2426,6 @@
|
|
|
2436
2426
|
}
|
|
2437
2427
|
]
|
|
2438
2428
|
},
|
|
2439
|
-
"circle_octicon": {
|
|
2440
|
-
"source": "https://github.com/primer/react/tree/main/packages/react/src/CircleOcticon",
|
|
2441
|
-
"id": "circle_octicon",
|
|
2442
|
-
"name": "CircleOcticon",
|
|
2443
|
-
"status": "deprecated",
|
|
2444
|
-
"a11yReviewed": "2025-01-08",
|
|
2445
|
-
"stories": [
|
|
2446
|
-
{
|
|
2447
|
-
"id": "deprecated-components-circleocticon--default",
|
|
2448
|
-
"code": "() => (\n <CircleOcticon\n icon={CheckIcon}\n size={32}\n sx={{\n backgroundColor: 'success.emphasis',\n color: 'fg.onEmphasis',\n }}\n aria-label=\"Changes approved\"\n />\n)"
|
|
2449
|
-
}
|
|
2450
|
-
],
|
|
2451
|
-
"importPath": "@primer/react",
|
|
2452
|
-
"props": [
|
|
2453
|
-
{
|
|
2454
|
-
"name": "icon",
|
|
2455
|
-
"type": "Octicon"
|
|
2456
|
-
},
|
|
2457
|
-
{
|
|
2458
|
-
"name": "size",
|
|
2459
|
-
"defaultValue": "32",
|
|
2460
|
-
"type": "number",
|
|
2461
|
-
"description": "Set the width and height of the icon in pixels."
|
|
2462
|
-
},
|
|
2463
|
-
{
|
|
2464
|
-
"name": "sx",
|
|
2465
|
-
"type": "SystemStyleObject",
|
|
2466
|
-
"deprecated": true
|
|
2467
|
-
}
|
|
2468
|
-
],
|
|
2469
|
-
"subcomponents": []
|
|
2470
|
-
},
|
|
2471
2429
|
"confirmationdialog": {
|
|
2472
2430
|
"source": "https://github.com/primer/react/tree/main/packages/react/src/ConfirmationDialog",
|
|
2473
2431
|
"id": "confirmationdialog",
|
|
@@ -3039,13 +2997,7 @@
|
|
|
3039
2997
|
}
|
|
3040
2998
|
],
|
|
3041
2999
|
"importPath": "@primer/react",
|
|
3042
|
-
"props": [
|
|
3043
|
-
{
|
|
3044
|
-
"name": "sx",
|
|
3045
|
-
"type": "SystemStyleObject",
|
|
3046
|
-
"deprecated": true
|
|
3047
|
-
}
|
|
3048
|
-
],
|
|
3000
|
+
"props": [],
|
|
3049
3001
|
"subcomponents": [
|
|
3050
3002
|
{
|
|
3051
3003
|
"name": "Details.Summary",
|
|
@@ -3060,11 +3012,6 @@
|
|
|
3060
3012
|
{
|
|
3061
3013
|
"name": "children",
|
|
3062
3014
|
"type": "React.ReactNode"
|
|
3063
|
-
},
|
|
3064
|
-
{
|
|
3065
|
-
"name": "sx",
|
|
3066
|
-
"type": "SystemStyleObject",
|
|
3067
|
-
"deprecated": true
|
|
3068
3015
|
}
|
|
3069
3016
|
]
|
|
3070
3017
|
}
|
|
@@ -3092,7 +3039,7 @@
|
|
|
3092
3039
|
},
|
|
3093
3040
|
{
|
|
3094
3041
|
"id": "components-dialog-features--repro-multistep-dialog-with-conditional-footer",
|
|
3095
|
-
"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 <
|
|
3042
|
+
"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}"
|
|
3096
3043
|
},
|
|
3097
3044
|
{
|
|
3098
3045
|
"id": "components-dialog-features--bottom-sheet-narrow",
|
|
@@ -3116,7 +3063,7 @@
|
|
|
3116
3063
|
},
|
|
3117
3064
|
{
|
|
3118
3065
|
"id": "components-dialog-features--retains-focus-trap-with-dynamic-content",
|
|
3119
|
-
"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 <
|
|
3066
|
+
"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}"
|
|
3120
3067
|
}
|
|
3121
3068
|
],
|
|
3122
3069
|
"importPath": "@primer/react",
|
|
@@ -3272,7 +3219,7 @@
|
|
|
3272
3219
|
"stories": [
|
|
3273
3220
|
{
|
|
3274
3221
|
"id": "components-dialog--default",
|
|
3275
|
-
"code": "() => {\n const [isOpen, setIsOpen] = useState(false)\n const returnFocusRef = useRef(null)\n return (\n <div>\n <
|
|
3222
|
+
"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}"
|
|
3276
3223
|
}
|
|
3277
3224
|
],
|
|
3278
3225
|
"importPath": "@primer/react/deprecated",
|
|
@@ -3365,27 +3312,27 @@
|
|
|
3365
3312
|
},
|
|
3366
3313
|
{
|
|
3367
3314
|
"id": "components-flash-features--success",
|
|
3368
|
-
"code": "() => (\n <Flash\n variant=\"success\"\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <
|
|
3315
|
+
"code": "() => (\n <Flash\n variant=\"success\"\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <Octicon icon={CheckCircleIcon} aria-label=\"Success\" />\n </div>\n <div className={classes.Message}>Success</div>\n </Flash>\n)"
|
|
3369
3316
|
},
|
|
3370
3317
|
{
|
|
3371
3318
|
"id": "components-flash-features--danger",
|
|
3372
|
-
"code": "() => (\n <Flash\n variant=\"danger\"\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <
|
|
3319
|
+
"code": "() => (\n <Flash\n variant=\"danger\"\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <Octicon icon={InfoIcon} aria-label=\"Danger\" />\n </div>\n <div className={classes.Message}>Danger</div>\n </Flash>\n)"
|
|
3373
3320
|
},
|
|
3374
3321
|
{
|
|
3375
3322
|
"id": "components-flash-features--warning",
|
|
3376
|
-
"code": "() => (\n <Flash\n variant=\"warning\"\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <
|
|
3323
|
+
"code": "() => (\n <Flash\n variant=\"warning\"\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <Octicon icon={AlertIcon} aria-label=\"Warning\" />\n </div>\n <div className={classes.Message}>Warning</div>\n </Flash>\n)"
|
|
3377
3324
|
},
|
|
3378
3325
|
{
|
|
3379
3326
|
"id": "components-flash-features--full",
|
|
3380
|
-
"code": "() => (\n <Flash\n full\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <
|
|
3327
|
+
"code": "() => (\n <Flash\n full\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateAreas: `'visual message actions'`,\n }}\n >\n <div className={classes.Visual}>\n <Octicon icon={InfoIcon} aria-label=\"Info\" />\n </div>\n <div className={classes.Message}>Full</div>\n </Flash>\n)"
|
|
3381
3328
|
},
|
|
3382
3329
|
{
|
|
3383
3330
|
"id": "components-flash-features--with-icon-and-action",
|
|
3384
|
-
"code": "() => (\n <Flash\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateRows: 'min-content',\n gridTemplateAreas: `'visual message actions'`,\n '@media screen and (max-width: 543.98px)': {\n gridTemplateColumns: 'min-content 1fr',\n gridTemplateRows: 'min-content min-content',\n gridTemplateAreas: `\n 'visual message'\n '. actions'\n `,\n },\n }}\n >\n <
|
|
3331
|
+
"code": "() => (\n <Flash\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateRows: 'min-content',\n gridTemplateAreas: `'visual message actions'`,\n '@media screen and (max-width: 543.98px)': {\n gridTemplateColumns: 'min-content 1fr',\n gridTemplateRows: 'min-content min-content',\n gridTemplateAreas: `\n 'visual message'\n '. actions'\n `,\n },\n }}\n >\n <div className={classes.Visual}>\n <Octicon icon={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)"
|
|
3385
3332
|
},
|
|
3386
3333
|
{
|
|
3387
3334
|
"id": "components-flash-features--with-icon-action-dismiss",
|
|
3388
|
-
"code": "() => (\n <Flash\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateRows: 'min-content',\n gridTemplateAreas: `'visual message actions close'`,\n '@media screen and (max-width: 543.98px)': {\n gridTemplateColumns: 'min-content 1fr',\n gridTemplateRows: 'min-content min-content',\n gridTemplateAreas: `\n 'visual message close'\n '. actions actions'\n `,\n },\n }}\n >\n <
|
|
3335
|
+
"code": "() => (\n <Flash\n sx={{\n display: 'grid',\n gridTemplateColumns: 'min-content 1fr minmax(0, auto)',\n gridTemplateRows: 'min-content',\n gridTemplateAreas: `'visual message actions close'`,\n '@media screen and (max-width: 543.98px)': {\n gridTemplateColumns: 'min-content 1fr',\n gridTemplateRows: 'min-content min-content',\n gridTemplateAreas: `\n 'visual message close'\n '. actions actions'\n `,\n },\n }}\n >\n <div className={classes.Visual}>\n <Octicon icon={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\n variant=\"invisible\"\n icon={XIcon}\n aria-label=\"Dismiss\"\n sx={{\n svg: {\n margin: '0',\n color: 'fg.muted',\n },\n }}\n />\n </div>\n </Flash>\n)"
|
|
3389
3336
|
}
|
|
3390
3337
|
],
|
|
3391
3338
|
"importPath": "@primer/react",
|
|
@@ -3802,11 +3749,11 @@
|
|
|
3802
3749
|
},
|
|
3803
3750
|
{
|
|
3804
3751
|
"id": "experimental-components-hidden-features--hide-content",
|
|
3805
|
-
"code": "() => (\n <
|
|
3752
|
+
"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)"
|
|
3806
3753
|
},
|
|
3807
3754
|
{
|
|
3808
3755
|
"id": "experimental-components-hidden-features--render-content-responsively",
|
|
3809
|
-
"code": "() => (\n <
|
|
3756
|
+
"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)"
|
|
3810
3757
|
}
|
|
3811
3758
|
],
|
|
3812
3759
|
"importPath": "@primer/react/experimental",
|
|
@@ -3878,11 +3825,11 @@
|
|
|
3878
3825
|
"stories": [
|
|
3879
3826
|
{
|
|
3880
3827
|
"id": "experimental-components-keybindinghint-features--on-emphasis",
|
|
3881
|
-
"code": "(args) => (\n <
|
|
3828
|
+
"code": "(args) => (\n <div className={classes.EmphasisBackground}>\n <KeybindingHint {...args} />\n </div>\n)"
|
|
3882
3829
|
},
|
|
3883
3830
|
{
|
|
3884
3831
|
"id": "experimental-components-keybindinghint-features--on-primary",
|
|
3885
|
-
"code": "(args) => (\n <
|
|
3832
|
+
"code": "(args) => (\n <div className={classes.PrimaryBackground}>\n <KeybindingHint {...args} />\n </div>\n)"
|
|
3886
3833
|
}
|
|
3887
3834
|
],
|
|
3888
3835
|
"importPath": "@primer/react",
|
|
@@ -4448,11 +4395,11 @@
|
|
|
4448
4395
|
},
|
|
4449
4396
|
{
|
|
4450
4397
|
"id": "private-components-overlay-features--dialog-overlay",
|
|
4451
|
-
"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 <
|
|
4398
|
+
"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}"
|
|
4452
4399
|
},
|
|
4453
4400
|
{
|
|
4454
4401
|
"id": "private-components-overlay-features--positioned-overlays",
|
|
4455
|
-
"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 <
|
|
4402
|
+
"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 sx={{\n mt: 2,\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}"
|
|
4456
4403
|
}
|
|
4457
4404
|
],
|
|
4458
4405
|
"importPath": "@primer/react",
|
|
@@ -4505,7 +4452,7 @@
|
|
|
4505
4452
|
{
|
|
4506
4453
|
"name": "maxHeight",
|
|
4507
4454
|
"type": "| 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'",
|
|
4508
|
-
"defaultValue": "",
|
|
4455
|
+
"defaultValue": "100vh",
|
|
4509
4456
|
"description": "Sets the maximum height of the `Overlay`, pick from our set list of heights. `xsmall` corresponds to `192px`, `small` corresponds to `256px`, `medium` corresponds to `320px`, `large` corresponds to `432px`, `xlarge` corresponds to `600px`."
|
|
4510
4457
|
},
|
|
4511
4458
|
{
|
|
@@ -4565,7 +4512,7 @@
|
|
|
4565
4512
|
"type": "'hidden' | 'scroll' | 'auto' | 'visible'",
|
|
4566
4513
|
"required": false,
|
|
4567
4514
|
"description": "",
|
|
4568
|
-
"defaultValue": ""
|
|
4515
|
+
"defaultValue": "hidden"
|
|
4569
4516
|
},
|
|
4570
4517
|
{
|
|
4571
4518
|
"name": "preventOverflow",
|
|
@@ -5460,11 +5407,6 @@
|
|
|
5460
5407
|
"type": "function",
|
|
5461
5408
|
"defaultValue": "(props: PageProps) => ReactNode",
|
|
5462
5409
|
"description": "Provide a custom component or render prop to render each page link within the component."
|
|
5463
|
-
},
|
|
5464
|
-
{
|
|
5465
|
-
"name": "sx",
|
|
5466
|
-
"type": "SystemStyleObject",
|
|
5467
|
-
"deprecated": true
|
|
5468
5410
|
}
|
|
5469
5411
|
],
|
|
5470
5412
|
"subcomponents": []
|
|
@@ -5473,15 +5415,15 @@
|
|
|
5473
5415
|
"source": "https://github.com/primer/react/tree/main/packages/react/src/PointerBox",
|
|
5474
5416
|
"id": "pointer_box",
|
|
5475
5417
|
"name": "PointerBox",
|
|
5476
|
-
"status": "
|
|
5418
|
+
"status": "deprecated",
|
|
5477
5419
|
"a11yReviewed": "2025-01-08",
|
|
5478
5420
|
"stories": [
|
|
5479
5421
|
{
|
|
5480
|
-
"id": "components-pointerbox--default",
|
|
5422
|
+
"id": "deprecated-components-pointerbox--default",
|
|
5481
5423
|
"code": "() => <PointerBox>Pointer box content</PointerBox>"
|
|
5482
5424
|
}
|
|
5483
5425
|
],
|
|
5484
|
-
"importPath": "@primer/react",
|
|
5426
|
+
"importPath": "@primer/react/deprecated",
|
|
5485
5427
|
"props": [
|
|
5486
5428
|
{
|
|
5487
5429
|
"name": "bg",
|
|
@@ -5600,19 +5542,19 @@
|
|
|
5600
5542
|
"stories": [
|
|
5601
5543
|
{
|
|
5602
5544
|
"id": "behaviors-portal--default",
|
|
5603
|
-
"code": "() => (\n <>\n Root position\n <
|
|
5545
|
+
"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><BaseStyles></code> root.\n </Portal>\n </div>\n </div>\n </>\n)"
|
|
5604
5546
|
},
|
|
5605
5547
|
{
|
|
5606
5548
|
"id": "behaviors-portal-features--custom-portal-root-by-id",
|
|
5607
|
-
"code": "() => (\n <>\n Root position\n <
|
|
5549
|
+
"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)"
|
|
5608
5550
|
},
|
|
5609
5551
|
{
|
|
5610
5552
|
"id": "behaviors-portal-features--custom-portal-root-by-registration",
|
|
5611
|
-
"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 <
|
|
5553
|
+
"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}"
|
|
5612
5554
|
},
|
|
5613
5555
|
{
|
|
5614
5556
|
"id": "behaviors-portal-features--multiple-portal-roots",
|
|
5615
|
-
"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 <
|
|
5557
|
+
"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><BaseStyles></code>{' '}\n root.\n </Portal>\n </>\n ) : null}\n Inner container\n </div>\n </div>\n </>\n )\n}"
|
|
5616
5558
|
}
|
|
5617
5559
|
],
|
|
5618
5560
|
"importPath": "@primer/react",
|
|
@@ -6681,11 +6623,6 @@
|
|
|
6681
6623
|
"type": "string",
|
|
6682
6624
|
"description": "The className of the skeleton box",
|
|
6683
6625
|
"defaultValue": ""
|
|
6684
|
-
},
|
|
6685
|
-
{
|
|
6686
|
-
"name": "sx",
|
|
6687
|
-
"type": "SystemStyleObject",
|
|
6688
|
-
"deprecated": true
|
|
6689
6626
|
}
|
|
6690
6627
|
],
|
|
6691
6628
|
"subcomponents": []
|
|
@@ -7711,47 +7648,47 @@
|
|
|
7711
7648
|
"source": "https://github.com/primer/react/tree/main/packages/react/src/TextInputWithTokens",
|
|
7712
7649
|
"id": "text_input_with_tokens",
|
|
7713
7650
|
"name": "TextInputWithTokens",
|
|
7714
|
-
"status": "
|
|
7651
|
+
"status": "deprecated",
|
|
7715
7652
|
"a11yReviewed": "2025-01-08",
|
|
7716
7653
|
"stories": [
|
|
7717
7654
|
{
|
|
7718
|
-
"id": "components-textinputwithtokens--default",
|
|
7655
|
+
"id": "deprecated-components-textinputwithtokens--default",
|
|
7719
7656
|
"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}"
|
|
7720
7657
|
},
|
|
7721
7658
|
{
|
|
7722
|
-
"id": "components-textinputwithtokens-features--with-leading-visual",
|
|
7659
|
+
"id": "deprecated-components-textinputwithtokens-features--with-leading-visual",
|
|
7723
7660
|
"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}"
|
|
7724
7661
|
},
|
|
7725
7662
|
{
|
|
7726
|
-
"id": "components-textinputwithtokens-features--with-trailing-visual",
|
|
7663
|
+
"id": "deprecated-components-textinputwithtokens-features--with-trailing-visual",
|
|
7727
7664
|
"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}"
|
|
7728
7665
|
},
|
|
7729
7666
|
{
|
|
7730
|
-
"id": "components-textinputwithtokens-features--with-loading-indicator",
|
|
7667
|
+
"id": "deprecated-components-textinputwithtokens-features--with-loading-indicator",
|
|
7731
7668
|
"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}"
|
|
7732
7669
|
},
|
|
7733
7670
|
{
|
|
7734
|
-
"id": "components-textinputwithtokens-features--using-issue-label-tokens",
|
|
7671
|
+
"id": "deprecated-components-textinputwithtokens-features--using-issue-label-tokens",
|
|
7735
7672
|
"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}"
|
|
7736
7673
|
},
|
|
7737
7674
|
{
|
|
7738
|
-
"id": "components-textinputwithtokens-features--unstyled",
|
|
7675
|
+
"id": "deprecated-components-textinputwithtokens-features--unstyled",
|
|
7739
7676
|
"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}"
|
|
7740
7677
|
},
|
|
7741
7678
|
{
|
|
7742
|
-
"id": "components-textinputwithtokens-features--prevent-tokens-from-wrapping",
|
|
7679
|
+
"id": "deprecated-components-textinputwithtokens-features--prevent-tokens-from-wrapping",
|
|
7743
7680
|
"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}"
|
|
7744
7681
|
},
|
|
7745
7682
|
{
|
|
7746
|
-
"id": "components-textinputwithtokens-features--max-height",
|
|
7683
|
+
"id": "deprecated-components-textinputwithtokens-features--max-height",
|
|
7747
7684
|
"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}"
|
|
7748
7685
|
},
|
|
7749
7686
|
{
|
|
7750
|
-
"id": "components-textinputwithtokens-features--size",
|
|
7687
|
+
"id": "deprecated-components-textinputwithtokens-features--size",
|
|
7751
7688
|
"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}"
|
|
7752
7689
|
},
|
|
7753
7690
|
{
|
|
7754
|
-
"id": "components-textinputwithtokens-features--truncated",
|
|
7691
|
+
"id": "deprecated-components-textinputwithtokens-features--truncated",
|
|
7755
7692
|
"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}"
|
|
7756
7693
|
}
|
|
7757
7694
|
],
|
|
@@ -9011,7 +8948,7 @@
|
|
|
9011
8948
|
"stories": [
|
|
9012
8949
|
{
|
|
9013
8950
|
"id": "deprecated-components-selectpanel--default",
|
|
9014
|
-
"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 <
|
|
8951
|
+
"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}"
|
|
9015
8952
|
},
|
|
9016
8953
|
{
|
|
9017
8954
|
"id": "deprecated-components-selectpanel-examples--minimal",
|
|
@@ -9019,7 +8956,7 @@
|
|
|
9019
8956
|
},
|
|
9020
8957
|
{
|
|
9021
8958
|
"id": "deprecated-components-selectpanel-examples--short-select-panel",
|
|
9022
|
-
"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 <
|
|
8959
|
+
"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 <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}"
|
|
9023
8960
|
},
|
|
9024
8961
|
{
|
|
9025
8962
|
"id": "deprecated-components-selectpanel-features--instant-selection-variant",
|
|
@@ -9047,7 +8984,7 @@
|
|
|
9047
8984
|
},
|
|
9048
8985
|
{
|
|
9049
8986
|
"id": "deprecated-components-selectpanel-examples--with-filter-buttons",
|
|
9050
|
-
"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 <
|
|
8987
|
+
"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 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 </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}"
|
|
9051
8988
|
}
|
|
9052
8989
|
],
|
|
9053
8990
|
"importPath": "@primer/react/experimental",
|