diff --git a/.changeset/fluffy-crabs-rhyme.md b/.changeset/fluffy-crabs-rhyme.md new file mode 100644 index 00000000000..9548f46ac53 --- /dev/null +++ b/.changeset/fluffy-crabs-rhyme.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +update version of lit-labs/react to latest lit/react. diff --git a/.changeset/hot-jobs-marry.md b/.changeset/hot-jobs-marry.md new file mode 100644 index 00000000000..9d0fb77920d --- /dev/null +++ b/.changeset/hot-jobs-marry.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Add forward ref to Popover diff --git a/.changeset/lovely-hats-guess.md b/.changeset/lovely-hats-guess.md new file mode 100644 index 00000000000..0f270a72919 --- /dev/null +++ b/.changeset/lovely-hats-guess.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Convert PageLayout to CSS modules behind feature flags diff --git a/.changeset/quiet-garlics-compare.md b/.changeset/quiet-garlics-compare.md new file mode 100644 index 00000000000..45b10547d46 --- /dev/null +++ b/.changeset/quiet-garlics-compare.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Do not pass through hoverColor prop into DOM element diff --git a/.changeset/tidy-turtles-protect.md b/.changeset/tidy-turtles-protect.md new file mode 100644 index 00000000000..6d378fe75da --- /dev/null +++ b/.changeset/tidy-turtles-protect.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +Check certain refs for nullishness to address HMR issues in dotcom diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-colorblind-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-colorblind-linux.png new file mode 100644 index 00000000000..9c9be1bf233 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-dimmed-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-dimmed-linux.png new file mode 100644 index 00000000000..d04ec76d0a5 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-high-contrast-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-high-contrast-linux.png new file mode 100644 index 00000000000..b81ee92059b Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-linux.png new file mode 100644 index 00000000000..9c9be1bf233 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-tritanopia-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-tritanopia-linux.png new file mode 100644 index 00000000000..9c9be1bf233 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-colorblind-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-colorblind-linux.png new file mode 100644 index 00000000000..187994fbcc5 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-high-contrast-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-high-contrast-linux.png new file mode 100644 index 00000000000..187994fbcc5 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-linux.png new file mode 100644 index 00000000000..187994fbcc5 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-linux.png differ diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-tritanopia-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-tritanopia-linux.png new file mode 100644 index 00000000000..187994fbcc5 Binary files /dev/null and b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-tritanopia-linux.png differ diff --git a/e2e/components/AvatarStack.test.ts b/e2e/components/AvatarStack.test.ts index 4d814a808bf..8a3332d9371 100644 --- a/e2e/components/AvatarStack.test.ts +++ b/e2e/components/AvatarStack.test.ts @@ -2,310 +2,82 @@ import {test, expect} from '@playwright/test' import {visit} from '../test-helpers/storybook' import {themes} from '../test-helpers/themes' -test.describe('AvatarStack', () => { - test.describe('Default', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--default', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Default.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--default', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) +const stories: Array<{title: string; id: string}> = [ + { + title: 'Default', + id: 'components-avatarstack--default', + }, + { + title: 'Playground', + id: 'components-avatarstack--playground', + }, + { + title: 'Align Left', + id: 'components-avatarstack-features--align-left', + }, + { + title: 'Align Right', + id: 'components-avatarstack-features--align-right', + }, + { + title: 'Disable Expand On Hover', + id: 'components-avatarstack-features--disable-expand-on-hover', + }, + { + title: 'Custom Size On Parent', + id: 'components-avatarstack-features--custom-size-on-parent', + }, + { + title: 'Custom Size On Parent Responsive', + id: 'components-avatarstack-features--custom-size-on-parent-responsive', + }, + { + title: 'Custom Size On Children', + id: 'components-avatarstack-features--custom-size-on-children', + }, + { + title: 'Custom Size On Children Responsive', + id: 'components-avatarstack-features--custom-size-on-children-responsive', + }, + { + title: 'SX Prop', + id: 'components-avatarstack-dev--sx-prop', + }, +] - test.describe('Playground', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--playground', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Playground.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--playground', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Align Left', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-left', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Align Left.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-left', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Align Right', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-right', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Align Right.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-right', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Disable Expand On Hover', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--disable-expand-on-hover', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Disable Expand On Hover.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--disable-expand-on-hover', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Custom Size On Parent', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Parent.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Custom Size On Parent Responsive', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent-responsive', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Parent Responsive.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent-responsive', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', +test.describe('AvatarStack', () => { + for (const story of stories) { + test.describe(story.title, () => { + for (const theme of themes) { + test.describe(theme, () => { + test('@vrt', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, }, - }, - }) - }) - }) - } - }) + }) - test.describe('Custom Size On Children', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children', - globals: { - colorScheme: theme, - }, + expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.${story.title}.${theme}.png`) }) - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Children.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', + test('@aat', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, }, - }, - }) - }) - }) - } - }) - - test.describe('Custom Size On Children Responsive', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children-responsive', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Children Responsive.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children-responsive', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', + }) + await expect(page).toHaveNoViolations({ + rules: { + 'color-contrast': { + enabled: theme !== 'dark_dimmed', + }, }, - }, + }) }) }) - }) - } - }) + } + }) + } }) diff --git a/package-lock.json b/package-lock.json index 8394b00ba12..65761b1359b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5101,14 +5101,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@lit-labs/react": { - "version": "1.2.1", - "license": "BSD-3-Clause" - }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.2.0", "license": "BSD-3-Clause" }, + "node_modules/@lit/react": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.6.tgz", + "integrity": "sha512-QIss8MPh6qUoFJmuaF4dSHts3qCsA36S3HcOLiNPShxhgYPr4XJRnCBKPipk85sR9xr6TQrOcDMfexwbNdJHYA==", + "license": "BSD-3-Clause", + "peerDependencies": { + "@types/react": "17 || 18" + } + }, "node_modules/@manypkg/find-root": { "version": "1.1.0", "dev": true, @@ -30448,7 +30453,7 @@ "dependencies": { "@github/relative-time-element": "^4.4.3", "@github/tab-container-element": "^4.8.0", - "@lit-labs/react": "1.2.1", + "@lit/react": "^1.0.6", "@oddbird/popover-polyfill": "^0.4.4", "@primer/behaviors": "^1.7.2", "@primer/live-region-element": "^0.7.1", diff --git a/packages/react/jest.config.js b/packages/react/jest.config.js index d24acdbd0bd..b028c61cf8d 100644 --- a/packages/react/jest.config.js +++ b/packages/react/jest.config.js @@ -28,5 +28,5 @@ module.exports = { setupFiles: ['/src/utils/test-helpers.tsx'], setupFilesAfterEnv: ['/src/utils/test-matchers.tsx', '/src/utils/test-deprecations.tsx'], testMatch: ['/**/*.test.[jt]s?(x)', '!**/*.types.test.[jt]s?(x)'], - transformIgnorePatterns: ['node_modules/(?!@github/[a-z-]+-element|@lit-labs/react|@oddbird/popover-polyfill)'], + transformIgnorePatterns: ['node_modules/(?!@github/[a-z-]+-element|@lit/react|@oddbird/popover-polyfill)'], } diff --git a/packages/react/package.json b/packages/react/package.json index 46f16abefba..6b51224433f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -80,7 +80,7 @@ "dependencies": { "@github/relative-time-element": "^4.4.3", "@github/tab-container-element": "^4.8.0", - "@lit-labs/react": "1.2.1", + "@lit/react": "^1.0.6", "@oddbird/popover-polyfill": "^0.4.4", "@primer/behaviors": "^1.7.2", "@primer/live-region-element": "^0.7.1", diff --git a/packages/react/rollup.config.mjs b/packages/react/rollup.config.mjs index b201e7dbba3..98ba333a1b7 100644 --- a/packages/react/rollup.config.mjs +++ b/packages/react/rollup.config.mjs @@ -1,7 +1,7 @@ import path from 'node:path' import commonjs from '@rollup/plugin-commonjs' import resolve from '@rollup/plugin-node-resolve' -import babel from '@rollup/plugin-babel' +import {babel} from '@rollup/plugin-babel' import replace from '@rollup/plugin-replace' import terser from '@rollup/plugin-terser' import {visualizer} from 'rollup-plugin-visualizer' @@ -42,7 +42,7 @@ const ESM_ONLY = new Set([ '@github/paste-markdown', '@github/relative-time-element', '@github/tab-container-element', - '@lit-labs/react', + '@lit/react', '@oddbird/popover-polyfill', ]) const dependencies = [ diff --git a/packages/react/src/ActionBar/ActionBar.docs.json b/packages/react/src/ActionBar/ActionBar.docs.json index 7b8f2659f96..8d1ce1dba9b 100644 --- a/packages/react/src/ActionBar/ActionBar.docs.json +++ b/packages/react/src/ActionBar/ActionBar.docs.json @@ -3,29 +3,45 @@ "name": "ActionBar", "status": "alpha", "a11yReviewed": true, - "stories": [], + "stories": [ + { + "id": "components-actionbar--default" + } + ], "importPath": "@primer/react", "props": [ { - "name": "size", - "type": "'small' | 'medium' | 'large'", + "name": "aria-label", + "type": "string", "required": false, - "description": "Size of the action bar" + "description": "When provided, a label is added to the action bar", + "defaultValue": "" }, { - "name": "aria-label", + "name": "aria-labelledby", "type": "string", - "description": "When provided, a label is added to the action bar" + "required": false, + "description": "When provided, uses the element with that ID as the accessible name for the ActionBar", + "defaultValue": "" }, { "name": "children", - "type": "React.ReactElement", - "required": true + "type": "ReactNode", + "required": false, + "description": "Buttons in the action bar", + "defaultValue": "" + }, + { + "name": "size", + "type": "'small' | 'large' | 'medium'", + "required": false, + "description": "Size of the action bar", + "defaultValue": "" } ], "subcomponents": [ { - "name": "ActionBar.Icon", + "name": "ActionBar.IconButton", "props": [ { "name": "children", @@ -38,19 +54,19 @@ "name": "icon", "type": "Component", "defaultValue": "", - "description": "provide an octicon. It will be placed in the center of the button" + "description": "Provide an octicon. It will be placed in the center of the button" }, { "name": "aria-label", "type": "string", "defaultValue": "", "description": "Use an aria label to describe the functionality of the button. Please refer to [our guidance on alt text](https://primer.style/guides/accessibility/alternative-text-for-images) for tips on writing good alternative text." - }, - { - "name": "sx", - "type": "SystemStyleObject" } - ] + ], + "passthrough": { + "element": "IconButton", + "url": "/react/IconButton" + } }, { "name": "ActionBar.Divider", diff --git a/packages/react/src/ActionList/ActionList.docs.json b/packages/react/src/ActionList/ActionList.docs.json index 2d7ff88c1a9..59bbc7ae805 100644 --- a/packages/react/src/ActionList/ActionList.docs.json +++ b/packages/react/src/ActionList/ActionList.docs.json @@ -26,10 +26,10 @@ "description": "Whether multiple items or a single item can be selected." }, { - "name": "showDivider", + "name": "showDividers", "type": "boolean", - "defaultValue": "false", - "description": "Display a divider above each item in this list when it does not follow a header or divider." + "description": "Display a divider above each `Item` in this `List` when it does not follow a `Header` or `Divider`.", + "defaultValue": "" }, { "name": "role", @@ -51,7 +51,7 @@ "type": "React.ReactNode | ActionList.LeadingVisual | ActionList.Description | ActionList.TrailingVisual", "defaultValue": "", "required": true, - "description": "" + "description": "Primary content for an Item" }, { "name": "variant", @@ -100,6 +100,13 @@ "defaultValue": "", "description": "ARIA role describing the function of the item. `option` is a common value." }, + { + "name": "id", + "type": "string", + "required": false, + "description": "id to attach to the root element of the Item", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -123,6 +130,13 @@ "required": false, "description": "The level of the heading" }, + { + "name": "visuallyHidden", + "type": "boolean", + "required": false, + "description": "", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -154,6 +168,13 @@ "type": "React.ElementType", "defaultValue": "\"a\"" }, + { + "name": "inactiveText", + "type": "string", + "required": false, + "description": "Text describing why the item is inactive. This may be used when an item's usual functionality\nis unavailable due to a system error such as a database outage.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -277,6 +298,20 @@ "defaultValue": "'subtle'", "description": "`filled` style has a background color and top and bottom borders. Subtle style has no background or borders." }, + { + "name": "auxiliaryText", + "type": "string", + "required": false, + "description": "Secondary text which provides additional information about a `Group`.", + "defaultValue": "" + }, + { + "name": "visuallyHidden", + "type": "boolean", + "required": false, + "description": "", + "defaultValue": "" + }, { "name": "as", "type": "h1 | h2 | h3 | h4 | h5 | h6", @@ -336,6 +371,16 @@ "type": "SystemStyleObject" } ] + }, + { + "filePath": "/Users/mperrotti/work-dir/react/packages/react/src/ActionList/Divider.tsx", + "name": "ActionList.Divider", + "props": [ + { + "name": "sx", + "type": "SystemStyleObject" + } + ] } ] -} \ No newline at end of file +} diff --git a/packages/react/src/ActionMenu/ActionMenu.docs.json b/packages/react/src/ActionMenu/ActionMenu.docs.json index e1b262a66b1..cdd205fd7db 100644 --- a/packages/react/src/ActionMenu/ActionMenu.docs.json +++ b/packages/react/src/ActionMenu/ActionMenu.docs.json @@ -3,7 +3,29 @@ "name": "ActionMenu", "status": "beta", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-actionmenu--default" + }, + { + "id": "components-actionmenu-features--links-and-actions" + }, + { + "id": "components-actionmenu-features--single-select" + }, + { + "id": "components-actionmenu-features--multi-select" + }, + { + "id": "components-actionmenu-features--inactive-items" + }, + { + "id": "components-actionmenu-features--loading-items" + }, + { + "id": "components-actionmenu-features--submenus" + } + ], "importPath": "@primer/react", "props": [ { @@ -58,6 +80,12 @@ "defaultValue": "", "required": true, "description": "Accepts a single child element" + }, + { + "name": "id", + "type": "string", + "description": "", + "defaultValue": "" } ] }, @@ -82,6 +110,13 @@ "type": "| 'inside-top' | 'inside-bottom' | 'inside-left' | 'inside-right' | 'inside-center' | 'outside-top' | 'outside-bottom' | 'outside-left' | 'outside-right'", "defaultValue": "'outside-bottom'", "description": "Controls which side of the anchor the menu will appear" + }, + { + "name": "data-test-id", + "type": "unknown", + "required": false, + "description": "ID to use for React testing utilities.", + "defaultValue": "" } ], "passthrough": { diff --git a/packages/react/src/ActionMenu/ActionMenu.tsx b/packages/react/src/ActionMenu/ActionMenu.tsx index 376dce0ac1a..b2dd4b81a9b 100644 --- a/packages/react/src/ActionMenu/ActionMenu.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.tsx @@ -260,7 +260,9 @@ const Overlay: React.FC> = ({ // If the menu anchor is an icon button, we need to label the menu by tooltip that also labelled the anchor. const [anchorAriaLabelledby, setAnchorAriaLabelledby] = useState(null) useEffect(() => { - if (anchorRef.current) { + // Necessary for HMR reloads + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (anchorRef?.current) { const ariaLabelledby = anchorRef.current.getAttribute('aria-labelledby') if (ariaLabelledby) { setAnchorAriaLabelledby(ariaLabelledby) diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json b/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json index 1cb80dfa148..699fd82c050 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json @@ -3,18 +3,56 @@ "name": "AnchoredOverlay", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-anchoredoverlay--default" + }, + { + "id": "components-anchoredoverlay-features--portal-inside-scrolling-element" + }, + { + "id": "components-anchoredoverlay-features--custom-anchor-id" + }, + { + "id": "components-anchoredoverlay-features--height" + }, + { + "id": "components-anchoredoverlay-features--width" + }, + { + "id": "components-anchoredoverlay-features--anchor-alignment" + }, + { + "id": "components-anchoredoverlay-features--anchor-side" + }, + { + "id": "components-anchoredoverlay-features--offset-position-from-anchor" + }, + { + "id": "components-anchoredoverlay-features--offset-alignment-from-anchor" + }, + { + "id": "components-anchoredoverlay-features--focus-trap-overrides" + }, + { + "id": "components-anchoredoverlay-features--focus-zone-overrides" + }, + { + "id": "components-anchoredoverlay-features--overlay-props-overrides" + } + ], "importPath": "@primer/react", "props": [ { "name": "open", "type": "boolean", + "required": true, "defaultValue": "false", "description": "Determines whether the overlay portion of the component should be shown or not." }, { "name": "onOpen", - "type": "(gesture: 'anchor-click' | 'anchor-key-press') => unknown", + "type": "(gesture: 'anchor-click' | 'anchor-key-press', event?: KeyboardEvent | undefined) => unknown", "defaultValue": "", "description": "A callback that is called whenever the overlay is currently closed and an \"open gesture\" is detected." }, @@ -95,6 +133,20 @@ "type": "boolean", "defaultValue": "true", "description": "Determines if the Overlay width should be adjusted responsively if there is not enough space to display the Overlay. If `preventOverflow` is set to `false`, the Overlay will be displayed at the maximum width that fits within the viewport." + }, + { + "name": "height", + "type": "'small' | 'initial' | 'large' | 'medium' | 'auto' | 'fit-content' | 'xsmall' | 'xlarge'", + "required": false, + "description": "", + "defaultValue": "" + }, + { + "name": "width", + "type": "'small' | 'large' | 'medium' | 'auto' | 'xlarge' | 'xxlarge'", + "required": false, + "description": "", + "defaultValue": "" } ] } diff --git a/packages/react/src/Autocomplete/Autocomplete.docs.json b/packages/react/src/Autocomplete/Autocomplete.docs.json index ff776c4ab01..94b13ca91e6 100644 --- a/packages/react/src/Autocomplete/Autocomplete.docs.json +++ b/packages/react/src/Autocomplete/Autocomplete.docs.json @@ -3,12 +3,52 @@ "name": "Autocomplete", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-autocomplete--default" + }, + { + "id": "components-autocomplete-features--with-token-input" + }, + { + "id": "components-autocomplete-features--add-new-item" + }, + { + "id": "components-autocomplete-features--custom-search-filter-fn" + }, + { + "id": "components-autocomplete-features--custom-sort-after-menu-close" + }, + { + "id": "components-autocomplete-features--with-callback-when-overlay-open-state-changes" + }, + { + "id": "components-autocomplete-features--async-loading-of-items" + }, + { + "id": "components-autocomplete-features--rendering-the-menu-outside-an-overlay" + }, + { + "id": "components-autocomplete-features--custom-overlay-menu-anchor" + }, + { + "id": "components-autocomplete-features--in-overlay-with-custom-scroll-container-ref" + }, + { + "id": "components-autocomplete-features--in-a-dialog" + } + ], "importPath": "@primer/react", "props": [ { "name": "children", "type": "React.ReactNode" + }, + { + "name": "id", + "type": "string", + "description": "May be used to customize how the ID is set on the text input to be used by ARIA attributes on related elements.", + "defaultValue": "" } ], "subcomponents": [ @@ -68,7 +108,7 @@ { "name": "selectedItemIds", "required": true, - "type": "(string | number)[]", + "type": "string[]", "description": "The IDs of the selected items" }, { diff --git a/packages/react/src/Avatar/Avatar.docs.json b/packages/react/src/Avatar/Avatar.docs.json index ca2581332dc..e678fec6eb5 100644 --- a/packages/react/src/Avatar/Avatar.docs.json +++ b/packages/react/src/Avatar/Avatar.docs.json @@ -3,7 +3,23 @@ "name": "Avatar", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-avatar--default" + }, + { + "id": "components-avatar-features--square" + }, + { + "id": "components-avatar-features--square-sx-prop" + }, + { + "id": "components-avatar-features--size" + }, + { + "id": "components-avatar-features--size-responsive" + } + ], "importPath": "@primer/react", "props": [ { @@ -24,6 +40,13 @@ "defaultValue": "false", "description": "If true, the avatar will be square instead of circular." }, + { + "name": "src", + "type": "string", + "required": false, + "description": "URL of the avatar image.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/AvatarPair/AvatarPair.docs.json b/packages/react/src/AvatarPair/AvatarPair.docs.json index 6185196dff3..176ec3916df 100644 --- a/packages/react/src/AvatarPair/AvatarPair.docs.json +++ b/packages/react/src/AvatarPair/AvatarPair.docs.json @@ -3,7 +3,17 @@ "name": "AvatarPair", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-avatarpair--default" + }, + { + "id": "components-avatarpair-features--parent-circle" + }, + { + "id": "components-avatarpair-features--parent-square" + } + ], "importPath": "@primer/react", "props": [ { diff --git a/packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx b/packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx new file mode 100644 index 00000000000..e1da2e33122 --- /dev/null +++ b/packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx @@ -0,0 +1,23 @@ +import React from 'react' +import type {Meta} from '@storybook/react' +import AvatarStack from './AvatarStack' +import Avatar from '../Avatar' + +export default { + title: 'Components/AvatarStack/Dev', + component: AvatarStack, +} as Meta + +export const SxProp = () => ( + + + + + + +) diff --git a/packages/react/src/AvatarStack/AvatarStack.docs.json b/packages/react/src/AvatarStack/AvatarStack.docs.json index 3f38da7c4eb..286e889c4d8 100644 --- a/packages/react/src/AvatarStack/AvatarStack.docs.json +++ b/packages/react/src/AvatarStack/AvatarStack.docs.json @@ -3,9 +3,43 @@ "name": "AvatarStack", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-avatarstack--default" + }, + { + "id": "components-avatarstack-features--align-left" + }, + { + "id": "components-avatarstack-features--align-right" + }, + { + "id": "components-avatarstack-features--disable-expand-on-hover" + }, + { + "id": "components-avatarstack-features--custom-size-on-parent" + }, + { + "id": "components-avatarstack-features--custom-size-on-parent-responsive" + }, + { + "id": "components-avatarstack-features--custom-size-on-children" + }, + { + "id": "components-avatarstack-features--custom-size-on-children-responsive" + }, + { + "id": "components-avatarstack-features--with-single-avatar" + } + ], "importPath": "@primer/react", "props": [ + { + "name": "children", + "type": "ReactNode", + "description": "A set of Avatar components to stack", + "defaultValue": "" + }, { "name": "alignRight", "type": "boolean", @@ -24,6 +58,12 @@ "defaultValue": "20", "description": "The size of the avatar children in pixels." }, + { + "name": "className", + "type": "string", + "description": "Class name for custom styling.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/Banner/Banner.docs.json b/packages/react/src/Banner/Banner.docs.json index 9451a4dbef5..5e2c8980b3b 100644 --- a/packages/react/src/Banner/Banner.docs.json +++ b/packages/react/src/Banner/Banner.docs.json @@ -1,10 +1,53 @@ { "id": "banner", "name": "Banner", - "status": "draft", + "status": "alpha", "a11yReviewed": true, "importPath": "@primer/react/experimental", - "stories": [], + "stories": [ + { + "id": "components-banner--default" + }, + { + "id": "components-banner-features--critical" + }, + { + "id": "components-banner-features--info" + }, + { + "id": "components-banner-features--success" + }, + { + "id": "components-banner-features--upsell" + }, + { + "id": "components-banner-features--warning" + }, + { + "id": "components-banner-features--dismiss" + }, + { + "id": "components-banner-features--dismiss-with-actions" + }, + { + "id": "components-banner-features--with-hidden-title" + }, + { + "id": "components-banner-features--with-hidden-title-and-actions" + }, + { + "id": "components-banner-features--dismissible-with-hidden-title-and-actions" + }, + { + "id": "components-banner-features--dismissible-with-hidden-title-and-secondary-action" + }, + { + "id": "components-banner-features--with-actions" + }, + { + "id": "components-banner-features--custom-icon" + } + ], "props": [ { "name": "aria-label", @@ -69,15 +112,30 @@ }, { "name": "Banner.Description", - "props": [] + "props": [ + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" + } + ] }, { "name": "Banner.PrimaryAction", - "props": [] + "props": [], + "passthrough": { + "element": "Button", + "url": "/react/Button" + } }, { "name": "Banner.SecondaryAction", - "props": [] + "props": [], + "passthrough": { + "element": "Button", + "url": "/react/Button" + } } ] } diff --git a/packages/react/src/Blankslate/Blankslate.docs.json b/packages/react/src/Blankslate/Blankslate.docs.json index 9241118b4ea..a2cf0807b05 100644 --- a/packages/react/src/Blankslate/Blankslate.docs.json +++ b/packages/react/src/Blankslate/Blankslate.docs.json @@ -3,13 +3,35 @@ "name": "Blankslate", "status": "draft", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "drafts-components-blankslate--default" + }, + { + "id": "drafts-components-blankslate-features--with-visual" + }, + { + "id": "drafts-components-blankslate-features--with-primary-action" + }, + { + "id": "drafts-components-blankslate-features--with-secondary-action" + }, + { + "id": "drafts-components-blankslate-features--with-border" + }, + { + "id": "drafts-components-blankslate-features--narrow" + }, + { + "id": "drafts-components-blankslate-features--spacious" + } + ], "importPath": "@primer/react/experimental", "props": [ { "name": "border", "type": "boolean", - "description": "" + "description": "Add a border around this component" }, { "name": "narrow", @@ -20,6 +42,12 @@ "name": "spacious", "type": "boolean", "description": "" + }, + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" } ], "subcomponents": [ @@ -45,7 +73,8 @@ "props": [ { "name": "href", - "type": "string" + "type": "string", + "description": "Link to complete primary action" } ] }, @@ -54,7 +83,8 @@ "props": [ { "name": "href", - "type": "string" + "type": "string", + "description": "Link to complete secondary action" } ] } diff --git a/packages/react/src/BranchName/BranchName.docs.json b/packages/react/src/BranchName/BranchName.docs.json index 7529b5ef337..585a62d2720 100644 --- a/packages/react/src/BranchName/BranchName.docs.json +++ b/packages/react/src/BranchName/BranchName.docs.json @@ -3,7 +3,17 @@ "name": "BranchName", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-branchname--default" + }, + { + "id": "components-branchname-features--with-branch-icon" + }, + { + "id": "components-branchname-features--not-a-link" + } + ], "importPath": "@primer/react", "props": [ { @@ -21,4 +31,4 @@ } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json b/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json index 640e078d600..1ee3dcb3b4c 100644 --- a/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json +++ b/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json @@ -3,9 +3,20 @@ "name": "Breadcrumbs", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-breadcrumbs--default" + } + ], "importPath": "@primer/react", "props": [ + { + "name": "className", + "type": "string", + "required": false, + "description": "", + "defaultValue": "" + }, { "name": "children", "type": "Breadcrumbs.Item[]", @@ -25,7 +36,14 @@ "name": "selected", "type": "boolean", "defaultValue": "false", - "description": "" + "description": "Whether this item represents the current page" + }, + { + "name": "to", + "type": "string | Partial", + "required": false, + "description": "Used when the item is rendered using a component like React Router's `Link`. The path to navigate to.", + "defaultValue": "" }, { "name": "ref", @@ -47,4 +65,4 @@ } } ] -} \ No newline at end of file +} diff --git a/packages/react/src/Button/Button.docs.json b/packages/react/src/Button/Button.docs.json index 627f75d6808..39e688b1acf 100644 --- a/packages/react/src/Button/Button.docs.json +++ b/packages/react/src/Button/Button.docs.json @@ -3,7 +3,86 @@ "name": "Button", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-button--default" + }, + { + "id": "components-button-features--primary" + }, + { + "id": "components-button-features--danger" + }, + { + "id": "components-button-features--invisible" + }, + { + "id": "components-button-features--link" + }, + { + "id": "components-button-features--leading-visual" + }, + { + "id": "components-button-features--trailing-visual" + }, + { + "id": "components-button-features--trailing-counter" + }, + { + "id": "components-button-features--trailing-counter-with-no-text" + }, + { + "id": "components-button-features--trailing-counter-all-variants" + }, + { + "id": "components-button-features--trailing-action" + }, + { + "id": "components-button-features--block" + }, + { + "id": "components-button-features--disabled" + }, + { + "id": "components-button-features--inactive" + }, + { + "id": "components-button-features--small" + }, + { + "id": "components-button-features--medium" + }, + { + "id": "components-button-features--large" + }, + { + "id": "components-button-features--loading" + }, + { + "id": "components-button-features--loading-custom-announcement" + }, + { + "id": "components-button-features--loading-with-leading-visual" + }, + { + "id": "components-button-features--loading-with-trailing-visual" + }, + { + "id": "components-button-features--loading-with-trailing-action" + }, + { + "id": "components-button-features--loading-trigger" + }, + { + "id": "components-button-features--label-wrap" + }, + { + "id": "components-button-features--inactive-button-with-tooltip" + }, + { + "id": "components-button-features--expanded-button" + } + ], "importPath": "@primer/react", "props": [ { @@ -29,7 +108,7 @@ }, { "name": "count", - "type": "number | string", + "type": "number", "description": "For counter buttons, the number to display." }, { @@ -83,9 +162,14 @@ "type": "React.ElementType", "description": "A visual to display after the button text." }, + { + "name": "trailingAction", + "type": "React.ElementType", + "description": "Trailing action appears to the right of the trailing visual and is always locked to the end" + }, { "name": "variant", - "type": "'default'\n| 'primary'\n| 'danger'\n| 'invisible'", + "type": "'default'\n| 'primary'\n| 'danger'\n| 'invisible'\n| 'link'", "defaultValue": "'default'", "description": "Change the visual style of the button." }, @@ -94,6 +178,12 @@ "type": "boolean", "defaultValue": "false", "description": "Whether the button label should wrap to multiple lines of it is longer than the button width." + }, + { + "name": "disabled", + "type": "boolean", + "description": "Avoid disabling buttons because it will make them inaccessible to users who rely on keyboard navigation. Buttons that are disabled can not be clicked, selected, or navigated through.", + "defaultValue": "" } ], "passthrough": { diff --git a/packages/react/src/Button/IconButton.docs.json b/packages/react/src/Button/IconButton.docs.json index dc357c85695..4513186be1c 100644 --- a/packages/react/src/Button/IconButton.docs.json +++ b/packages/react/src/Button/IconButton.docs.json @@ -3,7 +3,56 @@ "name": "IconButton", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-iconbutton--default" + }, + { + "id": "components-iconbutton-features--primary" + }, + { + "id": "components-iconbutton-features--danger" + }, + { + "id": "components-iconbutton-features--invisible" + }, + { + "id": "components-iconbutton-features--disabled" + }, + { + "id": "components-iconbutton-features--small" + }, + { + "id": "components-iconbutton-features--medium" + }, + { + "id": "components-iconbutton-features--large" + }, + { + "id": "components-iconbutton-features--with-description" + }, + { + "id": "components-iconbutton-features--external-tooltip" + }, + { + "id": "components-iconbutton-features--external-tooltip-version1" + }, + { + "id": "components-iconbutton-features--as-a-menu-anchor" + }, + { + "id": "components-iconbutton-features--loading" + }, + { + "id": "components-iconbutton-features--loading-trigger" + }, + { + "id": "components-iconbutton-features--keyshortcuts-on-description" + }, + { + "id": "components-iconbutton-features--keyshortcuts" + } + ], "importPath": "@primer/react", "props": [ { @@ -56,6 +105,13 @@ "description": "The direction of the tooltip. ", "required": false }, + { + "name": "description", + "type": "string", + "required": false, + "description": "If `description` is provided, we will use a Tooltip to describe the button. Then `aria-label` is used to label the button.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/Button/types.ts b/packages/react/src/Button/types.ts index 2d3fae5b07b..2f94f999eba 100644 --- a/packages/react/src/Button/types.ts +++ b/packages/react/src/Button/types.ts @@ -31,7 +31,7 @@ export type ButtonBaseProps = { */ size?: Size /** - * Items that are disabled can not be clicked, selected, or navigated through. + * Avoid disabling buttons because it will make them inaccessible to users who rely on keyboard navigation. that are disabled can not be clicked, selected, or navigated through. */ disabled?: boolean /** diff --git a/packages/react/src/ButtonGroup/ButtonGroup.docs.json b/packages/react/src/ButtonGroup/ButtonGroup.docs.json index 06c470b1253..bc7c4828eb8 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.docs.json +++ b/packages/react/src/ButtonGroup/ButtonGroup.docs.json @@ -3,7 +3,23 @@ "name": "ButtonGroup", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-buttongroup--default" + }, + { + "id": "components-buttongroup-features--icon-buttons" + }, + { + "id": "components-buttongroup-features--loading-buttons" + }, + { + "id": "components-buttongroup-features--dropdown-split" + }, + { + "id": "components-buttongroup-features--as-toolbar" + } + ], "importPath": "@primer/react", "props": [ { @@ -16,4 +32,4 @@ } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/Checkbox/Checkbox.docs.json b/packages/react/src/Checkbox/Checkbox.docs.json index 8e493070d97..ffe55c31e13 100644 --- a/packages/react/src/Checkbox/Checkbox.docs.json +++ b/packages/react/src/Checkbox/Checkbox.docs.json @@ -3,7 +3,23 @@ "name": "Checkbox", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-checkbox--default" + }, + { + "id": "components-checkbox-features--with-leading-visual" + }, + { + "id": "components-checkbox-features--disabled" + }, + { + "id": "components-checkbox-features--with-caption" + }, + { + "id": "components-checkbox-features--indeterminate" + } + ], "importPath": "@primer/react", "props": [ { @@ -63,4 +79,4 @@ } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json b/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json index 4d289ce5c81..d32a6d208f8 100644 --- a/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json +++ b/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json @@ -3,7 +3,26 @@ "name": "CheckboxGroup", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-checkboxgroup--default" + }, + { + "id": "components-checkboxgroup-features--visually-hidden-label" + }, + { + "id": "components-checkboxgroup-features--with-external-label" + }, + { + "id": "components-checkboxgroup-features--error" + }, + { + "id": "components-checkboxgroup-features--success" + }, + { + "id": "components-checkboxgroup-features--caption" + } + ], "importPath": "@primer/react", "props": [ { @@ -102,4 +121,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/react/src/CounterLabel/CounterLabel.docs.json b/packages/react/src/CounterLabel/CounterLabel.docs.json index 17a0b4cb94e..b551fb900a0 100644 --- a/packages/react/src/CounterLabel/CounterLabel.docs.json +++ b/packages/react/src/CounterLabel/CounterLabel.docs.json @@ -3,7 +3,17 @@ "name": "CounterLabel", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-counterlabel--default" + }, + { + "id": "components-counterlabel-features--primary-theme" + }, + { + "id": "components-counterlabel-features--secondary-theme" + } + ], "importPath": "@primer/react", "props": [ { @@ -11,7 +21,17 @@ "type": "'primary' | 'secondary'", "defaultValue": "", "description": "Pass in 'primary' for a darker background and inverse text, or 'secondary' for a lighter background and primary text. Omitting the scheme prop renders the default counter scheme" + }, + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" + }, + { + "name": "sx", + "type": "BetterSystemStyleObject" } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/DataTable/DataTable.docs.json b/packages/react/src/DataTable/DataTable.docs.json index d4d298fb049..773441478d2 100644 --- a/packages/react/src/DataTable/DataTable.docs.json +++ b/packages/react/src/DataTable/DataTable.docs.json @@ -5,40 +5,43 @@ "a11yReviewed": true, "stories": [ { - "id": "experimental-components-datatable-features--with-title" + "id": "drafts-components-datatable--default" }, { - "id": "experimental-components-datatable-features--with-title-and-subtitle" + "id": "drafts-components-datatable-features--with-title" }, { - "id": "experimental-components-datatable-features--with-sorting" + "id": "drafts-components-datatable-features--with-title-and-subtitle" }, { - "id": "experimental-components-datatable-features--with-actions" + "id": "drafts-components-datatable-features--with-sorting" }, { - "id": "experimental-components-datatable-features--with-action" + "id": "drafts-components-datatable-features--with-actions" }, { - "id": "experimental-components-datatable-features--with-row-action" + "id": "drafts-components-datatable-features--with-action" }, { - "id": "experimental-components-datatable-features--with-row-actions" + "id": "drafts-components-datatable-features--with-row-action" }, { - "id": "experimental-components-datatable-features--with-row-action-menu" + "id": "drafts-components-datatable-features--with-row-actions" }, { - "id": "experimental-components-datatable-features--with-custom-heading" + "id": "drafts-components-datatable-features--with-row-action-menu" }, { - "id": "experimental-components-datatable-features--with-no-content" + "id": "drafts-components-datatable-features--with-custom-heading" }, { - "id": "experimental-components-datatable-features--with-loading" + "id": "drafts-components-datatable-features--with-no-content" }, { - "id": "experimental-components-datatable-features--with-pagination" + "id": "drafts-components-datatable-features--with-loading" + }, + { + "id": "drafts-components-datatable-features--with-pagination" } ], "importPath": "@primer/react/experimental", @@ -67,6 +70,34 @@ "name": "cellPadding", "type": "'condensed' | 'normal' | 'spacious'", "description": "Specify the amount of space that should be available around the contents of a cell" + }, + { + "name": "aria-describedby", + "type": "string", + "required": false, + "description": "Provide an id to an element which uniquely describes this table", + "defaultValue": "" + }, + { + "name": "aria-labelledby", + "type": "string", + "required": false, + "description": "Provide an id to an element which uniquely labels this table", + "defaultValue": "" + }, + { + "name": "initialSortColumn", + "type": "string | number", + "required": false, + "description": "Provide the id or field of the column by which the table is sorted. When\nusing this `prop`, the input data must be sorted by this column in\nascending order", + "defaultValue": "" + }, + { + "name": "initialSortDirection", + "type": "'ASC' | 'DESC'", + "required": false, + "description": "Provide the sort direction that the table should be sorted by on the\ncurrently sorted column", + "defaultValue": "" } ], "subcomponents": [ @@ -103,6 +134,15 @@ } ] }, + { + "name": "Table.Actions", + "props": [ + { + "name": "children", + "type": "React.ReactNode" + } + ] + }, { "name": "Table.Body", "props": [ @@ -124,6 +164,13 @@ { "name": "Table.Header", "props": [ + { + "name": "align", + "type": "'end' | 'start'", + "required": false, + "description": "The horizontal alignment of the cell's content", + "defaultValue": "" + }, { "name": "children", "type": "React.ReactNode" @@ -133,6 +180,13 @@ { "name": "Table.Cell", "props": [ + { + "name": "align", + "type": "'end' | 'start'", + "required": false, + "description": "The horizontal alignment of the cell's content", + "defaultValue": "" + }, { "name": "children", "type": "React.ReactNode" @@ -144,6 +198,10 @@ } ] }, + { + "name": "Table.CellPlaceholder", + "props": [] + }, { "name": "Table.Container", "props": [ @@ -153,6 +211,10 @@ } ] }, + { + "name": "Table.Divider", + "props": [] + }, { "name": "Table.Title", "props": [ @@ -163,7 +225,8 @@ { "name": "id", "type": "string", - "required": true + "required": true, + "description": "Provide a unique id for the table subtitle. This should be used along with\n`aria-labelledby` on `DataTable`" } ] }, @@ -177,7 +240,8 @@ { "name": "id", "type": "string", - "required": true + "required": true, + "description": "Provide a unique id for the table subtitle. This should be used along with\n`aria-describedby` on `DataTable`" } ] }, @@ -187,16 +251,19 @@ { "name": "cellPadding", "type": "'condensed' | 'normal' | 'spacious'", - "description": "Specify the amount of space that should be available around the contents of a cell" + "description": "Specify the amount of space that should be available around the contents of a cell", + "defaultValue": "normal" }, { "name": "columns", + "required": true, "type": "Array>" }, { "name": "rows", "type": "number", - "description": "Optionally specify the number of rows which should be included in the skeleton state of the component" + "description": "Optionally specify the number of rows which should be included in the skeleton state of the component", + "defaultValue": "10" } ] }, @@ -206,28 +273,42 @@ { "name": "aria-label", "type": "string", - "required": true + "required": true, + "description": "Defines a string value that labels the current element.\nProvide a label for the navigation landmark rendered by this component\n@see aria-labelledby." }, { "name": "defaultPageIndex", - "type": "string" + "type": "string", + "description": "Provide an optional index to specify the default selected page" }, { "name": "id", - "type": "string" + "type": "string", + "description": "Optionally provide an `id` that is placed on the navigation landmark\nrendered by this component" }, { "name": "onChange", - "type": "({ pageIndex }: { pageIndex: number }) => void" + "type": "({ pageIndex }: { pageIndex: number }) => void", + "description": "Optionally provide a handler that is called whenever the pagination state\nis updated" }, { "name": "pageSize", - "type": "number" + "type": "number", + "description": "Optionally specify the number of items within a page", + "defaultValue": "25" }, { "name": "totalCount", "type": "number", - "required": true + "required": true, + "description": "Specify the total number of items within the collection" + }, + { + "name": "showPages", + "type": "boolean | { narrow?: boolean; regular?: boolean; wide?: boolean; }", + "required": false, + "description": "Whether to show the page numbers", + "defaultValue": "{narrow: false}" } ] }, @@ -258,6 +339,31 @@ } ] }, + { + "name": "Table.SortHeader", + "props": [ + { + "name": "direction", + "type": "'ASC' | 'DESC' | 'NONE'", + "required": true, + "description": "Specify the sort direction for the TableHeader", + "defaultValue": "" + }, + { + "name": "onToggleSort", + "type": "() => void", + "required": true, + "description": "Provide a handler that is called when the sortable TableHeader is\ninteracted with via a click or keyboard interaction", + "defaultValue": "" + }, + { + "name": "align", + "type": "'end' | 'start'", + "description": "The horizontal alignment of the cell's content", + "defaultValue": "" + } + ] + }, { "name": "Column options", "props": [ diff --git a/packages/react/src/Details/Details.docs.json b/packages/react/src/Details/Details.docs.json index 0dff5c8d6da..6b4ce4e945a 100644 --- a/packages/react/src/Details/Details.docs.json +++ b/packages/react/src/Details/Details.docs.json @@ -3,7 +3,11 @@ "name": "Details", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-details--default" + } + ], "importPath": "@primer/react", "props": [ { diff --git a/packages/react/src/Dialog/Dialog.docs.json b/packages/react/src/Dialog/Dialog.docs.json index 695b5c553c4..195991edd36 100644 --- a/packages/react/src/Dialog/Dialog.docs.json +++ b/packages/react/src/Dialog/Dialog.docs.json @@ -6,19 +6,34 @@ "a11yReviewed": false, "stories": [ { - "id": "components-dialog--default" + "id": "drafts-components-dialog--default" }, { - "id": "components-dialog-features--bottom-sheet-narrow" + "id": "drafts-components-dialog-features--with-custom-renderers" }, { - "id": "components-dialog-features--full-screen-narrow" + "id": "drafts-components-dialog-features--stress-test" }, { - "id": "components-dialog-features--side-sheet" + "id": "drafts-components-dialog-features--repro-multistep-dialog-with-conditional-footer" }, { - "id": "components-dialog-features--return-focus-ref" + "id": "drafts-components-dialog-features--bottom-sheet-narrow" + }, + { + "id": "drafts-components-dialog-features--full-screen-narrow" + }, + { + "id": "drafts-components-dialog-features--side-sheet" + }, + { + "id": "drafts-components-dialog-features--return-focus-ref" + }, + { + "id": "drafts-components-dialog-features--new-issues" + }, + { + "id": "drafts-components-dialog-features--retains-focus-trap-with-dynamic-content" } ], "importPath": "@primer/react/experimental", @@ -61,15 +76,17 @@ { "name": "role", "type": "'dialog' | 'alertdialog'", - "description": "The ARIA role to assign to this dialog." + "description": "The ARIA role to assign to this dialog. @see https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal\n@see https://www.w3.org/TR/wai-aria-practices-1.1/#alertdialog" }, { "name": "width", - "type": "'small' | 'medium' | 'large' | 'xlarge'" + "type": "'small' | 'medium' | 'large' | 'xlarge'", + "description": "The width of the dialog.\nsmall: 296px\nmedium: 320px\nlarge: 480px\nxlarge: 640px" }, { "name": "height", - "type": "'small' | 'large' | 'auto'" + "type": "'small' | 'large' | 'auto'", + "description": "The height of the dialog.\nsmall: 296x480\nlarge: 480x640\nauto: variable based on contents" }, { "name": "returnFocusRef", @@ -81,6 +98,13 @@ "type": "React.RefObject", "description": "Focus this element when the Dialog opens" }, + { + "name": "position", + "type": "'center' | 'left' | 'right' | { narrow: 'center' | 'left' | 'right' | 'bottom' | 'fullscreen', regular: 'center' | 'left' | 'right' | 'bottom' | 'fullscreen', wide: 'center' | 'left' | 'right' | 'bottom' | 'fullscreen' }", + "required": false, + "description": "The position of the dialog", + "defaultValue": "" + }, { "name": "className", "type": "string | undefined", @@ -88,5 +112,70 @@ "description": "CSS string" } ], - "subcomponents": [] + "subcomponents": [ + { + "name": "Dialog.Body", + "props": [] + }, + { + "name": "Dialog.Buttons", + "props": [ + { + "name": "buttons", + "type": "DialogButtonProps[] (see table below)", + "required": true + } + ] + }, + { + "name": "Dialog.CloseButton", + "props": [ + { + "name": "onClose", + "type": "() => void", + "required": true, + "description": "Callback for closing the Dialog", + "defaultValue": "" + } + ] + }, + { + "name": "Dialog.Footer", + "props": [] + }, + { + "name": "Dialog.Header", + "props": [] + }, + { + "name": "Dialog.Title", + "props": [] + }, + { + "name": "DialogButtonProps", + "props": [ + { + "name": "buttonType", + "type": "'default' | 'danger' | 'primary' | 'normal'", + "description": "The variant of Button to use" + }, + { + "name": "content", + "type": "React.ReactNode", + "required": true, + "description": "The Button's inner text" + }, + { + "name": "autoFocus", + "type": "boolean", + "description": "If true, and if this is the only button with autoFocus set to true, focus this button automatically when the dialog appears." + }, + { + "name": "ref", + "type": "React.RefObject", + "description": " A reference to the rendered Button’s DOM node, used together with `autoFocus` for `focusTrap`’s `initialFocus`." + } + ] + } + ] } diff --git a/packages/react/src/Dialog/Dialog.tsx b/packages/react/src/Dialog/Dialog.tsx index de6299e7e1f..65799b75fb5 100644 --- a/packages/react/src/Dialog/Dialog.tsx +++ b/packages/react/src/Dialog/Dialog.tsx @@ -31,7 +31,7 @@ import {clsx} from 'clsx' */ export type DialogButtonProps = Omit & { /** - * The type of Button element to use + * The variant of Button to use */ buttonType?: 'default' | 'primary' | 'danger' | 'normal' diff --git a/packages/react/src/DialogV1/Dialog.docs.json b/packages/react/src/DialogV1/Dialog.docs.json index 254859970d8..77b44d8279a 100644 --- a/packages/react/src/DialogV1/Dialog.docs.json +++ b/packages/react/src/DialogV1/Dialog.docs.json @@ -4,7 +4,11 @@ "name": "Dialog", "status": "deprecated", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-dialog--default" + } + ], "importPath": "@primer/react/deprecated", "props": [ { @@ -37,6 +41,14 @@ "type": "string", "description": "Pass a label to be used to describe the Dialog. Use either a `aria-label` or an `aria-labelledby` but not both." }, + { + "name": "narrow", + "type": "boolean" + }, + { + "name": "wide", + "type": "boolean" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/FeatureFlags/FeatureFlags.docs.json b/packages/react/src/FeatureFlags/FeatureFlags.docs.json new file mode 100644 index 00000000000..a39f86ceea8 --- /dev/null +++ b/packages/react/src/FeatureFlags/FeatureFlags.docs.json @@ -0,0 +1,17 @@ +{ + "id": "feature_flags", + "name": "FeatureFlags", + "status": "draft", + "a11yReviewed": false, + "stories": [], + "importPath": "@primer/react/experimental", + "props": [ + { + "name": "flags", + "type": "FeatureFlags", + "required": true, + "description": "Object where keys are feature flag names and values are boolean" + } + ], + "subcomponents": [] +} diff --git a/packages/react/src/Flash/Flash.docs.json b/packages/react/src/Flash/Flash.docs.json index 90f03a9fc48..806ca0e2cb5 100644 --- a/packages/react/src/Flash/Flash.docs.json +++ b/packages/react/src/Flash/Flash.docs.json @@ -3,7 +3,29 @@ "name": "Flash", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-flash--default" + }, + { + "id": "components-flash-features--success" + }, + { + "id": "components-flash-features--danger" + }, + { + "id": "components-flash-features--warning" + }, + { + "id": "components-flash-features--full" + }, + { + "id": "components-flash-features--with-icon-and-action" + }, + { + "id": "components-flash-features--with-icon-action-dismiss" + } + ], "importPath": "@primer/react", "props": [ { diff --git a/packages/react/src/FormControl/FormControl.docs.json b/packages/react/src/FormControl/FormControl.docs.json index 94dcd39ad7c..24f3fff2670 100644 --- a/packages/react/src/FormControl/FormControl.docs.json +++ b/packages/react/src/FormControl/FormControl.docs.json @@ -3,7 +3,56 @@ "name": "FormControl", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-formcontrol--default" + }, + { + "id": "components-formcontrol-features--with-complex-inputs" + }, + { + "id": "components-formcontrol-features--form-control-with-custom-input" + }, + { + "id": "components-formcontrol-features--with-checkbox-and-radio-inputs" + }, + { + "id": "components-formcontrol-features--single-input" + }, + { + "id": "components-formcontrol-features--validation-example" + }, + { + "id": "components-formcontrol-features--with-select-panel" + }, + { + "id": "components-formcontrol-features--with-leading-visual" + }, + { + "id": "components-formcontrol-features--disabled-inputs" + }, + { + "id": "components-formcontrol-features--custom-required" + }, + { + "id": "components-formcontrol-features--with-caption" + }, + { + "id": "components-formcontrol-features--with-caption-and-disabled" + }, + { + "id": "components-formcontrol-features--with-hidden-label" + }, + { + "id": "components-formcontrol-features--with-required-indicator" + }, + { + "id": "components-formcontrol-features--with-success-validation" + }, + { + "id": "components-formcontrol-features--with-error-validation" + } + ], "importPath": "@primer/react", "props": [ { @@ -31,6 +80,24 @@ "defaultValue": "false", "description": "If true, the user must specify a value for the input before the owning form can be submitted" }, + { + "name": "id", + "type": "string", + "description": "The unique identifier for this control. Used to associate the label, validation text, and caption text", + "defaultValue": "" + }, + { + "name": "layout", + "type": "'vertical' | 'horizontal'", + "description": "The direction the content flows.\nVertical layout is used by default, and horizontal layout is used for checkbox and radio inputs.", + "defaultValue": "vertical" + }, + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -68,6 +135,23 @@ "defaultValue": "true", "description": "Whether to show or hide the required text in the accessibility tree, the required text is still shown visually." }, + { + "name": "htmlFor", + "type": "string", + "description": "This prop may be used to override the `htmlFor` set from FormControl's React Context.\nThe unique identifier for the associated input", + "defaultValue": "" + }, + { + "name": "id", + "type": "string", + "description": "When `as` prop is 'label', it may be used to override the `htmlFor` given to the