diff --git a/docs/content/AnchoredOverlay.mdx b/docs/content/AnchoredOverlay.mdx index cb30a361a36..32ed584a946 100644 --- a/docs/content/AnchoredOverlay.mdx +++ b/docs/content/AnchoredOverlay.mdx @@ -15,23 +15,19 @@ The overlay can be opened and navigated using keyboard or mouse. const closeOverlay = React.useCallback(() => setIsOpen(false), [setIsOpen]) return ( ( - - Click me to open - - )} + renderAnchor={anchorProps => Click me to open} open={isOpen} onOpen={openOverlay} onClose={closeOverlay} > - +

- This menu automatically receives a focus trap and focus zone. Use up/down keys to navigate between buttons + This menu automatically receives a focus trap and focus zone. Use up/down keys to navigate between buttons

-
+
) }} diff --git a/docs/content/Dialog.md b/docs/content/Dialog.md index 4098e4397d8..2f1d75c53c6 100644 --- a/docs/content/Dialog.md +++ b/docs/content/Dialog.md @@ -1,6 +1,7 @@ --- title: Dialog --- + import State from '../components/State' The dialog component is used for all modals. It renders on top of the rest of the app with an overlay. @@ -27,8 +28,15 @@ If you're running into z-index issues or are rendering the component inside of a const returnFocusRef = React.useRef(null) return ( <> - - setIsOpen(false)} aria-labelledby="header-id"> + + setIsOpen(false)} + aria-labelledby="header-id" + > Title Some content @@ -40,7 +48,6 @@ If you're running into z-index issues or are rendering the component inside of a ``` - You can also pass any non-text content into the header: ```jsx live @@ -49,17 +56,26 @@ You can also pass any non-text content into the header: const returnFocusRef = React.useRef(null) return ( <> - - setIsOpen(false)} aria-labelledby="label"> + + setIsOpen(false)} + aria-labelledby="label" + > - Are you sure you'd like to delete this issue? - + + Are you sure you'd like to delete this issue? + + Delete - + @@ -74,13 +90,13 @@ You can also pass any non-text content into the header: ## Component props -| Prop name | Type | Description | -| :- | :- | :- | -| isOpen | Boolean | Set whether or not the dialog is shown | -| onDismiss | Function | A user-provided function that should close the dialog | -| returnFocusRef | React ref | The element to restore focus back to after the `Dialog` is closed | +| Prop name | Type | Description | +| :-------------- | :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| isOpen | Boolean | Set whether or not the dialog is shown | +| onDismiss | Function | A user-provided function that should close the dialog | +| returnFocusRef | React ref | The element to restore focus back to after the `Dialog` is closed | | initialFocusRef | React ref | Element inside of the `Dialog` you'd like to be focused when the Dialog is opened. If nothing is passed to `initialFocusRef` the close button is focused. | -| aria-labelledby | string | Pass an id to use for the aria-label. Use either a `aria-label` or an `aria-labelledby` but not both. | -| aria-label | string | Pass a label to be used to describe the Dialog. Use either a `aria-label` or an `aria-labelledby` but not both. | +| aria-labelledby | string | Pass an id to use for the aria-label. Use either a `aria-label` or an `aria-labelledby` but not both. | +| aria-label | string | Pass a label to be used to describe the Dialog. Use either a `aria-label` or an `aria-labelledby` but not both. | `Dialog.Header` does not take any non-system props. diff --git a/docs/content/Overlay.mdx b/docs/content/Overlay.mdx index 685db5826de..c544ebd6aec 100644 --- a/docs/content/Overlay.mdx +++ b/docs/content/Overlay.mdx @@ -47,11 +47,11 @@ const Demo = () => { onClickOutside={() => setIsOpen(false)} aria-labelledby="title" > - + Are you sure you would like to delete this item? - + )} @@ -67,14 +67,14 @@ render() ## Component props -| Name | Type | Default | Description | -| :-------------- | :-------------------------------- | :---------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| ignoreClickRefs | `React.RefObject []` | `undefined` | Optional. An array of ref objects to ignore clicks on in the `onOutsideClick` behavior. This is often used to ignore clicking on the element that toggles the open/closed state for the `Overlay` to prevent the `Overlay` from being toggled twice. | -| initialFocusRef | `React.RefObject` | `undefined` | Optional. Ref for the element to focus when the `Overlay` is opened. If nothing is provided, the first focusable element in the `Overlay` body is focused. | -| anchorRef | `React.RefObject` | `undefined` | Required. Element the `Overlay` should be anchored to. | -| returnFocusRef | `React.RefObject` | `undefined` | Required. Ref for the element to focus when the `Overlay` is closed. | -| onClickOutside | `function` | `undefined` | Required. Function to call when clicking outside of the `Overlay`. Typically this function sets the `Overlay` visibility state to `false`. | -| onEscape | `function` | `undefined` | Required. Function to call when user presses `Escape`. Typically this function sets the `Overlay` visibility state to `false`. | -| width | `'small' │ 'medium' │ 'large' │ 'xlarge' │ 'xxlarge' │ 'auto'` | `auto` | Sets the width of the `Overlay`, pick from our set list of widths, or pass `auto` to automatically set the width based on the content of the `Overlay`. `small` corresponds to `256px`, `medium` corresponds to `320px`, `large` corresponds to `480px`, `xlarge` corresponds to `640px`, `xxlarge` corresponds to `960px`. | -| height | `'xsmall', 'small', 'medium', 'large', 'xlarge', 'auto'` | `auto` | Sets the height of the `Overlay`, pick from our set list of heights, or pass `auto` to automatically set the height based on the content of the `Overlay`. `xsmall` corresponds to `192px`, `small` corresponds to `256px`, `medium` corresponds to `320px`, `large` corresponds to `432px`, `xlarge` corresponds to `600px`. | -| visibility | `'visible', 'hidden'` | `visible` | Sets the visibility of the `Overlay`. | +| Name | Type | Default | Description | +| :-------------- | :------------------------------------------------------------- | :---------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ignoreClickRefs | `React.RefObject []` | `undefined` | Optional. An array of ref objects to ignore clicks on in the `onOutsideClick` behavior. This is often used to ignore clicking on the element that toggles the open/closed state for the `Overlay` to prevent the `Overlay` from being toggled twice. | +| initialFocusRef | `React.RefObject` | `undefined` | Optional. Ref for the element to focus when the `Overlay` is opened. If nothing is provided, the first focusable element in the `Overlay` body is focused. | +| anchorRef | `React.RefObject` | `undefined` | Required. Element the `Overlay` should be anchored to. | +| returnFocusRef | `React.RefObject` | `undefined` | Required. Ref for the element to focus when the `Overlay` is closed. | +| onClickOutside | `function` | `undefined` | Required. Function to call when clicking outside of the `Overlay`. Typically this function sets the `Overlay` visibility state to `false`. | +| onEscape | `function` | `undefined` | Required. Function to call when user presses `Escape`. Typically this function sets the `Overlay` visibility state to `false`. | +| width | `'small' │ 'medium' │ 'large' │ 'xlarge' │ 'xxlarge' │ 'auto'` | `auto` | Sets the width of the `Overlay`, pick from our set list of widths, or pass `auto` to automatically set the width based on the content of the `Overlay`. `small` corresponds to `256px`, `medium` corresponds to `320px`, `large` corresponds to `480px`, `xlarge` corresponds to `640px`, `xxlarge` corresponds to `960px`. | +| height | `'xsmall', 'small', 'medium', 'large', 'xlarge', 'auto'` | `auto` | Sets the height of the `Overlay`, pick from our set list of heights, or pass `auto` to automatically set the height based on the content of the `Overlay`. `xsmall` corresponds to `192px`, `small` corresponds to `256px`, `medium` corresponds to `320px`, `large` corresponds to `432px`, `xlarge` corresponds to `600px`. | +| visibility | `'visible', 'hidden'` | `visible` | Sets the visibility of the `Overlay`. | diff --git a/docs/content/PointerBox.md b/docs/content/PointerBox.md index 31239c18800..35dcad78e22 100644 --- a/docs/content/PointerBox.md +++ b/docs/content/PointerBox.md @@ -22,12 +22,12 @@ function PointerBoxDemo(props) { Caret Position - + {' '} Content{' '} - + ) } @@ -61,9 +61,9 @@ function CaretSelector(props) { )) return ( - + {choices} - + ) } diff --git a/docs/content/Popover.md b/docs/content/Popover.md index 2e412dcd1eb..4ee1e77e271 100644 --- a/docs/content/Popover.md +++ b/docs/content/Popover.md @@ -13,7 +13,7 @@ It can be useful to give the `Popover.Content` element a margin to help align th ## Default Example ```jxs live - + Hello! @@ -25,7 +25,7 @@ It can be useful to give the `Popover.Content` element a margin to help align th - + ``` ## Caret position @@ -39,45 +39,66 @@ function PopoverDemo(props) { return ( - Caret Position + + Caret Position + - Popover Visibility + + Popover Visibility + - + - {pos} caret + + {pos} caret + Message about this particular piece of UI. - + ) } function CaretSelector(props) { const choices = [ - 'top', 'bottom', 'left', 'right', - 'left-bottom', 'left-top', 'right-bottom', 'right-top', - 'top-left', 'bottom-left', 'top-right', 'bottom-right' - ].map((dir) => ( + 'top', + 'bottom', + 'left', + 'right', + 'left-bottom', + 'left-top', + 'right-bottom', + 'right-top', + 'top-left', + 'bottom-left', + 'top-right', + 'bottom-right' + ].map(dir => ( -)) + )) return ( - + {choices} - + ) } @@ -92,12 +113,12 @@ render() ### Popover -| Name | Type | Default | Description | -| :- | :- | :-: | :- | -| as | String | 'div' | Sets the HTML tag for the component. | -| caret | String | 'top' | Controls the position of the caret. See below for the list of caret positions. | -| open | Boolean | false | Controls the visibility of the popover. | -| relative | Boolean | false | Set to true to render the popover using relative positioning. | +| Name | Type | Default | Description | +| :------- | :------ | :-----: | :----------------------------------------------------------------------------- | +| as | String | 'div' | Sets the HTML tag for the component. | +| caret | String | 'top' | Controls the position of the caret. See below for the list of caret positions. | +| open | Boolean | false | Controls the visibility of the popover. | +| relative | Boolean | false | Set to true to render the popover using relative positioning. | #### Caret Positions @@ -105,6 +126,6 @@ The `caret` prop can be one of the following values: `top`, `bottom`, `left`, `r ### Popover.Content -| Name | Type | Default | Description | -| :- | :- | :-: | :- | -| as | String | 'div' | Sets the HTML tag for the component. | +| Name | Type | Default | Description | +| :--- | :----- | :-----: | :----------------------------------- | +| as | String | 'div' | Sets the HTML tag for the component. | diff --git a/docs/content/SelectMenu.md b/docs/content/SelectMenu.md index 650bf772652..f2cb5992708 100644 --- a/docs/content/SelectMenu.md +++ b/docs/content/SelectMenu.md @@ -7,6 +7,7 @@ The `SelectMenu` components are a suite of components which can be combined toge 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 live @@ -23,12 +24,11 @@ Several additional components exist to provide even more functionality: `SelectM ``` ## SelectMenu + Main wrapper component for select menu. ```jsx - - {/* all other sub components are wrapped here*/} - +{/* all other sub components are wrapped here*/} ``` ### System props @@ -36,25 +36,28 @@ Main wrapper component for select menu. SelectMenu components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### 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 | + +| 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 | ## 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). + +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`. | +| 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 import {SelectMenu, Button} from `@primer/components` import React, {useContext} from 'react' @@ -79,6 +82,7 @@ const MyButton = () => { ``` ## SelectMenu.Modal + Used to wrap the content in a `SelectMenu`. ```jsx @@ -92,7 +96,7 @@ Used to wrap the content in a `SelectMenu`. 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 live - + @@ -105,7 +109,7 @@ Use the `align='right'` prop to align the modal to the right. Note that this onl - + ``` ### System Props @@ -114,20 +118,17 @@ SelectMenu.Modal components get `COMMON` system props. Read our [System Props](/ ### 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 | - +| 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 | ## SelectMenu.List -Used to wrap the select menu list content. All menu items **must** be wrapped in a SelectMenu.List in order for the accessbility 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. +Used to wrap the select menu list content. All menu items **must** be wrapped in a SelectMenu.List in order for the accessbility 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 - - {/* all menu list items are wrapped in the list*/} - +{/* all menu list items are wrapped in the list*/} ``` ### System Props @@ -135,8 +136,8 @@ Used to wrap the select menu list content. All menu items **must** be wrapped i SelectMenu.List components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### Component Props -SelectMenu.List components do not get any additional props besides system props. +SelectMenu.List components do not get any additional props besides system props. ## SelectMenu.Item @@ -155,12 +156,14 @@ You can use a `button` tag instead by utilizing the [`as` prop](/core-concepts#t SelectMenu.Item components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### 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. | + +| 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. | ## 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 live @@ -168,7 +171,7 @@ Use a `SelectMenu.Filter` to add a filter UI to your select menu. Users are expe Filter by Project - + Primer React bugs Primer React roadmap @@ -180,19 +183,20 @@ Use a `SelectMenu.Filter` to add a filter UI to your select menu. Users are expe ``` - ### System Props + SelectMenu.Filter components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### 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 | +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 | ## SelectMenu.Tabs + Use `SelectMenu.Tabs` to wrap the 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`. @@ -209,8 +213,8 @@ If you need access to the selected tab state, you can find it in the MenuContext Projects - - + + Primer React bugs @@ -231,9 +235,11 @@ If you need access to the selected tab state, you can find it in the MenuContext SelectMenu.Tabs components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### Component Props + SelectMenu.Tabs components do not get any additional props besides system props. ## 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. @@ -244,35 +250,39 @@ The `onClick` prop is optional and can be used for any events or data fetching y ``` ### System Props + SelectMenu.Tab components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### 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. | + +| 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. | ## 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 - - {/* Wraps content for each tab */} - +{/* Wraps content for each tab */} ``` ### System Props + SelectMenu.TabPanel components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### 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. + +| 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. | ## SelectMenu.Divider + Use a `SelectMenu.Divider` to add information between items in a `SelectMenu.List`. ```jsx live @@ -296,9 +306,11 @@ Use a `SelectMenu.Divider` to add information between items in a `SelectMenu.Lis SelectMenu.Divder components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### Component Props + SelectMenu.Divider components do not get any additional props besides system props. ## SelectMenu.Footer + Use a `SelectMenu.Footer` to add content to the bottom of the select menu. ```jsx live @@ -322,9 +334,11 @@ Use a `SelectMenu.Footer` to add content to the bottom of the select menu. SelectMenu.Footer components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### Component Props + SelectMenu.Footer components do not get any additional props besides system props. ## SelectMenu.Header + Use a `SelectMenu.Header` to add a header to the top of the select menu content. ```jsx live @@ -348,20 +362,24 @@ Use a `SelectMenu.Header` to add a header to the top of the select menu content. SelectMenu.Header components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### Component Props + SelectMenu.Header components do not get any additional props besides system props. ## 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. +**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 live Projects - - {true ? : + + {true ? ( + + ) : ( Primer React bugs Primer React roadmap @@ -369,7 +387,7 @@ Use a `SelectMenu.LoadingAnimation` to add a loading animation inside of the Sel Project 4 Use ⌥ + click/return to exclude labels. - } + )} ``` @@ -379,4 +397,5 @@ Use a `SelectMenu.LoadingAnimation` to add a loading animation inside of the Sel SelectMenu.LoadingAnimation components get `COMMON` system props. Read our [System Props](/system-props) doc page for a full list of available props. ### Component Props + SelectMenu.LoadingAnimation components do not get any additional props besides system props. diff --git a/docs/content/anchoredPosition.mdx b/docs/content/anchoredPosition.mdx index dd9b326314f..955e088169c 100644 --- a/docs/content/anchoredPosition.mdx +++ b/docs/content/anchoredPosition.mdx @@ -120,7 +120,7 @@ export const AnchoredPositionExample = () => { const {floatingElementRef, anchorElementRef, position} = useAnchoredPosition({side: 'outside-bottom', align: 'center'}) return (
- { ref={floatingElementRef as React.RefObject} > Floating element - + }> Anchor Element diff --git a/docs/content/core-concepts.md b/docs/content/core-concepts.md index ccfebac2b7b..8180a7dc998 100644 --- a/docs/content/core-concepts.md +++ b/docs/content/core-concepts.md @@ -5,6 +5,7 @@ title: Core Concepts This document aims to discuss some of the core concepts of building with Primer React. ## Responsive props + It's really easy to set different values for most of our component props based on screen size! We take advantage of [styled-system](https://github.com/styled-system/styled-system)'s responsive props API in our components. ``` @@ -20,6 +21,7 @@ or You can provide your own theme to Primer React! There are a few ways of doing this to varying degrees, checkout the [theme docs](https://primer.style/components/primer-theme) for more information. ## The `css` prop + When push comes to shove and you just _really_ need to add a custom CSS rule, you can do that with the `css` prop. Please don't abuse this :) ``` @@ -35,35 +37,34 @@ We categorize our components into 3 general types. Building block components, pa - Building Blocks - Building block components are components that are basic in their functions and can be used together with other components to build just about any UI. Some examples of building block components are `Box`, `Avatar`, `Details`, and `Link`. - - - Pattern Components +Building block components are components that are basic in their functions and can be used together with other components to build just about any UI. Some examples of building block components are `Box`, `Avatar`, `Details`, and `Link`. - Pattern components are components that are made up of several building block components to represent a commonly used pattern in our UI. Some examples of pattern components are `UnderlineNav` and `FilterList`. We plan on expanding our offering of pattern components in the near future. +- Pattern Components - - Helper Components +Pattern components are components that are made up of several building block components to represent a commonly used pattern in our UI. Some examples of pattern components are `UnderlineNav` and `FilterList`. We plan on expanding our offering of pattern components in the near future. - Helper components are components that help the user achieve common CSS patterns while maintaining some control over values used. Some examples of helper components are `Flex`, `Text`, `Grid`, and the `Position` components. +- Helper Components +Helper components are components that help the user achieve common CSS patterns while maintaining some control over values used. Some examples of helper components are `Flex`, `Text`, `Grid`, and the `Position` components. - ## The `as` prop - The `as` prop is a feature that all of our components get from [styled-components](https://www.styled-components.com). It allows you to pass a HTML tag or another component to a Primer Component to be rendered as the base tag of that component along with all of it's styles and props. +## The `as` prop +The `as` prop is a feature that all of our components get from [styled-components](https://www.styled-components.com). It allows you to pass a HTML tag or another component to a Primer Component to be rendered as the base tag of that component along with all of it's styles and props. - For example, say you are using a `Button` component, and you really need to apply `Flex` styles to it. You can compose `Flex` and `Button` like so: +For example, say you are using a `Button` component, and you really need to apply `Box` styles to it. You can compose `Box` and `Button` like so: - ```.jsx - Hello - ``` +```.jsx +Hello +``` - This will allow you to use all of the `Button` props _and_ all of the `Flex` props without having to wrap your `Button` component in another `Flex` component. +This will allow you to use all of the `Button` props _and_ all of the `Box` props without having to wrap your `Button` component in another `Box` component. - **This pattern does have some limitations.** Usage of the `as` prop can lead to unexpected output. In the example above, if the user had done ` - + ``` diff --git a/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js b/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js index b4a9b447e60..d83ab453b35 100644 --- a/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js +++ b/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js @@ -44,9 +44,9 @@ function LiveCode({code, language, noinline}) { const handleChange = updatedLiveCode => setLiveCode(updatedLiveCode) return ( - + - - - + + - + - - + + - + ) } diff --git a/playroom/util.js b/playroom/util.js index af92dacaa17..e8f7e03da0f 100644 --- a/playroom/util.js +++ b/playroom/util.js @@ -43,10 +43,10 @@ export const WithPseudoClass = props => { export const StickerSheet = ({children, title}) => { return ( - + {title} {children} - + ) } @@ -88,22 +88,24 @@ export const ComponentStickerSheet = ({props = [], pseudoClasses = [], title, ch ) }) return ( - + {title} {propsModifiedChildren[0]} {pseudoClassChildren} {propsModifiedChildren.slice(1)} - + ) } const StickerSheetRow = ({children, label, childWrapper}) => { return ( - + {label} - {React.Children.map(children, child => childWrapper(child))} - + + {React.Children.map(children, child => childWrapper(child))} + + ) } diff --git a/src/AvatarPair.tsx b/src/AvatarPair.tsx index de402a58259..5fa8dbf2b38 100644 --- a/src/AvatarPair.tsx +++ b/src/AvatarPair.tsx @@ -2,7 +2,7 @@ import React from 'react' import styled from 'styled-components' import Avatar from './Avatar' import {get} from './constants' -import {Relative, RelativeProps} from './Position' +import {Box, BoxProps} from './Box' const ChildAvatar = styled(Avatar)` position: absolute; @@ -11,7 +11,7 @@ const ChildAvatar = styled(Avatar)` box-shadow: ${get('shadows.avatar.childShadow')}; ` -export type AvatarPairProps = RelativeProps +export type AvatarPairProps = BoxProps const AvatarPair = ({children, ...rest}: AvatarPairProps) => { const avatars = React.Children.map(children, (child, i) => { @@ -19,9 +19,9 @@ const AvatarPair = ({children, ...rest}: AvatarPairProps) => { return i === 0 ? React.cloneElement(child, {size: 40}) : }) return ( - + {avatars} - + ) } diff --git a/src/AvatarStack.tsx b/src/AvatarStack.tsx index e2768db6d5b..70e69de26d1 100644 --- a/src/AvatarStack.tsx +++ b/src/AvatarStack.tsx @@ -2,7 +2,7 @@ import classnames from 'classnames' import React from 'react' import styled from 'styled-components' import {COMMON, get, SystemCommonProps} from './constants' -import {Absolute} from './Position' +import {Box} from './Box' import sx, {SxProp} from './sx' import {ComponentProps} from './utils/types' @@ -151,9 +151,9 @@ const AvatarStack = ({children, alignRight, ...rest}: AvatarStackProps) => { }) return ( - + {transformChildren(children)} - + ) } diff --git a/src/CircleOcticon.tsx b/src/CircleOcticon.tsx index 509d0665626..d51e3d28bbe 100644 --- a/src/CircleOcticon.tsx +++ b/src/CircleOcticon.tsx @@ -1,28 +1,28 @@ import {IconProps} from '@primer/octicons-react' import React from 'react' import BorderBox from './BorderBox' -import Flex, {FlexProps} from './Flex' +import Box, {BoxProps} from './Flex' export type CircleOcticonProps = { as?: React.ElementType size?: number icon: React.ComponentType<{size?: IconProps['size']}> -} & FlexProps +} & BoxProps function CircleOcticon(props: CircleOcticonProps) { const {size, as} = props const {icon: IconComponent, bg, ...rest} = props return ( - + - + ) } CircleOcticon.defaultProps = { - ...Flex.defaultProps, + ...Box.defaultProps, size: 32 } diff --git a/src/Dialog.tsx b/src/Dialog.tsx index d475153d350..2549f44fc26 100644 --- a/src/Dialog.tsx +++ b/src/Dialog.tsx @@ -2,7 +2,7 @@ import React, {forwardRef, useRef} from 'react' import styled from 'styled-components' import ButtonClose from './Button/ButtonClose' import {COMMON, get, LAYOUT, SystemCommonProps, SystemLayoutProps} from './constants' -import Flex from './Flex' +import Box from './Box' import useDialog from './hooks/useDialog' import sx, {SxProp} from './sx' import Text from './Text' @@ -44,9 +44,10 @@ const DialogBase = styled.div` ${sx}; ` -const DialogHeaderBase = styled(Flex)` +const DialogHeaderBase = styled(Box)` border-radius: ${get('radii.2')} ${get('radii.2')} 0px 0px; border-bottom: 1px solid ${get('colors.border.primary')}; + display: flex; @media screen and (max-width: 750px) { border-radius: 0px; @@ -138,7 +139,7 @@ DialogHeader.defaultProps = { } DialogHeader.propTypes = { - ...Flex.propTypes + ...Box.propTypes } DialogHeader.displayName = 'Dialog.Header' diff --git a/src/Dialog/Dialog.tsx b/src/Dialog/Dialog.tsx index 73477ee318b..57b5a056df8 100644 --- a/src/Dialog/Dialog.tsx +++ b/src/Dialog/Dialog.tsx @@ -216,13 +216,13 @@ const DefaultHeader: React.FC = ({dialogLabelId, title, subti }, [onClose]) return ( - - + + {title ?? 'Dialog'} {subtitle && {subtitle}} - + - + ) } diff --git a/src/FilteredActionList/FilteredActionList.tsx b/src/FilteredActionList/FilteredActionList.tsx index ca471baaffe..80565f23f3f 100644 --- a/src/FilteredActionList/FilteredActionList.tsx +++ b/src/FilteredActionList/FilteredActionList.tsx @@ -127,7 +127,7 @@ export function FilteredActionList({ useScrollFlash(listContainerRef) return ( - + )} - + ) } diff --git a/src/SelectPanel/SelectPanel.tsx b/src/SelectPanel/SelectPanel.tsx index 7abb2b9d7de..a18300451c0 100644 --- a/src/SelectPanel/SelectPanel.tsx +++ b/src/SelectPanel/SelectPanel.tsx @@ -6,7 +6,7 @@ import {FocusZoneHookSettings} from '../hooks/useFocusZone' import {DropdownButton} from '../DropdownMenu' import {ItemProps} from '../ActionList' import {AnchoredOverlay, AnchoredOverlayProps} from '../AnchoredOverlay' -import Flex from '../Flex' +import Box from '../Box' import {TextInputProps} from '../TextInput' import {useProvidedStateOrCreate} from '../hooks/useProvidedStateOrCreate' @@ -146,7 +146,7 @@ export function SelectPanel({ focusTrapSettings={focusTrapSettings} focusZoneSettings={focusZoneSettings} > - + - + ) } diff --git a/src/SubNav.tsx b/src/SubNav.tsx index 481ae4fad47..f00b3615d74 100644 --- a/src/SubNav.tsx +++ b/src/SubNav.tsx @@ -4,7 +4,7 @@ import * as History from 'history' import React from 'react' import styled from 'styled-components' import {COMMON, FLEX, get, SystemBorderProps, SystemCommonProps, SystemFlexProps} from './constants' -import Flex, {FlexProps} from './Flex' +import Box, {BoxProps} from './Box' import sx, {SxProp} from './sx' import {ComponentProps} from './utils/types' @@ -54,10 +54,10 @@ function SubNav({actions, className, children, label, ...rest}: SubNavProps) { ) } -export type SubNavLinksProps = FlexProps +export type SubNavLinksProps = BoxProps function SubNavLinks(props: SubNavLinksProps) { - return + return } type StyledSubNavLinkProps = { diff --git a/src/Timeline.tsx b/src/Timeline.tsx index 66a9d5af719..6bce456aa74 100644 --- a/src/Timeline.tsx +++ b/src/Timeline.tsx @@ -3,12 +3,13 @@ import React from 'react' import styled, {css} from 'styled-components' import Box from './Box' import {COMMON, get} from './constants' -import Flex, {FlexProps} from './Flex' +import Box, {BoxProps} from './Flex' import {Relative} from './Position' import sx from './sx' import {ComponentProps} from './utils/types' -const Timeline = styled(Flex)<{clipSidebar?: boolean}>` +const Timeline = styled(Box)<{clipSidebar?: boolean}>` + display: flex; flex-direction: column; ${props => props.clipSidebar && @@ -27,7 +28,7 @@ const Timeline = styled(Flex)<{clipSidebar?: boolean}>` type StyledTimelineItemProps = {condensed?: boolean} -const TimelineItem = styled(Flex).attrs(props => ({ +const TimelineItem = styled(Box).attrs(props => ({ className: classnames('Timeline-Item', props.className) }))` position: relative; @@ -68,12 +69,13 @@ const TimelineItem = styled(Flex).attrs(props => ({ ${sx}; ` -export type TimelineBadgeProps = FlexProps +export type TimelineBadgeProps = BoxProps const TimelineBadge = (props: TimelineBadgeProps) => { return ( - - + { {...props} > {props.children} - - + + ) } diff --git a/src/__tests__/Overlay.tsx b/src/__tests__/Overlay.tsx index 21ef6374335..6121f39b229 100644 --- a/src/__tests__/Overlay.tsx +++ b/src/__tests__/Overlay.tsx @@ -1,5 +1,5 @@ import React, {useRef, useState} from 'react' -import {Overlay, Position, Flex, Text, ButtonDanger, Button} from '..' +import {Overlay, Box, Text, ButtonDanger, Button} from '..' import {render, cleanup, waitFor, fireEvent, act} from '@testing-library/react' import userEvent from '@testing-library/user-event' import {axe, toHaveNoViolations} from 'jest-axe' @@ -22,7 +22,7 @@ const TestComponent = ({initialFocus, callback}: TestComponentSettings) => { } } return ( - + @@ -36,16 +36,16 @@ const TestComponent = ({initialFocus, callback}: TestComponentSettings) => { onClickOutside={closeOverlay} width="small" > - + Are you sure? Cancel - + ) : null} - + ) } diff --git a/src/stories/ConfirmationDialog.stories.tsx b/src/stories/ConfirmationDialog.stories.tsx index 4e86927813b..9aba5eb9161 100644 --- a/src/stories/ConfirmationDialog.stories.tsx +++ b/src/stories/ConfirmationDialog.stories.tsx @@ -1,7 +1,7 @@ import React, {useState, useRef, useCallback} from 'react' import {Meta} from '@storybook/react' -import {BaseStyles, Button, Flex, ThemeProvider, useTheme} from '..' +import {BaseStyles, Button, Box, ThemeProvider, useTheme} from '..' import {ConfirmationDialog, useConfirm} from '../Dialog/ConfirmationDialog' import {ActionMenu} from '../ActionMenu' @@ -63,7 +63,7 @@ export const ShorthandHook = () => { [confirm, theme] ) return ( - + @@ -76,7 +76,7 @@ export const ShorthandHook = () => { - + ) } @@ -90,7 +90,7 @@ export const ShorthandHookFromActionMenu = () => { }, [confirm]) return ( - + } items={[ @@ -100,6 +100,6 @@ export const ShorthandHookFromActionMenu = () => { } ]} /> - + ) } diff --git a/src/stories/Overlay.stories.tsx b/src/stories/Overlay.stories.tsx index eb05fa8db79..e60771637d1 100644 --- a/src/stories/Overlay.stories.tsx +++ b/src/stories/Overlay.stories.tsx @@ -1,7 +1,7 @@ import React, {useState, useRef, useCallback} from 'react' import {Meta} from '@storybook/react' import styled from 'styled-components' -import {BaseStyles, Overlay, Button, Text, ButtonDanger, ThemeProvider, Position, Flex} from '..' +import {BaseStyles, Overlay, Button, Text, ButtonDanger, ThemeProvider, Box} from '..' import {DropdownMenu, DropdownButton} from '../DropdownMenu' import {ItemInput} from '../ActionList/List' @@ -57,13 +57,13 @@ export const DropdownOverlay = () => { onEscape={() => setIsOpen(false)} onClickOutside={() => setIsOpen(false)} > - + Copy link Quote reply Reference in new issue Edit Delete - + ) : null} @@ -77,7 +77,7 @@ export const DialogOverlay = () => { const anchorRef = useRef(null) const closeOverlay = () => setIsOpen(false) return ( - + @@ -90,16 +90,16 @@ export const DialogOverlay = () => { onClickOutside={closeOverlay} width="small" > - + Are you sure? Cancel - + ) : null} - + ) } @@ -137,7 +137,7 @@ export const OverlayOnTopOfOverlay = () => { ) const [selectedItem, setSelectedItem] = React.useState() return ( - +