diff --git a/.changeset/clever-wolves-move.md b/.changeset/clever-wolves-move.md new file mode 100644 index 00000000000..3b9fb7a92a9 --- /dev/null +++ b/.changeset/clever-wolves-move.md @@ -0,0 +1,8 @@ +--- +'@primer/react': major +--- + +Remove components from deprecated +- `BorderBox`, `ChoiceFieldset`, `Flex`, `Grid`, `Position`, `Dropdown`, `FormGroup`, `SelectMenu`, `InputField`, `Label`, `Button`, `DropdownButton`, `DropdownMenu` +- Update deprecated `Button` usage in `Dialog` and `ConfirmationDialog` +- Update deprecated `DropdownButton` usage in `SelectPanel` diff --git a/docs/content/deprecated/ActionList.mdx b/docs/content/deprecated/ActionList.mdx index 13bfce59100..c34c097202c 100644 --- a/docs/content/deprecated/ActionList.mdx +++ b/docs/content/deprecated/ActionList.mdx @@ -4,7 +4,7 @@ status: Deprecated source: https://github.com/primer/react/tree/main/src/deprecated/ActionList --- -An `ActionList` is a list of items which can be activated or selected. `ActionList` is the base component for many of our menu-type components, including `DropdownMenu` and `ActionMenu`. +An `ActionList` is a list of items which can be activated or selected. `ActionList` is the base component for many of our menu-type components, including `ActionMenu`. ## Deprecation diff --git a/docs/content/deprecated/BorderBox.md b/docs/content/deprecated/BorderBox.md deleted file mode 100644 index 151a410d746..00000000000 --- a/docs/content/deprecated/BorderBox.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: BorderBox -status: Deprecated ---- - -BorderBox is a Box component with a border. When no `borderColor` is present, the component defaults to a primary border. - -## Deprecation - -Use [Box](/Box) instead. - -### Before - -```jsx deprecated -Item 1 -``` - -### After - -```jsx deprecated - - Item 1 - -``` - -## Default example - -```jsx live deprecated -This is a BorderBox -``` - -Note that `BorderBox` has default props set for `borderWidth`, `borderStyle`, and `borderColor`. This means that you cannot use `border={0} borderBottom={1}` or similar patterns; instead, use individual properties like `borderWidth={0} borderBottomWidth={1}`. - -## System props - -BorderBox components get `COMMON`, `LAYOUT`, `BORDER`, and `FLEX` system props. Read our [System Props](/system-props) doc page for a full list of available props. - -## Component props - -| Prop name | Type | Default | Description | -| :----------- | :--------------- | :---------------------------: | :------------------------------------------------------------ | -| borderWidth | String | '1px' | Sets the border, use theme values or provide your own. | -| borderStyle | String | 'solid' | Sets the border style, use theme values or provide your own. | -| borderColor | String | 'border.primary' (from theme) | Sets the border color, use theme values or provide your own. | -| borderRadius | String or Number | 2 (from theme) | Sets the border radius, use theme values or provide your own. | -| boxShadow | String | | Sets box shadow, use theme values or provide your own. | diff --git a/docs/content/deprecated/Buttons.mdx b/docs/content/deprecated/Buttons.mdx deleted file mode 100644 index 3da951cec97..00000000000 --- a/docs/content/deprecated/Buttons.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Button (legacy) -status: Deprecated -source: https://github.com/primer/react/blob/main/src/Button -storybook: '/react/storybook?path=/story/components-button--default-button' ---- - -## Deprecation - -Use [Button](/Button) instead. - -`Button` is used for actions, like in forms, while `Link` is used for destinations, or moving from one page to another. - -In special cases where you'd like to use a `` styled like a Button, use `` and provide an `href`. - -To create a button group, wrap `Button` elements in the `ButtonGroup` element. `ButtonGroup` gets the same props as `Box`. - -## Examples - -### Kitchen sink - -```jsx live deprecated -<> - Button - Button danger - Button outline - Button primary - Button invisible - window.alert('button clicked')} /> - - - Button - Button - Button - - - Button table list -> -``` - -## Props - -Native `` HTML attributes are forwarded to the underlying React `button` component and are not listed below. - - - - - - - -## Status - - diff --git a/docs/content/deprecated/ChoiceFieldset.mdx b/docs/content/deprecated/ChoiceFieldset.mdx deleted file mode 100644 index fddae43210a..00000000000 --- a/docs/content/deprecated/ChoiceFieldset.mdx +++ /dev/null @@ -1,405 +0,0 @@ ---- -title: ChoiceFieldset -status: Deprecated -source: https://github.com/primer/react/blob/main/src/ChoiceFieldset/ChoiceFieldset.tsx -storybook: '/react/storybook/?path=/story/forms-choicefieldset--radio-group' ---- - -import {ChoiceFieldset, Box} from '@primer/components' -import {CheckIcon, XIcon, AlertIcon} from '@primer/octicons-react' - -A `ChoiceFieldset` is a controlled component that is used to render a related set of checkbox or radio inputs. - -## Deprecation - -Use [CheckboxGroup](/CheckboxGroup) or [RadioGroup](/RadioGroup) instead. - -## Examples - -### Basic - -```jsx live deprecated - - Color mode - - Dark - High-contrast dark - Light - High-contrast light - - -``` - -### Using an onSelect handler - -```javascript live noinline deprecated -const WithOnSelectHandler = () => { - const [selectedChoices, setSelectedChoices] = React.useState([]) - const choices = [ - { - value: 'figma', - displayName: 'Figma library', - description: 'The Figma file where we have Figma symbols and light documentation', - }, - { - value: 'css', - displayName: 'Primer CSS', - description: 'The OG. A CSS library with utility styles and component styles', - }, - { - value: 'react', - displayName: 'Primer React components', - description: 'The React component library that these docs belong to', - }, - { - value: 'viewcomponents', - displayName: 'Primer ViewComponents', - description: 'The Rails and Web Components implementation of our components', - }, - ] - - return ( - <> - { - setSelectedChoices(selectedValues) - }} - selected={selectedChoices} - > - Prefered Primer component interface - - Your choice won't be used for anything, this is just a React example - - - {choices.map(choice => ( - - {choice.displayName} - {choice.description} - - ))} - - - {selectedChoices.length ? ( - - {choices.find(choice => choice.value === selectedChoices[0]).displayName} is your favorite? Ours too. - - ) : null} - > - ) -} - -render() -``` - -### Checkbox group - -```jsx live deprecated - - Prefered Primer component interface - - - Figma library - Primer CSS - Primer React components - Primer ViewComponents - - -``` - -### Disabled - -```jsx live deprecated - - Color mode - - Dark - High-contrast dark - Light - High-contrast light - - -``` - -### Required - -```jsx live deprecated - - Color mode - - Dark - High-contrast dark - Light - High-contrast light - - -``` - -### With pre-selected choices - -```jsx live deprecated - - Prefered Primer component interface - - - Figma library - Primer CSS - Primer React components - Primer ViewComponents - - -``` - -### With validation - -```javascript live noinline deprecated -const choices = [ - { - value: 'figma', - displayName: 'Figma library', - description: 'The Figma file where we have Figma symbols and light documentation', - }, - { - value: 'css', - displayName: 'Primer CSS', - description: 'The OG. A CSS library with utility styles and component styles', - }, - { - value: 'react', - displayName: 'Primer React components', - description: 'The React component library that these docs belong to', - }, - { - value: 'viewcomponents', - displayName: 'Primer ViewComponents', - description: 'The Rails and Web Components implementation of our components', - }, -] - -const ChoiceFieldsetWithValidation = () => { - const [selectedChoices, setSelectedChoices] = React.useState([]) - const [validationResult, setValidationResult] = React.useState() - - React.useEffect(() => { - if (selectedChoices.length && selectedChoices.length > 2) { - setValidationResult('tooManySelections') - } else { - setValidationResult(undefined) - } - }, [selectedChoices]) - - return ( - { - setSelectedChoices(selectedValues) - }} - validationMap={{tooManySelections: 'error'}} - validationResult={validationResult} - selected={selectedChoices} - > - Prefered Primer component interface - Pick your top two - - - {choices.map(choice => ( - - {choice.displayName} - {choice.description} - - ))} - - - - Only two selections are allowed - - - ) -} - -render() -``` - -### A visually hidden legend - -```jsx live deprecated - - Color mode - - Dark - High-contrast dark - Light - High-contrast light - - -``` - -### With a ChoiceFieldset.Description - -```jsx live deprecated - - Notification preferences - - Your selection will affect notifications sent to your email and mobile device - - - - - - - - All notifications - Every possible notification - - - - - - Relevant notifications - Only the ones you'll care about - - - - - - No notifications - Notifications won't be sent - - - -``` - -### With one disabled item - -```jsx live deprecated - - Color mode - - - Dark - - High-contrast dark - Light - High-contrast light - - -``` - -### Items with a caption and a leading visual - -```jsx live deprecated - - Notification preferences - - - - - - - All notifications - Every possible notification - - - - - - Relevant notifications - Only the ones you'll care about - - - - - - No notifications - Notifications won't be sent - - - -``` - -## Props - -### ChoiceFieldset - -| Name | Type | Default | Description | -| :--------------- | :-------------------------------------------------------------------------------------------------------- | :-----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| children\* | `ChoiceFieldset.Legend`, `ChoiceFieldset.Description`, `ChoiceFieldset.List`, `ChoiceFieldset.Validation` | – | The list of choices and contextual information | -| disabled | `boolean` | – | Whether the fieldset is NOT ready for user input | -| id | `string` | – | The unique identifier for this fieldset. Used to associate the validation text with the fieldset If an ID is not passed, one will be automatically generated | -| name | `string` | – | The unique identifier used to associate radio inputs with eachother If a name is not passed and the fieldset renders radio inputs, a name will be automatically generated | -| onSelect | `(selectedValues?: string[]) => void` | – | The callback that is called when a user toggles a choice on or off | -| required | `boolean` | – | Whether this field must have a value for the user to complete their task | -| selected | `string[]` | – | The selected values | -| validationMap | `Record` | – | A map of validation statuses and their associated validation keys. When one of the validation keys is passed to the `validationResult` prop, the associated validation message will be rendered in the correct style | -| validationResult | `keyof validationMap` | – | The key of the validation message to show | - -### ChoiceFieldset.Legend - -A title for the set of choices. A `ChoiceFieldset.Legend` must be passed, but it may be visually hidden. - -| Name | Type | Default | Description | -| :------------- | :-------- | :-----: | :------------------------------------------- | -| visuallyHidden | `boolean` | – | Whether to visually hide the fieldset legend | - -### ChoiceFieldset.List - -The list choices are rendered in. - -| Name | Type | Default | Description | -| :--------------- | :--------------------- | :-----: | :------------------------------------------------------ | -| children\* | `ChoiceFieldset.Item` | – | The choices that render as a checkbox or radio field | -| selectionVariant | `'single'\|'multiple'` | – | Whether multiple items or a single item can be selected | - -### ChoiceFieldset.Item - -Renders a choice to the list as a checkbox or radio field. - -| Name | Type | Default | Description | -| :--------- | :-------------------------------------------------------------------------------------------------- | :-----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| children\* | `ChoiceFieldset.Caption`, `ChoiceFieldset.Label`, `ChoiceFieldset.LeadingVisual`, `React.ReactNode` | – | The parts that make up the checkbox or radio field used to select the choice. If you **only** need a label, it's fine to pass in a string or JSX instead of wrapping it in the `Item.Label` component | -| value\* | `string` | – | The value that is being selected | -| disabled | `boolean` | – | Whether the field is ready for user input | -| id | `string` | – | The unique identifier for this field. Used to associate the label, validation text, and caption text. If an ID is not provided, one will be automatically generated. | - -### ChoiceFieldset.Description - -A `ChoiceFieldset.Description` may be used to render hint text if this list needs additional context to guide a user to make their selection - -| Name | Type | Default | Description | -| :--------- | :---------------- | :-----: | :---------------------- | -| children\* | `React.ReactNode` | – | The description content | - -### ChoiceFieldset.Validation - -If the user's selection has been flagged during validation, `ChoiceFieldset.Validation` may be used to render contextual validation information to help the user complete their task - -| Name | Type | Default | Description | -| :-------------- | :---------------- | :-----: | :--------------------------------------------------------------------------------------------------------------------------------- | -| children\* | `React.ReactNode` | – | The validation message | -| validationKey\* | `string` | – | When this matches the `validationResult` prop on the parent `ChoiceFieldset` component, this validation component will be rendered | - -## Status - - - -## Related components - -- [ChoiceInputField](/ChoiceInputField) -- [Checkbox](/Checkbox) -- [Radio](/Radio) diff --git a/docs/content/deprecated/ChoiceInputField.mdx b/docs/content/deprecated/ChoiceInputField.mdx deleted file mode 100644 index fc9cef58607..00000000000 --- a/docs/content/deprecated/ChoiceInputField.mdx +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: ChoiceInputField -status: Deprecated -description: The ChoiceInputField component is used to render a labelled checkbox or radio inputs with optional hint text. -source: https://github.com/primer/react/blob/main/src/ChoiceInputField.tsx -storybook: '/react/storybook?path=/story/forms-choiceinputfield--checkbox-input-field' ---- - -import {Checkbox, Radio} from '@primer/react' -import {MarkGithubIcon} from '@primer/octicons-react' - -## Deprecation - -Use [FormControl](/FormControl) instead. - -## Examples - -### Checkbox - -```jsx live deprecated - - Option one - - -``` - -### Radio - -```jsx live deprecated - - - Option one - - - - Option two - - - -``` - -### Disabled field - -```jsx live deprecated - - Option one - - -``` - -### With a caption - -```jsx live deprecated - - Option One - - Hint: the first and only option - -``` - -### With a LeadingVisual - -```jsx live deprecated -<> - - Option one - - - - - - - - Option two - - - - - This one has a caption - -> -``` - -## Props - -### ChoiceInputField - -The container that handles the layout and passes the relevant IDs and ARIA attributes it's children. - -`ChoiceInputField.Label` and `ChoiceInputField.Input` are required children. - - - - - - - -### ChoiceInputField.Label - -A `ChoiceInputField.Label` must be passed, but it may be visually hidden. - - - - - -### ChoiceInputField.Caption - -If this field needs additional context, a `ChoiceInputField.Caption` may be used to render hint text. - - - - - -### ChoiceInputField.LeadingVisual - -If the selectable option would be easier to understand with a visual, the `ChoiceInputField.LeadingVisual` component may be used. - - - - - -## Status - - diff --git a/docs/content/deprecated/Dropdown.md b/docs/content/deprecated/Dropdown.md deleted file mode 100644 index 54ca06b1953..00000000000 --- a/docs/content/deprecated/Dropdown.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Dropdown -status: Deprecated ---- - -## Deprecation - -Use [ActionMenu](/ActionMenu) instead. - ---- - -The Dropdown component is a lightweight context menu for housing navigation and actions. - -Use `Dropdown.Button` as the trigger for the dropdown, or use a custom `summary` element if you would like. **You must use a `summary` tag in order for the dropdown to behave properly!**. You should also add `aria-haspopup="true"` to custom dropdown triggers for accessibility purposes. You can use the `Dropdown.Caret` component to add a caret to a custom dropdown trigger. - -Dropdown.Menu wraps your menu content. Be sure to pass a `direction` prop to this component to position the menu in relation to the Dropdown.Button. - -## Default example - -```jsx live deprecated - - Dropdown - - Item 1 - Item 2 - Item 3 - - -``` - -## With custom button - -```jsx live deprecated - - - Dropdown - - - - Item 1 - Item 2 - Item 3 - - -``` - -## Component props - -The Dropdown component is extended from the [`Details`](/Details) component and gets all props that the [`Details`](/Details) component gets. - -### Dropdown.Menu - -| Name | Type | Default | Description | -| :-------- | :---------------- | :-----: | :------------------------------------------------------------------------------------ | -| direction | String | 'sw' | Sets the direction of the dropdown menu. Pick from 'ne', 'e', 'se', 's', 'sw', or 'w' | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -### Dropdown.Button - -See https://primer.style/react/Buttons#component-props - -### Dropdown.Caret - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -### Dropdown.Item - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | diff --git a/docs/content/deprecated/DropdownMenu.mdx b/docs/content/deprecated/DropdownMenu.mdx deleted file mode 100644 index bd4ba02bc67..00000000000 --- a/docs/content/deprecated/DropdownMenu.mdx +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: DropdownMenu -status: Deprecated ---- - -A `DropdownMenu` provides an anchor (button by default) that will open a floating menu of selectable items. The menu can be opened and navigated using keyboard or mouse. When an item is selected, the menu will close and the `onChange` callback will be called. If the default anchor button is used, the anchor contents will be updated with the selection. - -## Deprecation - -Use [new version of ActionMenu](/ActionMenu#with-selection) with composable API, design updates and accessibility fixes. - -### Before - -```jsx -const fieldTypes = [ - {key: 0, text: 'Text'}, - {key: 1, text: 'Number'}, - {key: 3, text: 'Date'}, - {key: 4, text: 'Single select'}, - {key: 5, text: 'Iteration'}, -] - -const Example = () => { - const [selectedType, setSelectedType] = React.useState() - - return ( - ( - - {children} - - )} - placeholder="Field type" - items={fieldTypes} - selectedItem={selectedType} - onChange={setSelectedType} - /> - ) -} -``` - -### After - -Instead of `DropdownMenu`, you can use the `ActionMenu` with `ActionList selectionVariant=single`, this will give menu items the correct semantics: - -```jsx -const fieldTypes = [ - {id: 0, text: 'Text'}, - {id: 1, text: 'Number'}, - {id: 3, text: 'Date'}, - {id: 4, text: 'Single select'}, - {id: 5, text: 'Iteration'}, -] - -const Example = () => { - const [selectedType, setSelectedType] = React.useState() - - render( - - {selectedType.name || 'Field type'} - - - {fieldTypes.map(type => ( - setSelectedType(type)} - > - {type.name} - - ))} - - - , - ) -} -``` - -Or continue using deprecated API: - -```js -import {DropdownMenu} from '@primer/react/deprecated' -``` - -## Example - -```javascript live noinline deprecated -function DemoComponent() { - const items = React.useMemo( - () => [ - {text: '🔵 Cyan', id: 5, key: 'cyan'}, - {text: '🔴 Magenta', key: 'magenta'}, - {text: '🟡 Yellow', key: 'yellow'}, - ], - [], - ) - const [selectedItem, setSelectedItem] = React.useState() - - return ( - ( - - {children} - - )} - placeholder="🎨" - items={items} - selectedItem={selectedItem} - onChange={setSelectedItem} - /> - ) -} - -render() -``` - -## Component props - -| Name | Type | Default | Description | -| :------------ | :-------------------------------------------- | :---------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| items | `ItemProps[]` | `undefined` | Required. A list of item objects to display in the menu | -| selectedItem | `ItemInput` | `undefined` | An `ItemProps` item from the list of `items` which is currently selected. This item will receive a checkmark next to it in the menu. | -| onChange? | (item?: ItemInput) => unknown | `undefined` | A callback which receives the selected item or `undefined` when an item is activated in the menu. If the activated item is the same as the current `selectedItem`, `undefined` will be passed. | -| placeholder | `string` | `undefined` | Optional. A placeholder value to display when there is no current selection. | -| renderAnchor | `(props: DropdownButtonProps) => JSX.Element` | `DropdownButton` | Optional. If defined, provided component will be used to render the menu anchor. Will receive the selected `Item` text as `children` prop when an item is activated. | -| renderItem | `(props: ItemProps) => JSX.Element` | `ActionList.Item` | Optional. If defined, each item in `items` will be passed to this function, allowing for custom item rendering. | -| groupMetadata | `GroupProps[]` | `undefined` | Optional. If defined, `DropdownMenu` will group `items` into `ActionList.Group`s separated by `ActionList.Divider` according to their `groupId` property. | diff --git a/docs/content/deprecated/Flex.md b/docs/content/deprecated/Flex.md deleted file mode 100644 index a272f1ad12b..00000000000 --- a/docs/content/deprecated/Flex.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Flex -status: Deprecated ---- - -The `Flex` component behaves the same as the `Box` component except that it has `display: flex` set by default. - -## Deprecation - -Use [Box](/Box) instead. - -### Before - -```jsx deprecated - - - Item 1 - - -``` - -### After - -```jsx deprecated - - - Item 1 - - -``` - -## Default example - -```jsx deprecated live - - - - Item 1 - - - Item 2 - - - Item 3 - - - -``` - -## System props - -Flex components get `FLEX`, `COMMON`, and `LAYOUT` system props. - -Read our [System Props](/system-props) doc page for a full list of available props. - -## Component props - -`Flex` does not get any additional props other than the system props mentioned above. diff --git a/docs/content/deprecated/FormGroup.md b/docs/content/deprecated/FormGroup.md deleted file mode 100644 index cb0a3143274..00000000000 --- a/docs/content/deprecated/FormGroup.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: FormGroup -status: Deprecated ---- - -Adds styles for multiple form elements used together. - -## Deprecation - -Use [FormControl](/FormControl) instead. - -## Default example - -```jsx live deprecated -<> - - Example text - - - - - Example text - - -> -``` - -## Component props - -### FormGroup - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| as | String | `div` | Sets the HTML tag for the component | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -### FormGroup.Label - -| Name | Type | Default | Description | -| :------ | :---------------- | :-----: | :----------------------------------------------------------------------------- | -| as | String | `label` | Sets the HTML tag for the component | -| htmlFor | String | | The value of `htmlFor` needs to be the same as the `id` of the input it labels | -| sx | SystemStyleObject | {} | Style to be applied to the component | diff --git a/docs/content/deprecated/Grid.md b/docs/content/deprecated/Grid.md deleted file mode 100644 index d01036e31c5..00000000000 --- a/docs/content/deprecated/Grid.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: Grid -status: Deprecated ---- - -Grid is a component that exposes grid system props. See the [CSS Tricks Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) to learn more about Grid Layout. - -## Deprecation - -Use [Box](/Box) instead. - -### Before - -```jsx deprecated - - - 1 - - - 2 - - -``` - -### After - -```jsx deprecated - - - 1 - - - 2 - - -``` - -## Default example - -```jsx deprecated live - - - 1 - - - 2 - - -``` - -## System props - -Grid components get `GRID`, `COMMON`, and `LAYOUT` system props. - -Read our [System Props](/system-props) doc page for a full list of available props. - -## Component props - -`Grid` does not get any additional props other than the system props mentioned above. diff --git a/docs/content/deprecated/InputField.mdx b/docs/content/deprecated/InputField.mdx deleted file mode 100644 index 347afe1f3c1..00000000000 --- a/docs/content/deprecated/InputField.mdx +++ /dev/null @@ -1,276 +0,0 @@ ---- -title: InputField -status: Deprecated -description: The InputField component is used to render a labelled text input and, optionally, associated validation text and hint text. -source: https://github.com/primer/react/blob/main/src/InputField/InputField.tsx -storybook: '/react/storybook?path=/story/forms-inputfield--text-input-field' ---- - -import {TextInputWithTokens, Autocomplete, Select} from '@primer/react' - -## Deprecation - -Use [FormControl](/FormControl) instead. - -## Examples - -### Basic - -```jsx live deprecated - - Name - - -``` - -### Required - -```jsx live deprecated - - Name - - -``` - -### Disabled - -```jsx live deprecated - - Name - - -``` - -### Using different input components - -```javascript live noinline deprecated -const TextInputWithTokensExample = () => { - const [tokens, setTokens] = React.useState([ - {text: 'zero', id: 0}, - {text: 'one', id: 1}, - {text: 'two', id: 2}, - ]) - const onTokenRemove = tokenId => { - setTokens(tokens.filter(token => token.id !== tokenId)) - } - - return ( - * + *': { - marginTop: 4, - }, - }} - > - - TextInputWithTokens - - - - Autocomplete - - - - - - - - - Select - - Figma - Primer CSS - Primer React components - Primer ViewComponents - - - - ) -} - -render(TextInputWithTokensExample) -``` - -### With a visually hidden label - - - -Every input must have a corresponding label to be accessible to assistive technology. That's why you'd use `InputField` instead of using [`TextInput`](/TextInput) directly. - -`InputField` also provides an interface for showing a hint text caption and a validation message, and associating those with the input for assistive technology. - - - -```jsx live deprecated - - Name - - -``` - -### With a caption - -```jsx live deprecated - - Name - - Hint: your first name - -``` - -### With validation - -```javascript live noinline deprecated -const ValidationExample = () => { - const [value, setValue] = React.useState('mona lisa') - const [validationResult, setValidationResult] = React.useState() - const doesValueContainSpaces = inputValue => /\s/g.test(inputValue) - const handleInputChange = e => { - setValue(e.currentTarget.value) - } - - React.useEffect(() => { - if (doesValueContainSpaces(value)) { - setValidationResult('noSpaces') - } else if (value) { - setValidationResult('validName') - } - }, [value]) - - return ( - - GitHub handle - - GitHub handles cannot contain spaces - Valid name - With or without "@". For example "monalisa" or "@monalisa" - - ) -} - -render(ValidationExample) -``` - -## Props - -### InputField - -The container that handles the layout and passes the relevant IDs and ARIA attributes it's children. - - - - - - - - - - -### InputField.Label - -A `InputField.Label` must be passed for the field to be accessible to assistive technology, but it may be visually hidden. - - - - - -### InputField.Caption - -`InputField.Caption` may be used to render hint text for fields that require additional context. - - - - - -### InputField.Validation - -`InputField.Validation` may be used to render contextual validation information if the field was flagged during validation. - - - - - - -## Component status - - - -## Related components - -- [ChoiceInputField](/ChoiceInputField) -- [TextInput](/TextInput) diff --git a/docs/content/deprecated/Label.mdx b/docs/content/deprecated/Label.mdx deleted file mode 100644 index 99e3b054a54..00000000000 --- a/docs/content/deprecated/Label.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Label (legacy) -description: Use Label components to add contextual metadata to a design. -status: Deprecated -source: https://github.com/primer/react/blob/main/src/Label.tsx -componentId: legacy_label ---- - -## Deprecation - -Use the new [Label](/Label) instead. - -## Example - -```jsx live deprecated -<> - - small - - - medium (default) - - - large - - xl label - - - - good first issue - - - 🚂 deploy: train - - - css - - - documentation - - - primer - -> -``` - -## Props - - - - - - - - -## Status - - diff --git a/docs/content/deprecated/Position.md b/docs/content/deprecated/Position.md deleted file mode 100644 index 6efa8d557af..00000000000 --- a/docs/content/deprecated/Position.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Position -status: Deprecated ---- - -The Position component is a wrapper component that gives the containing component css positioning abilities. - -## Deprecation - -Use [Box](/Box) instead. - -### Before - -```jsx deprecated -<> - ... - ... - ... - ... - ... -> -``` - -### After - -```jsx deprecated -<> - ... - ... - ... - ... - ... -> -``` - -## Default examples - -```jsx deprecated live - - Relative + Absolute - - - - rt - - - lt - - - rb - - - lb - - - bl - - - br - - - tl - - - tr - - - - - Sticky - - - - I'm sticky! - - - - Fixed - (see the bottom right of the screen) - - - I'm fixed to the bottom right. - - -``` - -## System props - -Position components get `POSITION`, `LAYOUT`, `FLEX`, and `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. - -## Component props - -Position does not get any additional props other than the system props mentioned above. diff --git a/docs/content/deprecated/SelectMenu.md b/docs/content/deprecated/SelectMenu.md deleted file mode 100644 index e1bc0fd38ce..00000000000 --- a/docs/content/deprecated/SelectMenu.md +++ /dev/null @@ -1,374 +0,0 @@ ---- -title: SelectMenu -status: Deprecated ---- - -## Deprecation - -Use [ActionMenu](/ActionMenu) instead. - ---- - -The `SelectMenu` components are a suite of components which can be combined together to make several different variations of our GitHub select menu. At it's most basic form, a select menu is comprised of a `SelectMenu` wrapper, which contains a `summary` component of your choice and a `Select.Modal` which contains the select menu content. Use `SelectMenu.List` to wrap items in the select menu, and `SelectMenu.Item` to wrap each item. - -Several additional components exist to provide even more functionality: `SelectMenu.Header`, `SelectMenu.Filter`, `SelectMenu.Tabs`, `SelectMenu.TabPanel` `SelectMenu.Footer` and `SelectMenu.Divider`. - -## Basic Example - -```jsx deprecated live - - Projects - - Projects - - Primer React bugs - Primer React roadmap - Project 3 - Project 4 - - - -``` - -## SelectMenu - -Main wrapper component for select menu. - -```jsx deprecated -{/* all other sub components are wrapped here*/} -``` - -### Component Props - -| Name | Type | Default | Description | -| :--------- | :---------------- | :-----: | :--------------------------------------------------------------------------------------------------------------------------------------- | -| initialTab | String | | If using the `SelectMenu.Tabs` component, you can use this prop to change the tab shown on open. By default, the first tab will be used. | -| ref | React ref | | ref to pass down to SelectMenu component | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.MenuContext - -SelectMenu.MenuContext is a [context object](https://reactjs.org/docs/context.html#reactcreatecontext) that exposes some helpful state values to be used via [`React.useContext`](https://reactjs.org/docs/hooks-reference.html#usecontext) in consuming applications. SelectMenu.MenuContext can only be used in components that are already wrapped in a `SelectMenu` as `SelectMenu` contains the [context provider](https://reactjs.org/docs/context.html#contextprovider). - -### Values available on MenuContext - -| Name | Type | Description | -| :------------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | -| selectedTab | string | The currently selected tab | -| setSelectedTab | function | Used to update the currently selected tab state | -| open | boolean | State for open/closed status of the menu modal | -| setOpen | function | Used to update the `open` state | -| initialTab | string | Mostly used internally to pass down which tab should be set to open by default. To change this value use the `initialTab` prop on `SelectMenu`. | - -### Example Usage - -```jsx deprecated -import {SelectMenu, Button} from '@primer/react' -import React, {useContext} from 'react' - -const MyMenu = () => ( - - - content - -) - -// note that we can only use the context in components that are already wrapped by SelectMenu (and thus the Context.Provider) -const MyButton = () => { - const menuContext = useContext(SelectMenu.MenuContext) - - return {menuContext.open ? 'Open' : 'Closed'} -} -``` - -## SelectMenu.Modal - -Used to wrap the content in a `SelectMenu`. - -```jsx deprecated -{/* all menu content is wrapped in the modal*/} -``` - -### Right-aligned modal - -Use the `align='right'` prop to align the modal to the right. Note that this only modifies alignment for the modal, and not the SelectMenu itself. You will need to wrap the SelectMenu in a relatively positioned element for this to work properly. - -```jsx deprecated live - - - Projects - - Projects - - Primer React bugs - Primer React roadmap - Project 3 - Project 4 - - - - -``` - -### Component Props - -| Prop name | Type | Default | Description | -| :-------- | :---------------- | :------ | ------------------------------------------------- | -| align | String | 'left' | Use `right` to align the select menu to the right | -| width | String or Number | 300px | Sets the modal width | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.List - -Used to wrap the select menu list content. All menu items **must** be wrapped in a SelectMenu.List in order for the accessibility keyboard handling to function properly. If you are using the `SelectMenu.TabPanel` you do not need to provide a `SelectMenu.List` as that component renders a `SelectMenu.List` as a wrapper. - -```jsx deprecated -{/* all menu list items are wrapped in the list*/} -``` - -### Component Props - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Item - -Individual items in a select menu. SelectMenu.Item renders an anchor tag by default, you'll need to make sure to provide the appropriate `href`. - -You can use a `button` tag instead by utilizing the [`as` prop](/core-concepts#the-as-prop). Be sure to consider [which HTML element is the right choice](https://marcysutton.com/links-vs-buttons-in-modern-web-applications) for your usage of the component. - -```jsx deprecated - - {/* wraps an individual list item*/} - -``` - -### Component Props - -| Name | Type | Default | Description | -| :------- | :---------------- | :-----: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| selected | boolean | | Used to apply styles to the selected items in the list. | -| onClick | function | | Function called when item is clicked. By default we also close the menu when items are clicked. If you would like the menu to stay open, pass an `e.preventDefault()` to your onClick handler. | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Filter - -Use a `SelectMenu.Filter` to add a filter UI to your select menu. Users are expected to implement their own filtering and manage the state of the `value` prop on the input. This gives users more flexibility over the type of filtering and type of content passed into each select menu item. - -```jsx deprecated live - - Projects - - Filter by Project - - - Primer React bugs - Primer React roadmap - More Options - Project 3 - Project 4 - - - -``` - -### Component Props - -SelectMenu.Filter components receive all the props that the [TextInput](/TextInput) component gets. - -| Name | Type | Default | Description | -| :---- | :---------------- | :-----: | :------------------------------------------------------------------------------------------------------------- | -| value | String | | Users of this component must provide a value for the filter input that is managed in the consuming application | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Tabs - -Use `SelectMenu.Tabs` to wrap the tab navigation and `SelectMenu.Tab` for each tab in the navigation. - -`SelectMenu.TabPanel` should wrap each corresponding panel for each of the tabs. The `tabName` prop for each `SelectMenu.TabPanel` must match the name provided in the `tabName` prop on `SelectMenu.Tab`. - -To set one of the tabs to be open by default, use `initialTab` on the main `SelectMenu` component. Otherwise, the first tab will be shown by default. - -Each `Select.Menu` tab will need to have an `index` prop. The first tab should be at index `0`, the second at index `1` and so forth. The `index` prop is used to show the first tab by default. - -If you need access to the selected tab state, you can find it in the MenuContext object exported from `SelectMenu` as `MenuContext.selectedTab`. - -```jsx deprecated live - - Projects - - Projects - - - - - - Primer React bugs - Primer React roadmap - Project 3 - Project 4 - - - Project 2 - - Showing 3 of 3 - - -``` - -### Component Props - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Tab - -Used for each individual tab inside of a `SelectMenu.Tabs`. Be sure to set the `index` prop to correspond to the order the tab is in. The `tabName` prop should correspond to the `tabName` set on the `SelectMenu.TabPanel`. - -The `onClick` prop is optional and can be used for any events or data fetching you might need to trigger on tab clicks. - -```jsx deprecated -<> - - -> -``` - -### Component Props - -| Name | Type | Default | Description | -| :------ | :---------------- | :-----: | :------------------------------------------------------------------------------------------------------------------------- | -| tabName | String | | Used to identify the corresponding tab. Must match the string used in the `tabs` array in the `SelectMenu.Tabs` component. | -| index | Number | | The index at which the tab is in the list of tabs | -| onClick | Function | | Function to be called when the tab is clicked. Optional. | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.TabPanel - -Wraps the content for each tab. Make sure to use the `tabName` prop to identify each tab panel with the correct tab in the tab navigation. - -**Note**: SelectMenu.TabPanel wraps content in a SelectMenu.List, so adding a SelectMenu.List manually is not necessary. - -```jsx deprecated -{/* Wraps content for each tab */} -``` - -### Component Props - -| Name | Type | Default | Description | -| :------ | :---------------- | :-----: | :------------------------------------------------------------------------------------------------------------------------- | -| tabName | String | | Used to identify the corresponding tab. Must match the string used in the `tabs` array in the `SelectMenu.Tabs` component. | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Divider - -Use a `SelectMenu.Divider` to add information between items in a `SelectMenu.List`. - -```jsx deprecated live - - Projects - - Projects - - Primer React bugs - Primer React roadmap - More Options - Project 3 - Project 4 - - - -``` - -### Component Props - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Footer - -Use a `SelectMenu.Footer` to add content to the bottom of the select menu. - -```jsx deprecated live - - Projects - - Projects - - Primer React bugs - Primer React roadmap - Project 3 - Project 4 - Use ⌥ + click/return to exclude labels. - - - -``` - -### Component Props - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.Header - -Use a `SelectMenu.Header` to add a header to the top of the select menu content. - -```jsx deprecated live - - Projects - - Projects - - Primer React bugs - Primer React roadmap - Project 3 - Project 4 - Use ⌥ + click/return to exclude labels. - - - -``` - -### Component Props - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | - -## SelectMenu.LoadingAnimation - -Use a `SelectMenu.LoadingAnimation` to add a loading animation inside of the SelectMenu. - -**Note**: You will need to handle showing/hiding the appropriate modal content for your application during the loading state. We recommend always showing the `SelectMenu.Filter` and `SelectMenu.Header` (if used) and hiding the rest of the modal content during the loading state. - -```jsx deprecated live - - Projects - - Projects - - {true ? ( - - ) : ( - - Primer React bugs - Primer React roadmap - Project 3 - Project 4 - Use ⌥ + click/return to exclude labels. - - )} - - -``` - -### Component Props - -| Name | Type | Default | Description | -| :--- | :---------------- | :-----: | :----------------------------------- | -| sx | SystemStyleObject | {} | Style to be applied to the component | diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index d6ef3c6b2c8..0cc74a68f49 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -108,7 +108,7 @@ Primer React includes TypeScript support and ships with its own typings. You wil Once installed, you can import components and their prop type interfaces from the `@primer/react` package: ```typescript -import {BorderBox, BorderBoxProps} from '@primer/react' +import {Button, ButtonProps} from '@primer/react' ``` ### Fixing "Duplicate identifier 'FormData'" diff --git a/docs/src/@primer/gatsby-theme-doctocat/nav.yml b/docs/src/@primer/gatsby-theme-doctocat/nav.yml index da1d837ce2b..07826d61189 100644 --- a/docs/src/@primer/gatsby-theme-doctocat/nav.yml +++ b/docs/src/@primer/gatsby-theme-doctocat/nav.yml @@ -178,31 +178,5 @@ url: /deprecated/ActionList - title: ActionMenu (legacy) url: /deprecated/ActionMenu - - title: BorderBox - url: /deprecated/BorderBox - - title: Buttons (legacy) - url: /deprecated/Buttons - - title: ChoiceFieldset - url: /deprecated/ChoiceFieldset - - title: ChoiceInputField - url: /deprecated/ChoiceInputField - - title: Dropdown - url: /deprecated/Dropdown - - title: DropdownMenu - url: /deprecated/DropdownMenu - - title: Flex - url: /deprecated/Flex - - title: FormGroup - url: /deprecated/FormGroup - - title: Grid - url: /deprecated/Grid - - title: InputField - url: /deprecated/InputField - - title: Label - url: /deprecated/Label - - title: Position - url: /deprecated/Position - - title: SelectMenu - url: /deprecated/SelectMenu - title: SideNav url: /deprecated/SideNav diff --git a/src/ActionList/ActionListContainerContext.tsx b/src/ActionList/ActionListContainerContext.tsx index bc57c3a06de..421e6cb96ae 100644 --- a/src/ActionList/ActionListContainerContext.tsx +++ b/src/ActionList/ActionListContainerContext.tsx @@ -6,7 +6,7 @@ import {AriaRole} from '../utils/types' type ContextProps = { container?: string listRole?: AriaRole - selectionVariant?: 'single' | 'multiple' // TODO: Remove after DropdownMenu2 deprecation + selectionVariant?: 'single' | 'multiple' // TODO: Remove after DropdownMenu2 deprecation (DropdownMenu is removed now.) selectionAttribute?: 'aria-selected' | 'aria-checked' listLabelledBy?: string // This can be any function, we don't know anything about the arguments diff --git a/src/ActionList/Item.tsx b/src/ActionList/Item.tsx index 60126e3528a..dbf89a55c62 100644 --- a/src/ActionList/Item.tsx +++ b/src/ActionList/Item.tsx @@ -44,6 +44,7 @@ export const Item = React.forwardRef( /** Infer item role based on the container */ let itemRole: ActionListItemProps['role'] + //TODO: Remove this DropdownMenu is removed if (container === 'ActionMenu' || container === 'DropdownMenu') { if (selectionVariant === 'single') itemRole = 'menuitemradio' else if (selectionVariant === 'multiple') itemRole = 'menuitemcheckbox' diff --git a/src/Details/__tests__/Details.test.tsx b/src/Details/__tests__/Details.test.tsx index dc91cfd704b..58f87efb595 100644 --- a/src/Details/__tests__/Details.test.tsx +++ b/src/Details/__tests__/Details.test.tsx @@ -2,10 +2,10 @@ import {render} from '@testing-library/react' import userEvent from '@testing-library/user-event' import React from 'react' import {Details, useDetails, Box} from '../..' -import {Button, ButtonPrimary} from '../../deprecated' -import {ButtonProps} from '../../deprecated/Button/Button' +import {Button, IconButton} from '../../Button' import {behavesAsComponent, checkExports} from '../../utils/testing' import {axe} from 'jest-axe' +import {XIcon} from '@primer/octicons-react' describe('Details', () => { behavesAsComponent({Component: Details}) @@ -59,7 +59,6 @@ describe('Details', () => { it('Can manipulate state with setOpen', async () => { const user = userEvent.setup() - const CloseButton = (props: ButtonProps) => const Component = () => { const {getDetailsProps, setOpen, open} = useDetails({closeOnOutsideClick: true, defaultOpen: true}) return ( @@ -67,7 +66,7 @@ describe('Details', () => { {open ? 'Open' : 'Closed'} - setOpen(false)}>Close + setOpen(false)} aria-label="Close" icon={XIcon} /> ) } @@ -90,7 +89,7 @@ describe('Details', () => { {open ? 'Open' : 'Closed'} - test + test ) diff --git a/src/Dialog.tsx b/src/Dialog.tsx index 2df90952959..e6f66fdbe4e 100644 --- a/src/Dialog.tsx +++ b/src/Dialog.tsx @@ -1,6 +1,7 @@ import React, {forwardRef, useRef} from 'react' import styled from 'styled-components' -import ButtonClose from './deprecated/Button/ButtonClose' +import {IconButton} from './Button' +import {XIcon} from '@primer/octicons-react' import {get} from './constants' import Box from './Box' import useDialog from './hooks/useDialog' @@ -119,10 +120,12 @@ const Dialog = forwardRef( <> - {children} diff --git a/src/Dialog/ConfirmationDialog.tsx b/src/Dialog/ConfirmationDialog.tsx index 2fa2259849e..2b6e573749e 100644 --- a/src/Dialog/ConfirmationDialog.tsx +++ b/src/Dialog/ConfirmationDialog.tsx @@ -37,7 +37,7 @@ export interface ConfirmationDialogProps { /** * The type of button to use for the confirm button. Default: Button. */ - confirmButtonType?: 'normal' | 'primary' | 'danger' + confirmButtonType?: 'default' | 'primary' | 'danger' } const StyledConfirmationHeader = styled.div` @@ -106,7 +106,7 @@ export const ConfirmationDialog: React.FC` ${sx}; ` -const buttonTypes = { - normal: Button, - primary: ButtonPrimary, - danger: ButtonDanger, -} const Buttons: React.FC> = ({buttons}) => { const autoFocusRef = useProvidedRefOrCreate(buttons.find(button => button.autoFocus)?.ref) let autoFocusCount = 0 @@ -387,17 +382,16 @@ const Buttons: React.FC> return ( <> {buttons.map((dialogButtonProps, index) => { - const {content, buttonType = 'normal', autoFocus = false, ...buttonProps} = dialogButtonProps - const ButtonElement = buttonTypes[buttonType] + const {children, buttonType = 'default', autoFocus = false, ...buttonProps} = dialogButtonProps return ( - - {content} - + {children} + ) })} > diff --git a/src/Overlay/Overlay.test.tsx b/src/Overlay/Overlay.test.tsx index 2808aeb0f9e..32158f690f1 100644 --- a/src/Overlay/Overlay.test.tsx +++ b/src/Overlay/Overlay.test.tsx @@ -1,6 +1,6 @@ import React, {useRef, useState} from 'react' import {Overlay, Box, Text} from '..' -import {ButtonDanger, Button} from '../deprecated' +import {Button} from '../Button' import {render, waitFor, fireEvent} from '@testing-library/react' import userEvent from '@testing-library/user-event' import {axe} from 'jest-axe' @@ -43,7 +43,9 @@ const TestComponent = ({initialFocus, callback}: TestComponentSettings) => { > Are you sure? - Cancel + + Cancel + Confirm diff --git a/src/SelectPanel/SelectPanel.tsx b/src/SelectPanel/SelectPanel.tsx index b0d53fc760c..4b3ea84c31a 100644 --- a/src/SelectPanel/SelectPanel.tsx +++ b/src/SelectPanel/SelectPanel.tsx @@ -3,7 +3,8 @@ import {FilteredActionList, FilteredActionListProps} from '../FilteredActionList import {OverlayProps} from '../Overlay' import {ItemInput} from '../deprecated/ActionList/List' import {FocusZoneHookSettings} from '../hooks/useFocusZone' -import {DropdownButton} from '../deprecated/DropdownMenu' +import {Button} from '../Button' +import {TriangleDownIcon} from '@primer/octicons-react' import {ItemProps} from '../deprecated/ActionList' import {AnchoredOverlay, AnchoredOverlayProps} from '../AnchoredOverlay' import {TextInputProps} from '../TextInput' @@ -50,7 +51,14 @@ const focusZoneSettings: Partial = { export function SelectPanel({ open, onOpenChange, - renderAnchor = props => , + renderAnchor = props => { + const {children, ...rest} = props + return ( + + {children} + + ) + }, anchorRef: externalAnchorRef, placeholder, selected, diff --git a/src/TextInput/TextInput.tsx b/src/TextInput/TextInput.tsx index eb715d4dc5f..96e72776878 100644 --- a/src/TextInput/TextInput.tsx +++ b/src/TextInput/TextInput.tsx @@ -50,7 +50,7 @@ export type TextInputNonPassthroughProps = { export type TextInputProps = Merge, TextInputNonPassthroughProps> -// using forwardRef is important so that other components (ex. SelectMenu) can autofocus the input +// using forwardRef is important so that other components can autofocus the input const TextInput = React.forwardRef( ( { diff --git a/src/__tests__/AnchoredOverlay.test.tsx b/src/__tests__/AnchoredOverlay.test.tsx index fa005064c40..4905ffd7c45 100644 --- a/src/__tests__/AnchoredOverlay.test.tsx +++ b/src/__tests__/AnchoredOverlay.test.tsx @@ -4,7 +4,7 @@ import {behavesAsComponent, checkExports} from '../utils/testing' import {render as HTMLRender, fireEvent} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' import {SSRProvider} from '../index' -import {Button} from '../deprecated' +import {Button} from '../Button' import theme from '../theme' import BaseStyles from '../BaseStyles' import {ThemeProvider} from '../ThemeProvider' diff --git a/src/__tests__/BorderBox.test.tsx b/src/__tests__/BorderBox.test.tsx deleted file mode 100644 index 01909c4da22..00000000000 --- a/src/__tests__/BorderBox.test.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react' -import theme from '../theme' -import {BorderBox} from '../deprecated' -import {render, behavesAsComponent, checkExports} from '../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('BorderBox', () => { - behavesAsComponent({Component: BorderBox}) - - checkExports('deprecated/BorderBox', { - default: BorderBox, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('renders borders', () => { - expect(render()).toHaveStyleRule( - 'border-color', - theme.colorSchemes.light.colors.success?.emphasis, - ) - expect(render()).toHaveStyleRule('border-bottom', '0') - }) - - it('renders border radius', () => { - expect(render()).toHaveStyleRule('border-radius', theme.radii[2]) - }) - - // the test returns the box shadow value without spaces, so had to manually provide the expected string here - it('renders box shadow', () => { - expect(render()).toHaveStyleRule( - 'box-shadow', - theme.colorSchemes.light.shadows.shadow?.small, - ) - }) -}) diff --git a/src/__tests__/ConfirmationDialog.test.tsx b/src/__tests__/ConfirmationDialog.test.tsx index 32e604d21a6..be2c670f6dd 100644 --- a/src/__tests__/ConfirmationDialog.test.tsx +++ b/src/__tests__/ConfirmationDialog.test.tsx @@ -5,7 +5,7 @@ import React, {useCallback, useRef, useState} from 'react' import {ActionMenu} from '../deprecated/ActionMenu' import BaseStyles from '../BaseStyles' import Box from '../Box' -import Button from '../deprecated/Button/Button' +import {Button} from '../Button' import {ConfirmationDialog, useConfirm} from '../Dialog/ConfirmationDialog' import theme from '../theme' import {ThemeProvider} from '../ThemeProvider' diff --git a/src/__tests__/Dialog.test.tsx b/src/__tests__/Dialog.test.tsx index 5d4e51078f6..9fd294899e4 100644 --- a/src/__tests__/Dialog.test.tsx +++ b/src/__tests__/Dialog.test.tsx @@ -1,6 +1,6 @@ import React, {useState, useRef} from 'react' import {Dialog, Box, Text} from '..' -import {Button} from '../deprecated' +import {Button} from '../Button' import {render as HTMLRender, fireEvent} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' import {behavesAsComponent, checkExports} from '../utils/testing' diff --git a/src/__tests__/Dropdown.test.tsx b/src/__tests__/Dropdown.test.tsx deleted file mode 100644 index 08af8c9fa43..00000000000 --- a/src/__tests__/Dropdown.test.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react' -import {Dropdown} from '../deprecated' -import {behavesAsComponent, checkExports} from '../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('Dropdown', () => { - behavesAsComponent({Component: Dropdown, toRender: () => Hello!}) - - checkExports('deprecated/Dropdown', { - default: Dropdown, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) -}) - -describe('Dropdown.Item', () => { - behavesAsComponent({ - Component: Dropdown.Item, - toRender: () => Hello!, - }) -}) - -describe('Dropdown.Button', () => { - behavesAsComponent({ - Component: Dropdown.Button, - toRender: () => Hello!, - }) -}) - -describe('Dropdown.Caret', () => { - behavesAsComponent({Component: Dropdown.Caret}) -}) - -describe('Dropdown.Menu', () => { - behavesAsComponent({ - Component: Dropdown.Menu, - toRender: () => ( - - 1 - 2 - 3 - - ), - }) -}) diff --git a/src/__tests__/Dropdown.types.test.tsx b/src/__tests__/Dropdown.types.test.tsx deleted file mode 100644 index 06402f96573..00000000000 --- a/src/__tests__/Dropdown.types.test.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react' -import Dropdown from '../deprecated/Dropdown' - -export function shouldAcceptCallWithNoProps() { - return -} - -export function shouldNotAcceptSystemProps() { - return ( - <> - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - > - ) -} diff --git a/src/__tests__/Flex.test.tsx b/src/__tests__/Flex.test.tsx deleted file mode 100644 index 750eeb44c89..00000000000 --- a/src/__tests__/Flex.test.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react' -import {Flex} from '../deprecated' -import {render, behavesAsComponent, checkExports} from '../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('Flex', () => { - behavesAsComponent({Component: Flex}) - - checkExports('deprecated/Flex', { - default: Flex, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('gets display: flex by default', () => { - expect(render()).toHaveStyleRule('display', 'flex') - }) - - it('respects flexWrap', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects flexDirection', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects justifyContent', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects alignItems', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects alignContent', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects display', () => { - expect(render()).toHaveStyleRule('display', 'inline-flex') - }) - - it('respects responsive display', () => { - expect(render()).toMatchSnapshot() - }) - - it('renders a div by default', () => { - expect(render().type).toEqual('div') - }) -}) diff --git a/src/__tests__/FormGroup.types.test.tsx b/src/__tests__/FormGroup.types.test.tsx deleted file mode 100644 index c35f16d3bd1..00000000000 --- a/src/__tests__/FormGroup.types.test.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import FormGroup from '../deprecated/FormGroup' - -export function shouldAcceptCallWithNoProps() { - return -} - -export function shouldNotAcceptSystemProps() { - // @ts-expect-error system props should not be accepted - return -} diff --git a/src/__tests__/Grid.test.tsx b/src/__tests__/Grid.test.tsx deleted file mode 100644 index aa227cef5d5..00000000000 --- a/src/__tests__/Grid.test.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react' -import {Grid} from '../deprecated' -import {render, behavesAsComponent, checkExports} from '../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('Grid', () => { - behavesAsComponent({Component: Grid}) - - checkExports('deprecated/Grid', { - default: Grid, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('gets display: grid by default', () => { - expect(render()).toHaveStyleRule('display', 'grid') - }) - - it('respects gridGap', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridColumnGap', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridRowGap', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridColumn', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridRow', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridArea', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridAutoFlow', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridAutoRows', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridAutoColumns', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridTemplateColumns', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridTemplateRows', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects gridTemplateAreas', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects responsive display', () => { - expect(render()).toMatchSnapshot() - }) - - it('renders a div by default', () => { - expect(render().type).toEqual('div') - }) -}) diff --git a/src/__tests__/Position.test.tsx b/src/__tests__/Position.test.tsx deleted file mode 100644 index 304f0a45170..00000000000 --- a/src/__tests__/Position.test.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from 'react' -import {Box} from '..' -import {Position, Absolute, Fixed, Relative, Sticky} from '../deprecated' -import {render, behavesAsComponent, checkExports} from '../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('position components', () => { - describe('Absolute', () => { - behavesAsComponent({Component: Absolute}) - - checkExports('deprecated/Position', { - default: Position, - Absolute, - Fixed, - Relative, - Sticky, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('sets position: absolute', () => { - expect(render()).toHaveStyleRule('position', 'absolute') - }) - - it('can render other components with the as prop', () => { - const result = render( - , - ) - expect(result).toHaveStyleRule('position', 'absolute') - expect(result).toHaveStyleRule('border-width', '1px') - expect(result).toHaveStyleRule('border-style', 'solid') - }) - }) - - describe('Fixed', () => { - behavesAsComponent({Component: Fixed}) - - it('respects the "as" prop', () => { - expect(render().type).toEqual('span') - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('sets position: fixed', () => { - expect(render()).toHaveStyleRule('position', 'fixed') - }) - - it('can render other components with the as prop', () => { - const result = render( - , - ) - expect(result).toHaveStyleRule('position', 'fixed') - expect(result).toHaveStyleRule('border-width', '1px') - expect(result).toHaveStyleRule('border-style', 'solid') - }) - }) - - describe('Relative', () => { - behavesAsComponent({Component: Relative}) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('sets position: relative', () => { - expect(render()).toHaveStyleRule('position', 'relative') - }) - - it('can render other components with the as prop', () => { - const result = render( - , - ) - expect(result).toHaveStyleRule('position', 'relative') - expect(result).toHaveStyleRule('border-width', '1px') - expect(result).toHaveStyleRule('border-style', 'solid') - }) - }) - - describe('Sticky', () => { - behavesAsComponent({Component: Sticky}) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('sets position: sticky', () => { - expect(render()).toHaveStyleRule('position', 'sticky') - }) - - it('can render other components with the as prop', () => { - const result = render( - , - ) - expect(result).toHaveStyleRule('position', 'sticky') - expect(result).toHaveStyleRule('border-width', '1px') - expect(result).toHaveStyleRule('border-style', 'solid') - }) - }) -}) diff --git a/src/__tests__/SelectMenu.test.tsx b/src/__tests__/SelectMenu.test.tsx deleted file mode 100644 index a6fd21bdd48..00000000000 --- a/src/__tests__/SelectMenu.test.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import {render as HTMLRender} from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import React from 'react' -import {SelectMenu, Button} from '../deprecated' -import {render, renderRoot, COMPONENT_DISPLAY_NAME_REGEX, checkExports} from '../utils/testing' -import {axe} from 'jest-axe' -import {SelectMenuModalProps, SelectMenuItemProps, SelectMenuTabProps} from '../deprecated/SelectMenu' - -const BasicSelectMenu = ({ - onClick, - as, - align = 'left', -}: { - onClick?: SelectMenuItemProps['onClick'] - // eslint-disable-next-line @typescript-eslint/no-explicit-any - as?: any - align?: SelectMenuModalProps['align'] -}) => { - return ( - - Projects - - - - Primer Components bugs - - - Primer Components roadmap - - stuff - Project 3 - Project 4 - footer - - - - ) -} - -const MenuWithTabs = ({onClick}: {onClick?: SelectMenuTabProps['onClick']}) => { - return ( - - Projects - - - - - - - Primer Components bugs - Primer Components roadmap - Project 3 - Project 4 - - - Project 2 - - Showing 3 of 3 - - - ) -} - -describe('SelectMenu', () => { - checkExports('deprecated/SelectMenu', { - default: SelectMenu, - }) - - for (const Comp of [ - SelectMenu.List, - SelectMenu.Divider, - SelectMenu.Filter, - SelectMenu.Item, - SelectMenu.List, - SelectMenu.Modal, - SelectMenu.Tabs, - SelectMenu.Tab, - SelectMenu.TabPanel, - SelectMenu.Header, - ]) { - it('sets a valid displayName', () => { - expect(Comp.displayName).toMatch(COMPONENT_DISPLAY_NAME_REGEX) - }) - } - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('does not allow the "as" prop on SelectMenu', () => { - const {container} = HTMLRender() - expect(container.firstElementChild?.tagName).toBe('DETAILS') - }) - - it('shows correct initial tab', () => { - const testInstance = renderRoot() - // `findByProps` is a method on the renderer, not testing-library - // eslint-disable-next-line testing-library/await-async-query - expect(testInstance.findByProps({'aria-selected': true}).props.children).toBe('Organization') - }) - - it('clicking on a tab opens the tab', async () => { - const user = userEvent.setup() - const {getByRole} = HTMLRender() - - await user.click(getByRole('tab', {name: 'Repository'})) - - expect(getByRole('tab', {name: 'Repository'})).toHaveAttribute('aria-selected', 'true') - }) - - it('selected items have aria-checked', () => { - const testInstance = renderRoot() - // `findByProps` is a method on the renderer, not testing-library - // eslint-disable-next-line testing-library/await-async-query - expect(testInstance.findByProps({'aria-checked': true}).props.children[1]).toBe('Primer Components bugs') - }) - - it('clicking on a list item calls user provided onClick handler', async () => { - const user = userEvent.setup() - const onClick = jest.fn() - const {getByRole} = HTMLRender() - - await user.click(getByRole('menuitemcheckbox', {name: 'Primer Components roadmap'})) - - expect(onClick).toHaveBeenCalledTimes(1) - }) - - it('clicking on a tab calls user provided onClick handler', async () => { - const user = userEvent.setup() - const onClick = jest.fn() - const {getByRole} = HTMLRender() - - await user.click(getByRole('tab', {name: 'Repository'})) - - expect(onClick).toHaveBeenCalledTimes(1) - }) - - it('clicking on an item closes the modal', async () => { - const user = userEvent.setup() - const {container, getByRole} = HTMLRender() - - await user.click(getByRole('menuitemcheckbox', {name: 'Primer Components roadmap'})) - - expect(container.firstElementChild).not.toHaveAttribute('open') - }) - - it('right-aligned modal has right: 0px', () => { - expect(render()).toMatchSnapshot() - }) -}) diff --git a/src/__tests__/SelectMenu.types.test.tsx b/src/__tests__/SelectMenu.types.test.tsx deleted file mode 100644 index 66e57ddef0b..00000000000 --- a/src/__tests__/SelectMenu.types.test.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react' -import SelectMenu from '../deprecated/SelectMenu' - -export function shouldAcceptCallWithNoProps() { - return -} - -export function shouldNotAcceptSystemProps() { - return ( - <> - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - {/* @ts-expect-error system props should not be accepted */} - - > - ) -} diff --git a/src/__tests__/__snapshots__/BorderBox.test.tsx.snap b/src/__tests__/__snapshots__/BorderBox.test.tsx.snap deleted file mode 100644 index 804d86dac97..00000000000 --- a/src/__tests__/__snapshots__/BorderBox.test.tsx.snap +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`BorderBox renders consistently 1`] = ` -.c0 { - border-width: 1px; - border-style: solid; - border-color: #d0d7de; - border-radius: 6px; -} - - -`; diff --git a/src/__tests__/__snapshots__/Button.test.tsx.snap b/src/__tests__/__snapshots__/Button.test.tsx.snap deleted file mode 100644 index 58a254a85f8..00000000000 --- a/src/__tests__/__snapshots__/Button.test.tsx.snap +++ /dev/null @@ -1,1904 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Button renders consistently 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 6px; - border: 1px solid; - border-color: rgba(31,35,40,0.15); - font-family: inherit; - font-weight: 500; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: #24292f; - background-color: #f6f8fa; - box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: #8c959f; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - background-color: #f3f4f6; - border-color: rgba(31,35,40,0.15); -} - -.c0:active:not([disabled]) { - background-color: hsla(220,14%,93%,1); - border-color: rgba(31,35,40,0.15); -} - -.c0[aria-expanded=true] { - background-color: hsla(220,14%,93%,1); - border-color: rgba(31,35,40,0.15); -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - -`; - -exports[`Button respects block prop 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 2; - border: 1px solid; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: btn.text; - background-color: btn.bg; - box-shadow: undefined,undefined; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: primer.fg.disabled; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - background-color: btn.hoverBg; - border-color: btn.hoverBorder; -} - -.c0:active:not([disabled]) { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -.c0[aria-expanded=true] { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Block - - - -`; - -exports[`Button respects the alignContent prop 1`] = ` -.c1 { - -webkit-box-pack: start; - -webkit-justify-content: flex-start; - -ms-flex-pack: start; - justify-content: flex-start; -} - -.c0 { - border-radius: 2; - border: 1px solid; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: btn.text; - background-color: btn.bg; - box-shadow: undefined,undefined; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: primer.fg.disabled; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - background-color: btn.hoverBg; - border-color: btn.hoverBorder; -} - -.c0:active:not([disabled]) { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -.c0[aria-expanded=true] { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Align start - - - -`; - -exports[`Button respects the large size prop 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 2; - border: 1px solid; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: btn.text; - background-color: btn.bg; - box-shadow: undefined,undefined; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: primer.fg.disabled; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - background-color: btn.hoverBg; - border-color: btn.hoverBorder; -} - -.c0:active:not([disabled]) { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -.c0[aria-expanded=true] { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Smol - - - -`; - -exports[`Button respects the small size prop 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 2; - border: 1px solid; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: btn.text; - background-color: btn.bg; - box-shadow: undefined,undefined; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: primer.fg.disabled; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - background-color: btn.hoverBg; - border-color: btn.hoverBorder; -} - -.c0:active:not([disabled]) { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -.c0[aria-expanded=true] { - background-color: btn.activeBg; - border-color: btn.activeBorder; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Smol - - - -`; - -exports[`Button styles danger button appropriately 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 2; - border: 1px solid; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: btn.danger.text; - background-color: btn.bg; - box-shadow: undefined; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: btn.danger.disabledText; - background-color: btn.danger.disabledBg; - border-color: btn.danger.disabledBorder; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; - background-color: btn.danger.disabledCounterBg; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; - color: btn.danger.text; - background-color: btn.danger.counterBg; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - color: btn.danger.hoverText; - background-color: btn.danger.hoverBg; - border-color: btn.danger.hoverBorder; - box-shadow: undefined; -} - -.c0:hover:not([disabled]) [data-component=ButtonCounter] { - background-color: btn.danger.hoverCounterBg; - color: btn.danger.hoverText; -} - -.c0:active:not([disabled]) { - color: btn.danger.selectedText; - background-color: btn.danger.selectedBg; - box-shadow: undefined; - border-color: btn.danger.selectedBorder; -} - -.c0[aria-expanded=true] { - color: btn.danger.selectedText; - background-color: btn.danger.selectedBg; - box-shadow: undefined; - border-color: btn.danger.selectedBorder; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Danger - - - -`; - -exports[`Button styles invisible button appropriately 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 2; - border: 1px solid; - border-color: transparent; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: accent.fg; - background-color: transparent; - box-shadow: none; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: primer.fg.disabled; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; - color: fg.muted; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; - color: fg.muted; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - background-color: btn.hoverBg; -} - -.c0:active:not([disabled]) { - background-color: btn.selectedBg; -} - -.c0[aria-expanded=true] { - background-color: btn.selectedBg; -} - -.c0[data-component="IconButton"][data-no-visuals] { - color: fg.muted; -} - -.c0[data-no-visuals] { - color: accent.fg; -} - -.c0:has([data-component="ButtonCounter"]) { - color: accent.fg; -} - -.c0:disabled[data-no-visuals] { - color: primer.fg.disabled; -} - -.c0:disabled[data-no-visuals] [data-component=ButtonCounter] { - color: inherit; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Invisible - - - -`; - -exports[`Button styles primary button appropriately 1`] = ` -.c1 { - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.c0 { - border-radius: 2; - border: 1px solid; - border-color: btn.primary.border; - font-family: inherit; - font-weight: semibold; - font-size: 14px; - cursor: pointer; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - height: 32px; - padding: 0 12px; - gap: 8px; - min-width: -webkit-max-content; - min-width: -moz-max-content; - min-width: max-content; - -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); - transition: 80ms cubic-bezier(0.65,0,0.35,1); - -webkit-transition-property: color,fill,background-color,border-color; - transition-property: color,fill,background-color,border-color; - color: btn.primary.text; - background-color: btn.primary.bg; - box-shadow: undefined; -} - -.c0:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c0:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: -2px; -} - -.c0[href] { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.c0[href]:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:hover { - -webkit-transition-duration: 80ms; - transition-duration: 80ms; -} - -.c0:active { - -webkit-transition: none; - transition: none; -} - -.c0:disabled { - cursor: not-allowed; - box-shadow: none; - color: btn.primary.disabledText; - background-color: btn.primary.disabledBg; -} - -.c0:disabled [data-component=ButtonCounter] { - color: inherit; -} - -.c0 [data-component=ButtonCounter] { - font-size: 14px; - background-color: btn.primary.counterBg; - color: btn.primary.text; -} - -.c0[data-component=IconButton] { - display: inline-grid; - padding: unset; - place-content: center; - width: 32px; - min-width: unset; -} - -.c0[data-size="small"] { - padding: 0 8px; - height: 28px; - gap: 4px; - font-size: 12px; -} - -.c0[data-size="small"] [data-component="text"] { - line-height: calc(20 / 12); -} - -.c0[data-size="small"] [data-component=ButtonCounter] { - font-size: 12px; -} - -.c0[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 4px; -} - -.c0[data-size="small"][data-component=IconButton] { - width: 28px; - padding: unset; -} - -.c0[data-size="large"] { - padding: 0 16px; - height: 40px; - gap: 8px; -} - -.c0[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0[data-size="large"][data-component=IconButton] { - width: 40px; - padding: unset; -} - -.c0[data-block="block"] { - width: 100%; -} - -.c0 [data-component="leadingVisual"] { - grid-area: leadingVisual; -} - -.c0 [data-component="text"] { - grid-area: text; - line-height: calc(20/14); - white-space: nowrap; -} - -.c0 [data-component="trailingVisual"] { - grid-area: trailingVisual; -} - -.c0 [data-component="trailingAction"] { - margin-right: -4px; -} - -.c0 [data-component="buttonContent"] { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - display: grid; - grid-template-areas: "leadingVisual text trailingVisual"; - grid-template-columns: min-content minmax(0,auto) min-content; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} - -.c0 [data-component="buttonContent"] > :not(:last-child) { - margin-right: 8px; -} - -.c0:hover:not([disabled]) { - color: btn.primary.hoverText; - background-color: btn.primary.hoverBg; -} - -.c0:focus:not([disabled]) { - box-shadow: inset 0 0 0 3px; -} - -.c0:focus-visible:not([disabled]) { - box-shadow: inset 0 0 0 3px; -} - -.c0:active:not([disabled]) { - background-color: btn.primary.selectedBg; - box-shadow: undefined; -} - -.c0[aria-expanded=true] { - background-color: btn.primary.selectedBg; - box-shadow: undefined; -} - -@media (forced-colors:active) { - .c0:focus { - outline: solid 1px transparent; - } -} - - - - - Primary - - - -`; diff --git a/src/__tests__/__snapshots__/Dropdown.test.tsx.snap b/src/__tests__/__snapshots__/Dropdown.test.tsx.snap deleted file mode 100644 index 5fc9fbc3644..00000000000 --- a/src/__tests__/__snapshots__/Dropdown.test.tsx.snap +++ /dev/null @@ -1,247 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Dropdown renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; -} - -.c0 > summary { - list-style: none; -} - -.c0 > summary::-webkit-details-marker { - display: none; -} - - - Hello! - -`; - -exports[`Dropdown.Button renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #24292f; - background-color: #f6f8fa; - border: 1px solid rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - background-color: #f3f4f6; - border-color: rgba(31,35,40,0.15); -} - -.c0:focus { - outline: solid 2px #0969da; -} - -.c0:active { - background-color: hsla(220,14%,94%,1); -} - -.c0:disabled { - color: #8c959f; - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - -.c1 { - border: 4px solid transparent; - margin-left: 12px; - border-top-color: currentcolor; - border-bottom-width: 0; - content: ''; - display: inline-block; - height: 0; - vertical-align: middle; - width: 0; -} - - - Hello! - - -`; - -exports[`Dropdown.Caret renders consistently 1`] = ` -.c0 { - border: 4px solid transparent; - margin-left: 12px; - border-top-color: currentcolor; - border-bottom-width: 0; - content: ''; - display: inline-block; - height: 0; - vertical-align: middle; - width: 0; -} - - -`; - -exports[`Dropdown.Item renders consistently 1`] = ` -.c0 { - display: block; - padding: 4px 10px 4px 15px; - overflow: hidden; - color: #1F2328; - text-overflow: ellipsis; - white-space: nowrap; -} - -.c0 a { - color: #1F2328; - -webkit-text-decoration: none; - text-decoration: none; - display: block; - overflow: hidden; - color: #1F2328; - text-overflow: ellipsis; - white-space: nowrap; -} - -.c0:focus, -.c0 a:focus { - color: #ffffff; - -webkit-text-decoration: none; - text-decoration: none; - background-color: #0969da; -} - -.c0:hover, -.c0:hover a { - color: #ffffff; - -webkit-text-decoration: none; - text-decoration: none; - background-color: #0969da; - outline: none; -} - - - Hello! - -`; - -exports[`Dropdown.Menu renders consistently 1`] = ` -.c0 { - background-clip: padding-box; - background-color: #ffffff; - border: 1px solid #d0d7de; - border-radius: 6px; - box-shadow: 0 8px 24px rgba(140,149,159,0.2); - left: 0; - list-style: none; - margin-top: 2px; - padding: 5px 0 5px 0 !important; - position: absolute; - top: 100%; - width: 160px; - z-index: 100; - right: 0; - left: auto; -} - -.c0::before { - position: absolute; - display: inline-block; - content: ''; -} - -.c0::after { - position: absolute; - display: inline-block; - content: ''; -} - -.c0::before { - border: 8px solid transparent; - border-bottom-color: #ffffff; -} - -.c0::after { - border: 7px solid transparent; - border-bottom-color: #ffffff; -} - -.c0 > ul { - list-style: none; -} - -.c0::before { - top: -16px; - right: 9px; - left: auto; -} - -.c0::after { - top: -14px; - right: 10px; - left: auto; -} - - - - 1 - - - 2 - - - 3 - - -`; diff --git a/src/__tests__/__snapshots__/Flex.test.tsx.snap b/src/__tests__/__snapshots__/Flex.test.tsx.snap deleted file mode 100644 index 1059519e3ac..00000000000 --- a/src/__tests__/__snapshots__/Flex.test.tsx.snap +++ /dev/null @@ -1,130 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Flex renders consistently 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - - -`; - -exports[`Flex respects alignContent 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-content: start; - -ms-flex-line-pack: start; - align-content: start; -} - - -`; - -exports[`Flex respects alignItems 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: start; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: start; -} - - -`; - -exports[`Flex respects flexDirection 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; -} - - -`; - -exports[`Flex respects flexWrap 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-wrap: nowrap; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; -} - - -`; - -exports[`Flex respects justifyContent 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; -} - - -`; - -exports[`Flex respects responsive display 1`] = ` -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -@media screen and (min-width:544px) { - .c0 { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - } -} - - -`; diff --git a/src/__tests__/__snapshots__/Grid.test.tsx.snap b/src/__tests__/__snapshots__/Grid.test.tsx.snap deleted file mode 100644 index dceeb157bc1..00000000000 --- a/src/__tests__/__snapshots__/Grid.test.tsx.snap +++ /dev/null @@ -1,178 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Grid renders consistently 1`] = ` -.c0 { - display: grid; -} - - -`; - -exports[`Grid respects gridArea 1`] = ` -.c0 { - display: grid; - grid-area: sidebar; -} - - -`; - -exports[`Grid respects gridAutoColumns 1`] = ` -.c0 { - display: grid; - grid-auto-columns: 1fr; -} - - -`; - -exports[`Grid respects gridAutoFlow 1`] = ` -.c0 { - display: grid; - grid-auto-flow: row; -} - - -`; - -exports[`Grid respects gridAutoRows 1`] = ` -.c0 { - display: grid; - grid-auto-rows: 1fr; -} - - -`; - -exports[`Grid respects gridColumn 1`] = ` -.c0 { - display: grid; - grid-column: 1 / 2; -} - - -`; - -exports[`Grid respects gridColumnGap 1`] = ` -.c0 { - display: grid; - grid-column-gap: 8px; -} - - -`; - -exports[`Grid respects gridGap 1`] = ` -.c0 { - display: grid; - grid-gap: 4px; -} - - -`; - -exports[`Grid respects gridRow 1`] = ` -.c0 { - display: grid; - grid-row: 1 / 2; -} - - -`; - -exports[`Grid respects gridRowGap 1`] = ` -.c0 { - display: grid; - grid-row-gap: 8px; -} - - -`; - -exports[`Grid respects gridTemplateAreas 1`] = ` -.c0 { - display: grid; - grid-template-areas: sidebar main; -} - - -`; - -exports[`Grid respects gridTemplateColumns 1`] = ` -.c0 { - display: grid; - grid-template-columns: 200px 1fr; -} - - -`; - -exports[`Grid respects gridTemplateRows 1`] = ` -.c0 { - display: grid; - grid-template-rows: 200px 1fr; -} - - -`; - -exports[`Grid respects responsive display 1`] = ` -.c0 { - display: grid; -} - -@media screen and (min-width:544px) { - .c0 { - display: inline-grid; - } -} - - -`; diff --git a/src/__tests__/__snapshots__/Position.test.tsx.snap b/src/__tests__/__snapshots__/Position.test.tsx.snap deleted file mode 100644 index 5bcd50ad24c..00000000000 --- a/src/__tests__/__snapshots__/Position.test.tsx.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`position components Absolute renders consistently 1`] = ` -.c0 { - position: absolute; -} - - -`; - -exports[`position components Fixed renders consistently 1`] = ` -.c0 { - position: fixed; -} - - -`; - -exports[`position components Relative renders consistently 1`] = ` -.c0 { - position: relative; -} - - -`; - -exports[`position components Sticky renders consistently 1`] = ` -.c0 { - top: 0; - z-index: 1; - position: -webkit-sticky; - position: sticky; -} - - -`; diff --git a/src/__tests__/__snapshots__/SelectMenu.test.tsx.snap b/src/__tests__/__snapshots__/SelectMenu.test.tsx.snap deleted file mode 100644 index 3fd7842da9c..00000000000 --- a/src/__tests__/__snapshots__/SelectMenu.test.tsx.snap +++ /dev/null @@ -1,471 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`SelectMenu right-aligned modal has right: 0px 1`] = ` -.c1 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #24292f; - background-color: #f6f8fa; - border: 1px solid rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); -} - -.c1:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c1:focus { - outline: none; -} - -.c1:disabled { - cursor: default; -} - -.c1:disabled svg { - opacity: 0.6; -} - -.c1:hover { - background-color: #f3f4f6; - border-color: rgba(31,35,40,0.15); -} - -.c1:focus { - outline: solid 2px #0969da; -} - -.c1:active { - background-color: hsla(220,14%,94%,1); -} - -.c1:disabled { - color: #8c959f; - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - -.c6 { - padding: 4px 16px; - margin: 0; - font-size: 12px; - font-weight: 600; - color: #656d76; - background-color: #f6f8fa; - border-bottom: 1px solid hsla(210,18%,87%,1); -} - -.c7 { - margin-top: -1px; - padding: 8px 16px; - font-size: 12px; - color: #656d76; - text-align: center; - border-top: 1px solid hsla(210,18%,87%,1); -} - -.c5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 16px; - overflow: hidden; - text-align: left; - cursor: pointer; - background-color: #ffffff; - border: 0; - border-bottom: 1px solid hsla(210,18%,87%,1); - color: #656d76; - -webkit-text-decoration: none; - text-decoration: none; - font-size: 12px; - font-family: inherit; - width: 100%; -} - -.c5:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c5:focus { - outline: none; -} - -.c5[hidden] { - display: none !important; -} - -.c5 .SelectMenu-icon { - width: 16px; - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.c5 .SelectMenu-selected-icon { - visibility: hidden; - -webkit-transition: -webkit-transform 0.12s cubic-bezier(0.5,0.1,1,0.5),visibility 0s 0.12s linear; - -webkit-transition: transform 0.12s cubic-bezier(0.5,0.1,1,0.5),visibility 0s 0.12s linear; - transition: transform 0.12s cubic-bezier(0.5,0.1,1,0.5),visibility 0s 0.12s linear; - -webkit-transform: scale(0); - -ms-transform: scale(0); - transform: scale(0); -} - -.c5[aria-checked='true'] { - font-weight: 500; - color: #1F2328; -} - -.c5[aria-checked='true'] .SelectMenu-selected-icon { - visibility: visible; - -webkit-transition: -webkit-transform 0.12s cubic-bezier(0,0,0.2,1),visibility 0s linear; - -webkit-transition: transform 0.12s cubic-bezier(0,0,0.2,1),visibility 0s linear; - transition: transform 0.12s cubic-bezier(0,0,0.2,1),visibility 0s linear; - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); -} - -.c4 { - position: relative; - padding: 0; - margin: 0; - -webkit-flex: auto; - -ms-flex: auto; - flex: auto; - overflow-x: hidden; - overflow-y: auto; - background-color: #ffffff; - -webkit-overflow-scrolling: touch; -} - -.c3 { - position: relative; - z-index: 99; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - max-height: 66%; - margin: auto 0; - overflow: hidden; - pointer-events: auto; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - background-color: #ffffff; - border-radius: 6px; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); - -webkit-animation: lejQAW 0.12s cubic-bezier(0,0.1,0.1,1) backwards; - animation: lejQAW 0.12s cubic-bezier(0,0.1,0.1,1) backwards; - width: 300px; -} - -.c2 { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 99; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - padding: 16px; - pointer-events: none; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c2::before { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - pointer-events: none; - content: ''; - background-color: rgba(31,35,40,0.5); -} - -.c0 > summary { - list-style: none; -} - -.c0 > summary::before { - display: none; -} - -.c0 > summary::-webkit-details-marker { - display: none; -} - -@media (min-width:544px) { - .c7 { - padding: 4px 8px; - } -} - -@media (min-width:544px) { - .c5 { - padding-top: 8px; - padding-bottom: 8px; - } -} - -@media (hover:hover) { - .c5:hover, - .c5:active, - .c5:focus { - background-color: rgba(234,238,242,0.5); - } -} - -@media (hover:none) { - .c5 { - -webkit-tap-highlight-color: rgba(175,184,193,0.5); - } - - .c5:focus, - .c5:active { - background-color: #f6f8fa; - } -} - -@media (hover:hover) { - .c4 .SelectMenuTab:focus { - background-color: #b6e3ff; - } - - .c4 .SelectMenuTab:not([aria-checked='true']):hover { - color: #1F2328; - background-color: #f6f8fa; - } - - .c4 .SelectMenuTab:not([aria-checked='true']):active { - color: #1F2328; - background-color: #f6f8fa; - } -} - -@media (min-width:544px) { - .c3 { - height: auto; - max-height: 350px; - margin: 4px 0 16px 0; - font-size: 12px; - border: 1px solid #d0d7de; - border-radius: 6px; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); - } -} - -@media (min-width:544px) { - .c2::before { - display: none; - } -} - -@media (min-width:544px) { - .c2 { - position: absolute; - top: auto; - right: 0; - bottom: auto; - left: auto; - padding: 0; - } -} - - - - Projects - - - - - - - - - Primer Components bugs - - - - - - Primer Components roadmap - - - stuff - - - - - - Project 3 - - - - - - Project 4 - - - - - - -`; diff --git a/src/__tests__/__snapshots__/exports.test.ts.snap b/src/__tests__/__snapshots__/exports.test.ts.snap index 4b791e40326..2d571167482 100644 --- a/src/__tests__/__snapshots__/exports.test.ts.snap +++ b/src/__tests__/__snapshots__/exports.test.ts.snap @@ -99,33 +99,8 @@ exports[`@primer/react should not update exports without a semver change 1`] = ` exports[`@primer/react/decprecated should not update exports without a semver change 1`] = ` [ - "Absolute", "ActionList", "ActionMenu", - "BorderBox", - "Button", - "ButtonClose", - "ButtonDanger", - "ButtonInvisible", - "ButtonOutline", - "ButtonPrimary", - "ButtonTableList", - "ChoiceFieldset", - "ChoiceInputField", - "Dropdown", - "DropdownButton", - "DropdownMenu", - "Fixed", - "Flex", - "FormGroup", - "Grid", - "InputField", - "Item", - "Label", - "Position", - "Relative", - "SelectMenu", - "Sticky", ] `; diff --git a/src/__tests__/deprecated/Button.test.tsx b/src/__tests__/deprecated/Button.test.tsx deleted file mode 100644 index db324b1ffc7..00000000000 --- a/src/__tests__/deprecated/Button.test.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React from 'react' -import { - Button, - ButtonPrimary, - ButtonClose, - ButtonDanger, - ButtonOutline, - ButtonInvisible, - ButtonTableList, -} from '../../deprecated' -import {ButtonGroup} from '../..' -import {render, behavesAsComponent, checkExports} from '../../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -function noop() {} - -describe('Button', () => { - behavesAsComponent({Component: Button}) - - checkExports('deprecated/Button', { - default: Button, - ButtonPrimary, - ButtonDanger, - ButtonOutline, - ButtonInvisible, - ButtonTableList, - ButtonClose, - }) - checkExports('ButtonGroup', { - default: ButtonGroup, - }) - - it('renders a ', () => { - expect(render().type).toEqual('button') - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender(Click here) - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('preserves "onClick" prop', () => { - expect(render().props.onClick).toEqual(noop) - }) - - it('respects width props', () => { - expect(render()).toHaveStyleRule('width', '200px') - }) - - it('respects the "disabled" prop', () => { - const item = render() - expect(item.props.disabled).toEqual(true) - expect(item).toMatchSnapshot() - }) - - it('respects the "variant" prop', () => { - expect(render()).toHaveStyleRule('font-size', '12px') - expect(render()).toHaveStyleRule('font-size', '16px') - }) - - it('respects the "fontSize" prop over the "variant" prop', () => { - expect(render()).toHaveStyleRule('font-size', '20px') - }) -}) - -describe('ButtonPrimary', () => { - behavesAsComponent({Component: ButtonPrimary}) - - it('renders a ', () => { - expect(render().type).toEqual('button') - }) - - it('renders correct disabled styles', () => { - const item = render() - expect(item).toMatchSnapshot() - }) -}) - -describe('ButtonDanger', () => { - behavesAsComponent({Component: ButtonDanger}) - - it('renders a ', () => { - expect(render().type).toEqual('button') - }) - - it('renders correct disabled styles', () => { - const item = render() - expect(item).toMatchSnapshot() - }) -}) - -describe('ButtonOutline', () => { - behavesAsComponent({Component: ButtonOutline}) - - it('renders a by default', () => { - expect(render().type).toEqual('button') - }) - - it('renders correct disabled styles', () => { - const item = render() - expect(item).toMatchSnapshot() - }) -}) - -describe('ButtonInvisible', () => { - behavesAsComponent({Component: ButtonOutline}) - - it('renders a by default', () => { - expect(render().type).toEqual('button') - }) - - it('renders correct disabled styles', () => { - const item = render() - expect(item).toMatchSnapshot() - }) -}) - -describe('ButtonGroup', () => { - behavesAsComponent({Component: ButtonGroup}) -}) - -describe('ButtonTableList', () => { - behavesAsComponent({Component: ButtonTableList}) -}) diff --git a/src/__tests__/deprecated/ChoiceFieldset.test.tsx b/src/__tests__/deprecated/ChoiceFieldset.test.tsx deleted file mode 100644 index 0c115562782..00000000000 --- a/src/__tests__/deprecated/ChoiceFieldset.test.tsx +++ /dev/null @@ -1,315 +0,0 @@ -import React from 'react' -import {render} from '../../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {SSRProvider} from '../../' -import {MarkGithubIcon} from '@primer/octicons-react' -import userEvent from '@testing-library/user-event' -import ChoiceFieldset, {Item, ChoiceFieldsetProps} from '../../deprecated/ChoiceFieldset' -import {ChoiceFieldsetListProps} from '../../deprecated/ChoiceFieldset/ChoiceFieldsetList' - -const SelectableChoicelistFieldset: React.FC< - React.PropsWithChildren -> = ({onSelect, selectionVariant, selected = []}) => { - const [selectionVals, setSelectionVals] = React.useState(selected) - - React.useEffect(() => { - onSelect && onSelect(selectionVals) - }, [onSelect, selectionVals]) - - return ( - - { - setSelectionVals(selectedVals) - }} - selected={selectionVals} - > - Legend - - Label one - Label two - - - - ) -} - -describe('ChoiceFieldset', () => { - it('renders default', () => { - expect( - render( - - - Legend - - Label one - Label two - - - , - ), - ).toMatchSnapshot() - }) - it('renders a group of checkbox inputs when selectionVariant=single (default)', () => { - const {getByLabelText} = HTMLRender( - - - Legend - - Label one - Label two - - - , - ) - const firstInput = getByLabelText('Label one') - const secondInput = getByLabelText('Label one') - - expect(firstInput.getAttribute('type')).toBe('radio') - expect(secondInput.getAttribute('type')).toBe('radio') - }) - it('renders a group of checkbox inputs when selectionVariant=multiple', () => { - const {getByLabelText} = HTMLRender( - - - Legend - - Label one - Label two - - - , - ) - const firstInput = getByLabelText('Label one') - const secondInput = getByLabelText('Label one') - - expect(firstInput.getAttribute('type')).toBe('checkbox') - expect(secondInput.getAttribute('type')).toBe('checkbox') - }) - it('renders a list of items with leading visuals and captions', () => { - expect( - render( - - - Legend - - - - - - Label one - Caption one - - - - - - Label two - Caption two - - - - , - ), - ).toMatchSnapshot() - }) - it('renders a list with selected items', () => { - expect( - render( - - - Legend - - Label one - Label two - Label three - - - , - ), - ).toMatchSnapshot() - }) - it('renders a disabled list', () => { - expect( - render( - - - Legend - - Label one - Label two - - - , - ), - ).toMatchSnapshot() - }) - it('renders a required fieldset', () => { - expect( - render( - - - Legend - - Label one - Label two - - - , - ), - ).toMatchSnapshot() - }) - it('renders a fieldset with a description', () => { - expect( - render( - - - Legend - Description - - Label one - Label two - - - , - ), - ).toMatchSnapshot() - }) - it('renders with a custom name and id passed', () => { - expect( - render( - - - Legend - - Label one - Label two - - - , - ), - ).toMatchSnapshot() - }) - it('renders with a hidden legend', () => { - expect( - render( - - - Legend - - Label one - Label two - - - , - ), - ).toMatchSnapshot() - }) - it('renders with a success validation message', () => { - const {container, queryByText} = HTMLRender( - - - Legend - - Label one - Label two - - - You made the right selection - - - You made the wrong selection - - - , - ) - const successValidationMessage = queryByText('You made the right selection') - const errorValidationMessage = queryByText('You made the wrong selection') - - expect(container).toMatchSnapshot() - expect(successValidationMessage).not.toBeNull() - expect(errorValidationMessage).toBeNull() - }) - it('renders with an error validation message', () => { - const {container, queryByText} = HTMLRender( - - - Legend - - Label one - Label two - - - You made the right selection - - - You made the wrong selection - - - , - ) - const successValidationMessage = queryByText('You made the right selection') - const errorValidationMessage = queryByText('You made the wrong selection') - - expect(container).toMatchSnapshot() - expect(errorValidationMessage).not.toBeNull() - expect(successValidationMessage).toBeNull() - }) - it('calls onSelect with the values of the selected item (single selection)', async () => { - const user = userEvent.setup() - const onSelectHandler = jest.fn() - const {getByLabelText} = HTMLRender( - , - ) - const labelOneInputNode = getByLabelText('Label one') - - await user.click(labelOneInputNode) - expect(onSelectHandler).toHaveBeenCalledWith(['labelOne']) - }) - it('calls onSelect with the values of the selected items (multiple selections)', async () => { - const user = userEvent.setup() - const onSelectHandler = jest.fn() - - const {getByLabelText} = HTMLRender( - , - ) - const labelTwoInputNode = getByLabelText('Label two') - - await user.click(labelTwoInputNode) - expect(onSelectHandler).toHaveBeenCalledWith(['labelOne', 'labelTwo']) - }) - it('calls onSelect with an empty array if all values have be de-selected', async () => { - const user = userEvent.setup() - const onSelectHandler = jest.fn() - - const {getByLabelText} = HTMLRender( - , - ) - const labelTwoInputNode = getByLabelText('Label two') - - await user.click(labelTwoInputNode) - expect(onSelectHandler).toHaveBeenCalledWith([]) - }) - it('generates a name attribute for radio groups if one is not provided', () => { - const {getByLabelText} = HTMLRender( - - - Legend - - Label one - Label two - - - , - ) - - const labelOneInputNode = getByLabelText('Label one') - const labelTwoInputNode = getByLabelText('Label two') - - expect(labelOneInputNode.getAttribute('name')).toBeDefined() - expect(labelOneInputNode.getAttribute('name')).toEqual(labelTwoInputNode.getAttribute('name')) - }) -}) diff --git a/src/__tests__/deprecated/ChoiceInputField.test.tsx b/src/__tests__/deprecated/ChoiceInputField.test.tsx deleted file mode 100644 index c47de4a4c86..00000000000 --- a/src/__tests__/deprecated/ChoiceInputField.test.tsx +++ /dev/null @@ -1,224 +0,0 @@ -import React from 'react' -import {render} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' -import {Checkbox, Radio, SSRProvider} from '../../' -import ChoiceInputField from '../../deprecated/ChoiceInputField' -import {MarkGithubIcon} from '@primer/octicons-react' -expect.extend(toHaveNoViolations) - -const CHECKBOXINPUTFIELD_LABEL_TEXT = 'Option one' -const CHECKBOXINPUTFIELD_CAPTION_TEXT = 'Hint: a cool option' - -describe('ChoiceInputField', () => { - afterEach(() => { - jest.clearAllMocks() - }) - - describe('rendering', () => { - it('renders with a checkbox input', () => { - const {getByLabelText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(CHECKBOXINPUTFIELD_LABEL_TEXT) - - expect(input.getAttribute('type')).toBe('checkbox') - }) - it('renders with a radio input', () => { - const {getByLabelText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(CHECKBOXINPUTFIELD_LABEL_TEXT) - - expect(input.getAttribute('type')).toBe('radio') - }) - it('renders with a custom ID', () => { - const {getByLabelText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(CHECKBOXINPUTFIELD_LABEL_TEXT) - - expect(input.getAttribute('id')).toBe('customId') - }) - it('renders as disabled', () => { - const {getByLabelText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(CHECKBOXINPUTFIELD_LABEL_TEXT) - - expect(input.getAttribute('disabled')).not.toBeNull() - }) - it('renders with a caption', () => { - const {getByText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - - const caption = getByText(CHECKBOXINPUTFIELD_CAPTION_TEXT) - - expect(caption).toBeDefined() - }) - it('renders with a LeadingVisual', () => { - const {getByLabelText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - - - - - , - ) - - const leadingVisual = getByLabelText('leadingVisualIcon') - - expect(leadingVisual).toBeDefined() - }) - }) - - describe('ARIA attributes', () => { - it('associates the label with the input', () => { - const {getByLabelText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - - , - ) - - const inputNode = getByLabelText(CHECKBOXINPUTFIELD_LABEL_TEXT) - expect(inputNode).toBeDefined() - }) - it('associates caption text with the input', () => { - const fieldId = 'captionedInput' - const {getByLabelText, getByText} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - - const inputNode = getByLabelText(CHECKBOXINPUTFIELD_LABEL_TEXT) - const captionNode = getByText(CHECKBOXINPUTFIELD_CAPTION_TEXT) - - expect(captionNode.getAttribute('id')).toBe(`${fieldId}-caption`) - expect(inputNode.getAttribute('aria-describedby')).toBe(`${fieldId}-caption`) - }) - }) - - describe('warnings', () => { - it('should warn users if they do not pass an input', async () => { - const consoleSpy = jest.spyOn(global.console, 'warn').mockImplementation(() => {}) - render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - - expect(consoleSpy).toHaveBeenCalledWith( - 'To correctly render this field with the correct ARIA attributes passed to the input, please pass the Checkbox or Radio component from @primer/react as a direct child of the ChoiceInputField component', - ) - }) - - it('should warn users if they pass an id directly to the input', async () => { - const consoleSpy = jest.spyOn(global.console, 'warn').mockImplementation(() => {}) - render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - - expect(consoleSpy).toHaveBeenCalledWith( - `instead of passing the 'id' prop directly to the checkbox input, it should be passed to the parent component, `, - ) - }) - - it('should warn users if they pass a `disabled` prop directly to the input', async () => { - const consoleSpy = jest.spyOn(global.console, 'warn').mockImplementation(() => {}) - render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - - expect(consoleSpy).toHaveBeenCalledWith( - `instead of passing the 'disabled' prop directly to the checkbox input, it should be passed to the parent component, `, - ) - }) - - it('should warn users if they pass a `required` prop directly to the input', async () => { - const consoleSpy = jest.spyOn(global.console, 'warn').mockImplementation(() => {}) - render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - - expect(consoleSpy).toHaveBeenCalledWith( - `instead of passing the 'required' prop directly to the checkbox input, it should be passed to the parent component, `, - ) - }) - }) - - it('should have no axe violations', async () => { - const {container} = render( - - - {CHECKBOXINPUTFIELD_LABEL_TEXT} - - {CHECKBOXINPUTFIELD_CAPTION_TEXT} - - , - ) - const results = await axe(container) - expect(results).toHaveNoViolations() - }) -}) diff --git a/src/__tests__/deprecated/DropdownMenu.test.tsx b/src/__tests__/deprecated/DropdownMenu.test.tsx deleted file mode 100644 index 7fbe722402a..00000000000 --- a/src/__tests__/deprecated/DropdownMenu.test.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import {render as HTMLRender, fireEvent} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' -import React from 'react' -import theme from '../../theme' -import {DropdownMenu, DropdownButton} from '../../deprecated' -import {behavesAsComponent, checkExports} from '../../utils/testing' -import {BaseStyles, ThemeProvider, SSRProvider} from '../..' -import {ItemInput} from '../../deprecated/ActionList/List' - -expect.extend(toHaveNoViolations) - -const items = [{text: 'Foo'}, {text: 'Bar'}, {text: 'Baz'}, {text: 'Bon'}] as ItemInput[] - -function SimpleDropdownMenu(): JSX.Element { - const [selectedItem, setSelectedItem] = React.useState() - - return ( - - - - X - - - - - - ) -} - -describe('DropdownMenu', () => { - afterEach(() => { - jest.clearAllMocks() - }) - - behavesAsComponent({ - Component: DropdownMenu, - options: {skipAs: true, skipSx: true}, - toRender: () => ( - - - - ), - }) - - checkExports('deprecated/DropdownMenu', { - default: undefined, - DropdownMenu, - DropdownButton, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender() - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('should trigger the overlay on trigger click', async () => { - const menu = HTMLRender() - let portalRoot = menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeNull() - const anchor = await menu.findByText('Select an Option') - fireEvent.click(anchor) - portalRoot = menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeTruthy() - const itemText = items - .map((i: ItemInput) => { - if (i.hasOwnProperty('text')) { - return i.text - } - }) - .join('') - expect(portalRoot?.textContent?.trim()).toEqual(itemText) - }) - - it('should dismiss the overlay on dropdown item click', async () => { - const menu = HTMLRender() - let portalRoot = await menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeNull() - const anchor = await menu.findByText('Select an Option') - fireEvent.click(anchor) - portalRoot = menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeTruthy() - const menuItem = menu.queryByText('Baz') - fireEvent.click(menuItem as Element) - // portal is closed after click - expect(portalRoot?.textContent).toEqual('') // menu items are hidden - }) - - it('option should be selected when chosen from the dropdown menu', async () => { - const menu = HTMLRender() - let portalRoot = await menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeNull() - const anchor = await menu.findByText('Select an Option') - fireEvent.click(anchor) - portalRoot = menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeTruthy() - const menuItem = menu.queryByText('Baz') - fireEvent.click(menuItem as Element) - expect(anchor.textContent).toEqual('Baz') - }) - - it('should dismiss the overlay on clicking outside overlay', async () => { - const menu = HTMLRender() - let portalRoot = await menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeNull() - const anchor = await menu.findByText('Select an Option') - fireEvent.click(anchor) - portalRoot = menu.baseElement.querySelector('#__primerPortalRoot__') - expect(portalRoot).toBeTruthy() - const somethingElse = (await menu.baseElement.querySelector('#something-else')) as HTMLElement - fireEvent.mouseDown(somethingElse) - // portal is closed after click - expect(portalRoot?.textContent).toEqual('') // menu items are hidden - }) -}) diff --git a/src/__tests__/deprecated/FormGroup.test.tsx b/src/__tests__/deprecated/FormGroup.test.tsx deleted file mode 100644 index 9bbd2fbd160..00000000000 --- a/src/__tests__/deprecated/FormGroup.test.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import FormGroup from '../../deprecated/FormGroup' -import {behavesAsComponent, checkExports} from '../../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('FormGroup', () => { - behavesAsComponent({Component: FormGroup}) - - checkExports('deprecated/FormGroup', { - default: FormGroup, - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender( - - Example text - - , - ) - const results = await axe(container) - expect(results).toHaveNoViolations() - }) -}) - -describe('FormGroup.Label', () => { - behavesAsComponent({Component: FormGroup.Label}) - - it('should have no axe violations', async () => { - const {container} = HTMLRender(Example text) - const results = await axe(container) - expect(results).toHaveNoViolations() - }) -}) diff --git a/src/__tests__/deprecated/InputField.test.tsx b/src/__tests__/deprecated/InputField.test.tsx deleted file mode 100644 index 71e8d6c0273..00000000000 --- a/src/__tests__/deprecated/InputField.test.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import React from 'react' -import {render} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' -import {Autocomplete, SSRProvider, TextInput, TextInputWithTokens} from '../../' -import InputField from '../../deprecated/InputField' -expect.extend(toHaveNoViolations) - -const TEXTINPUTFIELD_LABEL_TEXT = 'Name' -const TEXTINPUTFIELD_CAPTION_TEXT = 'Hint: your first name' -const TEXTINPUTFIELD_SUCCESS_TEXT = 'This name is valid' -const TEXTINPUTFIELD_ERROR_TEXT = 'This name is invalid' - -describe('InputField', () => { - describe('snapshots', () => { - it('renders with a hidden label', () => { - const {getByLabelText, getByText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - const label = getByText(TEXTINPUTFIELD_LABEL_TEXT) - - expect(input).toBeDefined() - expect(label).toBeDefined() - }) - it('renders with a custom ID', () => { - const {getByLabelText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - - expect(input.getAttribute('id')).toBe('customId') - }) - it('renders as disabled', () => { - const {getByLabelText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - - expect(input.getAttribute('disabled')).not.toBeNull() - }) - it('renders as required', () => { - const {getByRole} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByRole('textbox', {name: TEXTINPUTFIELD_LABEL_TEXT}) - - expect(input.getAttribute('required')).not.toBeNull() - }) - it('renders with a caption', () => { - const {getByText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - {TEXTINPUTFIELD_CAPTION_TEXT} - - , - ) - - const caption = getByText(TEXTINPUTFIELD_CAPTION_TEXT) - - expect(caption).toBeDefined() - }) - it('renders with a successful validation message', () => { - const {getByText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - {TEXTINPUTFIELD_SUCCESS_TEXT} - - , - ) - - const validationMessage = getByText(TEXTINPUTFIELD_SUCCESS_TEXT) - - expect(validationMessage).toBeDefined() - }) - it('renders with an error validation message', () => { - const {getByText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - {TEXTINPUTFIELD_ERROR_TEXT} - - , - ) - - const validationMessage = getByText(TEXTINPUTFIELD_ERROR_TEXT) - - expect(validationMessage).toBeDefined() - }) - it('renders with the input as a TextInputWithTokens', () => { - const onRemoveMock = jest.fn() - const {getByLabelText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - , - ) - - const input = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - - expect(input).toBeDefined() - }) - it('renders with the input as an Autocomplete', () => { - const {getByLabelText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - - - , - ) - - const input = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - - expect(input).toBeDefined() - }) - }) - - describe('ARIA attributes', () => { - it('associates the label with the input', () => { - const {getByLabelText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - - , - ) - - const inputNode = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - expect(inputNode).toBeDefined() - }) - it('associates caption text with the input', () => { - const fieldId = 'captionedInput' - const {getByLabelText, getByText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - {TEXTINPUTFIELD_CAPTION_TEXT} - - , - ) - - const inputNode = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - const captionNode = getByText(TEXTINPUTFIELD_CAPTION_TEXT) - - expect(captionNode.getAttribute('id')).toBe(`${fieldId}-caption`) - expect(inputNode.getAttribute('aria-describedby')).toBe(`${fieldId}-caption`) - }) - it('associates validation text with the input', () => { - const fieldId = 'validatedInput' - const {getByLabelText, getByText} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - {TEXTINPUTFIELD_SUCCESS_TEXT} - - , - ) - - const inputNode = getByLabelText(TEXTINPUTFIELD_LABEL_TEXT) - const validationNode = getByText(TEXTINPUTFIELD_SUCCESS_TEXT) - - expect(validationNode.getAttribute('id')).toBe(`${fieldId}-validationMsg`) - expect(inputNode.getAttribute('aria-describedby')).toBe(`${fieldId}-validationMsg`) - }) - }) - - it('should have no axe violations', async () => { - const {container} = render( - - - {TEXTINPUTFIELD_LABEL_TEXT} - - {TEXTINPUTFIELD_CAPTION_TEXT} - - , - ) - const results = await axe(container) - expect(results).toHaveNoViolations() - }) -}) diff --git a/src/__tests__/deprecated/Label.test.tsx b/src/__tests__/deprecated/Label.test.tsx deleted file mode 100644 index 108eb2c51d5..00000000000 --- a/src/__tests__/deprecated/Label.test.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react' -import Label from '../../deprecated/Label' -import {render, behavesAsComponent, checkExports} from '../../utils/testing' -import {render as HTMLRender} from '@testing-library/react' -import {axe, toHaveNoViolations} from 'jest-axe' - -expect.extend(toHaveNoViolations) - -describe('Label', () => { - behavesAsComponent({Component: Label}) - - checkExports('deprecated/Label', { - default: Label, - }) - - it('renders a ', () => { - expect(render().type).toEqual('span') - }) - - it('should have no axe violations', async () => { - const {container} = HTMLRender(hello) - const results = await axe(container) - expect(results).toHaveNoViolations() - }) - - it('respects the "outline" prop', () => { - expect(render()).toMatchSnapshot() - }) - - it('respects the "variant" prop', () => { - expect(render()).toMatchSnapshot() - }) -}) diff --git a/src/__tests__/deprecated/Label.types.test.tsx b/src/__tests__/deprecated/Label.types.test.tsx deleted file mode 100644 index a88a34a76ef..00000000000 --- a/src/__tests__/deprecated/Label.types.test.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import Label from '../../deprecated/Label' - -export function shouldAcceptCallWithNoProps() { - return -} - -export function shouldNotAcceptSystemProps() { - // @ts-expect-error system props should not be accepted - return -} diff --git a/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap deleted file mode 100644 index 9c106f86e5a..00000000000 --- a/src/__tests__/deprecated/__snapshots__/Button.test.tsx.snap +++ /dev/null @@ -1,786 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Button renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #24292f; - background-color: #f6f8fa; - border: 1px solid rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - background-color: #f3f4f6; - border-color: rgba(31,35,40,0.15); -} - -.c0:focus { - outline: solid 2px #0969da; -} - -.c0:active { - background-color: hsla(220,14%,94%,1); -} - -.c0:disabled { - color: #8c959f; - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`Button respects the "disabled" prop 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #24292f; - background-color: #f6f8fa; - border: 1px solid rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - background-color: #f3f4f6; - border-color: rgba(31,35,40,0.15); -} - -.c0:focus { - outline: solid 2px #0969da; -} - -.c0:active { - background-color: hsla(220,14%,94%,1); -} - -.c0:disabled { - color: #8c959f; - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`ButtonDanger renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #cf222e; - border: 1px solid rgba(31,35,40,0.15); - background-color: #f6f8fa; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - color: #ffffff; - background-color: #a40e26; - border-color: rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:active { - color: #ffffff; - background-color: hsla(356,72%,44%,1); - box-shadow: inset 0 1px 0 rgba(76,0,20,0.2); - border-color: rgba(31,35,40,0.15); -} - -.c0:disabled { - color: rgba(207,34,46,0.5); - background-color: #f6f8fa; -} - - -`; - -exports[`ButtonDanger renders correct disabled styles 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #cf222e; - border: 1px solid rgba(31,35,40,0.15); - background-color: #f6f8fa; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - color: #ffffff; - background-color: #a40e26; - border-color: rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:active { - color: #ffffff; - background-color: hsla(356,72%,44%,1); - box-shadow: inset 0 1px 0 rgba(76,0,20,0.2); - border-color: rgba(31,35,40,0.15); -} - -.c0:disabled { - color: rgba(207,34,46,0.5); - background-color: #f6f8fa; -} - - -`; - -exports[`ButtonGroup renders consistently 1`] = ` -.c0 { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - vertical-align: middle; - isolation: isolate; -} - -.c0.c0 > * { - margin-inline-end: -1px; - position: relative; - border-radius: 0; -} - -.c0.c0 > *:first-child { - border-top-left-radius: 6px; - border-bottom-left-radius: 6px; -} - -.c0.c0 > *:last-child { - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; -} - -.c0.c0 > *:focus, -.c0.c0 > *:active, -.c0.c0 > *:hover { - z-index: 1; -} - - -`; - -exports[`ButtonInvisible renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #0969da; - border: 1px solid rgba(31,35,40,0.15); - background-color: #f6f8fa; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - color: #ffffff; - background-color: #0969da; - border-color: rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:active { - color: #ffffff; - background-color: hsla(212,92%,42%,1); - box-shadow: inset 0 1px 0 rgba(0,33,85,0.2); - border-color: rgba(31,35,40,0.15); -} - -.c0:disabled { - color: rgba(9,105,218,0.5); - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`ButtonInvisible renders correct disabled styles 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #0969da; - background-color: transparent; - border: 0; - border-radius: 6px; - box-shadow: none; -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:disabled { - color: #8c959f; -} - -.c0:focus { - outline: solid 2px #0969da; -} - -.c0:hover { - background-color: #f3f4f6; -} - -.c0:active { - background-color: hsla(220,14%,94%,1); -} - - -`; - -exports[`ButtonOutline renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #0969da; - border: 1px solid rgba(31,35,40,0.15); - background-color: #f6f8fa; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - color: #ffffff; - background-color: #0969da; - border-color: rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:active { - color: #ffffff; - background-color: hsla(212,92%,42%,1); - box-shadow: inset 0 1px 0 rgba(0,33,85,0.2); - border-color: rgba(31,35,40,0.15); -} - -.c0:disabled { - color: rgba(9,105,218,0.5); - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`ButtonOutline renders correct disabled styles 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #0969da; - border: 1px solid rgba(31,35,40,0.15); - background-color: #f6f8fa; - box-shadow: 0 1px 0 rgba(31,35,40,0.04); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - color: #ffffff; - background-color: #0969da; - border-color: rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:active { - color: #ffffff; - background-color: hsla(212,92%,42%,1); - box-shadow: inset 0 1px 0 rgba(0,33,85,0.2); - border-color: rgba(31,35,40,0.15); -} - -.c0:disabled { - color: rgba(9,105,218,0.5); - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`ButtonPrimary renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #ffffff; - border: 1px solid rgba(31,35,40,0.15); - background-color: #1f883d; - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - background-color: #1a7f37; - border-color: rgba(31,35,40,0.15); -} - -.c0:active { - background-color: hsla(137,66%,28%,1); - box-shadow: inset 0 1px 0 rgba(0,45,17,0.2); -} - -.c0:disabled { - color: rgba(255,255,255,0.8); - background-color: #94d3a2; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`ButtonPrimary renders correct disabled styles 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #ffffff; - border: 1px solid rgba(31,35,40,0.15); - background-color: #1f883d; - box-shadow: 0 1px 0 rgba(31,35,40,0.1); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - background-color: #1a7f37; - border-color: rgba(31,35,40,0.15); -} - -.c0:active { - background-color: hsla(137,66%,28%,1); - box-shadow: inset 0 1px 0 rgba(0,45,17,0.2); -} - -.c0:disabled { - color: rgba(255,255,255,0.8); - background-color: #94d3a2; - border-color: rgba(31,35,40,0.15); -} - - -`; - -exports[`ButtonTableList renders consistently 1`] = ` -.c0 { - display: inline-block; - padding: 0; - font-size: 14px; - color: #656d76; - -webkit-text-decoration: none; - text-decoration: none; - white-space: nowrap; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: transparent; - border: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} - -.c0:hover { - -webkit-text-decoration: underline; - text-decoration: underline; -} - -.c0:disabled, -.c0:disabled:hover { - color: #8c959f; - cursor: default; -} - -.c0:after { - display: inline-block; - margin-left: 4px; - width: 0; - height: 0; - vertical-align: -2px; - content: ''; - border: 4px solid transparent; - border-top-color: currentcolor; -} - - -`; diff --git a/src/__tests__/deprecated/__snapshots__/ChoiceFieldset.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/ChoiceFieldset.test.tsx.snap deleted file mode 100644 index ec6ae363d57..00000000000 --- a/src/__tests__/deprecated/__snapshots__/ChoiceFieldset.test.tsx.snap +++ /dev/null @@ -1,2535 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ChoiceFieldset renders a disabled list 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c7 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c2 { - color: #656d76; - font-size: 16px; - padding: 0; -} - -.c8 { - font-weight: 600; - font-size: 14px; - display: block; - color: #656d76; - cursor: not-allowed; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c6:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c6:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c6 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - -`; - -exports[`ChoiceFieldset renders a fieldset with a description 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c6 > input { - margin-left: 0; - margin-right: 0; -} - -.c8 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c9 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c3 { - font-size: 14px; - color: #1F2328; -} - -.c7 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c7:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c7:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c7:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c7:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c7:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c7:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c4 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c7 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - Description - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - -`; - -exports[`ChoiceFieldset renders a list of items with leading visuals and captions 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c8 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.c7 { - margin-left: 8px; - color: #1F2328; -} - -.c7 > * { - min-width: 24px; - min-height: 24px; - fill: currentColor; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c9 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c10 { - font-size: 12px; - color: #656d76; - display: block; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c6:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c6:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c6 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - - - - - - - - - - - - - - Label one - - - Caption one - - - - - - - - - - - - - - - - - Label two - - - Caption two - - - - - - - -`; - -exports[`ChoiceFieldset renders a list with selected items 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c7 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c8 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: 3px; - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c6::before { - width: var(--base-size-16,16px); - height: var(--base-size-16,16px); - visibility: hidden; - content: ''; - background-color: #ffffff; - -webkit-transition: visibility 0s linear 230ms; - transition: visibility 0s linear 230ms; - -webkit-clip-path: inset(var(--base-size-16,16px) 0 0 0); - clip-path: inset(var(--base-size-16,16px) 0 0 0); - -webkit-mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iOSIgdmlld0JveD0iMCAwIDEyIDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTEuNzgwMyAwLjIxOTYyNUMxMS45MjEgMC4zNjA0MjcgMTIgMC41NTEzMDUgMTIgMC43NTAzMTNDMTIgMC45NDkzMjEgMTEuOTIxIDEuMTQwMTkgMTEuNzgwMyAxLjI4MUw0LjUxODYgOC41NDA0MkM0LjM3Nzc1IDguNjgxIDQuMTg2ODIgOC43NiAzLjk4Nzc0IDguNzZDMy43ODg2NyA4Ljc2IDMuNTk3NzMgOC42ODEgMy40NTY4OSA4LjU0MDQyTDAuMjAxNjIyIDUuMjg2MkMwLjA2ODkyNzcgNS4xNDM4MyAtMC4wMDMzMDkwNSA0Ljk1NTU1IDAuMDAwMTE2NDkzIDQuNzYwOThDMC4wMDM1NTIwNSA0LjU2NjQzIDAuMDgyMzg5NCA0LjM4MDgxIDAuMjIwMDMyIDQuMjQzMjFDMC4zNTc2NjUgNC4xMDU2MiAwLjU0MzM1NSA0LjAyNjgxIDAuNzM3OTcgNC4wMjMzOEMwLjkzMjU4NCA0LjAxOTk0IDEuMTIwOTMgNC4wOTIxNyAxLjI2MzM0IDQuMjI0ODJMMy45ODc3NCA2Ljk0ODM1TDEwLjcxODYgMC4yMTk2MjVDMTAuODU5NSAwLjA3ODk5MjMgMTEuMDUwNCAwIDExLjI0OTUgMEMxMS40NDg1IDAgMTEuNjM5NSAwLjA3ODk5MjMgMTEuNzgwMyAwLjIxOTYyNVoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo='); - mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iOSIgdmlld0JveD0iMCAwIDEyIDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTEuNzgwMyAwLjIxOTYyNUMxMS45MjEgMC4zNjA0MjcgMTIgMC41NTEzMDUgMTIgMC43NTAzMTNDMTIgMC45NDkzMjEgMTEuOTIxIDEuMTQwMTkgMTEuNzgwMyAxLjI4MUw0LjUxODYgOC41NDA0MkM0LjM3Nzc1IDguNjgxIDQuMTg2ODIgOC43NiAzLjk4Nzc0IDguNzZDMy43ODg2NyA4Ljc2IDMuNTk3NzMgOC42ODEgMy40NTY4OSA4LjU0MDQyTDAuMjAxNjIyIDUuMjg2MkMwLjA2ODkyNzcgNS4xNDM4MyAtMC4wMDMzMDkwNSA0Ljk1NTU1IDAuMDAwMTE2NDkzIDQuNzYwOThDMC4wMDM1NTIwNSA0LjU2NjQzIDAuMDgyMzg5NCA0LjM4MDgxIDAuMjIwMDMyIDQuMjQzMjFDMC4zNTc2NjUgNC4xMDU2MiAwLjU0MzM1NSA0LjAyNjgxIDAuNzM3OTcgNC4wMjMzOEMwLjkzMjU4NCA0LjAxOTk0IDEuMTIwOTMgNC4wOTIxNyAxLjI2MzM0IDQuMjI0ODJMMy45ODc3NCA2Ljk0ODM1TDEwLjcxODYgMC4yMTk2MjVDMTAuODU5NSAwLjA3ODk5MjMgMTEuMDUwNCAwIDExLjI0OTUgMEMxMS40NDg1IDAgMTEuNjM5NSAwLjA3ODk5MjMgMTEuNzgwMyAwLjIxOTYyNVoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo='); - -webkit-mask-size: 75%; - mask-size: 75%; - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - -webkit-mask-position: center; - mask-position: center; -} - -.c6:checked, -.c6:indeterminate { - background: #0969da; - border-color: #0969da; -} - -.c6:checked { - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.32,0,0.67,0) 0ms; - transition: background-color,border-color 80ms cubic-bezier(0.32,0,0.67,0) 0ms; -} - -.c6:checked::before { - visibility: visible; - -webkit-transition: visibility 0s linear 0s; - transition: visibility 0s linear 0s; -} - -.c6:checked:disabled { - cursor: not-allowed; - background-color: #656d76; - border-color: #656d76; - opacity: 1; -} - -.c6:checked:disabled::before { - background-color: #ffffff; -} - -.c6:indeterminate { - background: #0969da; -} - -.c6:indeterminate::before { - -webkit-mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K'); - mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K'); - visibility: visible; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media screen and (prefers-reduced-motion:no-preference) { - .c6::before { - -webkit-animation: checkmarkOut 80ms cubic-bezier(0.65,0,0.35,1) forwards; - animation: checkmarkOut 80ms cubic-bezier(0.65,0,0.35,1) forwards; - } -} - -@media screen and (prefers-reduced-motion:no-preference) { - .c6:checked::before, - .c6:indeterminate::before { - -webkit-animation: checkmarkIn 80ms cubic-bezier(0.65,0,0.35,1) forwards 80ms; - animation: checkmarkIn 80ms cubic-bezier(0.65,0,0.35,1) forwards 80ms; - } -} - -@media (forced-colors:active) { - .c6:checked { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - - - - - - Label three - - - - - - - -`; - -exports[`ChoiceFieldset renders a required fieldset 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c6 > input { - margin-left: 0; - margin-right: 0; -} - -.c8 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c4 { - margin-right: 4px; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c9 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c7 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c7:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c7:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c7:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c7:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c7:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c7:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c5 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c7 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - - - Legend - - - * - - - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - -`; - -exports[`ChoiceFieldset renders default 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c7 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c8 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c6:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c6:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c6 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - -`; - -exports[`ChoiceFieldset renders with a custom name and id passed 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c7 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c8 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c6:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c6:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c6 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - -`; - -exports[`ChoiceFieldset renders with a hidden legend 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c4 > input { - margin-left: 0; - margin-right: 0; -} - -.c6 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c7 { - font-weight: 600; - font-size: 14px; - display: block; - color: #1F2328; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c1 { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - -webkit-clip: rect(0,0,0,0); - clip: rect(0,0,0,0); - white-space: nowrap; - border-width: 0; -} - -.c5 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-color: #6e7781; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c5:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); - border-color: #d0d7de; -} - -.c5:checked { - border-color: #0969da; - border-width: var(--base-size-4,4px); -} - -.c5:checked:disabled { - cursor: not-allowed; - border-color: #656d76; -} - -.c5:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c5:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c5:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid #0969da; - outline-offset: 2px; -} - -.c2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c2 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c5 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - -`; - -exports[`ChoiceFieldset renders with a success validation message 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c7 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c9 { - margin-top: 16px; -} - -.c10 { - height: auto; - overflow: hidden; -} - -.c13 { - margin-right: 4px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c8 { - font-weight: bold; - font-size: 14px; - display: block; - color: fg.default; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c11 { - -webkit-animation: 170ms eGcHP cubic-bezier(0.44,0.74,0.36,1); - animation: 170ms eGcHP cubic-bezier(0.44,0.74,0.36,1); -} - -.c12 { - font-size: 12px; - font-weight: bold; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - color: success.fg; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c12 a { - color: currentColor; - -webkit-text-decoration: underline; - text-decoration: underline; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); -} - -.c6:checked { - border-width: var(--base-size-4,4px); -} - -.c6:checked:disabled { - cursor: not-allowed; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c6 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - - - - - - - - - - - You made the right selection - - - - - - - -`; - -exports[`ChoiceFieldset renders with an error validation message 1`] = ` -.c0 { - margin: 0; - padding: 0; - border: none; -} - -.c1 { - margin-bottom: 16px; -} - -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c5 > input { - margin-left: 0; - margin-right: 0; -} - -.c7 { - margin-left: 8px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.c9 { - margin-top: 16px; -} - -.c10 { - height: auto; - overflow: hidden; -} - -.c13 { - margin-right: 4px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c2 { - font-size: 16px; - padding: 0; -} - -.c8 { - font-weight: bold; - font-size: 14px; - display: block; - color: fg.default; - cursor: pointer; - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; -} - -.c11 { - -webkit-animation: 170ms eGcHP cubic-bezier(0.44,0.74,0.36,1); - animation: 170ms eGcHP cubic-bezier(0.44,0.74,0.36,1); -} - -.c12 { - font-size: 12px; - font-weight: bold; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - color: danger.fg; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c12 a { - color: currentColor; - -webkit-text-decoration: underline; - text-decoration: underline; -} - -.c6 { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-style: solid; - border-width: 1px; - cursor: pointer; - display: grid; - height: var(--base-size-16,16px); - margin: 0; - margin-top: 0.125rem; - place-content: center; - position: relative; - width: var(--base-size-16,16px); - border-radius: var(--borderRadius-full,100vh); - -webkit-transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); - transition: background-color,border-color 80ms cubic-bezier(0.33,1,0.68,1); -} - -.c6:disabled { - background-color: var(--color-input-disabled-bg,rgba(175,184,193,0.2)); -} - -.c6:checked { - border-width: var(--base-size-4,4px); -} - -.c6:checked:disabled { - cursor: not-allowed; -} - -.c6:focus:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: 2px; -} - -.c6:focus:not(:disabled):not(:focus-visible) { - outline: solid 1px transparent; -} - -.c6:focus-visible:not(:disabled) { - box-shadow: none; - outline: 2px solid; - outline-offset: 2px; -} - -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; -} - -.c3 > li + li { - margin-top: 8px; -} - -@media (forced-colors:active) { - .c6 { - background-color: canvastext; - border-color: canvastext; - } -} - - - - - - - Legend - - - - - - - - - - - Label one - - - - - - - - - - - - Label two - - - - - - - - - - - - - - - - - You made the wrong selection - - - - - - - -`; diff --git a/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap deleted file mode 100644 index eacd73368f9..00000000000 --- a/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap +++ /dev/null @@ -1,104 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DropdownMenu renders consistently 1`] = ` -.c0 { - position: relative; - display: inline-block; - padding: 6px 16px; - font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-text-decoration: none; - text-decoration: none; - text-align: center; - font-size: 14px; - color: #24292f; - background-color: #f6f8fa; - border: 1px solid rgba(31,35,40,0.15); - box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - -.c0:focus { - outline: none; -} - -.c0:disabled { - cursor: default; -} - -.c0:disabled svg { - opacity: 0.6; -} - -.c0:hover { - background-color: #f3f4f6; - border-color: rgba(31,35,40,0.15); -} - -.c0:focus { - outline: solid 2px #0969da; -} - -.c0:active { - background-color: hsla(220,14%,94%,1); -} - -.c0:disabled { - color: #8c959f; - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); -} - -.c1 { - margin-left: 4px; -} - - - - - - -`; diff --git a/src/__tests__/deprecated/__snapshots__/FormGroup.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/FormGroup.test.tsx.snap deleted file mode 100644 index a2578a5fd45..00000000000 --- a/src/__tests__/deprecated/__snapshots__/FormGroup.test.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`FormGroup renders consistently 1`] = ` -.c0 { - margin: 16px 0; - font-weight: 400; -} - - -`; - -exports[`FormGroup.Label renders consistently 1`] = ` -.c0 { - display: block; - margin: 0 0 8px; - font-size: 14px; - font-weight: 600; -} - - -`; diff --git a/src/__tests__/deprecated/__snapshots__/Label.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/Label.test.tsx.snap deleted file mode 100644 index 61f7235fb4f..00000000000 --- a/src/__tests__/deprecated/__snapshots__/Label.test.tsx.snap +++ /dev/null @@ -1,73 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Label renders consistently 1`] = ` -.c0 { - display: inline-block; - font-weight: 500; - color: #ffffff; - border-radius: 100px; - background-color: #6e7781; - font-size: 12px; - line-height: 20px; - padding: 0 8px; -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - - -`; - -exports[`Label respects the "outline" prop 1`] = ` -.c0 { - display: inline-block; - font-weight: 500; - color: #ffffff; - border-radius: 100px; - background-color: #6e7781; - font-size: 12px; - line-height: 20px; - padding: 0 8px; - margin-top: -1px; - margin-bottom: -1px; - color: #656d76; - border: 1px solid #d0d7de; - box-shadow: none; - background-color: transparent; -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - - -`; - -exports[`Label respects the "variant" prop 1`] = ` -.c0 { - display: inline-block; - font-weight: 500; - color: #ffffff; - border-radius: 100px; - background-color: #6e7781; - font-size: 14px; - line-height: 16px; - padding: 8px 12px; -} - -.c0:hover { - -webkit-text-decoration: none; - text-decoration: none; -} - - -`; diff --git a/src/deprecated/BorderBox.tsx b/src/deprecated/BorderBox.tsx deleted file mode 100644 index ba41a444910..00000000000 --- a/src/deprecated/BorderBox.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import styled from 'styled-components' -import Box, {BoxProps} from '../Box' - -export type BorderBoxProps = BoxProps - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -const BorderBox = styled(Box)`` - -BorderBox.defaultProps = { - borderWidth: '1px', - borderStyle: 'solid', - borderColor: 'border.default', - borderRadius: 2, -} - -export default BorderBox diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldCaption.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldCaption.tsx deleted file mode 100644 index 47146864496..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldCaption.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import ChoiceInputField from '../ChoiceInputField' - -const ChoiceFieldCaption: React.FC> = ({children}) => ( - {children} -) - -export default ChoiceFieldCaption diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldLabel.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldLabel.tsx deleted file mode 100644 index cbd039a47dc..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldLabel.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import ChoiceInputField from '../ChoiceInputField' - -const ChoiceFieldLabel: React.FC> = ({children}) => ( - {children} -) - -export default ChoiceFieldLabel diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldset.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldset.tsx deleted file mode 100644 index 469ca189640..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldset.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import React from 'react' -import {Box, useSSRSafeId} from '../..' -import createSlots from '../utils/create-slots' -import {FormValidationStatus} from '../../utils/types/FormValidationStatus' -import ValidationAnimationContainer from '../../_ValidationAnimationContainer' -import InputValidation from '../../_InputValidation' -import ChoiceFieldsetListItem from './ChoiceFieldsetListItem' -import ChoiceFieldsetDescription from './ChoiceFieldsetDescription' -import ChoiceFieldsetLegend from './ChoiceFieldsetLegend' -import ChoiceFieldsetList from './ChoiceFieldsetList' -import ChoiceFieldsetValidation from './ChoiceFieldsetValidation' - -export interface ChoiceFieldsetProps> { - children?: React.ReactNode - /** - * Whether the fieldset is NOT ready for user input - */ - disabled?: boolean - /** - * The unique identifier for this fieldset. Used to associate the validation text with the fieldset - * If an ID is not passed, one will be automatically generated - */ - id?: string - /** - * The unique identifier used to associate radio inputs with eachother - * If a name is not passed and the fieldset renders radio inputs, a name will be automatically generated - */ - name?: string - /** - * The callback that is called when a user toggles a choice on or off - */ - onSelect?: (selectedValues: string[]) => void - /** - * Whether this field must have a value for the user to complete their task - */ - required?: boolean - /** - * The selected values - */ - selected?: string[] - /** - * A map of validation statuses and their associated validation keys. When one of the validation keys is passed to the `validationResult` prop, - * the associated validation message will be rendered in the correct style - */ - validationMap?: T - /** - * The key of the validation message to show - */ - validationResult?: keyof T -} - -export interface ChoiceFieldsetContext extends ChoiceFieldsetProps { - validationMessageId: string -} - -const {Slots, Slot} = createSlots(['Description', 'ChoiceList', 'Legend', 'Validation']) -export {Slot} - -const ChoiceFieldset = >({ - children, - disabled, - id, - name, - onSelect, - required, - selected, - validationMap, - validationResult, -}: ChoiceFieldsetProps) => { - const fieldsetId = useSSRSafeId(id) - const validationChildren: React.ReactElement[] | undefined | null = React.Children.map(children, child => - React.isValidElement(child) && child.type === ChoiceFieldsetValidation ? child : null, - )?.filter(Boolean) - const validationChildToRender = validationChildren?.find(child => child.props.validationKey === validationResult) - const validationMessageId = validationChildToRender ? `${fieldsetId}-validationMsg` : undefined - - return ( - - {slots => { - const isLegendVisible = React.isValidElement(slots.Legend) && slots.Legend.props.isVisible - - return ( - - - {React.Children.toArray(children).filter( - child => React.isValidElement(child) && child.type !== ChoiceFieldsetValidation, - )} - - {slots.Legend} - {slots.Description} - - {slots.ChoiceList} - - {validationChildToRender && ( - - {validationMap && validationResult && validationMessageId && ( - - - {validationChildToRender} - - - )} - - )} - - ) - }} - - ) -} - -export type {ChoiceFieldsetListProps} from './ChoiceFieldsetList' -export type {ChoiceFieldsetLegendProps} from './ChoiceFieldsetLegend' -export type {ChoiceFieldProps} from './ChoiceFieldsetListItem' -/** - * @deprecated Use `CheckboxGroup` or `RadioGroup` instead. See https://primer.style/react/CheckboxGroup and https://primer.style/react/RadioGroup for more info - */ -export default Object.assign(ChoiceFieldset, { - Description: ChoiceFieldsetDescription, - Item: ChoiceFieldsetListItem, - Legend: ChoiceFieldsetLegend, - List: ChoiceFieldsetList, - Validation: ChoiceFieldsetValidation, -}) diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldsetDescription.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldsetDescription.tsx deleted file mode 100644 index 960b22d8464..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldsetDescription.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import {Text} from '../..' -import {ChoiceFieldsetContext, Slot} from './ChoiceFieldset' - -const ChoiceFieldsetDescription: React.FC> = ({children}) => ( - - {({disabled}: ChoiceFieldsetContext) => ( - - {children} - - )} - -) - -export default ChoiceFieldsetDescription diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldsetLegend.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldsetLegend.tsx deleted file mode 100644 index ace09f02cb9..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldsetLegend.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react' -import {Box} from '../..' -import VisuallyHidden from '../../_VisuallyHidden' -import {ChoiceFieldsetContext, Slot} from './ChoiceFieldset' - -export interface ChoiceFieldsetLegendProps { - /** - * Whether to visually hide the fieldset legend - */ - visuallyHidden?: boolean -} - -const ChoiceFieldsetLegend: React.FC> = ({ - children, - visuallyHidden, -}) => ( - - {({required, disabled}: ChoiceFieldsetContext) => ( - - {required ? ( - - {children} - * - - ) : ( - children - )} - - )} - -) - -export default ChoiceFieldsetLegend diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldsetList.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldsetList.tsx deleted file mode 100644 index e1ef52dc8bc..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldsetList.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import {useSSRSafeId} from '../..' -import {get} from '../../constants' -import {Slot, ChoiceFieldsetContext} from './ChoiceFieldset' -import ChoiceFieldsetListContext from './ChoiceFieldsetListContext' - -export interface ChoiceFieldsetListProps { - /** - * Whether multiple items or a single item can be selected - */ - selectionVariant?: 'single' | 'multiple' -} - -const List = styled.ul` - display: flex; - flex-direction: column; - list-style: none; - margin: 0; - padding: 0; - - > li + li { - margin-top: ${get('space.2')}; - } -` - -const getSelectedCheckboxes = ( - value: string, - checked: boolean, - selectedValues: string[], - selectionVariant?: ChoiceFieldsetListProps['selectionVariant'], -): string[] => { - if (checked) { - return selectionVariant === 'multiple' ? [...selectedValues, value] : [value] - } - - return selectedValues.filter(selectedValue => selectedValue !== value) -} - -const ChoiceFieldsetList: React.FC> = ({ - selectionVariant = 'single', - children, -}) => { - const ssrSafeUniqueName = useSSRSafeId() - - return ( - - {({name, onSelect, disabled, selected = []}: ChoiceFieldsetContext) => { - return ( - { - const updatedSelections = getSelectedCheckboxes( - e.currentTarget.value, - e.currentTarget.checked, - selected, - selectionVariant, - ) - onSelect && onSelect(updatedSelections) - }, - selectionVariant, - }} - > - - {React.Children.map(children, (child, i) => ( - {child} - ))} - - - ) - }} - - ) -} - -export default ChoiceFieldsetList diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldsetListContext.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldsetListContext.tsx deleted file mode 100644 index 2413c2580ff..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldsetListContext.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import {ChangeEventHandler, createContext} from 'react' - -const ChoiceFieldsetListContext = createContext<{ - disabled?: boolean - name: string - onChange: ChangeEventHandler - selected?: string[] - selectionVariant?: 'single' | 'multiple' -} | null>(null) - -export default ChoiceFieldsetListContext diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldsetListItem.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldsetListItem.tsx deleted file mode 100644 index 6be6d7aa80e..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldsetListItem.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, {useContext} from 'react' -import {Checkbox, Radio, useSSRSafeId} from '../..' -import ChoiceInputField from '../ChoiceInputField' -import {ComponentProps} from '../../utils/types' -import ChoiceInputLeadingVisual from '../_ChoiceInputLeadingVisual' -import ChoiceFieldCaption from './ChoiceFieldCaption' -import ChoiceFieldLabel from './ChoiceFieldLabel' -import ChoiceFieldsetListContext from './ChoiceFieldsetListContext' - -export interface ChoiceFieldProps { - /** - * Whether the field is ready for user input - */ - disabled?: boolean - /** - * The unique identifier for this field. Used to associate the label, validation text, and caption text. - * If an ID is not provided, one will be automatically generated. - */ - id?: string - /** - * The value that is being selected - */ - value: string -} - -const ChoiceFieldsetListItem: React.FC> = ({ - children, - id, - disabled: disabledProp, - value, -}) => { - const choiceFieldsetListContext = useContext(ChoiceFieldsetListContext) - if (choiceFieldsetListContext === null) { - throw new Error('ChoiceFieldsetListContext returned null') - } - const {name, onChange, selected, disabled, selectionVariant} = choiceFieldsetListContext - const fieldId = useSSRSafeId(id) - const labelChild = React.Children.toArray(children).find( - child => React.isValidElement(child) && child.type === ChoiceFieldLabel, - ) - const otherValidChildren = React.Children.toArray(children).filter( - child => - React.isValidElement(child) && (child.type === ChoiceFieldCaption || child.type === ChoiceInputLeadingVisual), - ) - const ChoiceInput = selectionVariant === 'multiple' ? Checkbox : Radio - - return ( - - - {/* this ternary makes it possible for users to safely pass the label content directly as a child */} - {labelChild ? ( - // if was passed, we can just render the children as-is - children - ) : ( - // if was NOT passed, treat all the children except and as the label - <> - {children} - {otherValidChildren} - > - )} - - ) -} - -export type ChoiceFieldComponentProps = ComponentProps -export default Object.assign(ChoiceFieldsetListItem, { - Caption: ChoiceFieldCaption, - Label: ChoiceFieldLabel, - LeadingVisual: ChoiceInputLeadingVisual, -}) diff --git a/src/deprecated/ChoiceFieldset/ChoiceFieldsetValidation.tsx b/src/deprecated/ChoiceFieldset/ChoiceFieldsetValidation.tsx deleted file mode 100644 index 6307644d28a..00000000000 --- a/src/deprecated/ChoiceFieldset/ChoiceFieldsetValidation.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' - -export interface ChoiceFieldsetValidationProps { - validationKey: string -} - -const ChoiceFieldsetValidation: React.FC> = ({children}) => ( - <>{children}> -) - -export default ChoiceFieldsetValidation diff --git a/src/deprecated/ChoiceFieldset/index.ts b/src/deprecated/ChoiceFieldset/index.ts deleted file mode 100644 index a6f8344e959..00000000000 --- a/src/deprecated/ChoiceFieldset/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export {default} from './ChoiceFieldset' -export {default as Item} from './ChoiceFieldsetListItem' -export type {ChoiceFieldsetProps} from './ChoiceFieldset' diff --git a/src/deprecated/ChoiceInputField.tsx b/src/deprecated/ChoiceInputField.tsx deleted file mode 100644 index 6a5bd7ec87f..00000000000 --- a/src/deprecated/ChoiceInputField.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React from 'react' -import {Box, Checkbox, CheckboxProps, Radio, RadioProps, useSSRSafeId} from '..' -import {get} from '../constants' -import {Slots} from './InputField/slots' -import ChoiceInputLeadingVisual from './_ChoiceInputLeadingVisual' -import InputField, {Props as InputFieldProps} from './InputField/InputField' -import {FormValidationStatus} from '../utils/types/FormValidationStatus' -import InputFieldCaption from './InputField/_InputFieldCaption' - -export interface Props extends Pick { - /** - * Styles the field to visually communicate the result of form validation - */ - validationStatus?: FormValidationStatus -} - -const getInputToRender = (inputType: 'radio' | 'checkbox', children?: React.ReactNode) => { - const inputComponentMap = { - radio: Radio, - checkbox: Checkbox, - } - - return React.Children.toArray(children).find(child => - React.isValidElement(child) && child.type === inputComponentMap[inputType] ? child : null, - ) -} - -const ChoiceInputField: React.FC> = ({ - children, - disabled, - id: idProp, - validationStatus, -}) => { - const id = useSSRSafeId(idProp) - const captionChildren: React.ReactElement[] | undefined | null = React.Children.map(children, child => - React.isValidElement(child) && child.type === InputFieldCaption ? child : null, - )?.filter(Boolean) - const captionId = captionChildren?.length ? `${id}-caption` : undefined - const inputType = React.Children.toArray(children).some(child => - React.isValidElement(child) ? child.type === Checkbox : false, - ) - ? 'checkbox' - : 'radio' - const ChoiceInput = getInputToRender(inputType, children) - const choiceInputProps = React.isValidElement(ChoiceInput) ? ChoiceInput.props : undefined - - if (!ChoiceInput) { - // eslint-disable-next-line no-console - console.warn( - 'To correctly render this field with the correct ARIA attributes passed to the input, please pass the Checkbox or Radio component from @primer/react as a direct child of the ChoiceInputField component', - ) - } else { - if (choiceInputProps?.id) { - // eslint-disable-next-line no-console - console.warn( - `instead of passing the 'id' prop directly to the ${inputType} input, it should be passed to the parent component, `, - ) - } - - if (choiceInputProps?.disabled) { - // eslint-disable-next-line no-console - console.warn( - `instead of passing the 'disabled' prop directly to the ${inputType} input, it should be passed to the parent component, `, - ) - } - - if (choiceInputProps?.required) { - // eslint-disable-next-line no-console - console.warn( - `instead of passing the 'required' prop directly to the ${inputType} input, it should be passed to the parent component, `, - ) - } - } - - return ( - - {slots => { - return ( - - input': {marginLeft: 0, marginRight: 0}}}> - {React.isValidElement(ChoiceInput) && - React.cloneElement(ChoiceInput as React.ReactElement, { - id, - disabled, - ['aria-describedby']: captionId, - })} - {React.Children.toArray(children).filter( - child => - React.isValidElement(child) && - ![Checkbox, Radio].some(inputComponent => child.type === inputComponent), - )} - - {slots.LeadingVisual && ( - *': { - minWidth: slots.Caption ? get('fontSizes.4') : get('fontSizes.2'), - minHeight: slots.Caption ? get('fontSizes.4') : get('fontSizes.2'), - fill: 'currentColor', - }, - }} - ml={2} - > - {slots.LeadingVisual} - - )} - {(React.isValidElement(slots.Label) && !slots.Label.props.visuallyHidden) || slots.Caption ? ( - - {slots.Label} - {slots.Caption} - - ) : ( - <> - {slots.Label} - {slots.Caption} - > - )} - - ) - }} - - ) -} - -const Label: React.FC> = ({children}) => ( - {children} -) - -/** - * @deprecated Use `FormControl` instead. See https://primer.style/react/FormControl for more info - */ -export default Object.assign(ChoiceInputField, { - Label, - Caption: InputField.Caption, - LeadingVisual: ChoiceInputLeadingVisual, -}) diff --git a/src/deprecated/Dropdown.tsx b/src/deprecated/Dropdown.tsx deleted file mode 100644 index 985adb69b25..00000000000 --- a/src/deprecated/Dropdown.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import Button, {ButtonProps} from './Button' -import {get} from '../constants' -import Details, {DetailsProps} from '../Details' -import getDirectionStyles from '../DropdownStyles' -import useDetails from '../hooks/useDetails' -import sx, {SxProp} from '../sx' -import {ComponentProps} from '../utils/types' - -const StyledDetails = styled(Details)` - position: relative; - display: inline-block; -` - -export type DropdownProps = DetailsProps - -const Dropdown = ({children, className, ...rest}: DropdownProps) => { - const {getDetailsProps} = useDetails({closeOnOutsideClick: true}) - return ( - - {children} - - ) -} - -export type DropdownButtonProps = ButtonProps - -const DropdownButton = ({children, ...rest}: DropdownButtonProps) => { - return ( - - {children} - - - ) -} - -const DropdownCaret = styled.div` - border: 4px solid transparent; - margin-left: 12px; - border-top-color: currentcolor; - border-bottom-width: 0; - content: ''; - display: inline-block; - height: 0; - vertical-align: middle; - width: 0; - ${sx}; -` - -type StyledDropdownMenuProps = { - direction?: 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' -} & SxProp - -const DropdownMenu = styled.ul` - background-clip: padding-box; - background-color: ${get('colors.canvas.overlay')}; - border: 1px solid ${get('colors.border.default')}; - border-radius: ${get('radii.2')}; - box-shadow: ${get('shadows.shadow.large')}; - left: 0; - list-style: none; - margin-top: 2px; - padding: 5px 0 5px 0 !important; //TODO: fix this override on our markdown styles - position: absolute; - top: 100%; - width: 160px; - z-index: 100; - - &::before { - position: absolute; - display: inline-block; - content: ''; - } - - &::after { - position: absolute; - display: inline-block; - content: ''; - } - - &::before { - border: 8px solid transparent; - border-bottom-color: ${get('colors.canvas.overlay')}; - } - - &::after { - border: 7px solid transparent; - border-bottom-color: ${get('colors.canvas.overlay')}; - } - - // stylelint-disable-next-line selector-max-type - > ul { - list-style: none; - } - ${({direction = 'sw', ...rest}) => getDirectionStyles(rest.theme, direction)}; - ${sx}; -` - -const DropdownItem = styled.li` - display: block; - padding: ${get('space.1')} 10px ${get('space.1')} 15px; - overflow: hidden; - color: ${get('colors.fg.default')}; - text-overflow: ellipsis; - white-space: nowrap; - a { - color: ${get('colors.fg.default')}; - text-decoration: none; - display: block; - overflow: hidden; - color: ${get('colors.fg.default')}; - text-overflow: ellipsis; - white-space: nowrap; - } - - &:focus, - a:focus { - color: ${get('colors.fg.onEmphasis')}; - text-decoration: none; - background-color: ${get('colors.accent.emphasis')}; - } - - &:hover, - &:hover a { - color: ${get('colors.fg.onEmphasis')}; - text-decoration: none; - background-color: ${get('colors.accent.emphasis')}; - outline: none; - } - ${sx}; -` - -DropdownMenu.defaultProps = {direction: 'sw'} -DropdownMenu.displayName = 'Dropdown.Menu' - -DropdownItem.displayName = 'Dropdown.Item' - -DropdownButton.defaultProps = Button.defaultProps -DropdownButton.displayName = 'Dropdown.Button' - -DropdownCaret.displayName = 'Dropdown.Caret' - -Dropdown.defaultProps = Details.defaultProps - -export type DropdownCaretProps = ComponentProps -export type DropdownMenuProps = ComponentProps -export type DropdownItemProps = ComponentProps -/** - * @deprecated Use ActionMenu instead. See https://primer.style/react/ActionMenu for more details. - */ -export default Object.assign(Dropdown, { - Caret: DropdownCaret, - Menu: DropdownMenu, - Item: DropdownItem, - Button: DropdownButton, -}) diff --git a/src/deprecated/DropdownMenu/DropdownButton.tsx b/src/deprecated/DropdownMenu/DropdownButton.tsx deleted file mode 100644 index bef4ec1a761..00000000000 --- a/src/deprecated/DropdownMenu/DropdownButton.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react' -import {TriangleDownIcon} from '@primer/octicons-react' -import Button, {ButtonProps} from '../Button/Button' -import StyledOcticon from '../../StyledOcticon' - -export type DropdownButtonProps = ButtonProps - -/** - * @deprecated Use Button with Octicons instead. See https://primer.style/react/drafts/Button2#appending-an-icon for more details. - */ -export const DropdownButton = React.forwardRef>( - ({children, ...props}: React.PropsWithChildren, ref): JSX.Element => ( - - {children} - - - ), -) diff --git a/src/deprecated/DropdownMenu/DropdownMenu.tsx b/src/deprecated/DropdownMenu/DropdownMenu.tsx deleted file mode 100644 index 8fd6fd4dc73..00000000000 --- a/src/deprecated/DropdownMenu/DropdownMenu.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import React, {useCallback, useMemo} from 'react' -import {List, GroupedListProps, ListPropsBase, ItemInput} from '../ActionList/List' -import {DropdownButton, DropdownButtonProps} from './DropdownButton' -import {ItemProps} from '../ActionList/Item' -import {AnchoredOverlay} from '../../AnchoredOverlay' -import {OverlayProps} from '../../Overlay' -import {AnchoredOverlayWrapperAnchorProps} from '../../AnchoredOverlay/AnchoredOverlay' -import {useProvidedRefOrCreate} from '../../hooks/useProvidedRefOrCreate' -import {useProvidedStateOrCreate} from '../../hooks/useProvidedStateOrCreate' - -interface DropdownMenuBaseProps extends Partial>, ListPropsBase { - /** - * A placeholder value to display on the trigger button when no selection has been made. - */ - placeholder?: string - - /** - * An `ItemProps` item from the list of `items` which is currently selected. This item will receive a checkmark next to it in the menu. - */ - selectedItem?: ItemInput - - /** - * A callback which receives the selected item or `undefined` when an item is activated in the menu. If the activated item is the same as the current - * `selectedItem`, `undefined` will be passed. - */ - onChange?: (item?: ItemInput) => unknown - - /** - * Props to be spread on the internal `Overlay` component. - */ - overlayProps?: Partial - - /** - * If defined, will control the open/closed state of the overlay. If not defined, the overlay will manage its own state (in other words, an - * uncontrolled component). Must be used in conjunction with `onOpenChange`. - */ - open?: boolean - - /** - * If defined, will control the open/closed state of the overlay. Must be used in conjunction with `open`. - */ - onOpenChange?: (open: boolean) => void -} - -export type DropdownMenuProps = DropdownMenuBaseProps & AnchoredOverlayWrapperAnchorProps - -/** - * @deprecated Use ActionMenu with ActionList instead. See https://primer.style/react/ActionMenu#with-selection for more details. - */ -export function DropdownMenu({ - renderAnchor = (props: T) => , - anchorRef: externalAnchorRef, - placeholder, - selectedItem, - onChange, - overlayProps, - items, - open, - onOpenChange, - ...listProps -}: DropdownMenuProps): JSX.Element { - const [combinedOpenState, setCombinedOpenState] = useProvidedStateOrCreate(open, onOpenChange, false) - const onOpen = useCallback(() => setCombinedOpenState(true), [setCombinedOpenState]) - const onClose = useCallback(() => setCombinedOpenState(false), [setCombinedOpenState]) - - const anchorRef = useProvidedRefOrCreate(externalAnchorRef) - - const renderMenuAnchor = useMemo(() => { - if (renderAnchor === null) { - return null - } - return >(props: T) => - renderAnchor({ - ...props, - children: selectedItem?.text ?? placeholder, - }) - }, [placeholder, renderAnchor, selectedItem?.text]) - - const itemsToRender = useMemo(() => { - return items.map(item => { - return { - ...item, - role: 'option', - selected: item === selectedItem, - onAction: (itemFromAction, event) => { - item.onAction?.(itemFromAction, event) - - if (event.defaultPrevented) { - return - } - - onClose() - onChange?.(item === selectedItem ? undefined : item) - }, - } as ItemProps - }) - }, [items, onChange, onClose, selectedItem]) - - return ( - - - - ) -} - -DropdownMenu.displayName = 'DropdownMenu' diff --git a/src/deprecated/DropdownMenu/index.ts b/src/deprecated/DropdownMenu/index.ts deleted file mode 100644 index ba93a7e16a8..00000000000 --- a/src/deprecated/DropdownMenu/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export {DropdownMenu} from './DropdownMenu' -export type {DropdownMenuProps} from './DropdownMenu' -export {DropdownButton} from './DropdownButton' -export type {DropdownButtonProps} from './DropdownButton' diff --git a/src/deprecated/Flex.tsx b/src/deprecated/Flex.tsx deleted file mode 100644 index 6bccea61a3c..00000000000 --- a/src/deprecated/Flex.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styled from 'styled-components' -import Box, {BoxProps} from '../Box' - -export type FlexProps = BoxProps - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -const Flex = styled(Box)`` - -Flex.defaultProps = { - display: 'flex', -} - -export default Flex diff --git a/src/deprecated/FormGroup.tsx b/src/deprecated/FormGroup.tsx deleted file mode 100644 index 83dfbfaacec..00000000000 --- a/src/deprecated/FormGroup.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import styled from 'styled-components' -import {get} from '../constants' -import sx, {SxProp} from '../sx' -import {ComponentProps} from '../utils/types' - -const FormGroup = styled.div` - margin: ${get('space.3')} 0; - font-weight: ${get('fontWeights.normal')}; - ${sx}; -` - -/** @deprecated Use FormControl instead. See https://primer.style/react/FormControl for more details. */ -const FormGroupLabel = styled.label` - display: block; - margin: 0 0 ${get('space.2')}; - font-size: ${get('fontSizes.1')}; - font-weight: ${get('fontWeights.bold')}; - ${sx}; -` - -FormGroupLabel.displayName = 'FormGroup.Label' - -export type FormGroupProps = ComponentProps -export type FormGroupLabelProps = ComponentProps -/** @deprecated Use FormControl instead. See https://primer.style/react/FormControl for more details. */ -export default Object.assign(FormGroup, {Label: FormGroupLabel}) diff --git a/src/deprecated/Grid.tsx b/src/deprecated/Grid.tsx deleted file mode 100644 index bd063c070de..00000000000 --- a/src/deprecated/Grid.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import styled from 'styled-components' -import Box, {BoxProps} from '../Box' - -export type GridProps = BoxProps - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -const Grid = styled(Box)`` - -Grid.defaultProps = { - display: 'grid', -} - -export default Grid diff --git a/src/deprecated/InputField/InputField.tsx b/src/deprecated/InputField/InputField.tsx deleted file mode 100644 index 60f003a89a6..00000000000 --- a/src/deprecated/InputField/InputField.tsx +++ /dev/null @@ -1,171 +0,0 @@ -import React from 'react' -import {Autocomplete, Box, Select, TextInput, TextInputWithTokens, useSSRSafeId} from '../../' -import InputValidation from '../../_InputValidation' -import {ComponentProps} from '../../utils/types' -import {FormValidationStatus} from '../../utils/types/FormValidationStatus' -import InputFieldCaption from './_InputFieldCaption' -import InputFieldLabel from './_InputFieldLabel' -import InputFieldValidation from './_InputFieldValidation' -import {Slots} from './slots' -import ValidationAnimationContainer from '../../_ValidationAnimationContainer' -export interface Props> { - children?: React.ReactNode - /** - * Whether the field is ready for user input - */ - disabled?: boolean - /** - * The unique identifier for this field. Used to associate the label, validation text, and caption text - */ - id?: string - /** - * Whether this field must have a value for the user to complete their task - */ - required?: boolean - /** - * A map of validation statuses and their associated validation keys. When one of the validation keys is passed to the `validationResult` prop, - * the associated validation message will be rendered in the correct style - */ - validationMap?: T - /** - * The key of the validation message to show - */ - validationResult?: keyof T -} - -type InputFieldValidationProps = ComponentProps -export interface InputFieldContext - extends Pick>, 'disabled' | 'id' | 'required'> { - captionId: string - validationMessageId: string -} - -/** @deprecated Use FormControl instead. See https://primer.style/react/FormControl for more details. */ -const InputField = >({ - children, - disabled, - id: idProp, - required, - validationMap, - validationResult, -}: Props) => { - const expectedInputComponents = [TextInput, TextInputWithTokens, Autocomplete, Select] - const id = useSSRSafeId(idProp) - const validationChildren: React.ReactElement[] | undefined | null = React.Children.map( - children, - child => - React.isValidElement(child) && child.type === InputFieldValidation ? child : null, - )?.filter(Boolean) - const captionChildren: React.ReactElement[] | undefined | null = React.Children.map(children, child => - React.isValidElement(child) && child.type === InputFieldCaption ? child : null, - )?.filter(Boolean) - const labelChild: React.ReactNode | undefined | null = React.Children.toArray(children).find( - child => React.isValidElement(child) && child.type === InputFieldLabel, - ) - const validationChildToRender = validationChildren?.find(child => child.props.validationKey === validationResult) - const validationMessageId = validationChildToRender ? `${id}-validationMsg` : undefined - const captionId = captionChildren?.length ? `${id}-caption` : undefined - const InputComponent = React.Children.toArray(children).find(child => - expectedInputComponents.some(inputComponent => React.isValidElement(child) && child.type === inputComponent), - ) - const inputProps = React.isValidElement(InputComponent) ? InputComponent.props : undefined - - if (!InputComponent) { - // eslint-disable-next-line no-console - console.warn( - `To correctly render this field with the correct ARIA attributes passed to the input, please pass one of the component from @primer/react as a direct child of the InputField component: - - TextInput - - TextInputWithTokens - - Autocomplete`, - ) - } else { - if (inputProps?.id) { - // eslint-disable-next-line no-console - console.warn( - `instead of passing the 'id' prop directly to the input component, it should be passed to the parent component, `, - ) - } - if (inputProps?.disabled) { - // eslint-disable-next-line no-console - console.warn( - `instead of passing the 'disabled' prop directly to the input component, it should be passed to the parent component, `, - ) - } - if (inputProps?.required) { - // eslint-disable-next-line no-console - console.warn( - `instead of passing the 'required' prop directly to the input component, it should be passed to the parent component, `, - ) - } - } - - if (!labelChild) { - // eslint-disable-next-line no-console - console.error( - `The input field with the id ${id} MUST have a InputField.Label child.\n\nIf you want to hide the label, pass the 'visuallyHidden' prop to the InputField.Label component.`, - ) - } - - return ( - - {slots => { - const isLabelHidden = React.isValidElement(slots.Label) && slots.Label.props.visuallyHidden - - return ( - *:not(label) + *': {marginTop: 2}} : {'> * + *': {marginTop: 2}}} - > - {React.Children.toArray(children).filter( - child => - React.isValidElement(child) && - child.type !== InputFieldValidation && - !expectedInputComponents.some(inputComponent => child.type === inputComponent), - )} - {slots.Label} - {React.isValidElement(InputComponent) && - React.cloneElement( - InputComponent as React.ReactElement<{ - id: string - required: boolean - disabled: boolean - ['aria-describedby']: string - }>, - { - id, - required, - disabled, - ['aria-describedby']: [validationMessageId, captionId].filter(Boolean).join(' '), - }, - )} - {validationChildToRender && validationMap && validationResult && validationMessageId && ( - - - {validationChildToRender} - - - )} - {slots.Caption} - - ) - }} - - ) -} - -export type InputFieldComponentProps = ComponentProps -export default Object.assign(InputField, { - Caption: InputFieldCaption, - Label: InputFieldLabel, - Validation: InputFieldValidation, -}) diff --git a/src/deprecated/InputField/_InputFieldCaption.tsx b/src/deprecated/InputField/_InputFieldCaption.tsx deleted file mode 100644 index 2bdb9951d1b..00000000000 --- a/src/deprecated/InputField/_InputFieldCaption.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import InputCaption from '../../_InputCaption' -import {InputFieldContext} from './InputField' -import {Slot} from './slots' - -const InputFieldCaption: React.FC> = ({children}) => ( - - {({captionId, disabled}: InputFieldContext) => ( - - {children} - - )} - -) - -export default InputFieldCaption diff --git a/src/deprecated/InputField/_InputFieldLabel.tsx b/src/deprecated/InputField/_InputFieldLabel.tsx deleted file mode 100644 index f63e71135c2..00000000000 --- a/src/deprecated/InputField/_InputFieldLabel.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react' -import InputLabel from '../../_InputLabel' -import {InputFieldContext} from './InputField' -import {Slot} from './slots' - -export interface Props { - /** - * Whether the label should be visually hidden - */ - visuallyHidden?: boolean -} - -const InputFieldLabel: React.FC> = ({children, visuallyHidden}) => ( - - {({disabled, id, required}: InputFieldContext) => ( - - {children} - - )} - -) - -export default InputFieldLabel diff --git a/src/deprecated/InputField/_InputFieldValidation.tsx b/src/deprecated/InputField/_InputFieldValidation.tsx deleted file mode 100644 index 9125b78a9e9..00000000000 --- a/src/deprecated/InputField/_InputFieldValidation.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -export interface InputFieldValidationProps { - validationKey: string -} - -const InputFieldValidation: React.FC> = ({children}) => ( - <>{children}> -) - -export default InputFieldValidation diff --git a/src/deprecated/InputField/index.ts b/src/deprecated/InputField/index.ts deleted file mode 100644 index b0abd918bc3..00000000000 --- a/src/deprecated/InputField/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {default} from './InputField' diff --git a/src/deprecated/InputField/slots.ts b/src/deprecated/InputField/slots.ts deleted file mode 100644 index 1df9b0ed419..00000000000 --- a/src/deprecated/InputField/slots.ts +++ /dev/null @@ -1,3 +0,0 @@ -import createSlots from '../utils/create-slots' - -export const {Slots, Slot} = createSlots(['Caption', 'Input', 'Label', 'LeadingVisual']) diff --git a/src/deprecated/Label.tsx b/src/deprecated/Label.tsx deleted file mode 100644 index c1112551b8f..00000000000 --- a/src/deprecated/Label.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import styled, {css} from 'styled-components' -import {borderColor, BorderColorProps, variant} from 'styled-system' -import {get} from '../constants' -import sx, {SxProp} from '../sx' -import {ComponentProps} from '../utils/types' - -const outlineStyles = css` - margin-top: -1px; // offsets the 1px border - margin-bottom: -1px; // offsets the 1px border - color: ${get('colors.fg.muted')}; - border: ${get('borderWidths.1')} solid ${get('colors.border.default')}; - box-shadow: none; - ${borderColor}; - background-color: transparent; -` - -const sizeVariant = variant({ - variants: { - small: { - fontSize: 0, - lineHeight: '16px', - padding: '0px 8px', - }, - medium: { - fontSize: 0, - lineHeight: '20px', - padding: '0 8px', - }, - large: { - fontSize: 0, - lineHeight: '24px', - padding: '0 12px', - }, - // corresponds to StateLabel fontSize/lineHeight/padding - xl: { - fontSize: 1, - lineHeight: '16px', - padding: '8px 12px', - }, - }, -}) - -/** @deprecated Use the new Label instead. See https://primer.style/react/Label for more details. */ -const Label = styled.span< - { - variant?: 'small' | 'medium' | 'large' | 'xl' - dropshadow?: boolean - outline?: boolean - } & BorderColorProps & - SxProp ->` - display: inline-block; - font-weight: ${get('fontWeights.semibold')}; - color: ${get('colors.fg.onEmphasis')}; - border-radius: ${get('radii.3')}; - background-color: ${get('colors.neutral.emphasis')}; - - &:hover { - text-decoration: none; - } - - ${sizeVariant} - ${props => (props.dropshadow ? 'box-shadow: inset 0 -1px 0 rgba(27, 31, 35, 0.12)' : '')} - ${props => (props.outline ? outlineStyles : '')} // must be last to override other values - ${sx} -` - -Label.defaultProps = { - variant: 'medium', -} - -Label.displayName = 'Label' - -export type LabelProps = ComponentProps -export default Label diff --git a/src/deprecated/Position.tsx b/src/deprecated/Position.tsx deleted file mode 100644 index 2b3261e6f11..00000000000 --- a/src/deprecated/Position.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import Box from '../Box' -import {ComponentProps} from '../utils/types' - -type StyledPositionProps = {as?: React.ElementType} - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -const Position = styled(Box)`` - -export type PositionProps = ComponentProps - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -export default Position - -// Absolute -export type AbsoluteProps = Omit - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -export const Absolute = React.forwardRef((props: AbsoluteProps, ref) => { - return -}) -Absolute.displayName = 'Absolute' - -// Fixed -export type FixedProps = Omit - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -export const Fixed = React.forwardRef((props: AbsoluteProps, ref) => { - return -}) -Fixed.displayName = 'Fixed' - -// Relative -export type RelativeProps = Omit - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -export const Relative = React.forwardRef((props: RelativeProps, ref) => { - return -}) -Relative.displayName = 'Relative' - -// Sticky -export type StickyProps = Omit - -/** - * @deprecated Use the Box component instead (i.e. → ) - */ -export const Sticky = React.forwardRef(({top = 0, zIndex = 1, ...rest}: StickyProps, ref) => { - return -}) -Sticky.displayName = 'Sticky' diff --git a/src/deprecated/SelectMenu/SelectMenu.tsx b/src/deprecated/SelectMenu/SelectMenu.tsx deleted file mode 100644 index 00d0294bc15..00000000000 --- a/src/deprecated/SelectMenu/SelectMenu.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import React, {useCallback, useEffect, useRef, useState} from 'react' -import styled from 'styled-components' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' -import useKeyboardNav from './hooks/useKeyboardNav' -import {MenuContext} from './SelectMenuContext' -import SelectMenuDivider from './SelectMenuDivider' -import SelectMenuFilter from './SelectMenuFilter' -import SelectMenuFooter from './SelectMenuFooter' -import SelectMenuHeader from './SelectMenuHeader' -import SelectMenuItem from './SelectMenuItem' -import SelectMenuList from './SelectMenuList' -import SelectMenuLoadingAnimation from './SelectMenuLoadingAnimation' -import SelectMenuModal from './SelectMenuModal' -import SelectMenuTab from './SelectMenuTab' -import SelectMenuTabPanel from './SelectMenuTabPanel' -import SelectMenuTabs from './SelectMenuTabs' - -const wrapperStyles = ` - // Remove marker added by the display: list-item browser default - > summary { - list-style: none; - } - // Remove marker added by details polyfill - > summary::before { - display: none; - } - // Remove marker added by Chrome - > summary::-webkit-details-marker { - display: none; - } -` - -const StyledSelectMenu = styled.details` - ${wrapperStyles} - ${sx}; -` - -type SelectMenuInternalProps = { - initialTab?: string - as?: React.ReactElement -} & ComponentProps - -// 'as' is spread out because we don't want users to be able to change the tag. -const SelectMenu = React.forwardRef( - ({children, initialTab = '', as: _ignoredAs, ...rest}, forwardedRef) => { - const backupRef = useRef(null) - const ref = forwardedRef ?? backupRef - const [selectedTab, setSelectedTab] = useState(initialTab) - const [open, setOpen] = useState(false) - const menuProviderValues = { - selectedTab, - setSelectedTab, - setOpen, - open, - initialTab, - } - - const onClickOutside = useCallback( - (event: MouseEvent) => { - if ('current' in ref && ref.current && event.target instanceof Node && !ref.current.contains(event.target)) { - if (!event.defaultPrevented) { - setOpen(false) - } - } - }, - [ref, setOpen], - ) - - // handles the overlay behavior - closing the menu when clicking outside of it - useEffect(() => { - if (open) { - document.addEventListener('click', onClickOutside) - return () => { - document.removeEventListener('click', onClickOutside) - } - } - }, [open, onClickOutside]) - - function toggle(event: React.SyntheticEvent) { - setOpen((event.target as HTMLDetailsElement).open) - } - - useKeyboardNav(ref, open, setOpen) - - return ( - - - {children} - - - ) - }, -) - -SelectMenu.displayName = 'SelectMenu' - -export type SelectMenuProps = ComponentProps -export type {SelectMenuDividerProps} from './SelectMenuDivider' -export type {SelectMenuFilterProps} from './SelectMenuFilter' -export type {SelectMenuFooterProps} from './SelectMenuFooter' -export type {SelectMenuHeaderProps} from './SelectMenuHeader' -export type {SelectMenuItemProps} from './SelectMenuItem' -export type {SelectMenuListProps} from './SelectMenuList' -export type {SelectMenuLoadingAnimationProps} from './SelectMenuLoadingAnimation' -export type {SelectMenuModalProps} from './SelectMenuModal' -export type {SelectMenuTabProps} from './SelectMenuTab' -export type {SelectMenuTabPanelProps} from './SelectMenuTabPanel' -export type {SelectMenuTabsProps} from './SelectMenuTabs' - -/** - * @deprecated Use ActionMenu instead. See https://primer.style/react/ActionMenu for more details. - */ -export default Object.assign(SelectMenu, { - MenuContext, - List: SelectMenuList, - Divider: SelectMenuDivider, - Filter: SelectMenuFilter, - Footer: SelectMenuFooter, - Item: SelectMenuItem, - Modal: SelectMenuModal, - Tabs: SelectMenuTabs, - Tab: SelectMenuTab, - TabPanel: SelectMenuTabPanel, - Header: SelectMenuHeader, - LoadingAnimation: SelectMenuLoadingAnimation, -}) diff --git a/src/deprecated/SelectMenu/SelectMenuContext.tsx b/src/deprecated/SelectMenu/SelectMenuContext.tsx deleted file mode 100644 index 53803162eb2..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuContext.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import {createContext} from 'react' - -export const MenuContext = createContext<{ - selectedTab?: string - setSelectedTab?: React.Dispatch> - setOpen?: React.Dispatch> - open?: boolean - initialTab?: string -}>({}) diff --git a/src/deprecated/SelectMenu/SelectMenuDivider.tsx b/src/deprecated/SelectMenu/SelectMenuDivider.tsx deleted file mode 100644 index 1b978dfc5bb..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuDivider.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import styled, {css} from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -const dividerStyles = css` - padding: ${get('space.1')} ${get('space.3')}; - margin: 0; - font-size: ${get('fontSizes.0')}; - font-weight: ${get('fontWeights.bold')}; - color: ${get('colors.fg.muted')}; - background-color: ${get('colors.canvas.subtle')}; - border-bottom: ${get('borderWidths.1')} solid ${get('colors.border.muted')}; -` - -const SelectMenuDivider = styled.div` - ${dividerStyles} - ${sx}; -` - -SelectMenuDivider.displayName = 'SelectMenu.Divider' - -export type SelectMenuDividerProps = ComponentProps -export default SelectMenuDivider diff --git a/src/deprecated/SelectMenu/SelectMenuFilter.tsx b/src/deprecated/SelectMenu/SelectMenuFilter.tsx deleted file mode 100644 index 979ee43e920..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuFilter.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, {forwardRef, useContext, useEffect, useRef} from 'react' -import styled from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import TextInput, {TextInputProps} from '../../TextInput' -import {ComponentProps} from '../../utils/types' -import {MenuContext} from './SelectMenuContext' - -const StyledForm = styled.form` - padding: ${get('space.3')}; - margin: 0; - border-bottom: ${get('borderWidths.1')} solid ${get('colors.border.muted')}; - background-color: ${get('colors.canvas.overlay')}; - - @media (min-width: ${get('breakpoints.0')}) { - padding: ${get('space.2')}; - } - - ${sx}; -` - -type SelectMenuFilterInternalProps = { - value?: string -} & TextInputProps - -const SelectMenuFilter = forwardRef( - ({value, sx: sxProp, ...rest}, forwardedRef) => { - const inputRef = useRef(null) - const ref = forwardedRef ?? inputRef - const {open} = useContext(MenuContext) - - // puts focus on the filter input when the menu is opened - useEffect(() => { - if (open) { - inputRef.current?.focus() - } - }, [open]) - - return ( - - - - ) - }, -) - -SelectMenuFilter.displayName = 'SelectMenu.Filter' - -export type SelectMenuFilterProps = ComponentProps -export default SelectMenuFilter diff --git a/src/deprecated/SelectMenu/SelectMenuFooter.tsx b/src/deprecated/SelectMenu/SelectMenuFooter.tsx deleted file mode 100644 index 30d0c8d201c..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuFooter.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import styled, {css} from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -const footerStyles = css` - margin-top: -1px; - padding: ${get('space.2')} ${get('space.3')}; - font-size: ${get('fontSizes.0')}; - color: ${get('colors.fg.muted')}; - text-align: center; - border-top: ${get('borderWidths.1')} solid ${get('colors.border.muted')}; - - @media (min-width: ${get('breakpoints.0')}) { - padding: ${get('space.1')} ${get('space.2')}; - } -` - -const SelectMenuFooter = styled.footer` - ${footerStyles} - ${sx}; -` - -SelectMenuFooter.displayName = 'SelectMenu.Footer' - -export type SelectMenuFooterProps = ComponentProps -export default SelectMenuFooter diff --git a/src/deprecated/SelectMenu/SelectMenuHeader.tsx b/src/deprecated/SelectMenu/SelectMenuHeader.tsx deleted file mode 100644 index f29e69872b3..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuHeader.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -// SelectMenu.Header is intentionally not exported, it's an internal component used in -// SelectMenu.Modal - -const SelectMenuTitle = styled.h3` - color: ${get('colors.fg.default')}; - flex: auto; - font-size: ${get('fontSizes.1')}; - font-weight: ${get('fontWeights.bold')}; - margin: 0; - - @media (min-width: ${get('breakpoints.0')}) { - font-size: inherit; - } -` - -const StyledHeader = styled.header` - display: flex; - flex: none; // fixes header from getting squeezed in Safari iOS - padding: ${get('space.3')}; - border-bottom: ${get('borderWidths')} solid ${get('colors.border.muted')}; - - @media (min-width: ${get('breakpoints.0')}) { - padding-top: ${get('space.2')}; - padding-bottom: ${get('space.2')}; - } - - ${sx}; -` - -export type SelectMenuHeaderProps = ComponentProps - -const SelectMenuHeader = ({children, theme, ...rest}: SelectMenuHeaderProps) => { - return ( - - {children} - - ) -} - -SelectMenuHeader.displayName = 'SelectMenu.Header' - -export default SelectMenuHeader diff --git a/src/deprecated/SelectMenu/SelectMenuItem.tsx b/src/deprecated/SelectMenu/SelectMenuItem.tsx deleted file mode 100644 index 82d6f869096..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuItem.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import {CheckIcon} from '@primer/octicons-react' -import React, {forwardRef, useContext, useRef} from 'react' -import styled, {css} from 'styled-components' -import {get} from '../../constants' -import StyledOcticon from '../../StyledOcticon' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' -import {MenuContext} from './SelectMenuContext' - -export const listItemStyles = css` - display: flex; - align-items: center; - padding: ${get('space.3')}; - overflow: hidden; - text-align: left; - cursor: pointer; - background-color: ${get('colors.canvas.overlay')}; - border: 0; - border-bottom: ${get('borderWidths.1')} solid ${get('colors.border.muted')}; - color: ${get('colors.fg.muted')}; - text-decoration: none; - font-size: ${get('fontSizes.0')}; - font-family: inherit; // needed if user uses a "button" tag - width: 100%; - - &:hover { - text-decoration: none; - } - &:focus { - outline: none; - } - - &[hidden] { - display: none !important; - } - - @media (min-width: ${get('breakpoints.0')}) { - padding-top: ${get('space.2')}; - padding-bottom: ${get('space.2')}; - } - - .SelectMenu-icon { - width: ${get('space.3')}; - margin-right: ${get('space.2')}; - flex-shrink: 0; - } - - .SelectMenu-selected-icon { - visibility: hidden; - transition: transform 0.12s cubic-bezier(0.5, 0.1, 1, 0.5), visibility 0s 0.12s linear; - transform: scale(0); - } - - // selected items - &[aria-checked='true'] { - font-weight: 500; - color: ${get('colors.fg.default')}; - - .SelectMenu-selected-icon { - visibility: visible; - transition: transform 0.12s cubic-bezier(0, 0, 0.2, 1), visibility 0s linear; - transform: scale(1); - } - } - - // can hover states - @media (hover: hover) { - &:hover, - &:active, - &:focus { - background-color: ${get('colors.neutral.subtle')}; - } - } - - // Can not hover states - // - // For touch input - - @media (hover: none) { - // Android - &:focus, - &:active { - background-color: ${get('colors.canvas.subtle')}; - } - - // iOS Safari - // :active would work if ontouchstart is added to the button - // Instead this tweaks the "native" highlight color - -webkit-tap-highlight-color: ${get('colors.selectMenu.tapHighlight')}; - } -` - -const StyledItem = styled.a.attrs(() => ({ - role: 'menuitemcheckbox', -}))` - ${listItemStyles} - ${sx}; -` - -type SelectMenuItemInteralProps = { - as?: React.ElementType - selected?: boolean -} & ComponentProps - -const SelectMenuItem = forwardRef( - ({children, selected = false, theme, onClick, ...rest}, forwardedRef) => { - const menuContext = useContext(MenuContext) - const backupRef = useRef(null) - const itemRef = forwardedRef ?? backupRef - - // close the menu when an item is clicked - // this can be overridden if the user provides a `onClick` prop and prevents default in it - const handleClick = (e: React.MouseEvent) => { - onClick && onClick(e) - - if (!e.defaultPrevented) { - menuContext.setOpen?.(false) - } - } - return ( - - - {children} - - ) - }, -) - -SelectMenuItem.displayName = 'SelectMenu.Item' - -export type SelectMenuItemProps = ComponentProps -export default SelectMenuItem diff --git a/src/deprecated/SelectMenu/SelectMenuList.tsx b/src/deprecated/SelectMenu/SelectMenuList.tsx deleted file mode 100644 index b765a705ae8..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuList.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import styled, {css} from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -const listStyles = css` - position: relative; - padding: 0; - margin: 0; - flex: auto; - overflow-x: hidden; - overflow-y: auto; - background-color: ${get('colors.canvas.overlay')}; - -webkit-overflow-scrolling: touch; // Adds momentum + bouncy scrolling - - @media (hover: hover) { - .SelectMenuTab:focus { - background-color: ${get('colors.selectMenu.tapFocusBg')}; - } - - .SelectMenuTab:not([aria-checked='true']):hover { - color: ${get('colors.fg.default')}; - background-color: ${get('colors.canvas.subtle')}; - } - - .SelectMenuTab:not([aria-checked='true']):active { - color: ${get('colors.fg.default')}; - background-color: ${get('colors.canvas.subtle')}; - } - } -` - -const SelectMenuList = styled.div` - ${listStyles} - ${sx}; -` - -SelectMenuList.displayName = 'SelectMenu.List' - -export type SelectMenuListProps = ComponentProps -export default SelectMenuList diff --git a/src/deprecated/SelectMenu/SelectMenuLoadingAnimation.tsx b/src/deprecated/SelectMenu/SelectMenuLoadingAnimation.tsx deleted file mode 100644 index b5efa3ce1cf..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuLoadingAnimation.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import {get} from '../../constants' -import Spinner from '../../Spinner' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -const Animation = styled.div` - padding: ${get('space.6')} ${get('space.4')}; - text-align: center; - background-color: ${get('colors.canvas.overlay')}; - ${sx} -` - -export type SelectMenuLoadingAnimationProps = ComponentProps - -const SelectMenuLoadingAnimation = (props: SelectMenuLoadingAnimationProps) => { - return ( - - - - ) -} - -export default SelectMenuLoadingAnimation diff --git a/src/deprecated/SelectMenu/SelectMenuModal.tsx b/src/deprecated/SelectMenu/SelectMenuModal.tsx deleted file mode 100644 index 6c34b8530b0..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuModal.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from 'react' -import styled, {css, keyframes} from 'styled-components' -import {width, WidthProps} from 'styled-system' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -type StyledModalProps = { - filter?: boolean -} & WidthProps - -type StyledModalWrapperProps = { - align?: 'left' | 'right' -} & SxProp - -const animateModal = keyframes` - 0% { - opacity: 0; - transform: scale(0.9); - } -` - -const modalStyles = css` - position: relative; - z-index: 99; // Needs to be higher than .details-overlay's z-index: 80. - display: flex; - ${props => (props.filter ? 'height: 80%' : '')}; - max-height: ${props => (props.filter ? 'none' : '66%')}; - margin: auto 0; - ${props => (props.filter ? 'margin-top: 0' : '')}; - overflow: hidden; // Enables border radius on scrollable child elements - pointer-events: auto; - flex-direction: column; - background-color: ${get('colors.canvas.overlay')}; - border-radius: ${get('radii.2')}; - box-shadow: ${get('shadows.shadow.small')}; - animation: ${animateModal} 0.12s cubic-bezier(0, 0.1, 0.1, 1) backwards; - - @media (min-width: ${get('breakpoints.0')}) { - height: auto; - max-height: 350px; - margin: ${get('space.1')} 0 ${get('space.3')} 0; - font-size: ${get('fontSizes.0')}; - border: ${get('borderWidths.1')} solid ${get('colors.border.default')}; - border-radius: ${get('radii.2')}; - box-shadow: ${get('shadows.shadow.small')}; - } -` - -const modalWrapperStyles = css` - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 99; - display: flex; - padding: ${get('space.3')}; - pointer-events: none; - flex-direction: column; - - &::before { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - pointer-events: none; - content: ''; - background-color: ${get('colors.primer.canvas.backdrop')}; - - @media (min-width: ${get('breakpoints.0')}) { - display: none; - } - } - - @media (min-width: ${get('breakpoints.0')}) { - position: absolute; - top: auto; - right: ${props => (props.align === 'right' ? '0' : 'auto')}; - bottom: auto; - left: auto; - padding: 0; - } -` - -const Modal = styled.div` - ${modalStyles} - ${width} -` - -const ModalWrapper = styled.div` - ${modalWrapperStyles} - ${sx}; -` - -type SelectMenuModalInternalProps = Pick & ComponentProps - -const SelectMenuModal = React.forwardRef( - ({children, theme, width: widthProp = '300px', align = 'left', ...rest}, forwardedRef) => { - return ( - - - {children} - - - ) - }, -) - -SelectMenuModal.displayName = 'SelectMenu.Modal' - -export type SelectMenuModalProps = ComponentProps -export default SelectMenuModal diff --git a/src/deprecated/SelectMenu/SelectMenuTab.tsx b/src/deprecated/SelectMenu/SelectMenuTab.tsx deleted file mode 100644 index 4803bd57c32..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuTab.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import classnames from 'classnames' -import React, {useContext, useEffect} from 'react' -import styled, {css} from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' -import {MenuContext} from './SelectMenuContext' - -const tabStyles = css` - flex: 1; - padding: ${get('space.2')} ${get('space.3')}; - font-size: ${get('fontSizes.0')}; - font-weight: 500; - color: ${get('colors.fg.muted')}; - text-align: center; - background-color: transparent; - border: 0; - box-shadow: inset 0 -1px 0 ${get('colors.border.muted')}; - - @media (min-width: ${get('breakpoints.0')}) { - flex: none; - padding: ${get('space.1')} ${get('space.3')}; - border: ${get('borderWidths.1')} solid transparent; - border-bottom-width: 0; - border-top-left-radius: ${get('radii.2')}; - border-top-right-radius: ${get('radii.2')}; - } - - &[aria-selected='true'] { - z-index: 1; // Keeps box-shadow visible when hovering - color: ${get('colors.text-primary')}; - background-color: ${get('colors.canvas.overlay')}; - box-shadow: 0 0 0 1px ${get('colors.border.muted')}; - - @media (min-width: ${get('breakpoints.0')}) { - border-color: ${get('colors.border.muted')}; - box-shadow: none; - } - } - - &:focus { - background-color: ${get('colors.neutral.subtle')}; - } -` - -const StyledTab = styled.button` - ${tabStyles} - ${sx}; -` - -export type SelectMenuTabProps = {tabName?: string; index?: number} & ComponentProps - -const SelectMenuTab = ({tabName = '', index, className, onClick, ...rest}: SelectMenuTabProps) => { - const menuContext = useContext(MenuContext) - const handleClick = (e: React.MouseEvent) => { - // if consumer has attached an onClick event, call it - onClick && onClick(e) - if (!e.defaultPrevented) { - menuContext.setSelectedTab?.(tabName) - } - } - - // if no tab is selected when the component renders, show the first tab - useEffect(() => { - if (!menuContext.selectedTab && index === 0) { - menuContext.setSelectedTab?.(tabName) - } - }, [index, menuContext, tabName]) - - const isSelected = menuContext.selectedTab === tabName - - return ( - - {tabName} - - ) -} - -SelectMenuTab.displayName = 'SelectMenu.Tab' - -export default SelectMenuTab diff --git a/src/deprecated/SelectMenu/SelectMenuTabPanel.tsx b/src/deprecated/SelectMenu/SelectMenuTabPanel.tsx deleted file mode 100644 index d9537d51db7..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuTabPanel.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, {useContext} from 'react' -import styled from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' -import {MenuContext} from './SelectMenuContext' -import SelectMenuList from './SelectMenuList' - -const TabPanelBase = styled.div` - border-top: ${get('borderWidths.1')} solid ${get('colors.border.muted')}; - ${sx}; -` - -export type SelectMenuTabPanelProps = { - tabName?: string -} & ComponentProps - -const TabPanel = ({tabName, className, children, ...rest}: SelectMenuTabPanelProps) => { - const menuContext = useContext(MenuContext) - return ( - - {children} - - ) -} - -TabPanel.displayName = 'SelectMenu.TabPanel' - -export default TabPanel diff --git a/src/deprecated/SelectMenu/SelectMenuTabs.tsx b/src/deprecated/SelectMenu/SelectMenuTabs.tsx deleted file mode 100644 index 1a23525f759..00000000000 --- a/src/deprecated/SelectMenu/SelectMenuTabs.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react' -import styled, {css} from 'styled-components' -import {get} from '../../constants' -import sx, {SxProp} from '../../sx' -import {ComponentProps} from '../../utils/types' - -const tabWrapperStyles = css` - display: flex; - flex-shrink: 0; - margin-bottom: -1px; // hide border of element below - -webkit-overflow-scrolling: touch; - overflow-x: auto; - overflow-y: hidden; - - // Hide scrollbar so it doesn't cover the text - &::-webkit-scrollbar { - display: none; - } - - @media (min-width: ${get('breakpoints.0')}) { - padding: 0 ${get('space.2')}; - margin-top: ${get('space.3')}; - } -` - -const SelectMenuTabsBase = styled.div` - ${tabWrapperStyles} - ${sx}; -` - -export type SelectMenuTabsProps = ComponentProps - -const SelectMenuTabs = ({children, ...rest}: SelectMenuTabsProps) => { - return ( - - {children} - - ) -} - -SelectMenuTabs.displayName = 'SelectMenu.Tabs' - -export default SelectMenuTabs diff --git a/src/deprecated/SelectMenu/hooks/useKeyboardNav.js b/src/deprecated/SelectMenu/hooks/useKeyboardNav.js deleted file mode 100644 index 5f12d902584..00000000000 --- a/src/deprecated/SelectMenu/hooks/useKeyboardNav.js +++ /dev/null @@ -1,90 +0,0 @@ -import {useEffect, useCallback} from 'react' - -// adapted from details-menu web component https://github.com/github/details-menu-element -function useKeyboardNav(details, open, setOpen) { - const handleKeyDown = useCallback( - event => { - const closeDetails = () => { - setOpen(false) - const summary = details.current.querySelector('summary') - if (summary) summary.focus() - } - const openDetails = () => { - setOpen(true) - } - const focusItem = next => { - const options = Array.from( - details.current.querySelectorAll( - '[role^="menuitem"]:not([hidden]):not([disabled]):not([aria-disabled="true"])', - ), - ) - const selected = document.activeElement - const index = options.indexOf(selected) - const found = next ? options[index + 1] : options[index - 1] - const def = next ? options[0] : options[options.length - 1] - return found || def - } - - const isMenuItem = el => { - const role = el.getAttribute('role') - return role === 'menuitem' || role === 'menuitemcheckbox' || role === 'menuitemradio' - } - if (!(event instanceof KeyboardEvent)) return - const isSummaryFocused = event.target instanceof Element && event.target.tagName === 'SUMMARY' - switch (event.key) { - case 'Escape': - if (open) { - closeDetails(details) - event.preventDefault() - event.stopPropagation() - } - break - case 'ArrowDown': - { - if (isSummaryFocused && !open) { - openDetails(details) - } - const target = focusItem(true) - if (target) target.focus() - event.preventDefault() - } - break - case 'ArrowUp': - { - if (isSummaryFocused && !open) { - openDetails() - } - const target = focusItem(false) - if (target) target.focus() - event.preventDefault() - } - break - case ' ': - case 'Enter': - { - const selected = document.activeElement - if (selected && isMenuItem(selected) && selected.closest('details') === details) { - event.preventDefault() - event.stopPropagation() - selected.click() - } - } - break - default: - } - }, - [details, open, setOpen], - ) - - useEffect(() => { - const current = details.current - if (!current) return - - current.addEventListener('keydown', handleKeyDown) - return () => { - current.removeEventListener('keydown', handleKeyDown) - } - }, [details, handleKeyDown]) -} - -export default useKeyboardNav diff --git a/src/deprecated/SelectMenu/index.ts b/src/deprecated/SelectMenu/index.ts deleted file mode 100644 index 6e6bb2f0cf7..00000000000 --- a/src/deprecated/SelectMenu/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export {default} from './SelectMenu' -export type { - SelectMenuProps, - SelectMenuDividerProps, - SelectMenuFilterProps, - SelectMenuFooterProps, - SelectMenuItemProps, - SelectMenuListProps, - SelectMenuModalProps, - SelectMenuTabsProps, - SelectMenuHeaderProps, - SelectMenuTabProps, - SelectMenuTabPanelProps, - SelectMenuLoadingAnimationProps, -} from './SelectMenu' diff --git a/src/deprecated/_ChoiceInputLeadingVisual.tsx b/src/deprecated/_ChoiceInputLeadingVisual.tsx deleted file mode 100644 index 095273b94f3..00000000000 --- a/src/deprecated/_ChoiceInputLeadingVisual.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import {Slot} from '../deprecated/InputField/slots' - -const ChoiceInputLeadingVisual: React.FC> = ({children}) => ( - {children} -) - -export default ChoiceInputLeadingVisual diff --git a/src/deprecated/index.ts b/src/deprecated/index.ts index 9ced82cf98d..6749338cdb6 100644 --- a/src/deprecated/index.ts +++ b/src/deprecated/index.ts @@ -8,67 +8,8 @@ // Deprecated in v35.0.0 on March 9, 2022 // TODO: We can remove these 6 months after release: September 10, 2022 -export {default as BorderBox} from './BorderBox' -export type {BorderBoxProps} from './BorderBox' -export {default as ChoiceFieldset, Item} from './ChoiceFieldset' -export {default as ChoiceInputField} from './ChoiceInputField' -export {default as Flex} from './Flex' -export type {FlexProps} from './Flex' -export {default as Grid} from './Grid' -export type {GridProps} from './Grid' -export {default as Position, Absolute, Fixed, Relative, Sticky} from './Position' -export type {PositionProps, AbsoluteProps, FixedProps, RelativeProps, StickyProps} from './Position' -export {default as Dropdown} from './Dropdown' -export type { - DropdownProps, - DropdownCaretProps, - DropdownButtonProps, - DropdownItemProps, - DropdownMenuProps, -} from './Dropdown' -export {default as FormGroup} from './FormGroup' -export type {FormGroupProps, FormGroupLabelProps} from './FormGroup' -export {default as InputField} from './InputField' -export {default as Label} from './Label' -export type {LabelProps} from './Label' -export {default as SelectMenu} from './SelectMenu' -export type { - SelectMenuProps, - SelectMenuDividerProps, - SelectMenuFilterProps, - SelectMenuFooterProps, - SelectMenuItemProps, - SelectMenuListProps, - SelectMenuModalProps, - SelectMenuTabsProps, - SelectMenuHeaderProps, - SelectMenuTabProps, - SelectMenuTabPanelProps, - SelectMenuLoadingAnimationProps, -} from './SelectMenu' export {ActionList} from './ActionList' export type {ActionListProps} from './ActionList' export {ActionMenu} from './ActionMenu' export type {ActionMenuProps} from './ActionMenu' -export {DropdownButton, DropdownMenu} from './DropdownMenu' -// (copied over from src/index) not exporting new DropdownMenu types yet due to conflict with Dropdown types above -// export type {DropdownButtonProps, DropdownMenuProps} from './DropdownMenu' -export { - default as Button, - ButtonDanger, - ButtonOutline, - ButtonPrimary, - ButtonInvisible, - ButtonTableList, - ButtonClose, -} from './Button' -export type { - ButtonProps, - ButtonDangerProps, - ButtonOutlineProps, - ButtonPrimaryProps, - ButtonInvisibleProps, - ButtonTableListProps, - ButtonCloseProps, -} from './Button' // end of v35.0.0 diff --git a/src/stories/Dialog.stories.tsx b/src/stories/Dialog.stories.tsx index 9dab6838f5a..5440db836cb 100644 --- a/src/stories/Dialog.stories.tsx +++ b/src/stories/Dialog.stories.tsx @@ -125,8 +125,8 @@ export const BasicDialog = ({width, height, subtitle}: DialogStoryProps) => { width={width} height={height} footerButtons={[ - {buttonType: 'danger', content: 'Delete the universe', onClick: onDialogClose}, - {buttonType: 'primary', content: 'Proceed', onClick: openSecondDialog, autoFocus: true}, + {buttonType: 'danger', children: 'Delete the universe', onClick: onDialogClose}, + {buttonType: 'primary', children: 'Proceed', onClick: openSecondDialog, autoFocus: true}, ]} > {lipsum} @@ -189,8 +189,8 @@ export const WithCustomRenderers = ({width, height, subtitle}: DialogStoryProps) renderFooter={CustomFooter} onClose={onDialogClose} footerButtons={[ - {buttonType: 'danger', content: 'Delete the universe', onClick: onDialogClose}, - {buttonType: 'primary', content: 'Proceed'}, + {buttonType: 'danger', children: 'Delete the universe', onClick: onDialogClose}, + {buttonType: 'primary', children: 'Proceed'}, ]} > {lipsum} @@ -207,7 +207,7 @@ export const StressTest = ({width, height, subtitle}: DialogStoryProps) => { const onDialogClose = useCallback(() => setIsOpen(false), []) const onSecondDialogClose = useCallback(() => setSecondOpen(false), []) const openSecondDialog = useCallback(() => setSecondOpen(true), []) - const manyButtons = new Array(10).fill(undefined).map((_, i) => ({content: `Button ${i}`})) + const manyButtons = new Array(10).fill(undefined).map((_, i) => ({children: `Button ${i}`})) return ( <> setIsOpen(!isOpen)}> @@ -226,8 +226,8 @@ export const StressTest = ({width, height, subtitle}: DialogStoryProps) => { height={height} footerButtons={[ ...manyButtons, - {buttonType: 'danger', content: 'Delete the universe', onClick: onDialogClose}, - {buttonType: 'primary', content: 'Proceed', onClick: openSecondDialog, autoFocus: true}, + {buttonType: 'danger', children: 'Delete the universe', onClick: onDialogClose}, + {buttonType: 'primary', children: 'Proceed', onClick: openSecondDialog, autoFocus: true}, ]} > {lipsum} diff --git a/src/stories/deprecated/ActionMenu.stories.tsx b/src/stories/deprecated/ActionMenu.stories.tsx index f6ee3578781..11ea8683215 100644 --- a/src/stories/deprecated/ActionMenu.stories.tsx +++ b/src/stories/deprecated/ActionMenu.stories.tsx @@ -9,14 +9,16 @@ import { FilterIcon, GearIcon, ArrowRightIcon, + TriangleDownIcon, } from '@primer/octicons-react' import {Meta} from '@storybook/react' import React, {useCallback, useState, useRef} from 'react' import styled from 'styled-components' import {ThemeProvider} from '../..' import Link, {LinkProps} from '../../Link' -import {ActionMenu, ActionMenuProps, ActionList, DropdownButton, Button} from '../../deprecated' +import {ActionMenu, ActionMenuProps, ActionList} from '../../deprecated' import {ItemProps} from '../../deprecated/ActionList' +import {Button} from '../../Button' import BaseStyles from '../../BaseStyles' const meta: Meta = { @@ -281,6 +283,7 @@ export function ActionMenuWithExternalAnchor(): JSX.Element { const DoubleClickableAnchor: Exclude = ({ onClick: callback, + children, ...rest }) => { const onClick = useCallback( @@ -292,7 +295,11 @@ const DoubleClickableAnchor: Exclude + return ( + + {children} + + ) } export function ActionMenuWithDoubleClickStory(): JSX.Element { return ( diff --git a/src/stories/deprecated/Button.stories.tsx b/src/stories/deprecated/Button.stories.tsx deleted file mode 100644 index 9868ebe37cc..00000000000 --- a/src/stories/deprecated/Button.stories.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react' -import {Meta} from '@storybook/react' - -import { - Button, - ButtonClose, - ButtonDanger, - ButtonInvisible, - ButtonOutline, - ButtonPrimary, - ButtonTableList, -} from '../../deprecated' -import {ButtonStyleProps} from 'styled-system' -import {ButtonBaseProps} from '../../deprecated/Button/ButtonBase' -type StrictButtonStyleProps = ButtonStyleProps & {variant: ButtonBaseProps['variant']} - -export default { - title: 'Deprecated components/Button', - argTypes: { - as: { - table: { - disable: true, - }, - }, - theme: { - table: { - disable: true, - }, - }, - sx: { - table: { - disable: true, - }, - }, - variant: { - control: { - type: 'radio', - }, - options: ['small', 'medium', 'large'], - }, - }, -} as Meta - -// eslint-disable-next-line storybook/prefer-pascal-case -export const defaultButton = (args: StrictButtonStyleProps) => Default Button -defaultButton.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const dangerButton = (args: StrictButtonStyleProps) => Danger Button -dangerButton.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const outlineButton = (args: StrictButtonStyleProps) => Outline Button -outlineButton.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const primaryButton = (args: StrictButtonStyleProps) => Primary Button -primaryButton.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const invisibleButton = (args: StrictButtonStyleProps) => ( - Invisible Button -) -invisibleButton.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const closeButton = (args: ButtonStyleProps) => ( - alert('button clicked.')} /> -) -closeButton.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const buttonTableList = (args: ButtonStyleProps) => ( - Button Table List -) -buttonTableList.args = {variant: 'medium'} - -// eslint-disable-next-line storybook/prefer-pascal-case -export const disabledButton = (args: StrictButtonStyleProps) => { - const props = {disabled: true, ...args} - return Disabled -} diff --git a/src/stories/deprecated/DropdownMenu.stories.tsx b/src/stories/deprecated/DropdownMenu.stories.tsx deleted file mode 100644 index 2e59c64daba..00000000000 --- a/src/stories/deprecated/DropdownMenu.stories.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import {Meta} from '@storybook/react' -import React from 'react' -import {theme, ThemeProvider} from '../..' -import {ItemInput} from '../../deprecated/ActionList/List' -import BaseStyles from '../../BaseStyles' -import Box from '../../Box' -import {DropdownMenu, DropdownButton} from '../../deprecated' -import TextInput from '../../TextInput' - -const meta: Meta = { - title: 'Deprecated components/DropdownMenu', - component: DropdownMenu, - decorators: [ - (Story: React.ComponentType>): JSX.Element => { - return ( - - - - - - ) - }, - ], - parameters: { - controls: { - disable: true, - }, - }, -} -export default meta - -export function FavoriteColorStory(): JSX.Element { - const items = React.useMemo(() => [{text: '🔵 Cyan'}, {text: '🔴 Magenta'}, {text: '🟡 Yellow'}], []) - const [selectedItem, setSelectedItem] = React.useState() - - return ( - <> - Favorite Color - - Please select your favorite color: - ( - - {children} - - )} - placeholder="🎨" - items={items} - selectedItem={selectedItem} - onChange={setSelectedItem} - /> - > - ) -} -FavoriteColorStory.storyName = 'Favorite Color' - -export function ExternalAnchorStory(): JSX.Element { - const items = React.useMemo(() => [{text: '🔵 Cyan'}, {text: '🔴 Magenta'}, {text: '🟡 Yellow'}], []) - const [selectedItem, setSelectedItem] = React.useState() - const anchorRef = React.useRef(null) - const [open, setOpen] = React.useState(false) - - return ( - - - setOpen(true)}>Click me to open the dropdown - - Anchored on me! - - - - - ) -} -ExternalAnchorStory.storyName = 'DropdownMenu with External Anchor'
(see the bottom right of the screen)