From 6c1c4895f02eb039e64e31ed15b9e44fb84b35ca Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 30 Oct 2024 11:13:08 -0500 Subject: [PATCH 01/49] feat(keyboard-key): component init --- .../components/keyboard-key/CHANGELOG.md | 0 .../keyboard-key/__tests__/index.spec.tsx | 11 ++++ .../components/keyboard-key/build.js | 3 + .../components/keyboard-key/package.json | 59 +++++++++++++++++++ .../keyboard-key/src/KeyboardKey.tsx | 27 +++++++++ .../components/keyboard-key/src/index.tsx | 2 + .../keyboard-key/stories/index.stories.tsx | 18 ++++++ .../components/keyboard-key/tsconfig.json | 12 ++++ 8 files changed, 132 insertions(+) create mode 100644 packages/paste-core/components/keyboard-key/CHANGELOG.md create mode 100644 packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx create mode 100644 packages/paste-core/components/keyboard-key/build.js create mode 100644 packages/paste-core/components/keyboard-key/package.json create mode 100644 packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx create mode 100644 packages/paste-core/components/keyboard-key/src/index.tsx create mode 100644 packages/paste-core/components/keyboard-key/stories/index.stories.tsx create mode 100644 packages/paste-core/components/keyboard-key/tsconfig.json diff --git a/packages/paste-core/components/keyboard-key/CHANGELOG.md b/packages/paste-core/components/keyboard-key/CHANGELOG.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx new file mode 100644 index 0000000000..8bc4ef4069 --- /dev/null +++ b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import {render} from '@testing-library/react'; + +import {KeyboardKey} from '../src'; + +describe('KeyboardKey', () => { + it('should render', () => { + const {getByText} = render(test); + expect(getByText('test')).toBeDefined(); + }); +}); diff --git a/packages/paste-core/components/keyboard-key/build.js b/packages/paste-core/components/keyboard-key/build.js new file mode 100644 index 0000000000..a4edeab49b --- /dev/null +++ b/packages/paste-core/components/keyboard-key/build.js @@ -0,0 +1,3 @@ +const {build} = require('../../../../tools/build/esbuild'); + +build(require('./package.json')); diff --git a/packages/paste-core/components/keyboard-key/package.json b/packages/paste-core/components/keyboard-key/package.json new file mode 100644 index 0000000000..ab1b02d03a --- /dev/null +++ b/packages/paste-core/components/keyboard-key/package.json @@ -0,0 +1,59 @@ +{ + "name": "@twilio-paste/keyboard-key", + "version": "0.0.0", + "category": "typography", + "status": "production", + "description": "A keyboard key distinguishes a keyboard command or shortcut from other text.", + "author": "Twilio Inc.", + "license": "MIT", + "main:dev": "src/index.tsx", + "main": "dist/index.js", + "module": "dist/index.es.js", + "types": "dist/index.d.ts", + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "yarn clean && NODE_ENV=production node build.js && tsc", + "build:js": "NODE_ENV=development node build.js", + "build:typedocs": "tsx ../../../../tools/build/generate-type-docs", + "clean": "rm -rf ./dist", + "tsc": "tsc" + }, + "peerDependencies": { + "@twilio-paste/animation-library": "^2.0.0", + "@twilio-paste/box": "^10.2.0", + "@twilio-paste/color-contrast-utils": "^5.0.0", + "@twilio-paste/customization": "^8.1.1", + "@twilio-paste/design-tokens": "^10.3.0", + "@twilio-paste/style-props": "^9.1.1", + "@twilio-paste/styling-library": "^3.0.0", + "@twilio-paste/theme": "^11.0.1", + "@twilio-paste/types": "^6.0.0", + "@types/react": "^16.8.6 || ^17.0.2 || ^18.0.27", + "@types/react-dom": "^16.8.6 || ^17.0.2 || ^18.0.10", + "react": "^16.8.6 || ^17.0.2 || ^18.0.0", + "react-dom": "^16.8.6 || ^17.0.2 || ^18.0.0" + }, + "devDependencies": { + "@twilio-paste/animation-library": "^2.0.0", + "@twilio-paste/box": "^10.2.0", + "@twilio-paste/color-contrast-utils": "^5.0.0", + "@twilio-paste/customization": "^8.1.1", + "@twilio-paste/design-tokens": "^10.3.0", + "@twilio-paste/style-props": "^9.1.1", + "@twilio-paste/styling-library": "^3.0.0", + "@twilio-paste/theme": "^11.0.1", + "@twilio-paste/types": "^6.0.0", + "@types/react": "^18.0.27", + "@types/react-dom": "^18.0.10", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "tsx": "^3.12.10", + "typescript": "^4.9.4" + } +} diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx new file mode 100644 index 0000000000..23de8f21e6 --- /dev/null +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -0,0 +1,27 @@ +import { Box } from "@twilio-paste/box"; +import type { BoxProps } from "@twilio-paste/box"; +import type { HTMLPasteProps } from "@twilio-paste/types"; +import * as React from 'react'; + +export interface KeyboardKeyProps extends HTMLPasteProps<"div"> { + children?: React.ReactNode; + /** + * Overrides the default element name to apply unique styles with the Customization Provider + * @default '{constantCase component-name}' + * @type {BoxProps['element']} + * @memberof KeyboardKeyProps + */ + element?: BoxProps['element']; +} + +const KeyboardKey = React.forwardRef(({element = "KEYBOARD_KEY", ...props}, ref) => { + return ( + + {props.children} + + ); +}); + +KeyboardKey.displayName = 'KeyboardKey'; + +export {KeyboardKey}; diff --git a/packages/paste-core/components/keyboard-key/src/index.tsx b/packages/paste-core/components/keyboard-key/src/index.tsx new file mode 100644 index 0000000000..50a3e28029 --- /dev/null +++ b/packages/paste-core/components/keyboard-key/src/index.tsx @@ -0,0 +1,2 @@ +export KeyboardKey from './KeyboardKey' +export type { KeyboardKeyProps} from './KeyboardKey' diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx new file mode 100644 index 0000000000..0abc76ee5c --- /dev/null +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; + +import {KeyboardKey} from '../src'; + + +// eslint-disable-next-line import/no-default-export +export default { + title: 'Components/KeyboardKey', + component: KeyboardKey, +}; + +export const Default = (): React.ReactNode => { + return ( + + Initial story + + ); +}; diff --git a/packages/paste-core/components/keyboard-key/tsconfig.json b/packages/paste-core/components/keyboard-key/tsconfig.json new file mode 100644 index 0000000000..b5daed7034 --- /dev/null +++ b/packages/paste-core/components/keyboard-key/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "outDir": "dist/", + }, + "include": [ + "src/**/*", + ], + "exclude": [ + "node_modules" + ] +} From e8304e6832e1e76e389d48c8f09c864c133b5065 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 30 Oct 2024 11:16:00 -0500 Subject: [PATCH 02/49] chore(tools): plopfile syntax fix --- tools/plop-templates/component-index.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/plop-templates/component-index.hbs b/tools/plop-templates/component-index.hbs index 42e94b4bac..532e526b50 100644 --- a/tools/plop-templates/component-index.hbs +++ b/tools/plop-templates/component-index.hbs @@ -1,2 +1,2 @@ -export {{{pascalCase component-name}}} from './{{pascalCase component-name}}' +export { {{pascalCase component-name}} } from './{{pascalCase component-name}}' export type { {{pascalCase component-name}}Props} from './{{pascalCase component-name}}' From 461015e9276492984c30dbb10a6a79ed58ebbc0f Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 30 Oct 2024 11:19:47 -0500 Subject: [PATCH 03/49] chore(tools): plopfile syntax fix --- tools/plop-templates/component-component.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/plop-templates/component-component.hbs b/tools/plop-templates/component-component.hbs index bd498c3332..3fef8786d6 100644 --- a/tools/plop-templates/component-component.hbs +++ b/tools/plop-templates/component-component.hbs @@ -7,7 +7,7 @@ export interface {{pascalCase component-name}}Props extends HTMLPasteProps<"div" children?: React.ReactNode; /** * Overrides the default element name to apply unique styles with the Customization Provider - * @default '{constantCase component-name}' + * @default '{ {{constantCase component-name}} }' * @type {BoxProps['element']} * @memberof {{pascalCase component-name}}Props */ From 8edd0b4ed5ce95d803fa46a5ffe0ca7ad66a13ef Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 30 Oct 2024 11:20:52 -0500 Subject: [PATCH 04/49] chore(tools): plopfile syntax fix --- tools/plop-templates/component-component.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/plop-templates/component-component.hbs b/tools/plop-templates/component-component.hbs index 3fef8786d6..d65ec24bd1 100644 --- a/tools/plop-templates/component-component.hbs +++ b/tools/plop-templates/component-component.hbs @@ -7,7 +7,7 @@ export interface {{pascalCase component-name}}Props extends HTMLPasteProps<"div" children?: React.ReactNode; /** * Overrides the default element name to apply unique styles with the Customization Provider - * @default '{ {{constantCase component-name}} }' + * @default '{{constantCase component-name}}' * @type {BoxProps['element']} * @memberof {{pascalCase component-name}}Props */ From 693ea4a825969fd9cde65e2156ccec2401159504 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 30 Oct 2024 15:43:18 -0500 Subject: [PATCH 05/49] feat(keyboard-key): styled w/ hook unit tests --- .../keyboard-key/__tests__/hooks.spec.tsx | 350 ++++++++++++++++++ .../keyboard-key/__tests__/index.spec.tsx | 74 +++- .../keyboard-key/src/KeyboardKey.tsx | 66 +++- .../keyboard-key/src/KeyboardKeyContext.tsx | 11 + .../keyboard-key/src/KeyboardKeyGroup.tsx | 32 ++ .../components/keyboard-key/src/hooks.ts | 89 +++++ .../components/keyboard-key/src/index.tsx | 8 +- .../keyboard-key/stories/index.stories.tsx | 67 +++- yarn.lock | 55 ++- 9 files changed, 721 insertions(+), 31 deletions(-) create mode 100644 packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx create mode 100644 packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx create mode 100644 packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx create mode 100644 packages/paste-core/components/keyboard-key/src/hooks.ts diff --git a/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx new file mode 100644 index 0000000000..6c48efa1ad --- /dev/null +++ b/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx @@ -0,0 +1,350 @@ +import { act, fireEvent, render, renderHook, screen, waitFor } from "@testing-library/react"; +import * as React from "react"; + +import { useKeyCombination, useKeyCombinations } from "../src"; +import { Default } from "../stories/index.stories"; + +describe("Hooks", () => { + const wrapper = ({ children }) =>
{children}
; + + it("should handle pressed styling", async () => { + const { getByText } = render(); + + const controlKey = getByText("Control"); + const bKey = getByText("B"); + expect(controlKey).toBeDefined(); + expect(controlKey).toBeDefined(); + expect(controlKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); + expect(bKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); + + await act(async () => { + fireEvent.keyDown(controlKey, { key: "Control" }); + }); + + expect(controlKey).toHaveStyleRule("background-color", "rgb(225, 227, 234)"); + expect(bKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); + + await act(async () => { + fireEvent.keyUp(controlKey, { key: "Control" }); + }); + + expect(controlKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); + expect(bKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); + }); + + describe("useKeyCombination", () => { + it("should update activeKeys on keydown and keyup", async () => { + const { result } = renderHook( + () => useKeyCombination({ keys: ["Control", "b"], onCombinationPress: jest.fn() }), + { wrapper }, + ); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "d" }); + fireEvent.keyDown(eventTrigger, { key: "v" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "d", "v"]); + }); + + await act(async () => { + fireEvent.keyUp(eventTrigger, { key: "Control" }); + fireEvent.keyUp(eventTrigger, { key: "d" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["v"]); + }); + }); + + it("should call onCombinationPress when keys match", async () => { + const onCombinationPress = jest.fn(); + const { result } = renderHook(() => useKeyCombination({ keys: ["Control", "b"], onCombinationPress }), { + wrapper, + }); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "b"]); + expect(onCombinationPress).toHaveBeenCalled(); + }); + }); + + it("should not call onCombinationPress when keys do not match", async () => { + const onCombinationPress = jest.fn(); + const { result } = renderHook(() => useKeyCombination({ keys: ["Control", "b"], onCombinationPress }), { + wrapper, + }); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "d" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "d"]); + expect(onCombinationPress).not.toHaveBeenCalled(); + }); + }); + + it("should not call onCombinationPress when keys are present but more are pressed", async () => { + const onCombinationPress = jest.fn(); + const { result } = renderHook(() => useKeyCombination({ keys: ["Control", "b"], onCombinationPress }), { + wrapper, + }); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "v" }); + fireEvent.keyDown(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "v", "b"]); + expect(onCombinationPress).not.toHaveBeenCalled(); + }); + }); + + it("should not call onCombinationPress when disabled", async () => { + const onCombinationPress = jest.fn(); + const { result } = renderHook( + () => useKeyCombination({ keys: ["Control", "b"], onCombinationPress, disabled: true }), + { wrapper }, + ); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "b"]); + expect(onCombinationPress).not.toHaveBeenCalled(); + }); + }); + }); + + describe("useKeyCombinations", () => { + it("should update activeKeys on keydown and keyup", async () => { + const { result } = renderHook( + () => + useKeyCombinations({ + combinations: [ + { keys: ["Control", "b"], onCombinationPress: jest.fn() }, + { keys: ["Control", "c"], onCombinationPress: jest.fn() }, + ], + }), + { wrapper }, + ); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "d" }); + fireEvent.keyDown(eventTrigger, { key: "v" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "d", "v"]); + }); + + await act(async () => { + fireEvent.keyUp(eventTrigger, { key: "Control" }); + fireEvent.keyUp(eventTrigger, { key: "d" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["v"]); + }); + }); + + it("should call onCombinationPress when keys match", async () => { + const onCombinationPress1 = jest.fn(); + const onCombinationPress2 = jest.fn(); + + const { result } = renderHook( + () => + useKeyCombinations({ + combinations: [ + { keys: ["Control", "b"], onCombinationPress: onCombinationPress1 }, + { keys: ["Control", "c"], onCombinationPress: onCombinationPress2 }, + ], + }), + { wrapper }, + ); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "b"]); + expect(onCombinationPress1).toHaveBeenCalled(); + expect(onCombinationPress2).not.toHaveBeenCalled(); + }); + + await act(async () => { + onCombinationPress1.mockClear(); + fireEvent.keyDown(eventTrigger, { key: "c" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "b", "c"]); + expect(onCombinationPress1).not.toHaveBeenCalled(); + expect(onCombinationPress2).not.toHaveBeenCalled(); + }); + + await act(async () => { + fireEvent.keyUp(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "c"]); + expect(onCombinationPress1).not.toHaveBeenCalled(); + expect(onCombinationPress2).toHaveBeenCalled(); + }); + }); + + it("should not call onCOmbinationPress when disabled", async () => { + const onCombinationPress1 = jest.fn(); + const onCombinationPress2 = jest.fn(); + + const { result } = renderHook( + () => + useKeyCombinations({ + combinations: [ + { keys: ["Control", "b"], onCombinationPress: onCombinationPress1 }, + { keys: ["Control", "c"], onCombinationPress: onCombinationPress2, disabled: true }, + ], + }), + { wrapper }, + ); + + const eventTrigger = screen.getByTestId("event-trigger"); + expect(eventTrigger).toBeDefined(); + expect(result.current?.activeKeys).toEqual([]); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "Control" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control"]); + }); + + await act(async () => { + fireEvent.keyDown(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "b"]); + expect(onCombinationPress1).toHaveBeenCalled(); + expect(onCombinationPress2).not.toHaveBeenCalled(); + }); + + await act(async () => { + onCombinationPress1.mockClear(); + fireEvent.keyDown(eventTrigger, { key: "c" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "b", "c"]); + expect(onCombinationPress1).not.toHaveBeenCalled(); + expect(onCombinationPress2).not.toHaveBeenCalled(); + }); + + await act(async () => { + fireEvent.keyUp(eventTrigger, { key: "b" }); + }); + + await waitFor(() => { + expect(result.current?.activeKeys).toEqual(["Control", "c"]); + expect(onCombinationPress1).not.toHaveBeenCalled(); + expect(onCombinationPress2).not.toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx index 8bc4ef4069..c2f9c8f4fa 100644 --- a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx +++ b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx @@ -1,11 +1,71 @@ -import * as React from 'react'; -import {render} from '@testing-library/react'; +import { act, fireEvent, render } from "@testing-library/react"; +import * as React from "react"; -import {KeyboardKey} from '../src'; +import { CustomizationProvider } from "@twilio-paste/customization"; +import { Theme } from "@twilio-paste/theme"; +import { KeyboardKey, KeyboardKeyGroup } from "../src"; +import { Default } from "../stories/index.stories"; -describe('KeyboardKey', () => { - it('should render', () => { - const {getByText} = render(test); - expect(getByText('test')).toBeDefined(); +describe("KeyboardKey", () => { + it("should render", async () => { + const { getByText } = render(); + + const controlKey = getByText("Control"); + const bKey = getByText("B"); + expect(controlKey).toBeDefined(); + expect(controlKey).toBeDefined(); + expect(controlKey).toHaveAttribute("data-paste-element", "KEYBOARD_KEY"); + expect(bKey).toHaveAttribute("data-paste-element", "KEYBOARD_KEY"); + expect(controlKey.parentElement).toHaveAttribute("data-paste-element", "KEYBOARD_KEY_GROUP"); + }); + + describe("Customization", () => { + it("should accept custom element names", async () => { + const { getByText } = render( + + + Control + B + + , + ); + + const controlKey = getByText("Control"); + const bKey = getByText("B"); + expect(controlKey).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_ONE"); + expect(bKey).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_TWO"); + expect(controlKey.parentElement).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_GROUP"); + }); + + it("should customize styling", async () => { + const { getByText } = render( + + + + Control + B + + + , + ); + + const controlKey = getByText("Control"); + const bKey = getByText("B"); + expect(controlKey).toHaveStyleRule("font-family", "'TwilioSansMono',Courier,monospace"); + expect(bKey).toHaveStyleRule("padding", "0.5rem"); + expect(controlKey.parentElement).toHaveStyleRule("background-color", "rgb(2, 99, 224)"); + }); }); }); diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 23de8f21e6..cc8ec66444 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -1,27 +1,67 @@ import { Box } from "@twilio-paste/box"; -import type { BoxProps } from "@twilio-paste/box"; +import type { BoxProps, BoxStyleProps } from "@twilio-paste/box"; import type { HTMLPasteProps } from "@twilio-paste/types"; -import * as React from 'react'; +import * as React from "react"; +import { KeyboardKeyCombinationContext } from "./KeyboardKeyContext"; + +const DisabledStyles: BoxStyleProps = { + color: "colorTextWeak", + borderBottomWidth: "borderWidth10", + borderColor: "colorBorderWeakest", +}; + +const PressedStyles: BoxStyleProps = { + borderBottomWidth: "borderWidth10", + backgroundColor: "colorBackgroundStrong", +}; export interface KeyboardKeyProps extends HTMLPasteProps<"div"> { children?: React.ReactNode; /** * Overrides the default element name to apply unique styles with the Customization Provider - * @default '{constantCase component-name}' + * @default 'KEYBOARD_KEY' * @type {BoxProps['element']} * @memberof KeyboardKeyProps */ - element?: BoxProps['element']; + element?: BoxProps["element"]; + /** + * Sets the key text that will be used to determine if the key has press stylings + * @default 'KEYBOARD_KEY' + * @type string + * @memberof KeyboardKeyProps + */ + keyText?: string; } -const KeyboardKey = React.forwardRef(({element = "KEYBOARD_KEY", ...props}, ref) => { - return ( - - {props.children} - - ); -}); +const KeyboardKey = React.forwardRef( + ({ element = "KEYBOARD_KEY", keyText, ...props }, ref) => { + const { disabled, activeKeys, enablePressStyles } = React.useContext(KeyboardKeyCombinationContext); + + const isKeyActive = !disabled && activeKeys && keyText && activeKeys.indexOf(keyText) >= 0; + + return ( + + {props.children} + + ); + }, +); -KeyboardKey.displayName = 'KeyboardKey'; +KeyboardKey.displayName = "KeyboardKey"; -export {KeyboardKey}; +export { KeyboardKey }; diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx new file mode 100644 index 0000000000..503b034555 --- /dev/null +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx @@ -0,0 +1,11 @@ +import * as React from "react"; + +export interface KeyboardCombinationState { + activeKeys?: string[]; + disabled?: boolean; + enablePressStyles?: boolean; +} + +export const KeyboardKeyCombinationContext = React.createContext( + {} as KeyboardCombinationState, +); diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx new file mode 100644 index 0000000000..771a8e12af --- /dev/null +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx @@ -0,0 +1,32 @@ +import { Box } from "@twilio-paste/box"; +import type { BoxProps } from "@twilio-paste/box"; +import type { HTMLPasteProps } from "@twilio-paste/types"; +import * as React from "react"; +import { KeyboardCombinationState, KeyboardKeyCombinationContext } from "./KeyboardKeyContext"; + +export interface KeyboardKeyGroupProps extends HTMLPasteProps<"div">, KeyboardCombinationState { + children?: React.ReactNode; + /** + * Overrides the default element name to apply unique styles with the Customization Provider + * @default 'KEYBOARD_KEY_GROUP' + * @type {BoxProps['element']} + * @memberof KeyboardKeyGroupProps + */ + element?: BoxProps["element"]; +} + +const KeyboardKeyGroup = React.forwardRef( + ({ element = "KEYBOARD_KEY_GROUP", activeKeys, disabled, enablePressStyles, ...props }, ref) => { + return ( + + + {props.children} + + + ); + }, +); + +KeyboardKeyGroup.displayName = "KeyboardKeyGroup"; + +export { KeyboardKeyGroup }; diff --git a/packages/paste-core/components/keyboard-key/src/hooks.ts b/packages/paste-core/components/keyboard-key/src/hooks.ts new file mode 100644 index 0000000000..5fd0b0bdaf --- /dev/null +++ b/packages/paste-core/components/keyboard-key/src/hooks.ts @@ -0,0 +1,89 @@ +import * as React from "react"; +import { KeyboardCombinationState } from "./KeyboardKeyContext"; + +export interface useKeyCombinationProps { + keys: string[]; + onCombinationPress: () => void; + disabled?: boolean; + enablePressStyles?: boolean; +} + +export interface useKeyCombinationsProps { + combinations: Omit[]; + enablePressStyles?: boolean; +} + +interface useKeyCombinationReturn extends Omit { + activeKeys: string[]; +} + +const useKeyEvents = (): { activeKeys: string[] } => { + const [activeKeys, setActiveKeys] = React.useState([]); + + const handleKeyDown = (e: KeyboardEvent) => { + if (!e.repeat) { + setActiveKeys((prev) => { + return Array.from(new Set([...prev, e.key])); + }); + } + }; + + const handleKeyUp = (e: KeyboardEvent) => { + setActiveKeys((prev) => [...prev].filter((k) => k !== e.key)); + }; + + React.useEffect(() => { + document.addEventListener("keydown", (e) => handleKeyDown(e)); + document.addEventListener("keyup", (e) => handleKeyUp(e)); + + return () => { + document.removeEventListener("keydown", (e) => handleKeyDown(e)); + document.removeEventListener("keyup", (e) => handleKeyUp(e)); + }; + }, []); + + return { activeKeys }; +}; +export const useKeyCombination = ({ + keys, + onCombinationPress, + disabled, + enablePressStyles, +}: useKeyCombinationProps): useKeyCombinationReturn => { + const { activeKeys } = useKeyEvents(); + + React.useEffect(() => { + const combinationMatch = + JSON.stringify(keys.map((k) => k.toLowerCase()).sort()) === + JSON.stringify(activeKeys.map((k) => k.toLowerCase()).sort()); + + if (combinationMatch && !disabled) { + // setActiveKeys([]); + onCombinationPress(); + } + }, [activeKeys]); + + return { activeKeys, disabled, enablePressStyles }; +}; + +export const useKeyCombinations = ({ + combinations, + enablePressStyles, +}: useKeyCombinationsProps): useKeyCombinationReturn => { + const { activeKeys } = useKeyEvents(); + + React.useEffect(() => { + const combinationMatch = combinations.find( + (combos) => + JSON.stringify(combos.keys.map((k) => k.toLowerCase()).sort()) === + JSON.stringify(activeKeys.map((k) => k.toLowerCase()).sort()), + ); + + if (combinationMatch && !combinationMatch.disabled) { + // setActiveKeys([]); + combinationMatch.onCombinationPress(); + } + }, [activeKeys, combinations]); + + return { activeKeys, enablePressStyles }; +}; diff --git a/packages/paste-core/components/keyboard-key/src/index.tsx b/packages/paste-core/components/keyboard-key/src/index.tsx index 50a3e28029..7a4e508548 100644 --- a/packages/paste-core/components/keyboard-key/src/index.tsx +++ b/packages/paste-core/components/keyboard-key/src/index.tsx @@ -1,2 +1,6 @@ -export KeyboardKey from './KeyboardKey' -export type { KeyboardKeyProps} from './KeyboardKey' +export { KeyboardKey } from "./KeyboardKey"; +export type { KeyboardKeyProps } from "./KeyboardKey"; +export { KeyboardKeyGroup } from "./KeyboardKeyGroup"; +export type { KeyboardKeyGroupProps } from "./KeyboardKeyGroup"; +export { useKeyCombination, useKeyCombinations } from "./hooks"; +export type { useKeyCombinationsProps, useKeyCombinationProps } from "./hooks"; diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx index 0abc76ee5c..7f91a855e4 100644 --- a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -1,18 +1,69 @@ -import * as React from 'react'; - -import {KeyboardKey} from '../src'; +import * as React from "react"; +import { CustomizationProvider } from "@twilio-paste/customization"; +import { Theme } from "@twilio-paste/theme"; +import { KeyboardKey, KeyboardKeyGroup, useKeyCombination } from "../src"; // eslint-disable-next-line import/no-default-export export default { - title: 'Components/KeyboardKey', + title: "Components/KeyboardKey", component: KeyboardKey, }; -export const Default = (): React.ReactNode => { +export const Default = () => { + const state = useKeyCombination({ + keys: ["Control", "b"], + onCombinationPress: () => { + console.log("Control + B pressed"); + }, + enablePressStyles: true, + }); + return ( - - Initial story - + + + Control + B + + ); }; + +export const Customization = () => { + const state = useKeyCombination({ + keys: ["Control", "b"], + onCombinationPress: () => { + console.log("Control + B pressed"); + }, + enablePressStyles: true, + }); + + return ( + + + + Control + B + + + + ); +}; + +Customization.paramters = { + a11y: { + // no need to a11y check customization + disabled: true, + }, +}; diff --git a/yarn.lock b/yarn.lock index ceb343b46e..8fc8a548cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13526,6 +13526,42 @@ __metadata: languageName: unknown linkType: soft +"@twilio-paste/keyboard-key@workspace:packages/paste-core/components/keyboard-key": + version: 0.0.0-use.local + resolution: "@twilio-paste/keyboard-key@workspace:packages/paste-core/components/keyboard-key" + dependencies: + "@twilio-paste/animation-library": ^2.0.0 + "@twilio-paste/box": ^10.2.0 + "@twilio-paste/color-contrast-utils": ^5.0.0 + "@twilio-paste/customization": ^8.1.1 + "@twilio-paste/design-tokens": ^10.3.0 + "@twilio-paste/style-props": ^9.1.1 + "@twilio-paste/styling-library": ^3.0.0 + "@twilio-paste/theme": ^11.0.1 + "@twilio-paste/types": ^6.0.0 + "@types/react": ^18.0.27 + "@types/react-dom": ^18.0.10 + react: ^18.0.0 + react-dom: ^18.0.0 + tsx: ^3.12.10 + typescript: ^4.9.4 + peerDependencies: + "@twilio-paste/animation-library": ^2.0.0 + "@twilio-paste/box": ^10.2.0 + "@twilio-paste/color-contrast-utils": ^5.0.0 + "@twilio-paste/customization": ^8.1.1 + "@twilio-paste/design-tokens": ^10.3.0 + "@twilio-paste/style-props": ^9.1.1 + "@twilio-paste/styling-library": ^3.0.0 + "@twilio-paste/theme": ^11.0.1 + "@twilio-paste/types": ^6.0.0 + "@types/react": ^16.8.6 || ^17.0.2 || ^18.0.27 + "@types/react-dom": ^16.8.6 || ^17.0.2 || ^18.0.10 + react: ^16.8.6 || ^17.0.2 || ^18.0.0 + react-dom: ^16.8.6 || ^17.0.2 || ^18.0.0 + languageName: unknown + linkType: soft + "@twilio-paste/label@^13.1.0, @twilio-paste/label@^13.1.1, @twilio-paste/label@workspace:packages/paste-core/components/label": version: 0.0.0-use.local resolution: "@twilio-paste/label@workspace:packages/paste-core/components/label" @@ -41899,7 +41935,7 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard -"source-map-support@npm:^0.5.16, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.19, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.21, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.19, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -43911,6 +43947,23 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard +"tsx@npm:^3.12.10": + version: 3.14.0 + resolution: "tsx@npm:3.14.0" + dependencies: + esbuild: ~0.18.20 + fsevents: ~2.3.3 + get-tsconfig: ^4.7.2 + source-map-support: ^0.5.21 + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: afcef5d9b90b5800cf1ffb749e943f63042d78a4c0d9eef6e13e43f4ecab465d45e2c9812a2c515cbdc2ee913ff1cd01bf5c606a48013dd3ce2214a631b45557 + languageName: node + linkType: hard + "tsx@npm:^4.0.0": version: 4.6.2 resolution: "tsx@npm:4.6.2" From ca523ac250737b92781301a6395099b6643ffbc1 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 1 Nov 2024 12:19:34 -0500 Subject: [PATCH 06/49] feat(keyboard-key): added variants and styles --- .../keyboard-key/src/KeyboardKey.tsx | 58 ++++++++++++++----- .../keyboard-key/src/KeyboardKeyContext.tsx | 1 + .../keyboard-key/src/KeyboardKeyGroup.tsx | 6 +- .../components/keyboard-key/src/hooks.ts | 2 - .../components/keyboard-key/src/index.tsx | 2 +- .../keyboard-key/stories/index.stories.tsx | 45 ++++++++++++-- 6 files changed, 89 insertions(+), 25 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index cc8ec66444..8638a187bf 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -3,16 +3,39 @@ import type { BoxProps, BoxStyleProps } from "@twilio-paste/box"; import type { HTMLPasteProps } from "@twilio-paste/types"; import * as React from "react"; import { KeyboardKeyCombinationContext } from "./KeyboardKeyContext"; +import { KeyboardKeyVariants } from "./KeyboardKeyGroup"; -const DisabledStyles: BoxStyleProps = { - color: "colorTextWeak", - borderBottomWidth: "borderWidth10", - borderColor: "colorBorderWeakest", +const BaseStyles: Record = { + default: { borderColor: "colorBorderWeak", backgroundColor: "colorBackgroundWeak" }, + inverse: { + borderColor: "colorBorderInverseWeaker", + backgroundColor: "colorBackgroundInverse", + color: "colorTextInverse", + }, }; -const PressedStyles: BoxStyleProps = { - borderBottomWidth: "borderWidth10", - backgroundColor: "colorBackgroundStrong", +const DisabledStyles: Record = { + default: { + color: "colorTextWeak", + borderBottomWidth: "borderWidth10", + borderColor: "colorBorderWeakest", + }, + inverse: { + color: "colorTextInverseWeaker", + borderBottomWidth: "borderWidth10", + borderColor: "colorBorderInverseWeakest", + }, +}; + +const PressedStyles: Record = { + default: { + borderBottomWidth: "borderWidth10", + backgroundColor: "colorBackgroundStrong", + }, + inverse: { + borderBottomWidth: "borderWidth10", + backgroundColor: "colorBackgroundInverseStronger", + }, }; export interface KeyboardKeyProps extends HTMLPasteProps<"div"> { @@ -35,7 +58,12 @@ export interface KeyboardKeyProps extends HTMLPasteProps<"div"> { const KeyboardKey = React.forwardRef( ({ element = "KEYBOARD_KEY", keyText, ...props }, ref) => { - const { disabled, activeKeys, enablePressStyles } = React.useContext(KeyboardKeyCombinationContext); + const { + disabled, + activeKeys, + enablePressStyles, + variant = "default", + } = React.useContext(KeyboardKeyCombinationContext); const isKeyActive = !disabled && activeKeys && keyText && activeKeys.indexOf(keyText) >= 0; @@ -43,18 +71,20 @@ const KeyboardKey = React.forwardRef( {props.children} diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx index 503b034555..714217916f 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKeyContext.tsx @@ -4,6 +4,7 @@ export interface KeyboardCombinationState { activeKeys?: string[]; disabled?: boolean; enablePressStyles?: boolean; + variant?: "default" | "inverse"; } export const KeyboardKeyCombinationContext = React.createContext( diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx index 771a8e12af..0d463766dc 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx @@ -4,6 +4,8 @@ import type { HTMLPasteProps } from "@twilio-paste/types"; import * as React from "react"; import { KeyboardCombinationState, KeyboardKeyCombinationContext } from "./KeyboardKeyContext"; +export type KeyboardKeyVariants = "default" | "inverse"; + export interface KeyboardKeyGroupProps extends HTMLPasteProps<"div">, KeyboardCombinationState { children?: React.ReactNode; /** @@ -16,9 +18,9 @@ export interface KeyboardKeyGroupProps extends HTMLPasteProps<"div">, KeyboardCo } const KeyboardKeyGroup = React.forwardRef( - ({ element = "KEYBOARD_KEY_GROUP", activeKeys, disabled, enablePressStyles, ...props }, ref) => { + ({ element = "KEYBOARD_KEY_GROUP", activeKeys, disabled, enablePressStyles, variant = "default", ...props }, ref) => { return ( - + {props.children} diff --git a/packages/paste-core/components/keyboard-key/src/hooks.ts b/packages/paste-core/components/keyboard-key/src/hooks.ts index 5fd0b0bdaf..0c7bfeacce 100644 --- a/packages/paste-core/components/keyboard-key/src/hooks.ts +++ b/packages/paste-core/components/keyboard-key/src/hooks.ts @@ -58,7 +58,6 @@ export const useKeyCombination = ({ JSON.stringify(activeKeys.map((k) => k.toLowerCase()).sort()); if (combinationMatch && !disabled) { - // setActiveKeys([]); onCombinationPress(); } }, [activeKeys]); @@ -80,7 +79,6 @@ export const useKeyCombinations = ({ ); if (combinationMatch && !combinationMatch.disabled) { - // setActiveKeys([]); combinationMatch.onCombinationPress(); } }, [activeKeys, combinations]); diff --git a/packages/paste-core/components/keyboard-key/src/index.tsx b/packages/paste-core/components/keyboard-key/src/index.tsx index 7a4e508548..a9c63115eb 100644 --- a/packages/paste-core/components/keyboard-key/src/index.tsx +++ b/packages/paste-core/components/keyboard-key/src/index.tsx @@ -1,5 +1,5 @@ export { KeyboardKey } from "./KeyboardKey"; -export type { KeyboardKeyProps } from "./KeyboardKey"; +export type { KeyboardKeyProps, KeyboardKeyVariants } from "./KeyboardKey"; export { KeyboardKeyGroup } from "./KeyboardKeyGroup"; export type { KeyboardKeyGroupProps } from "./KeyboardKeyGroup"; export { useKeyCombination, useKeyCombinations } from "./hooks"; diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx index 7f91a855e4..14de59166a 100644 --- a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -1,6 +1,8 @@ import * as React from "react"; +import { Box } from "@twilio-paste/box"; import { CustomizationProvider } from "@twilio-paste/customization"; +import { Stack } from "@twilio-paste/stack"; import { Theme } from "@twilio-paste/theme"; import { KeyboardKey, KeyboardKeyGroup, useKeyCombination } from "../src"; @@ -20,11 +22,42 @@ export const Default = () => { }); return ( - - - Control - B - + + + + Control + B + + + Control + B + + + + ); +}; + +export const Inverse = () => { + const state = useKeyCombination({ + keys: ["Control", "b"], + onCombinationPress: () => { + console.log("Control + B pressed"); + }, + enablePressStyles: true, + }); + + return ( + + + + Control + B + + + Control + B + + ); }; @@ -39,7 +72,7 @@ export const Customization = () => { }); return ( - + Date: Fri, 1 Nov 2024 12:37:41 -0500 Subject: [PATCH 07/49] chore(plop): update tsx dependency --- packages/paste-core/components/keyboard-key/package.json | 2 +- tools/plop-templates/package.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/package.json b/packages/paste-core/components/keyboard-key/package.json index ab1b02d03a..50e3664666 100644 --- a/packages/paste-core/components/keyboard-key/package.json +++ b/packages/paste-core/components/keyboard-key/package.json @@ -53,7 +53,7 @@ "@types/react-dom": "^18.0.10", "react": "^18.0.0", "react-dom": "^18.0.0", - "tsx": "^3.12.10", + "tsx": "^4.0.0", "typescript": "^4.9.4" } } diff --git a/tools/plop-templates/package.hbs b/tools/plop-templates/package.hbs index b8da359597..551b42a378 100644 --- a/tools/plop-templates/package.hbs +++ b/tools/plop-templates/package.hbs @@ -53,7 +53,7 @@ "@types/react-dom": "^18.0.10", "react": "^18.0.0", "react-dom": "^18.0.0", - "tsx": "^3.12.10", + "tsx": "^4.0.0", "typescript": "^4.9.4" } } From 18d09d2d16cd9c0a119409fec9dcffb47406c9b4 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 1 Nov 2024 12:38:12 -0500 Subject: [PATCH 08/49] chore(keyboard-key): internal exports in core --- .codesandbox/ci.json | 1 + .../paste-codemods/tools/.cache/mappings.json | 2 ++ packages/paste-core/core-bundle/package.json | 1 + packages/paste-core/core-bundle/src/index.tsx | 1 + yarn.lock | 24 ++++--------------- 5 files changed, 9 insertions(+), 20 deletions(-) diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index 0c92e15e99..b5a072e654 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -56,6 +56,7 @@ "/packages/paste-core/components/inline-control-group", "/packages/paste-core/components/input", "/packages/paste-core/components/input-box", + "/packages/paste-core/components/keyboard-key", "/packages/paste-core/components/label", "/packages/paste-libraries/lexical", "/packages/paste-core/components/list", diff --git a/packages/paste-codemods/tools/.cache/mappings.json b/packages/paste-codemods/tools/.cache/mappings.json index 280ffbc11e..a61019a6a7 100644 --- a/packages/paste-codemods/tools/.cache/mappings.json +++ b/packages/paste-codemods/tools/.cache/mappings.json @@ -147,6 +147,8 @@ "Prefix": "@twilio-paste/core/input-box", "Suffix": "@twilio-paste/core/input-box", "getInputChevronIconColor": "@twilio-paste/core/input-box", + "KeyboardKey": "@twilio/core/keyboard-key", + "KeyboardKeyGroup": "@twilio/core/keyboard-key", "Label": "@twilio-paste/core/label", "RequiredDot": "@twilio-paste/core/label", "List": "@twilio-paste/core/list", diff --git a/packages/paste-core/core-bundle/package.json b/packages/paste-core/core-bundle/package.json index 699746ee87..6b01b055dc 100644 --- a/packages/paste-core/core-bundle/package.json +++ b/packages/paste-core/core-bundle/package.json @@ -123,6 +123,7 @@ "@twilio-paste/inline-control-group": "^13.0.2", "@twilio-paste/input": "^9.1.3", "@twilio-paste/input-box": "^10.1.1", + "@twilio-paste/keyboard-key": "^0.0.0", "@twilio-paste/label": "^13.1.1", "@twilio-paste/lexical-library": "^4.2.0", "@twilio-paste/list": "^8.2.1", diff --git a/packages/paste-core/core-bundle/src/index.tsx b/packages/paste-core/core-bundle/src/index.tsx index 29a53f9e81..94c1e06948 100644 --- a/packages/paste-core/core-bundle/src/index.tsx +++ b/packages/paste-core/core-bundle/src/index.tsx @@ -42,6 +42,7 @@ export * from "@twilio-paste/inline-code"; export * from "@twilio-paste/inline-control-group"; export * from "@twilio-paste/input"; export * from "@twilio-paste/input-box"; +export * from "@twilio-paste/keyboard-key"; export * from "@twilio-paste/label"; export * from "@twilio-paste/list"; export * from "@twilio-paste/listbox-primitive"; diff --git a/yarn.lock b/yarn.lock index 8fc8a548cb..c4cdda7ea4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12321,6 +12321,7 @@ __metadata: "@twilio-paste/inline-control-group": ^13.0.2 "@twilio-paste/input": ^9.1.3 "@twilio-paste/input-box": ^10.1.1 + "@twilio-paste/keyboard-key": ^0.0.0 "@twilio-paste/label": ^13.1.1 "@twilio-paste/lexical-library": ^4.2.0 "@twilio-paste/list": ^8.2.1 @@ -13526,7 +13527,7 @@ __metadata: languageName: unknown linkType: soft -"@twilio-paste/keyboard-key@workspace:packages/paste-core/components/keyboard-key": +"@twilio-paste/keyboard-key@^0.0.0, @twilio-paste/keyboard-key@workspace:packages/paste-core/components/keyboard-key": version: 0.0.0-use.local resolution: "@twilio-paste/keyboard-key@workspace:packages/paste-core/components/keyboard-key" dependencies: @@ -13543,7 +13544,7 @@ __metadata: "@types/react-dom": ^18.0.10 react: ^18.0.0 react-dom: ^18.0.0 - tsx: ^3.12.10 + tsx: ^4.0.0 typescript: ^4.9.4 peerDependencies: "@twilio-paste/animation-library": ^2.0.0 @@ -41935,7 +41936,7 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard -"source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.21, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.19, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.16, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.19, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -43947,23 +43948,6 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard -"tsx@npm:^3.12.10": - version: 3.14.0 - resolution: "tsx@npm:3.14.0" - dependencies: - esbuild: ~0.18.20 - fsevents: ~2.3.3 - get-tsconfig: ^4.7.2 - source-map-support: ^0.5.21 - dependenciesMeta: - fsevents: - optional: true - bin: - tsx: dist/cli.mjs - checksum: afcef5d9b90b5800cf1ffb749e943f63042d78a4c0d9eef6e13e43f4ecab465d45e2c9812a2c515cbdc2ee913ff1cd01bf5c606a48013dd3ce2214a631b45557 - languageName: node - linkType: hard - "tsx@npm:^4.0.0": version: 4.6.2 resolution: "tsx@npm:4.6.2" From 33944964fc4cbcd12c79dcef7f8700933a552317 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 1 Nov 2024 12:52:50 -0500 Subject: [PATCH 09/49] chore(keyboard-key): typedocs & build --- .../paste-codemods/tools/.cache/mappings.json | 6 +- .../components/keyboard-key/src/hooks.ts | 15 +- .../components/keyboard-key/src/index.tsx | 4 +- .../components/keyboard-key/type-docs.json | 3233 +++++++++++++++++ packages/paste-core/core-bundle/.gitignore | 1 + .../core-bundle/src/keyboard-key.tsx | 1 + 6 files changed, 3247 insertions(+), 13 deletions(-) create mode 100644 packages/paste-core/components/keyboard-key/type-docs.json create mode 100644 packages/paste-core/core-bundle/src/keyboard-key.tsx diff --git a/packages/paste-codemods/tools/.cache/mappings.json b/packages/paste-codemods/tools/.cache/mappings.json index a61019a6a7..f76c9b97da 100644 --- a/packages/paste-codemods/tools/.cache/mappings.json +++ b/packages/paste-codemods/tools/.cache/mappings.json @@ -147,8 +147,10 @@ "Prefix": "@twilio-paste/core/input-box", "Suffix": "@twilio-paste/core/input-box", "getInputChevronIconColor": "@twilio-paste/core/input-box", - "KeyboardKey": "@twilio/core/keyboard-key", - "KeyboardKeyGroup": "@twilio/core/keyboard-key", + "KeyboardKey": "@twilio-paste/core/keyboard-key", + "KeyboardKeyGroup": "@twilio-paste/core/keyboard-key", + "useKeyCombination": "@twilio-paste/core/keyboard-key", + "useKeyCombinations": "@twilio-paste/core/keyboard-key", "Label": "@twilio-paste/core/label", "RequiredDot": "@twilio-paste/core/label", "List": "@twilio-paste/core/list", diff --git a/packages/paste-core/components/keyboard-key/src/hooks.ts b/packages/paste-core/components/keyboard-key/src/hooks.ts index 0c7bfeacce..657686724b 100644 --- a/packages/paste-core/components/keyboard-key/src/hooks.ts +++ b/packages/paste-core/components/keyboard-key/src/hooks.ts @@ -8,15 +8,14 @@ export interface useKeyCombinationProps { enablePressStyles?: boolean; } -export interface useKeyCombinationsProps { - combinations: Omit[]; - enablePressStyles?: boolean; -} - interface useKeyCombinationReturn extends Omit { activeKeys: string[]; } +export interface useKeyCombinationsProps { + combinations: Omit[]; +} + const useKeyEvents = (): { activeKeys: string[] } => { const [activeKeys, setActiveKeys] = React.useState([]); @@ -67,10 +66,8 @@ export const useKeyCombination = ({ export const useKeyCombinations = ({ combinations, - enablePressStyles, -}: useKeyCombinationsProps): useKeyCombinationReturn => { +}: useKeyCombinationsProps): Omit => { const { activeKeys } = useKeyEvents(); - React.useEffect(() => { const combinationMatch = combinations.find( (combos) => @@ -83,5 +80,5 @@ export const useKeyCombinations = ({ } }, [activeKeys, combinations]); - return { activeKeys, enablePressStyles }; + return { activeKeys }; }; diff --git a/packages/paste-core/components/keyboard-key/src/index.tsx b/packages/paste-core/components/keyboard-key/src/index.tsx index a9c63115eb..9c106d37a2 100644 --- a/packages/paste-core/components/keyboard-key/src/index.tsx +++ b/packages/paste-core/components/keyboard-key/src/index.tsx @@ -1,6 +1,6 @@ export { KeyboardKey } from "./KeyboardKey"; -export type { KeyboardKeyProps, KeyboardKeyVariants } from "./KeyboardKey"; +export type { KeyboardKeyProps } from "./KeyboardKey"; export { KeyboardKeyGroup } from "./KeyboardKeyGroup"; -export type { KeyboardKeyGroupProps } from "./KeyboardKeyGroup"; +export type { KeyboardKeyGroupProps, KeyboardKeyVariants } from "./KeyboardKeyGroup"; export { useKeyCombination, useKeyCombinations } from "./hooks"; export type { useKeyCombinationsProps, useKeyCombinationProps } from "./hooks"; diff --git a/packages/paste-core/components/keyboard-key/type-docs.json b/packages/paste-core/components/keyboard-key/type-docs.json new file mode 100644 index 0000000000..ea02ef773b --- /dev/null +++ b/packages/paste-core/components/keyboard-key/type-docs.json @@ -0,0 +1,3233 @@ +{ + "KeyboardKey": { + "about": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "accessKey": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "aria-activedescendant": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application." + }, + "aria-atomic": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute." + }, + "aria-autocomplete": { + "type": "\"list\" | \"none\" | \"inline\" | \"both\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made." + }, + "aria-busy": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user." + }, + "aria-checked": { + "type": "boolean | \"true\" | \"false\" | \"mixed\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the current \"checked\" state of checkboxes, radio buttons, and other widgets." + }, + "aria-colcount": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the total number of columns in a table, grid, or treegrid." + }, + "aria-colindex": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid." + }, + "aria-colspan": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid." + }, + "aria-controls": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element (or elements) whose contents or presence are controlled by the current element." + }, + "aria-current": { + "type": "| boolean\n | \"time\"\n | \"true\"\n | \"false\"\n | \"page\"\n | \"step\"\n | \"location\"\n | \"date\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the element that represents the current item within a container or set of related elements." + }, + "aria-describedby": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element (or elements) that describes the object." + }, + "aria-details": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element that provides a detailed, extended description for the object." + }, + "aria-disabled": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable." + }, + "aria-dropeffect": { + "type": "\"link\" | \"none\" | \"copy\" | \"execute\" | \"move\" | \"popup\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates what functions can be performed when a dragged object is released on the drop target." + }, + "aria-errormessage": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element that provides an error message for the object." + }, + "aria-expanded": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed." + }, + "aria-flowto": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion,\nallows assistive technology to override the general default of reading in document source order." + }, + "aria-grabbed": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates an element's \"grabbed\" state in a drag-and-drop operation." + }, + "aria-haspopup": { + "type": "| boolean\n | \"dialog\"\n | \"menu\"\n | \"true\"\n | \"false\"\n | \"grid\"\n | \"listbox\"\n | \"tree\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element." + }, + "aria-hidden": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether the element is exposed to an accessibility API." + }, + "aria-invalid": { + "type": "boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the entered value does not conform to the format expected by the application." + }, + "aria-keyshortcuts": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element." + }, + "aria-label": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines a string value that labels the current element." + }, + "aria-labelledby": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element (or elements) that labels the current element." + }, + "aria-level": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the hierarchical level of an element within a structure." + }, + "aria-live": { + "type": "\"off\" | \"assertive\" | \"polite\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region." + }, + "aria-modal": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether an element is modal when displayed." + }, + "aria-multiline": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether a text box accepts multiple lines of input or only a single line." + }, + "aria-multiselectable": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that the user may select more than one item from the current selectable descendants." + }, + "aria-orientation": { + "type": "\"horizontal\" | \"vertical\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous." + }, + "aria-owns": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship\nbetween DOM elements where the DOM hierarchy cannot be used to represent the relationship." + }, + "aria-placeholder": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value.\nA hint could be a sample value or a brief description of the expected format." + }, + "aria-posinset": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM." + }, + "aria-pressed": { + "type": "boolean | \"true\" | \"false\" | \"mixed\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the current \"pressed\" state of toggle buttons." + }, + "aria-readonly": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that the element is not editable, but is otherwise operable." + }, + "aria-relevant": { + "type": "| \"text\"\n | \"additions\"\n | \"additions removals\"\n | \"additions text\"\n | \"all\"\n | \"removals\"\n | \"removals additions\"\n | \"removals text\"\n | \"text additions\"\n | \"text removals\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified." + }, + "aria-required": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that user input is required on the element before a form may be submitted." + }, + "aria-roledescription": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines a human-readable, author-localized description for the role of an element." + }, + "aria-rowcount": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the total number of rows in a table, grid, or treegrid." + }, + "aria-rowindex": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid." + }, + "aria-rowspan": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid." + }, + "aria-selected": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the current \"selected\" state of various widgets." + }, + "aria-setsize": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM." + }, + "aria-sort": { + "type": "\"none\" | \"ascending\" | \"descending\" | \"other\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates if items in a table or grid are sorted in ascending or descending order." + }, + "aria-valuemax": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the maximum allowed value for a range widget." + }, + "aria-valuemin": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the minimum allowed value for a range widget." + }, + "aria-valuenow": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the current value for a range widget." + }, + "aria-valuetext": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the human readable text alternative of aria-valuenow for a range widget." + }, + "autoCapitalize": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "autoCorrect": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "autoSave": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "contentEditable": { + "type": "Booleanish | \"inherit\"", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "contextMenu": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "dangerouslySetInnerHTML": { + "type": "{ __html: string }", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "datatype": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "defaultChecked": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "defaultValue": { + "type": "string | number | readonly string[]", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "dir": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "draggable": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "element": { + "type": "string", + "defaultValue": "'KEYBOARD_KEY'", + "required": false, + "externalProp": false, + "description": "Overrides the default element name to apply unique styles with the Customization Provider" + }, + "hidden": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "id": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "inlist": { + "type": "any", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "inputMode": { + "type": "| \"text\"\n | \"none\"\n | \"search\"\n | \"tel\"\n | \"url\"\n | \"email\"\n | \"numeric\"\n | \"decimal\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Hints at the type of data that might be entered by the user while editing the element or its contents" + }, + "is": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Specify that a standard HTML element should behave like a defined custom built-in element" + }, + "itemID": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemProp": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemRef": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemScope": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemType": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "key": { + "type": "Key", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "keyText": { + "type": "string", + "defaultValue": "'KEYBOARD_KEY'", + "required": false, + "externalProp": false, + "description": "Sets the key text that will be used to determine if the key has press stylings" + }, + "lang": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "nonce": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAbort": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAbortCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationEnd": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationEndCapture": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationIteration": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationIterationCapture": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationStart": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationStartCapture": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAuxClick": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAuxClickCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBeforeInput": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBeforeInputCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBlur": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBlurCapture": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlay": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlayCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlayThrough": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlayThroughCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onChange": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onChangeCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onClick": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onClickCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionEnd": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionEndCapture": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionStart": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionStartCapture": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionUpdate": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionUpdateCapture": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onContextMenu": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onContextMenuCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCopy": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCopyCapture": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCut": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCutCapture": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDoubleClick": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDoubleClickCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDrag": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEnd": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEndCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEnter": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEnterCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragExit": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragExitCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragLeave": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragLeaveCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragOver": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragOverCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragStart": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragStartCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDrop": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDropCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDurationChange": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDurationChangeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEmptied": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEmptiedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEncrypted": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEncryptedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEnded": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEndedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onError": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onErrorCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onFocus": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onFocusCapture": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onGotPointerCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onGotPointerCaptureCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInput": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInputCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInvalid": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInvalidCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyDown": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyDownCapture": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyPress": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyPressCapture": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyUp": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyUpCapture": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoad": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedData": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedDataCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedMetadata": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedMetadataCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadStart": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadStartCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLostPointerCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLostPointerCaptureCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseDown": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseDownCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseEnter": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseLeave": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseMove": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseMoveCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOut": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOutCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOver": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOverCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseUp": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseUpCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPaste": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPasteCapture": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPause": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPauseCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlay": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlayCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlaying": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlayingCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerCancel": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerCancelCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerDown": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerDownCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerEnter": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerEnterCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerLeave": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerLeaveCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerMove": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerMoveCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOut": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOutCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOver": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOverCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerUp": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerUpCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onProgress": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onProgressCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onRateChange": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onRateChangeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onReset": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onResetCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onResize": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onResizeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onScroll": { + "type": "UIEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onScrollCapture": { + "type": "UIEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeeked": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeekedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeeking": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeekingCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSelect": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSelectCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onStalled": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onStalledCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSubmit": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSubmitCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSuspend": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSuspendCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTimeUpdate": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTimeUpdateCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchCancel": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchCancelCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchEnd": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchEndCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchMove": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchMoveCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchStart": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchStartCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTransitionEnd": { + "type": "TransitionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTransitionEndCapture": { + "type": "TransitionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onVolumeChange": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onVolumeChangeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWaiting": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWaitingCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWheel": { + "type": "WheelEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWheelCapture": { + "type": "WheelEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "placeholder": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "prefix": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "property": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "radioGroup": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "resource": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "results": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "role": { + "type": "AriaRole", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "security": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "slot": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "spellCheck": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "suppressContentEditableWarning": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "suppressHydrationWarning": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "tabIndex": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "title": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "translate": { + "type": "\"yes\" | \"no\"", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "typeof": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "unselectable": { + "type": "\"on\" | \"off\"", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "vocab": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + } + }, + "KeyboardKeyGroup": { + "about": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "accessKey": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "activeKeys": { + "type": "string[]", + "defaultValue": null, + "required": false, + "externalProp": false + }, + "aria-activedescendant": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application." + }, + "aria-atomic": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute." + }, + "aria-autocomplete": { + "type": "\"list\" | \"none\" | \"inline\" | \"both\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made." + }, + "aria-busy": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user." + }, + "aria-checked": { + "type": "boolean | \"true\" | \"false\" | \"mixed\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the current \"checked\" state of checkboxes, radio buttons, and other widgets." + }, + "aria-colcount": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the total number of columns in a table, grid, or treegrid." + }, + "aria-colindex": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid." + }, + "aria-colspan": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid." + }, + "aria-controls": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element (or elements) whose contents or presence are controlled by the current element." + }, + "aria-current": { + "type": "| boolean\n | \"time\"\n | \"true\"\n | \"false\"\n | \"page\"\n | \"step\"\n | \"location\"\n | \"date\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the element that represents the current item within a container or set of related elements." + }, + "aria-describedby": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element (or elements) that describes the object." + }, + "aria-details": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element that provides a detailed, extended description for the object." + }, + "aria-disabled": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable." + }, + "aria-dropeffect": { + "type": "\"link\" | \"none\" | \"copy\" | \"execute\" | \"move\" | \"popup\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates what functions can be performed when a dragged object is released on the drop target." + }, + "aria-errormessage": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element that provides an error message for the object." + }, + "aria-expanded": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed." + }, + "aria-flowto": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion,\nallows assistive technology to override the general default of reading in document source order." + }, + "aria-grabbed": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates an element's \"grabbed\" state in a drag-and-drop operation." + }, + "aria-haspopup": { + "type": "| boolean\n | \"dialog\"\n | \"menu\"\n | \"true\"\n | \"false\"\n | \"grid\"\n | \"listbox\"\n | \"tree\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element." + }, + "aria-hidden": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether the element is exposed to an accessibility API." + }, + "aria-invalid": { + "type": "boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the entered value does not conform to the format expected by the application." + }, + "aria-keyshortcuts": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element." + }, + "aria-label": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines a string value that labels the current element." + }, + "aria-labelledby": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies the element (or elements) that labels the current element." + }, + "aria-level": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the hierarchical level of an element within a structure." + }, + "aria-live": { + "type": "\"off\" | \"assertive\" | \"polite\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region." + }, + "aria-modal": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether an element is modal when displayed." + }, + "aria-multiline": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether a text box accepts multiple lines of input or only a single line." + }, + "aria-multiselectable": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that the user may select more than one item from the current selectable descendants." + }, + "aria-orientation": { + "type": "\"horizontal\" | \"vertical\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous." + }, + "aria-owns": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship\nbetween DOM elements where the DOM hierarchy cannot be used to represent the relationship." + }, + "aria-placeholder": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value.\nA hint could be a sample value or a brief description of the expected format." + }, + "aria-posinset": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM." + }, + "aria-pressed": { + "type": "boolean | \"true\" | \"false\" | \"mixed\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the current \"pressed\" state of toggle buttons." + }, + "aria-readonly": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that the element is not editable, but is otherwise operable." + }, + "aria-relevant": { + "type": "| \"text\"\n | \"additions\"\n | \"additions removals\"\n | \"additions text\"\n | \"all\"\n | \"removals\"\n | \"removals additions\"\n | \"removals text\"\n | \"text additions\"\n | \"text removals\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified." + }, + "aria-required": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates that user input is required on the element before a form may be submitted." + }, + "aria-roledescription": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines a human-readable, author-localized description for the role of an element." + }, + "aria-rowcount": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the total number of rows in a table, grid, or treegrid." + }, + "aria-rowindex": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid." + }, + "aria-rowspan": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid." + }, + "aria-selected": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates the current \"selected\" state of various widgets." + }, + "aria-setsize": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM." + }, + "aria-sort": { + "type": "\"none\" | \"ascending\" | \"descending\" | \"other\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Indicates if items in a table or grid are sorted in ascending or descending order." + }, + "aria-valuemax": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the maximum allowed value for a range widget." + }, + "aria-valuemin": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the minimum allowed value for a range widget." + }, + "aria-valuenow": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the current value for a range widget." + }, + "aria-valuetext": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Defines the human readable text alternative of aria-valuenow for a range widget." + }, + "autoCapitalize": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "autoCorrect": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "autoSave": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "contentEditable": { + "type": "Booleanish | \"inherit\"", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "contextMenu": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "dangerouslySetInnerHTML": { + "type": "{ __html: string }", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "datatype": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "defaultChecked": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "defaultValue": { + "type": "string | number | readonly string[]", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "dir": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "disabled": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": false + }, + "draggable": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "element": { + "type": "string", + "defaultValue": "'KEYBOARD_KEY_GROUP'", + "required": false, + "externalProp": false, + "description": "Overrides the default element name to apply unique styles with the Customization Provider" + }, + "enablePressStyles": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": false + }, + "hidden": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "id": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "inlist": { + "type": "any", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "inputMode": { + "type": "| \"text\"\n | \"none\"\n | \"search\"\n | \"tel\"\n | \"url\"\n | \"email\"\n | \"numeric\"\n | \"decimal\"", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Hints at the type of data that might be entered by the user while editing the element or its contents" + }, + "is": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Specify that a standard HTML element should behave like a defined custom built-in element" + }, + "itemID": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemProp": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemRef": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemScope": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "itemType": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "key": { + "type": "Key", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "lang": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "nonce": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAbort": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAbortCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationEnd": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationEndCapture": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationIteration": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationIterationCapture": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationStart": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAnimationStartCapture": { + "type": "AnimationEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAuxClick": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onAuxClickCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBeforeInput": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBeforeInputCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBlur": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onBlurCapture": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlay": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlayCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlayThrough": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCanPlayThroughCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onChange": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onChangeCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onClick": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onClickCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionEnd": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionEndCapture": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionStart": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionStartCapture": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionUpdate": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCompositionUpdateCapture": { + "type": "CompositionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onContextMenu": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onContextMenuCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCopy": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCopyCapture": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCut": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onCutCapture": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDoubleClick": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDoubleClickCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDrag": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEnd": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEndCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEnter": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragEnterCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragExit": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragExitCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragLeave": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragLeaveCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragOver": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragOverCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragStart": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDragStartCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDrop": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDropCapture": { + "type": "DragEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDurationChange": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onDurationChangeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEmptied": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEmptiedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEncrypted": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEncryptedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEnded": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onEndedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onError": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onErrorCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onFocus": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onFocusCapture": { + "type": "FocusEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onGotPointerCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onGotPointerCaptureCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInput": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInputCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInvalid": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onInvalidCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyDown": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyDownCapture": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyPress": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyPressCapture": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyUp": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onKeyUpCapture": { + "type": "KeyboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoad": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedData": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedDataCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedMetadata": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadedMetadataCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadStart": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLoadStartCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLostPointerCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onLostPointerCaptureCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseDown": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseDownCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseEnter": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseLeave": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseMove": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseMoveCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOut": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOutCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOver": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseOverCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseUp": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onMouseUpCapture": { + "type": "MouseEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPaste": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPasteCapture": { + "type": "ClipboardEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPause": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPauseCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlay": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlayCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlaying": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPlayingCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerCancel": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerCancelCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerDown": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerDownCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerEnter": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerEnterCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerLeave": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerLeaveCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerMove": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerMoveCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOut": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOutCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOver": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerOverCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerUp": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onPointerUpCapture": { + "type": "PointerEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onProgress": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onProgressCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onRateChange": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onRateChangeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onReset": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onResetCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onResize": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onResizeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onScroll": { + "type": "UIEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onScrollCapture": { + "type": "UIEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeeked": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeekedCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeeking": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSeekingCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSelect": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSelectCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onStalled": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onStalledCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSubmit": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSubmitCapture": { + "type": "FormEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSuspend": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onSuspendCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTimeUpdate": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTimeUpdateCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchCancel": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchCancelCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchEnd": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchEndCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchMove": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchMoveCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchStart": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTouchStartCapture": { + "type": "TouchEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTransitionEnd": { + "type": "TransitionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onTransitionEndCapture": { + "type": "TransitionEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onVolumeChange": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onVolumeChangeCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWaiting": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWaitingCapture": { + "type": "ReactEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWheel": { + "type": "WheelEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "onWheelCapture": { + "type": "WheelEventHandler", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "placeholder": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "prefix": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "property": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "radioGroup": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "resource": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "results": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "role": { + "type": "AriaRole", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "security": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "slot": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "spellCheck": { + "type": "Booleanish", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "suppressContentEditableWarning": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "suppressHydrationWarning": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "tabIndex": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "title": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "translate": { + "type": "\"yes\" | \"no\"", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "typeof": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "unselectable": { + "type": "\"on\" | \"off\"", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "variant": { + "type": "\"default\" | \"inverse\"", + "defaultValue": null, + "required": false, + "externalProp": false + }, + "vocab": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true + } + }, + "useKeyCombinations": { + "combinations": { + "type": "Omit[]", + "defaultValue": null, + "required": true, + "externalProp": false + } + }, + "useKeyCombination": { + "keys": { + "type": "string[]", + "defaultValue": null, + "required": true, + "externalProp": false + }, + "onCombinationPress": { + "type": "() => void", + "defaultValue": null, + "required": true, + "externalProp": false + }, + "disabled": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": false + }, + "enablePressStyles": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": false + } + } +} diff --git a/packages/paste-core/core-bundle/.gitignore b/packages/paste-core/core-bundle/.gitignore index 5729ccbc5f..dbbdf5405c 100644 --- a/packages/paste-core/core-bundle/.gitignore +++ b/packages/paste-core/core-bundle/.gitignore @@ -52,6 +52,7 @@ /inline-control-group /input /input-box +/keyboard-key /label /lexical-library /list diff --git a/packages/paste-core/core-bundle/src/keyboard-key.tsx b/packages/paste-core/core-bundle/src/keyboard-key.tsx new file mode 100644 index 0000000000..214484c5be --- /dev/null +++ b/packages/paste-core/core-bundle/src/keyboard-key.tsx @@ -0,0 +1 @@ +export * from "@twilio-paste/keyboard-key"; From c7617df64c56d9762ec1c5c66bf02ccde22c0923 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 1 Nov 2024 14:15:23 -0500 Subject: [PATCH 10/49] feat(keyboard-key): change to infline-flex style --- .../components/keyboard-key/src/KeyboardKey.tsx | 2 +- .../components/keyboard-key/src/KeyboardKeyGroup.tsx | 2 +- packages/paste-core/components/keyboard-key/src/hooks.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 8638a187bf..452e5086df 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -77,7 +77,7 @@ const KeyboardKey = React.forwardRef( borderStyle="solid" width="fit-content" minWidth="sizeBase60" - display="flex" + display="inline-flex" justifyContent="center" paddingX="space20" as="kbd" diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx index 0d463766dc..6594817c55 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKeyGroup.tsx @@ -21,7 +21,7 @@ const KeyboardKeyGroup = React.forwardRef ({ element = "KEYBOARD_KEY_GROUP", activeKeys, disabled, enablePressStyles, variant = "default", ...props }, ref) => { return ( - + {props.children} diff --git a/packages/paste-core/components/keyboard-key/src/hooks.ts b/packages/paste-core/components/keyboard-key/src/hooks.ts index 657686724b..7ff02b573f 100644 --- a/packages/paste-core/components/keyboard-key/src/hooks.ts +++ b/packages/paste-core/components/keyboard-key/src/hooks.ts @@ -32,12 +32,12 @@ const useKeyEvents = (): { activeKeys: string[] } => { }; React.useEffect(() => { - document.addEventListener("keydown", (e) => handleKeyDown(e)); - document.addEventListener("keyup", (e) => handleKeyUp(e)); + window.addEventListener("keydown", (e) => handleKeyDown(e)); + window.addEventListener("keyup", (e) => handleKeyUp(e)); return () => { - document.removeEventListener("keydown", (e) => handleKeyDown(e)); - document.removeEventListener("keyup", (e) => handleKeyUp(e)); + window.removeEventListener("keydown", (e) => handleKeyDown(e)); + window.removeEventListener("keyup", (e) => handleKeyUp(e)); }; }, []); From b13cde43dae595612d5f65fe8e9a4e463bfa82e0 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 1 Nov 2024 15:56:45 -0500 Subject: [PATCH 11/49] chore(keyboard-key): added stroy --- .../keyboard-key/src/KeyboardKey.tsx | 3 +- .../keyboard-key/stories/index.stories.tsx | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 452e5086df..62a1cdcd6a 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -65,7 +65,8 @@ const KeyboardKey = React.forwardRef( variant = "default", } = React.useContext(KeyboardKeyCombinationContext); - const isKeyActive = !disabled && activeKeys && keyText && activeKeys.indexOf(keyText) >= 0; + const isKeyActive = + !disabled && activeKeys && keyText && activeKeys.map((k) => k.toLowerCase()).indexOf(keyText.toLowerCase()) >= 0; return ( { ); }; +export const TriggerModal = () => { + const [isOpen, setIsOpen] = React.useState(false); + const state = useKeyCombination({ + keys: ["Control", "k"], + onCombinationPress: () => { + setIsOpen(true); + }, + enablePressStyles: true, + }); + + return ( + + Use the following shortcut to open a modal: + + Control + K + + + setIsOpen(false)} size="default"> + + Choose an author + + + + “If there’s a book that you want to read, but it hasn’t been written yet, then you must write it.” — Toni + Morrison + + + + + + + + + + ); +}; + export const Customization = () => { const state = useKeyCombination({ keys: ["Control", "b"], From 87ab0ff82f96398976d79f652d4c20c37ea6c774 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 1 Nov 2024 16:23:30 -0500 Subject: [PATCH 12/49] chore(keyboard-key): linting --- .../keyboard-key/__tests__/hooks.spec.tsx | 2 +- .../keyboard-key/__tests__/index.spec.tsx | 6 ++--- .../keyboard-key/src/KeyboardKey.tsx | 3 ++- .../keyboard-key/src/KeyboardKeyGroup.tsx | 1 + .../components/keyboard-key/src/hooks.ts | 27 +++++++++---------- .../keyboard-key/stories/index.stories.tsx | 24 ++++++++--------- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx index 6c48efa1ad..9522484439 100644 --- a/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx +++ b/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx @@ -5,7 +5,7 @@ import { useKeyCombination, useKeyCombinations } from "../src"; import { Default } from "../stories/index.stories"; describe("Hooks", () => { - const wrapper = ({ children }) =>
{children}
; + const wrapper = ({ children }): React.ReactElement =>
{children}
; it("should handle pressed styling", async () => { const { getByText } = render(); diff --git a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx index c2f9c8f4fa..0537df458b 100644 --- a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx +++ b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx @@ -1,8 +1,8 @@ -import { act, fireEvent, render } from "@testing-library/react"; -import * as React from "react"; - +import { render } from "@testing-library/react"; import { CustomizationProvider } from "@twilio-paste/customization"; import { Theme } from "@twilio-paste/theme"; +import * as React from "react"; + import { KeyboardKey, KeyboardKeyGroup } from "../src"; import { Default } from "../stories/index.stories"; diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 62a1cdcd6a..5e571dab4e 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -2,6 +2,7 @@ import { Box } from "@twilio-paste/box"; import type { BoxProps, BoxStyleProps } from "@twilio-paste/box"; import type { HTMLPasteProps } from "@twilio-paste/types"; import * as React from "react"; + import { KeyboardKeyCombinationContext } from "./KeyboardKeyContext"; import { KeyboardKeyVariants } from "./KeyboardKeyGroup"; @@ -66,7 +67,7 @@ const KeyboardKey = React.forwardRef( } = React.useContext(KeyboardKeyCombinationContext); const isKeyActive = - !disabled && activeKeys && keyText && activeKeys.map((k) => k.toLowerCase()).indexOf(keyText.toLowerCase()) >= 0; + !disabled && activeKeys && keyText && activeKeys.map((k) => k.toLowerCase()).includes(keyText.toLowerCase()); return ( { const [activeKeys, setActiveKeys] = React.useState([]); - const handleKeyDown = (e: KeyboardEvent) => { + const handleKeyDown = (e: KeyboardEvent): void => { if (!e.repeat) { setActiveKeys((prev) => { return Array.from(new Set([...prev, e.key])); @@ -27,22 +28,26 @@ const useKeyEvents = (): { activeKeys: string[] } => { } }; - const handleKeyUp = (e: KeyboardEvent) => { + const handleKeyUp = (e: KeyboardEvent): void => { setActiveKeys((prev) => [...prev].filter((k) => k !== e.key)); }; React.useEffect(() => { - window.addEventListener("keydown", (e) => handleKeyDown(e)); - window.addEventListener("keyup", (e) => handleKeyUp(e)); + window.addEventListener("keydown", handleKeyDown); + window.addEventListener("keyup", handleKeyUp); return () => { - window.removeEventListener("keydown", (e) => handleKeyDown(e)); - window.removeEventListener("keyup", (e) => handleKeyUp(e)); + window.removeEventListener("keydown", handleKeyDown); + window.removeEventListener("keyup", handleKeyUp); }; }, []); return { activeKeys }; }; + +const stringArrayMatches = (arr1: string[], arr2: string[]): boolean => + JSON.stringify(arr1.sort((a, b) => a.localeCompare(b))) === JSON.stringify(arr2.sort((a, b) => a.localeCompare(b))); + export const useKeyCombination = ({ keys, onCombinationPress, @@ -52,9 +57,7 @@ export const useKeyCombination = ({ const { activeKeys } = useKeyEvents(); React.useEffect(() => { - const combinationMatch = - JSON.stringify(keys.map((k) => k.toLowerCase()).sort()) === - JSON.stringify(activeKeys.map((k) => k.toLowerCase()).sort()); + const combinationMatch = stringArrayMatches(keys, activeKeys); if (combinationMatch && !disabled) { onCombinationPress(); @@ -69,11 +72,7 @@ export const useKeyCombinations = ({ }: useKeyCombinationsProps): Omit => { const { activeKeys } = useKeyEvents(); React.useEffect(() => { - const combinationMatch = combinations.find( - (combos) => - JSON.stringify(combos.keys.map((k) => k.toLowerCase()).sort()) === - JSON.stringify(activeKeys.map((k) => k.toLowerCase()).sort()), - ); + const combinationMatch = combinations.find((combos) => stringArrayMatches(combos.keys, activeKeys)); if (combinationMatch && !combinationMatch.disabled) { combinationMatch.onCombinationPress(); diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx index 7290cac255..aef749d3b8 100644 --- a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -1,14 +1,11 @@ -import * as React from "react"; - -import { Box } from "@twilio-paste/box"; import { Button } from "@twilio-paste/button"; import { CustomizationProvider } from "@twilio-paste/customization"; import { Modal, ModalBody, ModalFooter, ModalFooterActions, ModalHeader, ModalHeading } from "@twilio-paste/modal"; import { Paragraph } from "@twilio-paste/paragraph"; import { Stack } from "@twilio-paste/stack"; import { Theme } from "@twilio-paste/theme"; +import * as React from "react"; -import { ModalFilledIcon } from "evergreen-ui"; import { KeyboardKey, KeyboardKeyGroup, useKeyCombination } from "../src"; // eslint-disable-next-line import/no-default-export @@ -17,10 +14,11 @@ export default { component: KeyboardKey, }; -export const Default = () => { +export const Default = (): React.ReactElement => { const state = useKeyCombination({ keys: ["Control", "b"], - onCombinationPress: () => { + onCombinationPress: (): void => { + // eslint-disable-next-line no-console console.log("Control + B pressed"); }, enablePressStyles: true, @@ -42,10 +40,11 @@ export const Default = () => { ); }; -export const Inverse = () => { +export const Inverse = (): React.ReactElement => { const state = useKeyCombination({ keys: ["Control", "b"], - onCombinationPress: () => { + onCombinationPress: (): void => { + // eslint-disable-next-line no-console console.log("Control + B pressed"); }, enablePressStyles: true, @@ -67,11 +66,11 @@ export const Inverse = () => { ); }; -export const TriggerModal = () => { +export const TriggerModal = (): React.ReactElement => { const [isOpen, setIsOpen] = React.useState(false); const state = useKeyCombination({ keys: ["Control", "k"], - onCombinationPress: () => { + onCombinationPress: (): void => { setIsOpen(true); }, enablePressStyles: true, @@ -112,10 +111,11 @@ export const TriggerModal = () => { ); }; -export const Customization = () => { +export const Customization = (): React.ReactElement => { const state = useKeyCombination({ keys: ["Control", "b"], - onCombinationPress: () => { + onCombinationPress: (): void => { + // eslint-disable-next-line no-console console.log("Control + B pressed"); }, enablePressStyles: true, From c29afacd19cde95713952b75eaf11846ee0674dd Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 4 Nov 2024 11:03:21 -0600 Subject: [PATCH 13/49] fix(keyboard-key): command logic --- .../components/keyboard-key/src/hooks.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/paste-core/components/keyboard-key/src/hooks.ts b/packages/paste-core/components/keyboard-key/src/hooks.ts index de36357cc1..213fd08df1 100644 --- a/packages/paste-core/components/keyboard-key/src/hooks.ts +++ b/packages/paste-core/components/keyboard-key/src/hooks.ts @@ -23,13 +23,27 @@ const useKeyEvents = (): { activeKeys: string[] } => { const handleKeyDown = (e: KeyboardEvent): void => { if (!e.repeat) { setActiveKeys((prev) => { + // ignore any system conbimation triggers + if (prev.includes("Meta") || e.key === "Meta") { + e.preventDefault(); + e.stopPropagation(); + } return Array.from(new Set([...prev, e.key])); }); } }; const handleKeyUp = (e: KeyboardEvent): void => { - setActiveKeys((prev) => [...prev].filter((k) => k !== e.key)); + /** + * Meta (Command) key press on Mac OS modifies following keys and no longer provides the + * onKeyup event so need to remove all as we can no longer tell when a user releases the other + * keys. Without clearing whole thing it may cause shortcuts triggering when they shouldn't + */ + if (e.key === "Meta") { + setActiveKeys([]); + } else { + setActiveKeys((prev) => [...prev].filter((k) => k !== e.key)); + } }; React.useEffect(() => { From d910c26957d6875dce93cde50dc0149cd12706ab Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 4 Nov 2024 11:26:34 -0600 Subject: [PATCH 14/49] feat(design-tokens): added new box shadows to support keyboard-keys --- packages/paste-design-tokens/tokens/global/box-shadow.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/paste-design-tokens/tokens/global/box-shadow.yml b/packages/paste-design-tokens/tokens/global/box-shadow.yml index 9209039cf3..7242a1c1f1 100644 --- a/packages/paste-design-tokens/tokens/global/box-shadow.yml +++ b/packages/paste-design-tokens/tokens/global/box-shadow.yml @@ -218,6 +218,12 @@ props: shadow-border-bottom-inverse-new-weaker: value: "{!offset-0} {!offset-05} {!offset-0} {!palette-purple-70}" comment: Bottom shadow border for the sidebar beta badge + shadow-border-bottom-weak: + value: "{!offset-0} {!offset-05} {!offset-0} {!palette-gray-30}" + comment: Bottom shadow border for border weak color + shadow-border-bottom-inverse-weaker: + value: "{!offset-0} {!offset-05} {!offset-0} {!palette-gray-80}" + comment: Bottom shadow border for inverse border weaker color # User shadow-border-user: value: "{!offset-0} {!offset-0} {!offset-0} {!offset-05} {!palette-purple-50}" From 4504056f161d2d9faa21793d2e9c2b3d722e4532 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 4 Nov 2024 11:31:52 -0600 Subject: [PATCH 15/49] chore(ci-cd): added chagesets --- .changeset/confused-whale.md | 5 +++++ .changeset/shaggy-sheep-confess.md | 6 ++++++ .changeset/sweet-mugs-admire.md | 6 ++++++ 3 files changed, 17 insertions(+) create mode 100644 .changeset/confused-whale.md create mode 100644 .changeset/shaggy-sheep-confess.md create mode 100644 .changeset/sweet-mugs-admire.md diff --git a/.changeset/confused-whale.md b/.changeset/confused-whale.md new file mode 100644 index 0000000000..adf1aa81bc --- /dev/null +++ b/.changeset/confused-whale.md @@ -0,0 +1,5 @@ +--- +"@twilio-paste/codemods": minor +--- + +[KeyboardKey] added a new component to display visual indicators for keyboard shortcuts available to users diff --git a/.changeset/shaggy-sheep-confess.md b/.changeset/shaggy-sheep-confess.md new file mode 100644 index 0000000000..4e9cf68802 --- /dev/null +++ b/.changeset/shaggy-sheep-confess.md @@ -0,0 +1,6 @@ +--- +"@twilio-paste/core": patch +"@twilio-paste/design-tokens": patch +--- + +[Design Tokens] added new designs tokens shadowBorderBottomWeak and shadowBorderBottomInverseWeaker to support new feature KeybaordKey diff --git a/.changeset/sweet-mugs-admire.md b/.changeset/sweet-mugs-admire.md new file mode 100644 index 0000000000..7aa1bd1c6a --- /dev/null +++ b/.changeset/sweet-mugs-admire.md @@ -0,0 +1,6 @@ +--- +"@twilio-paste/keyboard-key": major +"@twilio-paste/core": major +--- + +[KeyboardKey] added a new component to display visual indicators for keyboard shortcuts available to users From 6775b368ce2713e6b14ddebed6d87c133726b960 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 4 Nov 2024 11:32:13 -0600 Subject: [PATCH 16/49] fix(keyboard-key): boxShadow stylings --- .../keyboard-key/src/KeyboardKey.tsx | 53 +++++++++++-------- .../components/keyboard-key/src/hooks.ts | 5 +- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 5e571dab4e..6ffd8f2a14 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -18,27 +18,32 @@ const BaseStyles: Record = { const DisabledStyles: Record = { default: { color: "colorTextWeak", - borderBottomWidth: "borderWidth10", borderColor: "colorBorderWeakest", }, inverse: { color: "colorTextInverseWeaker", - borderBottomWidth: "borderWidth10", borderColor: "colorBorderInverseWeakest", }, }; const PressedStyles: Record = { default: { - borderBottomWidth: "borderWidth10", backgroundColor: "colorBackgroundStrong", }, inverse: { - borderBottomWidth: "borderWidth10", backgroundColor: "colorBackgroundInverseStronger", }, }; +const BoxShadows: Record = { + default: { + boxShadow: "shadowBorderBottomWeak", + }, + inverse: { + boxShadow: "shadowBorderBottomInverseWeaker", + }, +}; + export interface KeyboardKeyProps extends HTMLPasteProps<"div"> { children?: React.ReactNode; /** @@ -70,25 +75,27 @@ const KeyboardKey = React.forwardRef( !disabled && activeKeys && keyText && activeKeys.map((k) => k.toLowerCase()).includes(keyText.toLowerCase()); return ( - - {props.children} + + + {props.children} + ); }, diff --git a/packages/paste-core/components/keyboard-key/src/hooks.ts b/packages/paste-core/components/keyboard-key/src/hooks.ts index 213fd08df1..a3bb9a9f8a 100644 --- a/packages/paste-core/components/keyboard-key/src/hooks.ts +++ b/packages/paste-core/components/keyboard-key/src/hooks.ts @@ -23,7 +23,7 @@ const useKeyEvents = (): { activeKeys: string[] } => { const handleKeyDown = (e: KeyboardEvent): void => { if (!e.repeat) { setActiveKeys((prev) => { - // ignore any system conbimation triggers + // ignore any system combination triggers if (prev.includes("Meta") || e.key === "Meta") { e.preventDefault(); e.stopPropagation(); @@ -35,9 +35,10 @@ const useKeyEvents = (): { activeKeys: string[] } => { const handleKeyUp = (e: KeyboardEvent): void => { /** - * Meta (Command) key press on Mac OS modifies following keys and no longer provides the + * Meta (Command) key press on Mac OS modifies following keys and no longer triggers the * onKeyup event so need to remove all as we can no longer tell when a user releases the other * keys. Without clearing whole thing it may cause shortcuts triggering when they shouldn't + * and press stlying still being applied. */ if (e.key === "Meta") { setActiveKeys([]); From 3cc0dff386294c7eb6af0e8efbb7dd0722cd9795 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 4 Nov 2024 11:33:01 -0600 Subject: [PATCH 17/49] fix(keyboard-key): remove null component wrapper --- .../keyboard-key/src/KeyboardKey.tsx | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 6ffd8f2a14..22e01c9f22 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -75,27 +75,25 @@ const KeyboardKey = React.forwardRef( !disabled && activeKeys && keyText && activeKeys.map((k) => k.toLowerCase()).includes(keyText.toLowerCase()); return ( - - - {props.children} - + + {props.children} ); }, From a9b59311f5df6b8583c80755d6991f5d21d13501 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Mon, 4 Nov 2024 11:36:49 -0600 Subject: [PATCH 18/49] fix(keyboard-key): aria-hidden --- packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 22e01c9f22..9ad81aa896 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -76,6 +76,8 @@ const KeyboardKey = React.forwardRef( return (
); From 528b13b24f34067596942d86776f29ea4707e86e Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Tue, 5 Nov 2024 10:42:56 -0600 Subject: [PATCH 28/49] chore(keyboard-key): stories update --- .../keyboard-key/stories/index.stories.tsx | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx index 89973dded4..d21fa3a32c 100644 --- a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -1,8 +1,10 @@ import { Button } from "@twilio-paste/button"; +import { Box } from "@twilio-paste/box"; import { CustomizationProvider } from "@twilio-paste/customization"; import { Modal, ModalBody, ModalFooter, ModalFooterActions, ModalHeader, ModalHeading } from "@twilio-paste/modal"; -import { Paragraph } from "@twilio-paste/paragraph"; +import { Text } from "@twilio-paste/text"; import { Stack } from "@twilio-paste/stack"; +import { Paragraph } from "@twilio-paste/paragraph"; import { Theme } from "@twilio-paste/theme"; import * as React from "react"; @@ -27,14 +29,24 @@ export const Default = (): React.ReactElement => { return ( - - Control - B - - - Control - B - + + + Deafult/pressed + + + Control + B + + + + + Disabled + + + Control + B + + ); @@ -53,14 +65,24 @@ export const Inverse = (): React.ReactElement => { return ( - - Control - B - - - Control - B - + + + Deafult/pressed + + + Control + B + + + + + Disabled + + + Control + B + + ); From 4fbce7b6d14900a1478a416412ded6bdb04c9035 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Tue, 5 Nov 2024 10:48:57 -0600 Subject: [PATCH 29/49] chore(keyboard-key): formatting fix --- .../components/keyboard-key/stories/index.stories.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx index d21fa3a32c..b2f26e0245 100644 --- a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -1,10 +1,10 @@ -import { Button } from "@twilio-paste/button"; import { Box } from "@twilio-paste/box"; +import { Button } from "@twilio-paste/button"; import { CustomizationProvider } from "@twilio-paste/customization"; import { Modal, ModalBody, ModalFooter, ModalFooterActions, ModalHeader, ModalHeading } from "@twilio-paste/modal"; -import { Text } from "@twilio-paste/text"; -import { Stack } from "@twilio-paste/stack"; import { Paragraph } from "@twilio-paste/paragraph"; +import { Stack } from "@twilio-paste/stack"; +import { Text } from "@twilio-paste/text"; import { Theme } from "@twilio-paste/theme"; import * as React from "react"; From c1714fb5a76af01f5fc21164766dd3ff692345f0 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Tue, 5 Nov 2024 10:53:47 -0600 Subject: [PATCH 30/49] chore(keyboard-key): typo --- .../components/keyboard-key/stories/index.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx index b2f26e0245..51ec512901 100644 --- a/packages/paste-core/components/keyboard-key/stories/index.stories.tsx +++ b/packages/paste-core/components/keyboard-key/stories/index.stories.tsx @@ -31,7 +31,7 @@ export const Default = (): React.ReactElement => { - Deafult/pressed + Default/pressed Control @@ -67,7 +67,7 @@ export const Inverse = (): React.ReactElement => { - Deafult/pressed + Default/pressed Control From acdf2d06a94dea7273a4b7ae4d3169f9ef58cf81 Mon Sep 17 00:00:00 2001 From: krisantrobus <55083528+krisantrobus@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:10:05 -0600 Subject: [PATCH 31/49] Update .changeset/sweet-mugs-admire.md Co-authored-by: Nora Krantz <75342690+nkrantz@users.noreply.github.com> --- .changeset/sweet-mugs-admire.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sweet-mugs-admire.md b/.changeset/sweet-mugs-admire.md index 7aa1bd1c6a..f4032d0eb1 100644 --- a/.changeset/sweet-mugs-admire.md +++ b/.changeset/sweet-mugs-admire.md @@ -1,6 +1,6 @@ --- "@twilio-paste/keyboard-key": major -"@twilio-paste/core": major +"@twilio-paste/core": minor --- [KeyboardKey] added a new component to display visual indicators for keyboard shortcuts available to users From e3d582744aa883b4797984c324b6861a8894c963 Mon Sep 17 00:00:00 2001 From: krisantrobus <55083528+krisantrobus@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:10:16 -0600 Subject: [PATCH 32/49] Update .changeset/shaggy-sheep-confess.md Co-authored-by: Nora Krantz <75342690+nkrantz@users.noreply.github.com> --- .changeset/shaggy-sheep-confess.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/shaggy-sheep-confess.md b/.changeset/shaggy-sheep-confess.md index bdd9eacf97..64e9ae135f 100644 --- a/.changeset/shaggy-sheep-confess.md +++ b/.changeset/shaggy-sheep-confess.md @@ -1,6 +1,6 @@ --- -"@twilio-paste/core": patch -"@twilio-paste/design-tokens": patch +"@twilio-paste/core": minor +"@twilio-paste/design-tokens": minor --- [Design Tokens] added new design tokens shadowBorderBottomWeak and shadowBorderBottomInverseWeaker to support new feature, KeybaordKey. From 781d0b0a753c42f29a9f7199c48087daee9cd5e1 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 6 Nov 2024 13:32:51 -0600 Subject: [PATCH 33/49] chore(keyboard-key): address PR comments --- .../keyboard-key/__tests__/hooks.spec.tsx | 1 - .../keyboard-key/__tests__/index.spec.tsx | 38 ++++++++----------- .../keyboard-key/src/KeyboardKey.tsx | 8 ++-- .../keyboard-key/src/KeyboardKeyContext.tsx | 6 +-- .../keyboard-key/src/KeyboardKeyGroup.tsx | 18 ++++++--- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx index 10a4626c91..e717daebf3 100644 --- a/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx +++ b/packages/paste-core/components/keyboard-key/__tests__/hooks.spec.tsx @@ -11,7 +11,6 @@ describe("Hooks", () => { const controlKey = getAllByText("Control")[0]; const bKey = getAllByText("B")[0]; expect(controlKey).toBeDefined(); - expect(controlKey).toBeDefined(); expect(controlKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); expect(bKey).toHaveStyleRule("background-color", "rgb(249, 249, 250)"); diff --git a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx index 637f72a91b..7fa4ec587b 100644 --- a/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx +++ b/packages/paste-core/components/keyboard-key/__tests__/index.spec.tsx @@ -21,41 +21,29 @@ describe("KeyboardKey", () => { describe("Customization", () => { it("should accept custom element names", async () => { - const { getAllByText } = render( - - - Control - B - - , - ); - - const controlKey = getAllByText("Control")[0]; - const bKey = getAllByText("B")[0]; - expect(controlKey).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_ONE"); - expect(bKey).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_TWO"); - expect(controlKey.parentElement).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_GROUP"); - }); - - it("should customize styling", async () => { const { getAllByText } = render( - - Control - B + + Control + B , @@ -63,8 +51,14 @@ describe("KeyboardKey", () => { const controlKey = getAllByText("Control")[0]; const bKey = getAllByText("B")[0]; + expect(controlKey).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_ONE"); + expect(bKey).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_TWO"); + expect(controlKey.parentElement).toHaveAttribute("data-paste-element", "MY_CUSTOM_KEY_GROUP"); + expect(controlKey).toHaveStyleRule("font-family", "'TwilioSansMono',Courier,monospace"); + expect(controlKey).toHaveStyleRule("border-radius", "8px"); expect(bKey).toHaveStyleRule("padding", "0.5rem"); + expect(bKey).toHaveStyleRule("border-radius", "16px"); expect(controlKey.parentElement).toHaveStyleRule("background-color", "rgb(2, 99, 224)"); }); }); diff --git a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx index 80be63a037..6ef2e0c7f6 100644 --- a/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx +++ b/packages/paste-core/components/keyboard-key/src/KeyboardKey.tsx @@ -1,10 +1,9 @@ -import { Box } from "@twilio-paste/box"; +import { Box, safelySpreadBoxProps } from "@twilio-paste/box"; import type { BoxProps, BoxStyleProps } from "@twilio-paste/box"; import type { HTMLPasteProps } from "@twilio-paste/types"; import * as React from "react"; -import { KeyboardKeyCombinationContext } from "./KeyboardKeyContext"; -import { KeyboardKeyVariants } from "./KeyboardKeyGroup"; +import { KeyboardKeyCombinationContext, KeyboardKeyVariants } from "./KeyboardKeyContext"; const BaseStyles: Record = { default: { @@ -44,7 +43,7 @@ const PressedStyles: Record = { }, }; -export interface KeyboardKeyProps extends HTMLPasteProps<"div"> { +export interface KeyboardKeyProps extends HTMLPasteProps<"kbd"> { children?: React.ReactNode; /** * Overrides the default element name to apply unique styles with the Customization Provider @@ -76,6 +75,7 @@ const KeyboardKey = React.forwardRef( return ( , KeyboardCombinationState { children?: React.ReactNode; /** @@ -19,10 +17,20 @@ export interface KeyboardKeyGroupProps extends HTMLPasteProps<"div">, KeyboardCo } const KeyboardKeyGroup = React.forwardRef( - ({ element = "KEYBOARD_KEY_GROUP", activeKeys, disabled, enablePressStyles, variant = "default", ...props }, ref) => { + ( + { + element = "KEYBOARD_KEY_GROUP", + activeKeys, + disabled = false, + enablePressStyles = false, + variant = "default", + ...props + }, + ref, + ) => { return ( - + {props.children} From 5ade11aea7a0461bad9c5a4e76a506888b5701bc Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Wed, 6 Nov 2024 14:15:31 -0600 Subject: [PATCH 34/49] feat(keyboard-tooltip): wip --- .../components/keyboard-key/src/index.tsx | 2 +- .../components/tooltip/src/Tooltip.tsx | 89 ++++++++++-- .../components/tooltip/src/index.tsx | 2 + .../tooltip/stories/keyboard-key.stories.tsx | 137 ++++++++++++++++++ 4 files changed, 218 insertions(+), 12 deletions(-) create mode 100644 packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx diff --git a/packages/paste-core/components/keyboard-key/src/index.tsx b/packages/paste-core/components/keyboard-key/src/index.tsx index 9c106d37a2..7a4e508548 100644 --- a/packages/paste-core/components/keyboard-key/src/index.tsx +++ b/packages/paste-core/components/keyboard-key/src/index.tsx @@ -1,6 +1,6 @@ export { KeyboardKey } from "./KeyboardKey"; export type { KeyboardKeyProps } from "./KeyboardKey"; export { KeyboardKeyGroup } from "./KeyboardKeyGroup"; -export type { KeyboardKeyGroupProps, KeyboardKeyVariants } from "./KeyboardKeyGroup"; +export type { KeyboardKeyGroupProps } from "./KeyboardKeyGroup"; export { useKeyCombination, useKeyCombinations } from "./hooks"; export type { useKeyCombinationsProps, useKeyCombinationProps } from "./hooks"; diff --git a/packages/paste-core/components/tooltip/src/Tooltip.tsx b/packages/paste-core/components/tooltip/src/Tooltip.tsx index 6ce4fa7735..8b55f7533d 100644 --- a/packages/paste-core/components/tooltip/src/Tooltip.tsx +++ b/packages/paste-core/components/tooltip/src/Tooltip.tsx @@ -1,5 +1,7 @@ import { Box, safelySpreadBoxProps } from "@twilio-paste/box"; import type { BoxProps } from "@twilio-paste/box"; +import { KeyboardKey, KeyboardKeyGroup } from "@twilio-paste/keyboard-key"; +import { Stack } from "@twilio-paste/stack"; import { Text } from "@twilio-paste/text"; import { StyledBase } from "@twilio-paste/theme"; import { TooltipPrimitive, TooltipPrimitiveReference, useTooltipPrimitiveState } from "@twilio-paste/tooltip-primitive"; @@ -60,17 +62,48 @@ export interface TooltipProps extends TooltipPrimitiveInitialState { * @memberof TooltipProps */ text: string; + actionHeader?: never; + keyCombinationsActions?: never; } +interface KeyboardActions { + name: string; + keyCombination: string[]; + disabled?: boolean; +} + +export interface KeyboardKeyTooltipProps + extends Omit { + text?: never; + /** + * The mapping of action names to their respective key combinations. + * + * @type {KeyboardActions} + * @memberof KeyboardKeyTooltipProps + */ + keyCombinationsActions: KeyboardActions; + /** + * The header content of the Tooltip. + * + * @type {string} + * @memberof KeyboardKeyTooltipProps + */ + actionHeader?: string; +} + +// Union will stop users from adding types from both TooltipProps and KeyboardKeyTooltipProps at the same time. +export type TooltipTypes = TooltipProps | KeyboardKeyTooltipProps; + /* *Tooltip's current structure does not allow for customization of its arrow. *TODO: refactor Tooltip so that the styling of its arrow can be customized *using Customization Provider. */ -const Tooltip = React.forwardRef( - ({ baseId, children, element = "TOOLTIP", state, text, ...props }, ref) => { +const Tooltip = React.forwardRef( + ({ baseId, children, element = "TOOLTIP", state, text, actionHeader, keyCombinationsActions, ...props }, ref) => { const tooltip = state || useTooltipPrimitiveState({ baseId: `paste-tooltip-${useUID()}`, ...props }); + return ( <> {React.Children.only( @@ -82,15 +115,49 @@ const Tooltip = React.forwardRef( {/* import Paste Theme Based Styles due to portal positioning. */} - - {text} - + {text && ( + + {text} + + )} + {keyCombinationsActions && ( + + {actionHeader && ( + + {actionHeader} + + )} + {keyCombinationsActions.map((action) => ( + + + {action.name} + + + {action.keyCombination.map((key) => ( + {key} + ))} + + + ))} + + )} diff --git a/packages/paste-core/components/tooltip/src/index.tsx b/packages/paste-core/components/tooltip/src/index.tsx index ffeacc73c3..fe539f708a 100644 --- a/packages/paste-core/components/tooltip/src/index.tsx +++ b/packages/paste-core/components/tooltip/src/index.tsx @@ -3,6 +3,8 @@ import type { TooltipStateReturn } from "./Tooltip"; export { Tooltip, useTooltipState } from "./Tooltip"; export type { TooltipProps, + TooltipTypes, + KeyboardKeyTooltipProps, TooltipStateReturn, UseTooltipInitialStateProps, } from "./Tooltip"; diff --git a/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx b/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx new file mode 100644 index 0000000000..9431349d8b --- /dev/null +++ b/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx @@ -0,0 +1,137 @@ +import type { StoryFn } from "@storybook/react"; +import { Anchor } from "@twilio-paste/anchor"; +import { Box } from "@twilio-paste/box"; +import { Button } from "@twilio-paste/button"; +import { CustomizationProvider } from "@twilio-paste/customization"; +import { InformationIcon } from "@twilio-paste/icons/esm/InformationIcon"; +import { Stack } from "@twilio-paste/stack"; +import { Text } from "@twilio-paste/text"; +import { Theme, useTheme } from "@twilio-paste/theme"; +import * as React from "react"; + +import { Tooltip, useTooltipState } from "../src"; + +// eslint-disable-next-line import/no-default-export +export default { + title: "Components/Tooltip/KeyboardKey", + excludeStories: ["StateHookExample"], + component: Tooltip, + parameters: { + chromatic: { delay: 3000, diffThreshold: 0.2 }, + }, +}; + +export const Default = (): React.ReactNode => { + return ( + + + + + + ); +}; + +export const CustomizedTooltip: StoryFn = (_args, { parameters: { isTestEnvironment } }) => { + const currentTheme = useTheme(); + return ( + + + + + + + + + + + + + + + ); +}; + +CustomizedTooltip.storyName = "Customized Tooltip"; +CustomizedTooltip.parameters = { + parameters: { + chromatic: { disableSnapshot: true }, + }, + a11y: { + // no need to a11y check customization + disable: true, + }, +}; From 774095c30f761cbacfa5e1f8c9227c0adc5e10b7 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 8 Nov 2024 08:26:40 -0600 Subject: [PATCH 35/49] chore(tooltip): update types --- .../components/keyboard-key/type-docs.json | 328 +++++++++--------- .../components/tooltip/src/Tooltip.tsx | 4 +- 2 files changed, 166 insertions(+), 166 deletions(-) diff --git a/packages/paste-core/components/keyboard-key/type-docs.json b/packages/paste-core/components/keyboard-key/type-docs.json index 18b6afb7a2..8b4790f66c 100644 --- a/packages/paste-core/components/keyboard-key/type-docs.json +++ b/packages/paste-core/components/keyboard-key/type-docs.json @@ -509,973 +509,973 @@ "externalProp": true }, "onAbort": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAbortCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAnimationEnd": { - "type": "AnimationEventHandler", + "type": "AnimationEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAnimationEndCapture": { - "type": "AnimationEventHandler", + "type": "AnimationEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAnimationIteration": { - "type": "AnimationEventHandler", + "type": "AnimationEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAnimationIterationCapture": { - "type": "AnimationEventHandler", + "type": "AnimationEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAnimationStart": { - "type": "AnimationEventHandler", + "type": "AnimationEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAnimationStartCapture": { - "type": "AnimationEventHandler", + "type": "AnimationEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAuxClick": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onAuxClickCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onBeforeInput": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onBeforeInputCapture": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onBlur": { - "type": "FocusEventHandler", + "type": "FocusEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onBlurCapture": { - "type": "FocusEventHandler", + "type": "FocusEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCanPlay": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCanPlayCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCanPlayThrough": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCanPlayThroughCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onChange": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onChangeCapture": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onClick": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onClickCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCompositionEnd": { - "type": "CompositionEventHandler", + "type": "CompositionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCompositionEndCapture": { - "type": "CompositionEventHandler", + "type": "CompositionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCompositionStart": { - "type": "CompositionEventHandler", + "type": "CompositionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCompositionStartCapture": { - "type": "CompositionEventHandler", + "type": "CompositionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCompositionUpdate": { - "type": "CompositionEventHandler", + "type": "CompositionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCompositionUpdateCapture": { - "type": "CompositionEventHandler", + "type": "CompositionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onContextMenu": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onContextMenuCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCopy": { - "type": "ClipboardEventHandler", + "type": "ClipboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCopyCapture": { - "type": "ClipboardEventHandler", + "type": "ClipboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCut": { - "type": "ClipboardEventHandler", + "type": "ClipboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onCutCapture": { - "type": "ClipboardEventHandler", + "type": "ClipboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDoubleClick": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDoubleClickCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDrag": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragEnd": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragEndCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragEnter": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragEnterCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragExit": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragExitCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragLeave": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragLeaveCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragOver": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragOverCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragStart": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDragStartCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDrop": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDropCapture": { - "type": "DragEventHandler", + "type": "DragEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDurationChange": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onDurationChangeCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onEmptied": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onEmptiedCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onEncrypted": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onEncryptedCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onEnded": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onEndedCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onError": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onErrorCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onFocus": { - "type": "FocusEventHandler", + "type": "FocusEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onFocusCapture": { - "type": "FocusEventHandler", + "type": "FocusEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onGotPointerCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onGotPointerCaptureCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onInput": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onInputCapture": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onInvalid": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onInvalidCapture": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onKeyDown": { - "type": "KeyboardEventHandler", + "type": "KeyboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onKeyDownCapture": { - "type": "KeyboardEventHandler", + "type": "KeyboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onKeyPress": { - "type": "KeyboardEventHandler", + "type": "KeyboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onKeyPressCapture": { - "type": "KeyboardEventHandler", + "type": "KeyboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onKeyUp": { - "type": "KeyboardEventHandler", + "type": "KeyboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onKeyUpCapture": { - "type": "KeyboardEventHandler", + "type": "KeyboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoad": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadedData": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadedDataCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadedMetadata": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadedMetadataCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadStart": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLoadStartCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLostPointerCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onLostPointerCaptureCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseDown": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseDownCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseEnter": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseLeave": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseMove": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseMoveCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseOut": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseOutCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseOver": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseOverCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseUp": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onMouseUpCapture": { - "type": "MouseEventHandler", + "type": "MouseEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPaste": { - "type": "ClipboardEventHandler", + "type": "ClipboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPasteCapture": { - "type": "ClipboardEventHandler", + "type": "ClipboardEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPause": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPauseCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPlay": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPlayCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPlaying": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPlayingCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerCancel": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerCancelCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerDown": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerDownCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerEnter": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerEnterCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerLeave": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerLeaveCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerMove": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerMoveCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerOut": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerOutCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerOver": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerOverCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerUp": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onPointerUpCapture": { - "type": "PointerEventHandler", + "type": "PointerEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onProgress": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onProgressCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onRateChange": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onRateChangeCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onReset": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onResetCapture": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onResize": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onResizeCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onScroll": { - "type": "UIEventHandler", + "type": "UIEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onScrollCapture": { - "type": "UIEventHandler", + "type": "UIEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSeeked": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSeekedCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSeeking": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSeekingCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSelect": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSelectCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onStalled": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onStalledCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSubmit": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSubmitCapture": { - "type": "FormEventHandler", + "type": "FormEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSuspend": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onSuspendCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTimeUpdate": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTimeUpdateCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchCancel": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchCancelCapture": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchEnd": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchEndCapture": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchMove": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchMoveCapture": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchStart": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTouchStartCapture": { - "type": "TouchEventHandler", + "type": "TouchEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTransitionEnd": { - "type": "TransitionEventHandler", + "type": "TransitionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onTransitionEndCapture": { - "type": "TransitionEventHandler", + "type": "TransitionEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onVolumeChange": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onVolumeChangeCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onWaiting": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onWaitingCapture": { - "type": "ReactEventHandler", + "type": "ReactEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onWheel": { - "type": "WheelEventHandler", + "type": "WheelEventHandler", "defaultValue": null, "required": false, "externalProp": true }, "onWheelCapture": { - "type": "WheelEventHandler", + "type": "WheelEventHandler", "defaultValue": null, "required": false, "externalProp": true @@ -2007,7 +2007,7 @@ }, "disabled": { "type": "boolean", - "defaultValue": "null", + "defaultValue": false, "required": false, "externalProp": false, "description": "Whether the keys should show the disbled state" @@ -2027,7 +2027,7 @@ }, "enablePressStyles": { "type": "boolean", - "defaultValue": "null", + "defaultValue": false, "required": false, "externalProp": false, "description": "Whether the keys should show pressed state when active keys contains the keyText mapped to KeyboardKey" diff --git a/packages/paste-core/components/tooltip/src/Tooltip.tsx b/packages/paste-core/components/tooltip/src/Tooltip.tsx index 8b55f7533d..c136f5ca7e 100644 --- a/packages/paste-core/components/tooltip/src/Tooltip.tsx +++ b/packages/paste-core/components/tooltip/src/Tooltip.tsx @@ -78,10 +78,10 @@ export interface KeyboardKeyTooltipProps /** * The mapping of action names to their respective key combinations. * - * @type {KeyboardActions} + * @type {Array} * @memberof KeyboardKeyTooltipProps */ - keyCombinationsActions: KeyboardActions; + keyCombinationsActions: Array; /** * The header content of the Tooltip. * From be97d29ce04213e7c4a8d1d1cd04789eede43e74 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Fri, 8 Nov 2024 08:26:46 -0600 Subject: [PATCH 36/49] chore(tooltip): update types --- .../components/tooltip/type-docs.json | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/packages/paste-core/components/tooltip/type-docs.json b/packages/paste-core/components/tooltip/type-docs.json index 98bc9cae97..d741f5be3d 100644 --- a/packages/paste-core/components/tooltip/type-docs.json +++ b/packages/paste-core/components/tooltip/type-docs.json @@ -7,6 +7,12 @@ "externalProp": false, "description": "The text content of the Tooltip." }, + "actionHeader": { + "type": "never", + "defaultValue": null, + "required": false, + "externalProp": false + }, "animated": { "type": "number | boolean", "defaultValue": null, @@ -35,6 +41,12 @@ "externalProp": true, "description": "Offset between the reference and the popover on the main axis. Should not be combined with `unstable_offset`." }, + "keyCombinationsActions": { + "type": "never", + "defaultValue": null, + "required": false, + "externalProp": false + }, "placement": { "type": "Placement", "defaultValue": null, @@ -91,6 +103,111 @@ "description": "Whether it's visible or not." } }, + "KeyboardKeyTooltip": { + "keyCombinationsActions": { + "type": "KeyboardActions[]", + "defaultValue": null, + "required": true, + "externalProp": false, + "description": "The mapping of action names to their respective key combinations." + }, + "actionHeader": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": false, + "description": "The header content of the Tooltip." + }, + "animated": { + "type": "number | boolean", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "If `true`, `animating` will be set to `true` when `visible` is updated.\nIt'll wait for `stopAnimation` to be called or a CSS transition ends.\nIf `animated` is set to a `number`, `stopAnimation` will be called only\nafter the same number of milliseconds have passed." + }, + "baseId": { + "type": "string", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "ID that will serve as a base for all the items IDs." + }, + "element": { + "type": "string", + "defaultValue": "TOOLTIP", + "required": false, + "externalProp": false, + "description": "Overrides the default element name to apply unique styles with the Customization Provider." + }, + "gutter": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Offset between the reference and the popover on the main axis. Should not be combined with `unstable_offset`." + }, + "placement": { + "type": "Placement", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Actual `placement`." + }, + "state": { + "type": "TooltipStateReturn", + "defaultValue": null, + "required": false, + "externalProp": false, + "description": "The returned state from the `useTooltipState` hook." + }, + "text": { + "type": "never", + "defaultValue": null, + "required": false, + "externalProp": false + }, + "unstable_fixed": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Whether or not the popover should have `position` set to `fixed`." + }, + "unstable_flip": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Flip the popover's placement when it starts to overlap its reference\nelement." + }, + "unstable_offset": { + "type": "[string | number, string | number]", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Offset between the reference and the popover: [main axis, alt axis]. Should not be combined with `gutter`." + }, + "unstable_preventOverflow": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Prevents popover from being positioned outside the boundary." + }, + "unstable_timeout": { + "type": "number", + "defaultValue": null, + "required": false, + "externalProp": true + }, + "visible": { + "type": "boolean", + "defaultValue": null, + "required": false, + "externalProp": true, + "description": "Whether it's visible or not." + } + }, "UseTooltipInitialState": { "animated": { "type": "number | boolean", From 4f693d2c3cc087e4ed3c1e6eb80e5efd7fae73a5 Mon Sep 17 00:00:00 2001 From: Kristian Antrobus Date: Thu, 14 Nov 2024 09:49:53 -0600 Subject: [PATCH 37/49] chore(tooltip): better var naming --- .../paste-core/components/tooltip/src/Tooltip.tsx | 4 ++-- .../tooltip/stories/keyboard-key.stories.tsx | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/paste-core/components/tooltip/src/Tooltip.tsx b/packages/paste-core/components/tooltip/src/Tooltip.tsx index c136f5ca7e..9225e4b43e 100644 --- a/packages/paste-core/components/tooltip/src/Tooltip.tsx +++ b/packages/paste-core/components/tooltip/src/Tooltip.tsx @@ -68,7 +68,7 @@ export interface TooltipProps extends TooltipPrimitiveInitialState { interface KeyboardActions { name: string; - keyCombination: string[]; + eventKeyCombination: string[]; disabled?: boolean; } @@ -150,7 +150,7 @@ const Tooltip = React.forwardRef( element={`${element}_ACTION_KEY_GROUP`} disabled={action.disabled} > - {action.keyCombination.map((key) => ( + {action.eventKeyCombination.map((key) => ( {key} ))} diff --git a/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx b/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx index 9431349d8b..62fcc6b822 100644 --- a/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx +++ b/packages/paste-core/components/tooltip/stories/keyboard-key.stories.tsx @@ -28,8 +28,8 @@ export const Default = (): React.ReactNode => { visible actionHeader="Search shortcuts" keyCombinationsActions={[ - { name: "Mac", keyCombination: ["Command", "K"] }, - { name: "Windows", keyCombination: ["Control", "K"] }, + { name: "Mac", eventKeyCombination: ["Command", "K"] }, + { name: "Windows", eventKeyCombination: ["Control", "K"] }, ]} >