Skip to content

Commit

Permalink
Merge branch 'main' into ddoyle2017/update-underlinepanels
Browse files Browse the repository at this point in the history
  • Loading branch information
ddoyle2017 authored Jan 17, 2025
2 parents 610baba + c87e80c commit c729575
Show file tree
Hide file tree
Showing 52 changed files with 1,296 additions and 331 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-bees-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Fix an issue in useAnnouncements.tsx causing a TypeError in production. The activeItem variable may be null.
5 changes: 5 additions & 0 deletions .changeset/lazy-jars-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Avoid accessing properties of potentially null document.body in PageLayout
5 changes: 0 additions & 5 deletions .changeset/serious-melons-own.md

This file was deleted.

3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,9 @@ jobs:
- name: Build components.json
run: npx tsx script/components-json/build.ts --storybook-data 'storybook-static/index.json'
working-directory: packages/react
- name: Build hooks.json
run: npx tsx script/hooks-json/build.ts'
working-directory: packages/react

sizes:
runs-on: ubuntu-latest
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"build:docs": "NODE_OPTIONS=--openssl-legacy-provider script/build-docs",
"build:docs:preview": "NODE_OPTIONS=--openssl-legacy-provider script/build-docs preview",
"build:components.json": "npm run build:components.json -w @primer/react",
"build:hooks.json": "npm run build:hooks.json -w @primer/react",
"lint": "eslint '**/*.{js,ts,tsx,md,mdx}' --max-warnings=0",
"lint:css": "stylelint --rd -q '**/*.css'",
"lint:css:fix": "npm run lint:css -- --fix",
Expand Down
1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"build:docs": "NODE_OPTIONS=--openssl-legacy-provider script/build-docs",
"build:docs:preview": "NODE_OPTIONS=--openssl-legacy-provider script/build-docs preview",
"build:components.json": "tsx script/components-json/build.ts",
"build:hooks.json": "tsx script/hooks-json/build.ts",
"build:precompile-color-schemes": "tsx script/precompile-color-schemes.ts",
"storybook": "storybook",
"type-check": "tsc --noEmit"
Expand Down
48 changes: 48 additions & 0 deletions packages/react/script/hooks-json/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import glob from 'fast-glob'
import fs from 'fs'
import keyBy from 'lodash.keyby'
import hookSchema from '../hooks-json/hook.schema.json'
import outputSchema from './output.schema.json'
import Ajv from 'ajv'

// Only includes fields we use in this script
type Hook = {
name: string
importPath: '@primer/react' | '@primer/react/experimental'
stories: Array<{id: string}>
}

const ajv = new Ajv()

const hookDocsFiles = glob.sync('src/**/*.hookDocs.json')

const hooks = hookDocsFiles.map(docsFilepath => {
const docs = JSON.parse(fs.readFileSync(docsFilepath, 'utf-8'))

// Create a validator for the hook schema
const validate = ajv.compile<Hook>(hookSchema)

// Validate the hook schema
if (!validate(docs)) {
throw new Error(`Invalid docs file ${docsFilepath}: ${JSON.stringify(validate.errors, null, 2)}}`)
}

return docs
})

const data = {schemaVersion: 2, hooks: keyBy(hooks, 'name')}

// Validate output
const validate = ajv.compile(outputSchema)

if (!validate(data)) {
throw new Error(`Invalid output: ${JSON.stringify(validate.errors, null, 2)}}`)
}

// Create `generated` directory if it doesn't exist
if (!fs.existsSync('generated')) {
fs.mkdirSync('generated')
}

// Write hooks.json file
fs.writeFileSync('generated/hooks.json', JSON.stringify(data, null, 2))
130 changes: 130 additions & 0 deletions packages/react/script/hooks-json/hook.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{
"$id": "hook.schema.json",
"type": "object",
"required": ["name", "stories", "importPath"],
"additionalProperties": false,
"definitions": {
"parameter": {
"type": "object",
"required": ["name", "type"],
"properties": {
"name": {
"type": "string",
"description": "The name of the parameter."
},
"type": {
"type": "string",
"description": "The type of the parameter in valid TypeScript syntax."
},
"defaultValue": {
"type": "string",
"description": "The default value of the parameter if defined."
},
"required": {
"type": "boolean",
"description": "Indicate whether the parameter is required."
},
"deprecated": {
"type": "boolean",
"description": "Indicate whether the parameter is deprecated."
},
"description": {
"type": "string",
"description": "A concise description of the parameter."
}
}
},
"relatedTypeProperty": {
"type": "object",
"required": ["name", "type"],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"description": "The name of the property."
},
"type": {
"type": "string",
"description": "The type of the property in valid TypeScript syntax."
},
"required": {
"type": "boolean",
"description": "Indicate whether the property is required."
},
"defaultValue": {
"type": "string",
"description": "The default value of the property if defined."
},
"description": {
"type": "string",
"description": "A concise description of the property."
}
}
},
"story": {
"type": "object",
"required": ["id"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "The Storybook story ID (e.g. \"hooks-usecolorschemevar--default\")."
}
}
}
},
"properties": {
"name": {
"type": "string",
"description": "The name of the hook."
},
"importPath": {
"type": "string",
"description": "The path to import the hook from. i.e. '@primer/react/experimental'"
},
"stories": {
"type": "array",
"description": "An array of Storybook story IDs to embed in the docs.",
"items": {
"$ref": "#/definitions/story"
}
},
"parameters": {
"type": "array",
"description": "An array of parameters the hook accepts.",
"items": {
"$ref": "#/definitions/parameter"
}
},
"returns": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of the returned value in valid TypeScript syntax."
}
}
},
"relatedTypes": {
"type": "array",
"description": "An array of the types or interfaces related to the hook.",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"description": "The name of the type or interface."
},
"properties": {
"type": "array",
"description": "An array of the properties in the type or interface.",
"items": {
"$ref": "#/definitions/relatedTypeProperty"
}
}
}
}
}
}
}
21 changes: 21 additions & 0 deletions packages/react/script/hooks-json/output.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$id": "output.schema.json",
"type": "object",
"required": ["schemaVersion", "hooks"],
"properties": {
"schemaVersion": {
"type": "number",
"enum": [2],
"description": "The version of the schema. We increment this when we make breaking changes to the schema."
},
"hooks": {
"type": "object",
"description": "Metadata about exported by @primer/react.",
"patternProperties": {
".*": {
"$ref": "./hook.schema.json#"
}
}
}
}
}
53 changes: 53 additions & 0 deletions packages/react/src/ConfirmationDialog/useConfirm.hookDocs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "useConfirm",
"importPath": "@primer/react",
"stories": [
{
"id": "components-confirmationdialog-features--shorthand-hook"
},
{
"id": "components-confirmationdialog-features--shorthand-hook-from-action-menu"
}
],
"returns": {
"type": "(options: ConfirmOptions) => Promise<boolean>",
"description": "An async function that shows a confirmation dialog and resolves with a boolean indicating whether the confirm button was used."
},
"relatedTypes": [
{
"name": "ConfirmOptions",
"properties": [
{
"name": "title",
"type": "React.ReactNode",
"required": true,
"description": "The title of the ConfirmationDialog. This is usually a brief question."
},
{
"name": "content",
"type": "React.ReactNode",
"required": true,
"description": "ConfirmationDialog body content."
},
{
"name": "cancelButtonContent",
"type": "React.ReactNode",
"defaultValue": "Cancel",
"description": "The text to use for the cancel button."
},
{
"name": "confirmButtonContent",
"type": "React.ReactNode",
"defaultValue": "OK",
"description": "The text to use for the confirm button."
},
{
"name": "confirmButtonType",
"type": "\"normal\" | \"primary\" | \"danger\"",
"defaultValue": "normal",
"description": "The type of button to use for the confirm button."
}
]
}
]
}
17 changes: 17 additions & 0 deletions packages/react/src/FeatureFlags/useFeatureFlag.hookDocs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "useFeatureFlag",
"importPath": "@primer/react",
"stories": [],
"parameters": [
{
"name": "flag",
"type": "string",
"required": true,
"description": "The feature flag ID."
}
],
"returns": {
"type": "boolean",
"description": "Whether the feature flag is enabled."
}
}
7 changes: 4 additions & 3 deletions packages/react/src/FilteredActionList/useAnnouncements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import {announce} from '@primer/live-region-element'
import {useEffect, useRef} from 'react'
import type {FilteredActionListProps} from './FilteredActionListEntry'
import type {ItemInput} from '../deprecated/ActionList/List'

// we add a delay so that it does not interrupt default screen reader announcement and queues after it
const delayMs = 500
Expand All @@ -28,10 +29,10 @@ const getItemWithActiveDescendant = (
const optionElements = listElement.querySelectorAll('[role="option"]')

const index = Array.from(optionElements).indexOf(activeItemElement)
const activeItem = items[index]
const activeItem = items[index] as ItemInput | undefined

const text = activeItem.text
const selected = activeItem.selected
const text = activeItem?.text
const selected = activeItem?.selected

return {index, text, selected}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "useFormControlForwardedProps",
"importPath": "@primer/react",
"stories": [{"id": "hooks-useformcontrolforwardedprops--autowired-custom-input"}],
"parameters": [
{
"name": "externalProps",
"type": "P",
"required": true,
"description": "The external props passed to this component. If provided, these props will be merged with the `FormControl` props, with external props taking priority."
}
],
"returns": {
"type": "P & FormControlForwardedProps"
},
"relatedTypes": [
{
"name": "FormControlForwardedProps",
"properties": [
{
"name": "disabled",
"type": "boolean",
"description": "Indicates if the form control is disabled."
},
{
"name": "id",
"type": "string",
"description": "The id of the form control."
},
{
"name": "required",
"type": "boolean",
"description": "Indicates if the form control is required."
},
{
"name": "aria-describedby",
"type": "string",
"description": "The id of the element that describes the form control."
}
]
}
]
}
Loading

0 comments on commit c729575

Please sign in to comment.