Skip to content

Latest commit

 

History

History
2462 lines (1670 loc) · 145 KB

CHANGELOG.md

File metadata and controls

2462 lines (1670 loc) · 145 KB

@primer/components

35.5.0

Minor Changes

Patch Changes

  • #2145 a2950ac4 Thanks @mperrotti! - Updates SegmentedControl component's keyboard navigation to align with the recommendations of GitHub's accessibility team.
  • #2143 d9b161a0 Thanks @mperrotti! - Fixes bugs in form components discovered while fixing/improving Storybook and docs.

35.4.0

Minor Changes

Patch Changes

  • #2099 40da598e Thanks @siddharthkp! - AnchoredOverlay: aria-expanded attribute is removed from anchor when overlay is not open
  • #2155 003cbcf0 Thanks @mperrotti! - Update Checkbox component to useIsomorphicLayoutEffect instead of useLayoutEffect to support SSR
  • #2125 78dc8134 Thanks @owenniblock! - Adds roles of tablist and tab to the TabNav component, required rearranging the HTML elements to be semantically correct
  • #2120 53713b2f Thanks @colebemis! - Deprecate SideNav in favor of NavList.

    Before

    <SideNav aria-label="Main">
      <SideNav.Link href="/" selected>
        Home
      </SideNav.Link>
      <SideNav.Link href="/about">About</SideNav.Link>
      <SideNav.Link href="/contact">Contact</SideNav.Link>
    </SideNav>

    After

    <NavList aria-label="Main">
      <NavList.Item href="/" aria-current="page">
        Home
      </NavList.Item>
      <NavList.Item href="/about">About</NavList.Item>
      <NavList.Item href="/contact">Contact</NavList.Item>
    </NavList>

35.3.0

Minor Changes

Patch Changes

  • #2083 ea69ccd6 Thanks @ty-v1! - Export new Dialog component from the @primer/react/drafts bundle:

    - import {Dialog} from '@primer/react/lib-esm/Dialog/Dialog'
    + import {Dialog} from '@primer/react/drafts'

35.2.2

Patch Changes

  • #2076 05301033 Thanks @colebemis! - Draft NavList.Item now accepts an as prop, allowing it to be rendered as a Next.js or React Router link
  • #2087 b319b29d Thanks @mperrotti! - Prevents the onRemove prop from being passed through to the HTML element from Token, AvatarToken, and IssueToken.
  • #2077 30f93ffb Thanks @colebemis! - Adds support for the sx prop on the draft implementation of NavList and all its subcomponents (e.g., NavList.Item)
  • #2054 a682735f Thanks @colebemis! - Fixes layout bug with ButtonGroup by changing the display property from inline-block to inline-flex
  • #2057 c8f7e235 Thanks @mperrotti! - - adds color-scheme style to inputs so they get the correct user-agent dark/light styles
    • crops ToggleSwitch knob's shadow inside the toggle switch boundaries
    • changes FormControl styles to prevent <select>, <textarea>, <input> from filling the parent's width when the block prop has not been passed to the input component

35.2.1

Patch Changes

  • #2013 5f6c5e22 Thanks @mperrotti! - 1. Fix a spacing issue with the loading spinner in a TextInputWithTokens 2. Bolds form validation text to be visually balanced with the icon
  • #2033 0d7a871a Thanks @mperrotti! - - Text input inner action's hover bg should not touch the text input edges
    • Increases touch target area of the text input inner action button
    • Deprecated children and variant props on the TextInputInnerAction component, but they're still supported for now.

35.2.0

Minor Changes

  • #1947 edc85c96 Thanks @mperrotti! - Adds the option to render a trailing action inside of the TextInput component

Patch Changes

  • #1998 cd8a5bb3 Thanks @mperrotti! - Updates the API for token components to align with our size-naming ADR, avatar guidelines, and icon guidelines

35.1.0

Minor Changes

Patch Changes

  • #1981 e9bb5956 Thanks @mperrotti! - Ensures select option text has acceptable contrast in Firefox when in dark mode
  • #1945 ef3b58a1 Thanks @pksjce! - Icon button fixes: Removes iconLabel and adds aria-label to the type
  • #1968 1b01485a Thanks @mperrotti! - Instead of rendering unexpected FormControl children before the rest of the content, we render them in the same spot we'd normally render a Primer input component

35.0.1

Patch Changes

  • #1958 be8f9014 Thanks @siddharthkp! - ActionList: Add focus styles for Windows high contrast mode ActionList: Fix incorrect role for ActionList.Group outside ActionMenu

35.0.0

Major Changes

  • #1893 17ef5ef8 Thanks @siddharthkp! -

    ActionList

    ⚠️ ActionList has been rewritten with a composable API, design updates and accessibility fixes.

    See full list of props and examples: https://primer.style/react/ActionList

    Before (v34) After (v35)
    <ActionList
      items={[
        {text: 'New file'},
        {text: 'Copy link'},
        {text: 'Edit file'},
        ActionList.Divider,
        {text: 'Delete file', variant: 'danger'}
      ]}
    />
    <ActionList>
      <ActionList.Item>New file</ActionList.Item>
      <ActionList.Item>Copy link</ActionList.Item>
      <ActionList.Item>Edit file</ActionList.Item>
      <ActionList.Divider />
      <ActionList.Item variant="danger">Delete file</ActionList.Item>
    </ActionList>
    <ActionList
      showItemDividers
      items={[
        {
          key: '0',
          leadingVisual: LinkIcon,
          text: 'github/primer'
        },
        {
          key: '1',
          leadingVisual: () => <Avatar src="https://github.com/mona.png" />,
          text: 'mona',
          description: 'Monalisa Octocat',
          descriptionVariant: 'block'
        },
        {
          key: '2',
          leadingVisual: GearIcon,
          text: 'View Settings',
          trailingVisual: ArrowRightIcon
        }
      ]}
    />
    <ActionList showDividers>
      <ActionList.Item>
        <ActionList.LeadingVisual>
          <LinkIcon />
        </ActionList.LeadingVisual>
        github/primer
      </ActionList.Item>
      <ActionList.Item>
        <ActionList.LeadingVisual>
          <Avatar src="https://github.com/mona.png" />
        </ActionList.LeadingVisual>
        mona
        <ActionList.Description variant="block">Monalisa Octocat</ActionList.Description>
      </ActionList.Item>
      <ActionList.Item>
        <ActionList.LeadingVisual>
          <GearIcon />
        </ActionList.LeadingVisual>
        View settings
        <ActionList.TrailingVisual>
          <ArrowRightIcon />
        </ActionList.TrailingVisual>
      </ActionList.Item>
    </ActionList>
    <ActionList
      groupMetadata={[
        {groupId: '0', header: {title: 'Live query'}},
        {groupId: '1', header: {title: 'Layout'}}
      ]}
      items={[
        {key: '0', text: 'repo:github/github', groupId: '0'},
        {key: '1', text: 'Table', groupId: '1'},
        {key: '2', text: 'Board', groupId: '1'},
        {key: '3', text: 'View settings'}
      ]}
    />
    <ActionList>
      <ActionList.Group title="Live query">
        <ActionList.Item>repo:github/github</ActionList.Item>
      </ActionList.Group>
      <ActionList.Divider />
    
      <ActionList.Group title="Layout">
        <ActionList.Item>Table</ActionList.Item>
        <ActionList.Item>Board Description</ActionList.Item>
      </ActionList.Group>
      <ActionList.Divider />
    
      <ActionList.Item>View settings</ActionList.Item>
    </ActionList>

    To continue to use the deprecated API for now, change the import path to @primer/react/deprecated:

    import {ActionList} from '@primer/react/deprecated'

    You can use the one-time codemod to change your import statements automatically.

  • #1883 310e6553 Thanks @siddharthkp! - ActionList2 exported types are now prefixed with ActionList:

    ListProps → ActionListProps
    GroupProps → ActionListGroupProps
    ItemProps → ActionListItemProps
    DescriptionProps → ActionListDescriptionProps
    LeadingVisualProps → ActionListLeadingVisualProps,
    TrailingVisualProps → ActionListTrailingVisualProps
    

    ActionMenu2 exported types are now prefixed with ActionMenu:

    MenuButtonProps → ActionMenuButtonProps
    MenuAnchorProps → ActionMenuAnchorProps
    
  • #1897 d4023572 Thanks @siddharthkp! -

    ActionMenu

    ⚠️ ActionMenu has been rewritten with a composable API, design updates and accessibility fixes.

    See full list of props and examples: https://primer.style/react/ActionMenu

    Main changes:

    1. Instead of using items prop, use ActionList inside ActionMenu
    2. Instead of using anchorContent on ActionMenu, use ActionMenu.Button with children
    3. Instead of using onAction prop on ActionMenu, use onSelect prop on ActionList.Item
    4. Instead of using groupMetadata on ActionMenu, use ActionList.Group
    5. Instead of overlayProps on ActionMenu, use ActionMenu.Overlay
    Before (v34) After (v35)
    <ActionMenu
      anchorContent="Menu"
      onAction={fn}
      items={[
        {text: 'New file'},
        {text: 'Copy link'},
        {text: 'Edit file'},
        ActionMenu.Divider,
        {text: 'Delete file', variant: 'danger'}
      ]}
      overlayProps={{width: 'small'}}
    />
    <ActionMenu>
      <ActionMenu.Button>Menu</ActionMenu.Button>
      <ActionMenu.Overlay width="small">
        <ActionList>
          <ActionList.Item onSelect={fn}>New file</ActionList.Item>
          <ActionList.Item>Copy link</ActionList.Item>
          <ActionList.Item>Edit file</ActionList.Item>
          <ActionList.Divider />
          <ActionList.Item variant="danger">Delete file</ActionList.Item>
        </ActionList>
      </ActionMenu.Overlay>
    </ActionMenu>

    To continue to use the deprecated API for now, change the import path to @primer/react/deprecated:

    import {ActionMenu} from '@primer/react/deprecated'

    You can use the one-time codemod to change your import statements automatically.

  • #1898 d6d1ca4c Thanks @siddharthkp! -

    DropdownMenu

    ⚠️ DropdownMenu has been deprecated in favor of ActionMenu with ActionList

    See example with selection: https://primer.style/react/ActionMenu#with-selection

    Migration guide:

    1. Instead of using items prop, use ActionList inside ActionMenu
    2. Use selectionVariant="single" on ActionList to set the right semantics for selection
    3. Instead of using selectedItem prop, use selected prop on ActionList.Item
    4. Instead of using renderAnchor and placeholder props on DropdownMenu, use ActionMenu.Button or ActionMenu.Anchor
    5. Instead of using onChange prop on DropdownMenu, use onSelect prop on ActionList.Item
    6. Instead of using groupMetadata on DropdownMenu, use ActionList.Group
    7. Instead of overlayProps on DropdownMenu, use ActionMenu.Overlay
    Before (v34) After (v35)
    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 (
        <DropdownMenu
          renderAnchor={({children, ...anchorProps}) => (
            <ButtonInvisible {...anchorProps}>
              {children} <GearIcon />
            </ButtonInvisible>
          )}
          placeholder="Field type"
          items={fieldTypes}
          selectedItem={selectedType}
          onChange={setSelectedType}
          overlayProps={{width: 'medium'}}
        />
      )
    }
    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(
        <ActionMenu>
          <ActionMenu.Button aria-label="Select field type">{selectedType.name || 'Field type'}</ActionMenu.Button>
          <ActionMenu.Overlay width="medium">
            <ActionList selectionVariant="single">
              {fieldTypes.map(type => (
                <ActionList.Item
                  key={type.id}
                  selected={type.id === selectedType.id}
                  onSelect={() => setSelectedType(type)}
                >
                  {type.name}
                </ActionList.Item>
              ))}
            </ActionList>
          </ActionMenu.Overlay>
        </ActionMenu>
      )
    }

    To continue to use the deprecated API for now, change the import path to @primer/react/deprecated:

    import {DropdownMenu} from '@primer/react/deprecated'

    You can use the one-time codemod to change your import statements automatically.

    drafts/DropdownMenu2

    ⚠️ DropdownMenu2 has been removed in favor of ActionMenu with ActionList

  • #1889 e9b81fae Thanks @mperrotti! -

    Label

    The Label component's API and visual design have been updated to be consistent with its counterpart in Primer ViewComponents' Label component.

    ⚠️ Major changes in the new Label component:

    • No more medium size - only small and large
    • Labels are outlined by default, so the outline prop has been removed
    • Custom text and background colors are discouraged, but still possible via the sx prop

    If you were using the Label component to render issue/PR labels, use the IssueLabelToken component instead.

    Before (v34) After (v35)
    import {Label} from '@primer/react'
    
    function Example() {
      return (
        <>
          <Label outline>default</Label>
          <Label variant="small" outline sx={{borderColor: 'danger.emphasis', color: 'danger.fg'}}>
            danger
          </Label>
        </>
      )
    }
    import {Label} from '@primer/react'
    
    function Example() {
      return (
        <>
          <Label>default</Label>
          <Label size="small" variant="danger">
            danger
          </Label>
        </>
      )
    }

    To continue to use the deprecated API for now, change the import path to @primer/react/deprecated:

    import {Label} from '@primer/react/deprecated'

    You can use the one-time codemod to change your import statements automatically.

  • #1908 61404aed Thanks @pksjce! -

    Button

    Before v35, Button was a set of seven independent components. In v35, we've simplified the Button API.

    Button variants

    We now support a variant property which takes values primary, invisible, outline and danger

    Before (v34) After (v35)
    import {ButtonPrimary, ButtonInvisible, ButtonOutline, ButtonDanger} from '@primer/react'
    
    function Example() {
      return (
        <>
          <ButtonPrimary>Primary Button</ButtonPrimary>
          <ButtonInvisible>Invisible Button</ButtonInvisible>
          <ButtonOutline>Outline Button</ButtonOutline>
          <ButtonDanger>Danger Button</ButtonDanger>
        </>
      )
    }
    import {Button} from '@primer/react'
    
    function Example() {
      return (
        <>
          <Button variant="primary">Primary Button</Button>
          <Button variant="invisible">Invisible Button</Button>
          <Button variant="outline">Outline Button</Button>
          <Button variant="danger">Danger Button</Button>
        </>
      )
    }

    Leading and trailing icons

    Previously including icons inside buttons required a lot of custom styling. In the new Button component, we now support first-class leadingIcon and trailingIcon props:

    Before (v34) After (v35)
    <Button>
      <SearchIcon />
      Search
    </Button>
    <Button leadingIcon={SearchIcon}>Search</Button>

    Icon buttons

    Icon-only buttons are common in many applications. We now have a component designed for this use-case:

    Before (v34) After (v35)
    <Button>
      <XIcon />
    </Button>
    <IconButton aria-label="Close button" icon={XIcon} />

    Size property

    Previously, we used a variant prop to set the size of buttons. We now have a prop called size which is more semantically correct.

    Before (v34) After (v35)
    <Button variant="small">Small button</Button>
    <Button size="small">Small button</Button>
  • #1900 d61b28ad Thanks @mperrotti! -

    ChoiceFieldset

    ⚠️ The CheckboxGroup and RadioGroup components are replacing the ChoiceFieldset component.

    CheckboxGroup and RadioGroup have the ability to render contextual content with your fieldset: labels, validation statuses, captions. They also handle the ARIA attributes that make the form controls accessible to assistive technology.

    Before (v34) After (v35)
    import {ChoiceFieldset} from '@primer/react'
    
    function Example() {
      return (
        <>
          {/* Multi-select */}
          <ChoiceFieldset>
            <ChoiceFieldset.Legend>Preferred Primer component interface</ChoiceFieldset.Legend>
            <ChoiceFieldset.List selectionVariant="multiple">
              <ChoiceFieldset.Item value="figma">Figma library</ChoiceFieldset.Item>
              <ChoiceFieldset.Item value="css">Primer CSS</ChoiceFieldset.Item>
              <ChoiceFieldset.Item value="react">Primer React components</ChoiceFieldset.Item>
              <ChoiceFieldset.Item value="viewcomponents">Primer ViewComponents</ChoiceFieldset.Item>
            </ChoiceFieldset.List>
          </ChoiceFieldset>
    
          {/* Single select */}
          <ChoiceFieldset>
            <ChoiceFieldset.Legend>Preferred Primer component interface</ChoiceFieldset.Legend>
            <ChoiceFieldset.List>
              <ChoiceFieldset.Item value="figma">Figma library</ChoiceFieldset.Item>
              <ChoiceFieldset.Item value="css">Primer CSS</ChoiceFieldset.Item>
              <ChoiceFieldset.Item value="react">Primer React components</ChoiceFieldset.Item>
              <ChoiceFieldset.Item value="viewcomponents">Primer ViewComponents</ChoiceFieldset.Item>
            </ChoiceFieldset.List>
          </ChoiceFieldset>
        </>
      )
    }
    import {CheckboxGroup, RadioGroup, FormControl, Checkbox, Radio} from '@primer/react'
    
    function Example() {
      return (
        <>
          {/* Multi-select */}
          <CheckboxGroup>
            <CheckboxGroup.Label>Preferred Primer component interface</CheckboxGroup.Label>
            <FormControl>
              <Checkbox value="figma" />
              <FormControl.Label>Figma</FormControl.Label>
            </FormControl>
            <FormControl>
              <Checkbox value="css" />
              <FormControl.Label>CSS</FormControl.Label>
            </FormControl>
            <FormControl>
              <Checkbox value="react" />
              <FormControl.Label>Primer React components</FormControl.Label>
            </FormControl>
            <FormControl>
              <Checkbox value="viewcomponents" />
              <FormControl.Label>Primer ViewComponents</FormControl.Label>
            </FormControl>
          </CheckboxGroup>
    
          {/* Single select */}
          <RadioGroup name="preferred-primer">
            <RadioGroup.Label>Preferred Primer component interface</RadioGroup.Label>
            <FormControl>
              <Radio value="figma" />
              <FormControl.Label>Figma</FormControl.Label>
            </FormControl>
            <FormControl>
              <Radio value="css" />
              <FormControl.Label>CSS</FormControl.Label>
            </FormControl>
            <FormControl>
              <Radio value="react" />
              <FormControl.Label>Primer React components</FormControl.Label>
            </FormControl>
            <FormControl>
              <Radio value="viewcomponents" />
              <FormControl.Label>Primer ViewComponents</FormControl.Label>
            </FormControl>
          </RadioGroup>
        </>
      )
    }

    To continue to use the deprecated API for now, change the import path to @primer/react/deprecated:

    import {ChoiceFieldset} from '@primer/react/deprecated'

    You can use the one-time codemod to change your import statements automatically.

  • #1882 df757521 Thanks @colebemis! -

    PageLayout

    PageLayout is being graduated from the drafts bundle to the main bundle.

    To upgrade, rewrite your imports accordingly:

    - import {PageLayout} from '@primer/react/drafts'
    + import {PageLayout} from '@primer/react'
  • #1888 f94dcd33 Thanks @mperrotti! -

    FormGroup, InputField, ChoiceInputField

    ⚠️ The FormControl component is replacing the FormGroup, InputField, and ChoiceInputField components. It has the ability to render contextual content with your inputs: labels, validation statuses, captions. It also handles the ARIA attributes that make the form controls accessible to assistive technology.

    Before (v34) After (v35)
    import {FormControl, Checkbox, TextInput} from '@primer/react'
    
    function Example() {
      return (
        <>
          <FormGroup>
            <FormGroup.Label htmlFor="example-text">Example text</FormGroup.Label>
            <TextInput id="example-text" />
          </FormGroup>
          {/* OR */}
          <InputField>
            <InputField.Label>Example text</InputField.Label>
            <TextInput />
          </InputField>
          {/* OR */}
          <ChoiceInputField>
            <ChoiceInputField.Label>Example text</ChoiceInputField.Label>
            <Checkbox />
          </ChoiceInputField>
        </>
      )
    }
    import {FormGroup, TextInput} from '@primer/react'
    
    function Example() {
      return (
        <>
          <FormControl>
            <FormControl.Label>Example text</FormControl.Label>
            <TextInput />
          </FormControl>
          {/* OR */}
          <FormControl>
            <FormControl.Label>Example text</FormControl.Label>
            <Checkbox />
          </FormControl>
        </>
      )
    }
    import {InputField, TextInput} from '@primer/react'
    
    function Example() {
      return (
        <InputField>
          <InputField.Label>Example text</InputField.Label>
          <TextInput />
        </InputField>
      )
    }
    import {FormControl, TextInput} from '@primer/react'
    
    function Example() {
      return (
        <FormControl>
          <FormControl.Label>Example text</FormControl.Label>
          <TextInput />
        </FormControl>
      )
    }

    To continue to use the deprecated API for now, change the import path to @primer/react/deprecated:

    import {FormGroup, ChoiceInputField, InputField} from '@primer/react/deprecated'

    You can use the one-time codemod to change your import statements automatically.

  • #1881 8cd12439 Thanks @pksjce! -

    SelectMenu

    ⚠️ SelectMenu has been deprecated. Please use ActionMenu instead.

    Before After
    <SelectMenu>
      <Button as="summary">Projects</Button>
      <SelectMenu.Modal>
        <SelectMenu.Header>Projects</SelectMenu.Header>
        <SelectMenu.List>
          <SelectMenu.Item href="#">Primer React bugs</SelectMenu.Item>
          <SelectMenu.Item href="#">Primer React roadmap</SelectMenu.Item>
          <SelectMenu.Item href="#">Project 3</SelectMenu.Item>
          <SelectMenu.Item href="#">Project 4</SelectMenu.Item>
        </SelectMenu.List>
      </SelectMenu.Modal>
    </SelectMenu>
    <ActionMenu>
      <ActionMenu.Button>Projects</ActionMenu.Button>
      <ActionMenu.Overlay>
        <ActionList showDividers>
          <ActionList.Group title="Projects">
            <ActionList.Item>Primer React bugs</ActionList.Item>
            <ActionList.Item>Primer React roadmap</ActionList.Item>
            <ActionList.Item>Project three</ActionList.Item>
            <ActionList.Item>Project four</ActionList.Item>
          </ActionList.Group>
        </ActionList>
      </ActionMenu.Overlay>
    </ActionMenu>

    See https://primer.style/react/ActionMenu for more migration examples.

    Dropdown

    ⚠️ Dropdown has been deprecated. Please use ActionMenu instead.

    Before After
    const fieldTypes = [
      {leadingVisual: TypographyIcon, text: 'Text'},
      {leadingVisual: NumberIcon, text: 'Number'}
    ]
    
    const Example = () => {
      const [selectedItem, setSelectedItem] = React.useState()
    
      return (
        <DropdownMenu
          renderAnchor={({children, ...anchorProps}) => <ButtonInvisible {...anchorProps}>{children}</ButtonInvisible>}
          placeholder="Select a field type"
          items={fieldTypes}
          selectedItem={selectedItem}
          onChange={() => setSelectedIndex(index)}
        />
      )
    }
    const fieldTypes = [
      {icon: <TypographyIcon />, name: 'Text'},
      {icon: <NumberIcon />, name: 'Number'}
    ]
    
    const Example = () => {
      const [selectedItem, setSelectedItem] = React.useState()
    
      return (
        <ActionMenu>
          <ActionMenu.Button>{selectedItem ? selectedItem.name : 'Select a field type'}</ActionMenu.Button>
          <ActionMenu.Overlay>
            <ActionList selectionVariant="single">
              {fieldTypes.map(field => (
                <ActionList.Item onSelect={() => setSelectedItem(field)} key={field.name}>
                  <ActionList.LeadingVisual>{field.icon}</ActionList.LeadingVisual>
                  {field.name}
                </ActionList.Item>
              ))}
            </ActionList>
          </ActionMenu.Overlay>
        </ActionMenu>
      )
    }

    See https://primer.style/react/ActionMenu for more migration examples.

    Flex

    ⚠️ Flex has been deprecated. Please use Box instead.

    Before After
    <Flex flexWrap="nowrap">
      <Box p={3} color="fg.onEmphasis" bg="accent.emphasis">
        Item 1
      </Box>
    </Flex>
    <Box display="flex" flexWrap="nowrap">
      <Box p={3} color="fg.onEmphasis" bg="accent.emphasis">
        Item 1
      </Box>
    </Box>

    Grid

    ⚠️ Grid has been deprecated. Please use Box instead.

    Before After
    <Grid gridTemplateColumns="repeat(2, auto)" gridGap={3}>
      <Box p={3} color="fg.onEmphasis" bg="accent.emphasis">
        1
      </Box>
      <Box p={3} color="fg.onEmphasis" bg="attention.emphasis">
        2
      </Box>
    </Grid>
    <Box display="grid" gridTemplateColumns="repeat(2, auto)" gridGap={3}>
      <Box p={3} color="fg.onEmphasis" bg="accent.emphasis">
        1
      </Box>
      <Box p={3} color="fg.onEmphasis" bg="attention.emphasis">
        2
      </Box>
    </Box>

    BorderBox

    ⚠️ BorderBox has been deprecated. Please use Box instead.

    Before After
    <BorderBox>Item 1</BorderBox>
    <Box borderWidth="1px" borderStyle="solid" borderColor="border.default" borderRadius={2}>
      Item 1
    </Box>

    Position

    ⚠️ Position has been deprecated. Please use Box instead.

    Before After
    <>
      <Position position="absolute">...</Position>
      <Absolute>...</Absolute>
      <Relative>...</Relative>
      <Fixed>...</Fixed>
      <Sticky>...</Sticky>
    </>
    <>
      <Box position="absolute">...</Box>
      <Box position="absolute">...</Box>
      <Box position="relative">...</Box>
      <Box position="fixed">...</Box>
      <Box position="sticky">...</Box>
    </>

Minor Changes

Patch Changes

  • #1915 a98091c1 Thanks @siddharthkp! - - Update styles for default variant of Button's active state
    • Use active state for Button when it is used to open an Overlay
  • #1934 33da6a0e Thanks @rezrah! - Surfaced the following components and hooks from the root index:

    • Portal
    • AnchoredOverlay
    • useFocusTrap
    • useFocusZone (and types)
    • sx (and types)
    • ConfirmationDialogProps

    These exports can now be imported from the root index, rather than from their nested subfolders.

    E.g.

    - import { ConfirmationDialogProps } from '@primer/react/lib-esm/Dialog/ConfirmationDialog';
    + import { ConfirmationDialogProps } from '@primer/react';

34.7.1

Patch Changes

  • #1913 92a02377 Thanks @siddharthkp! - Fixes the theming implementation with server side rendering to use a CSRF safe approach

34.7.0

Minor Changes

  • #1862 eebb3f27 Thanks @mperrotti! - Adds CheckboxGroup and RadioGroup components to replace the ChoiceFieldset component

Patch Changes

  • #1886 ecbf923e Thanks @mperrotti! - Makes it possible to render leading and trailing visuals in TextInputWithTokens just like we do in TextInput

34.6.0

Minor Changes

Patch Changes

  • #1866 01efa73f Thanks @siddharthkp! - Fix the behavior of Escape key in nested overlays #1854, now only the top most overlay will close instead of all of them.
  • #1826 004c4623 Thanks @PeterYangIO! - Remove unnecessary "required field" label title in favor for native required input attribute
  • #1864 8558ae5b Thanks @pksjce! - Small fixes to icon button sizes. Truthy checks for children props

34.5.0

Minor Changes

  • #1836 7e8ae653 Thanks @mperrotti! - Introduces FormControl component. The FormControl component combines the functionality of InputField and ChoiceInputField, and will replace FormGroup, InputField, and ChoiceInputField.

Patch Changes

34.4.0

Minor Changes

Patch Changes

  • #1824 4eab65e5 Thanks @siddharthkp! - Overlay: Attach escape handler to overlay container instead of document to fix stopPropagation
  • #1840 1c4786c7 Thanks @jclem! - Set Node.js and npm versions to ">=12" and ">=7", respectively, in package.json manifests, and update package-lock.json files accordingly.
  • #1842 11011f55 Thanks @jclem! - Allow KeyPaths type to accept any type in order to remove need for // @ts-ignore internally.

34.3.0

Minor Changes

Patch Changes

  • #1759 493c6ea1 Thanks @siddharthkp! - AnchoredOverlay: Add support for passing an id to the anchor. Remove unnecessary aria-labelledby on anchor. ActionMenu v2: Add aria-labelledby for ActionList
  • #1804 aa09ed79 Thanks @rezrah! - Fixes bug in PointerBox component where caret doesn't inherit correct styling. Backwards compatible with previous API.

34.2.0

Minor Changes

Patch Changes

  • #1794 a8c427da Thanks @rezrah! - replace Location | Pathname union type for to prop with more appropriate To
  • #1791 6a8472b4 Thanks @rezrah! - Fix type errors due to missing pathname (string) in union type for LocationDescriptor

34.1.0

Minor Changes

  • #1611 11382eeb Thanks @mperrotti! - Adds TextInputField, CheckboxInputField, and RadioInputField components. Also adds a few internal (private to primer/react) components to support form fields

Patch Changes

34.0.1

Patch Changes

34.0.0

Major Changes

  • #1676 1195336e Thanks @colebemis! - Rename npm package from @primer/components to @primer/react

    To upgrade, run:

    npm uninstall @primer/components
    npm install @primer/react

    Then update your imports:

    - import {Box} from '@primer/components'
    + import {Box} from '@primer/react'

33.1.0

Minor Changes

Patch Changes

  • #1675 2380b668 Thanks @siddharthkp! - ActionMenu v2: Added ActionMenu.Overlay which accepts props to customize the Menu overlay.

33.0.0

Major Changes

Minor Changes

Patch Changes

  • #1668 98dc6336 Thanks @siddharthkp! - ActionList: Fix multiple selection svg by overriding global shape-rendering for github.com
  • #1596 5c6dc644 Thanks @dmarcey! - Fix alignment of items in ActionList (single-select) if some of the items have wrapping text.

32.1.0

Minor Changes

Patch Changes

  • #1648 8b40a0a9 Thanks @jfuchs! - Fixed a bug with Overlay's type where DOM props were not allowed.

32.0.1

Patch Changes

32.0.0

Major Changes

Patch Changes

  • #1486 34cfca53 Thanks @pksjce! - ActionList: Add focus and hover colors to all themes in Item using functional variables

31.2.0

Minor Changes

  • #1544 5b55b0ab Thanks @jfuchs! - The sx prop now has types that will inform autocomplete for color and shadow values that are key paths into the theme.

Patch Changes

  • #1583 24b1ebbc Thanks @pksjce! - Add a utility to provide useIsoMorphicEffect function and use that instead of useLayoutEffect everywhere
  • #1592 8d3d491f Thanks @rezrah! - Fixes a styling bug in TextInput components while using its icon and block props together
  • #1609 5eb7ade9 Thanks @siddharthkp! - Rename @primer/components/unreleased to @primer/components/drafts to avoid confusion when referring to it.

31.1.0

Minor Changes

  • #1523 56e2f159 Thanks @mperrotti! - Add the ability to truncate tokens in the TextInputWithToken component when the input is not focused

Patch Changes

  • #1529 da566044 Thanks @mperrotti! - Fixes a bug in TextInputWithTokens where the next token would not receive focus after the user deleted the first token using the keyboard

31.0.1

Patch Changes

  • #1521 28b5980c Thanks @siddharthkp! - Add trailingVisual prop to ActionList/ActionMenu. Deprecate trailingIcon and trailingText props.

31.0.0

Major Changes

Patch Changes

30.3.0

Minor Changes

  • #1490 c156b07a Thanks @mperrotti! - Adds Autocomplete, AutocompleteMenu, AutocompleteInput, and AutocompleteOverlay components

30.2.1

Patch Changes

30.2.0

Minor Changes

  • #1497 b9d6a662 Thanks @jfuchs! - Updated ActionList's ItemInput type to accept DOM props for divs when renderItem is not provided

30.1.0

Minor Changes

  • #1463 bde3a034 Thanks @jfuchs! - ActionList.item accepts an as prop, allowing it to be a link, or (in combination with the renderItem prop) a Next.js or React Router link

Patch Changes

  • #1471 f1cebb7e Thanks @smockle! - Change the button which receives focus when a 'ConfirmationDialog' opens from the secondary (e.g. 'Cancel') to the primary (e.g. 'OK'). Fixes github/primer#313.

30.0.0

Major Changes

  • #1448 1a39fb02 Thanks @SferaDev! - Remove .Breadcrumb classname from the root element of the Breadcrumbs component. This change shouldn't break anything unless you have styles, scripts, or tests that reference the .Breadcrumb classname.

Minor Changes

Patch Changes

29.1.1

Patch Changes

  • #1441 f3f5afb9 Thanks @jfuchs! - Fix type error where css is a required prop of some components by excluding storybook stories from TypeScript compilation for builds

29.1.0

Minor Changes

29.0.0

Major Changes

  • #1414 f4e1de6d Thanks @jfuchs! - Removed system props support from <TextInput> and fixed its type definition.

Minor Changes

Patch Changes

28.5.0

Minor Changes

  • #1398 e4dac575 Thanks @jfuchs! - Default portal containers created by primer are absolutely positioned at 0,0
  • #1385 5470b61b Thanks @jfuchs! - Make top and left position explicit props of Overlay handled separately from other styles
  • #1388 83b888f0 Thanks @jfuchs! - Overlay takes a portalContainerName prop. This allows overlays with an anchor inside a scrolling container to track with their anchor, so long as the specified portal is also inside that scrolling container.

28.4.0

Minor Changes

Patch Changes

  • #1372 23be0ed7 Thanks @jfuchs! - Extends DropdownMenu to allow anchorRef, open, and onOpenChange props.
  • #1387 6b4d52da Thanks @jfuchs! - Guard against MediaQueryList.addEventListener calls where unavailable and possibly fall back to .addListener

28.3.2

Patch Changes

  • #1368 36f156a0 Thanks @dgreif! - Allow anchorRef to be passed into SelectPanel if you want to use an external anchor

28.3.1

Patch Changes

28.3.0

Minor Changes

  • #1316 4c063317 Thanks @VanAnderson! - The following components have been deprecated in favor of the Box component:

    Component Replacement
    Flex <Box display="flex">
    Grid <Box display="grid">
    Position <Box>
    Absolute <Box position="absolute">
    Fixed <Box position="fixed">
    Relative <Box position="relative">
    Sticky <Box position="sticky">
    BorderBox <Box borderWidth="1px" borderStyle="solid" borderColor="border.primary" borderRadius={2}>

    There is a codemod available to upgrade these components:

    • TypeScript example:

      npx jscodeshift -t node_modules/@primer/react/codemods/deprecateUtilityComponents.js
      --parser=tsx path/to/workspace/src/*.tsx
    • Babel example:

      npx jscodeshift -t node_modules/@primer/react/codemods/deprecateUtilityComponents.js
      --parser=babel path/to/workspace/src/*.tsx
  • #1336 489a718b Thanks @VanAnderson! - System props are deprecated in all components except Box. Move all system props into the sx prop instead. Example:

    - <Button mr={2}>...</Button>
    + <Button sx={{mr: 2}}>...</Button>

    There is a codemod available to migrate from system props to the sx prop:

    • TypeScript example:

      npx jscodeshift -t node_modules/@primer/react/codemods/removeSystemProps.js
      --parser=tsx path/to/workspace/src/*.tsx
    • Babel example:

      npx jscodeshift -t node_modules/@primer/react/codemods/removeSystemProps.js
      --parser=babel path/to/workspace/src/*.tsx

Patch Changes

  • #1308 a8f3ca6d Thanks @dgreif! - Focus zones will now update active-descendant on mousemove over focusable elements. ActionList has been updated to handle direct (key press) vs indirect (mousemove, DOM change, etc.) changes to active-descendant, and will use a distinct background color for the directly activated items.

28.2.5

Patch Changes

  • #1251 528e9a41 Thanks @VanAnderson! - Call useOnOutsideClick handlers in reverse order that they are registered, and allow propagation to stop if default is prevented or an non-outside click is detected.
  • #1312 76a38432 Thanks @smockle! - Ensure clicking an AnchoredOverlay’s trigger allows it to close without immediately reopening.

28.2.4

Patch Changes

  • #1293 1148a718 Thanks @smockle! - Restore "fix: Don’t focus first 'Item' of 'DropdownMenu' and 'SelectMenu' on open" by deferring the removal of a temporary tabIndex until focus moves within the container.
  • #1288 15207119 Thanks @dgreif! - Focus zones with an activeDescendantControl will now activate the first descendant as soon as the control element is focused, rather than waiting for an up/down arrow press. Descendants stay active until the control element is blurred. This is a breaking change to useFocusZone, but this behavior is still considered to be in alpha.

28.2.3

Patch Changes

28.2.2

Patch Changes

  • 2793ef48 #1286 Thanks @colebemis! - ThemeProvider now uses the first defined color scheme if passed an invalid color scheme name

28.2.1

Patch Changes

28.2.0

Minor Changes

  • 8368a83e #1238 Thanks @dgreif! - New sizes for Overlay and Dialog. Sizes have been changed from abbreviations to full words. xs -> xsmall, sm -> small, md -> medium, lg -> large, xl -> xlarge. The sizing for Overlay has also been updated to provide a wider range of options. The original values for Overlay were based on the needs of Dialog, but Dialog is not reliant on Overlay so they don't need to have similar sizing. This is technically a breaking change, but is being released as a minor because these components are both still in alpha status.

Patch Changes

  • 02e86095 Thanks @dgreif! - Allow filterValue to be provided to SelectPanel
  • 10df320b #1247 Thanks @dgreif! - Handle overflow and active-descendant scrolling within SelectPanel
  • 25d88c49 #1253 Thanks @dgreif! - Correct font size and truncate for description within ActionList Items
  • 9cb715cd #1258 Thanks @dgreif! - prevent focusTrap from causing a blur if trap container is not in DOM
  • aa7d80fc #1246 Thanks @dgreif! - Fix border radius on buttons and title font-weight in ConfirmationDialog

28.1.1

Patch Changes

  • c1991318 #1158 Thanks @dgreif! - Add background styles for focused action list items, instead of using default outline

28.1.0

Minor Changes

Patch Changes

  • e009e321 #1235 Thanks @VanAnderson! - Dialog properly auto-focuses cancel button by default when originating from a FocusZone/FocusTrap.

28.0.4

Patch Changes

28.0.3

Patch Changes

  • c63fa4b5 #1215 Thanks @dgreif! - Add selectionVariant: 'multiple' for Items. These will use a checkbox input instead of a checkmark icon for selected state
  • 4ab3d175 #1222 Thanks @dgreif! - Trap focus in AnchoredOverlay as soon as it opens, regardless of the event that triggered it to open

28.0.2

Patch Changes

  • d20a5996 #1209 Thanks @dgreif! - Allow Overlay height and width to be set through AnchoredOverlay Allow ActionList Items to supply an id instead of key Performance improvements when ActionList is not given any groups Enable focus zone as soon as AnchoredOverlay opens
  • d29741ca #1196 Thanks @dgreif! - Allow custom children in ActionItem. text and description can still be provided as a shortcut, but children is now available if you need more control over the rending of the item, without sacrificing benefits from Item by using renderItem.
  • 7aeb53fe #1200 Thanks @dgreif! - Perform ActionMenu actions after overlay has closed. This allows the action to move focus if so desired, without the ActionMenu focus trap preventing focus from moving away.

28.0.1

Patch Changes

  • b319ce43 #1197 Thanks @dmarcey! - Typescript declare files will now be published to the lib-esm directory, as well as lib

28.0.0

Major Changes

  • 5f85394d #1157 Thanks @dgreif! - Removed useMouseIntent in favor of :focus-visible. With the removal of useMouseIntent, the intent-mouse class will no longer be added to the <body>. Since :focus-visible is a relatively new psuedo-class, a polyfill is included. Any focused elements that meet the criteria for :focus-visible will also have a focus-visible class added to them by the polyfill.

Patch Changes

27.0.0

Major Changes

  • db478205 #1147 Thanks @colebemis! - Type definitions are now being generated by TypeScript instead of manually maintained. These new type definitions may differ from the previous type definitions and cause breaking changes. If you experience any new TypeScript errors, feel free to create an issue or reach out in Slack (#design-systems).

    Breaking changes

    • The following types are no longer exported:

      BaseProps
      UseDetailsProps
      AnchoredPositionHookSettings
      AnchorAlignment
      AnchorSide
      PositionSettings
      PaginationHrefBuilder
      PaginationPageChangeCallback
      PositionComponentProps
      
    • Props are now defined with types instead of interfaces which means in some cases you may not be able to create interfaces that extend them. To work around this issue, you may need to convert your interfaces to types:

      import {BoxProps} from '@primer/react'
      
      - interface MyFancyBox extends BoxProps {...}
      + type MyFancyBox = BoxProps & {...}
    • Some components now expect more specific ref types. For example:

      - const ref = React.useRef<HTMLElement>(null)
      + const ref = React.useRef<HTMLButtonElement>(null)
      
      return <Button ref={ref}>...</Button>

26.0.0

Major Changes

  • 016a273f #1115 Thanks @VanAnderson! - Removes deprecated presentational theme variables in favor of functional variables for styling components that are consistent across multiple themes.

    Migration guide

    If you don't use any color-related system props (e.g. color, bg, borderColor), all components should work without changes. If you're using color-related system props, you'll need to update them to use the new functional variables. Reference the tables below to see how old variables map to new functional variables.

    If you have any questions, feel free to reach out in the #design-systems channel.

    Text

    v25 v26
    color="text.gray" color="text.secondary"
    color="text.grayLight" color="text.tertiary"
    color="text.grayDark" color="text.primary"
    color="text.red" color="text.danger"
    color="text.white" color="text.inverse"
    color="gray.6" color="text.secondary"
    color="gray.5" color="text.tertiary"
    color="gray.9" color="text.primary"
    color="red.6" color="text.danger"
    color="white" color="text.inverse"
    color="blue.5" color="text.link"
    color="gray.4" color="text.disabled"
    color="green.5" color="text.success"
    color="yellow.8" color="text.warning"

    Icon

    v25 v25
    color="gray.9" color="icon.primary"
    color="gray.6" color="icon.secondary"
    color="gray.4" color="icon.tertiary"
    color="blue.5" color="icon.info"
    color="red.5" color="icon.danger"
    color="green.6" color="icon.success"
    color="yellow.8" color="icon.warning"

    Border

    v25 v26
    borderColor="border.blue" borderColor="border.info"
    borderColor="border.blueLight" n/a
    borderColor="border.grayLight" borderColor="border.primary"
    borderColor="border.grayDark" borderColor="border.tertiary"
    borderColor="border.grayDarker" n/a
    borderColor="border.green" borderColor="border.success"
    borderColor="border.greenLight" n/a
    borderColor="border.purple" n/a
    borderColor="border.red" borderColor="border.danger"
    borderColor="border.redLight" n/a
    borderColor="border.white" borderColor="border.inverse"
    borderColor="border.whiteFace" n/a
    borderColor="border.yellow" borderColor="border.warning"
    borderColor="border.blackFade" borderColor="fade.fg15"
    borderColor="border.whiteFade" borderCOlor="fade.white15"
    borderColor="blue.5" borderColor="border.info"
    borderColor="gray.2" borderColor="border.primary"
    borderColor="gray.3" borderColor="border.tertiary"
    borderColor="green.4" borderColor="border.success"
    borderColor="red.5" borderColor="border.danger"
    borderColor="white" borderColor="border.inverse"

    Background

    v25 v26
    bg="white" bg="bg.primary"
    bg="bg.grayLight" bg="bg.secondary"
    bg="bg.gray" bg="bg.tertiary"
    bg="bg.grayDark" bg="bg.canvasInverse"
    bg="blue.0" bg="bg.info"
    bg="blue.5" bg="bg.infoInverse"
    bg="red.0" bg="bg.danger"
    bg="red.5" bg="bg.dangerInverse"
    bg="green.1" bg="bg.success"
    bg="green.5" bg="bg.successInverse"

    Labels

    Note the change in pluralization from 'labels' to 'label'.

    v25 v26
    color="labels.grayDarkText" color="label.primary.text
    borderColor="labels.gray" borderColor="label.primary.border
    color="labels.grayText" color="label.secondary.text
    borderColor="labels.gray" borderColor="label.secondary.border
    color="labels.blueText" color="label.info.text
    borderColor="labels.blue" borderColor="label.info.border
    color="labels.greenText" color="label.success.text
    borderColor="labels.green" borderColor="label.success.border
    color="labels.yellowText" color="label.warning.text
    borderColor="labels.yellow" borderColor="label.warning.border
    color="labels.redText" color="label.danger.text
    borderColor="labels.red" borderColor="label.danger.border
    color="labels.orangeText" color="label.primary.text
    borderColor="labels.orange" borderColor="label.primary.text
    color="labels.pinkText" n/a
    borderColor="labels.pink" n/a
    color="labels.purpleText" n/a
    borderColor="labels.purple" n/a

    Counters

    v25 v26
    scheme="gray" scheme="primary"
    scheme="gray-light" scheme="secondary"

    Timeline

    v25 v26
    bg="red.5" bg="prState.closed.bg"
    bg="green.5" bg="prState.open.bg"
    bg="purple.5" bg="prState.merged.bg"
    bg="gray.5" bg="prState.draft.bg"
    color="white" (context: closed PR icon) color="prState.closed.text"
    color="white" (context: open PR icon) color="prState.open.text"
    color="white" (context: merged PR icon) color="prState.merged.text"
    color="white" (context: merged PR icon) color="prState.draft.text"

25.0.0

Major Changes

  • 8799f74a #1112 Thanks @colebemis! - Primer React now supports color modes! 🎉

    See the new Theming documentation for more details.

    Breaking changes

    • You'll need to replace the ThemeProvider from styled-components with the new Primer React ThemeProvider:
    - import {ThemeProvider} from 'styled-components'
    - import {theme} from '@primer/react
    + import {ThemeProvider} from '@primer/react'
    
    function App() {
      return (
    -   <ThemeProvider theme={theme}>
    +   <ThemeProvider>
          <div>your app here...</div>
        </ThemeProvider>
      )
    }
    • The structure of the theme object has changed to support color schemes:
    const theme = {
    - colors,
    - shadows,
    + colorSchemes: {
    +   light: {
    +     colors,
    +     shadows,
    +   },
    +   dark: {...},
    +   dark_dimmed: {...},
    + },
      space,
      fonts,
      fontSizes,
      fontWeights,
      lineHeights,
      borderWidths,
      radii,
      breakpoints,
      sizes,
    }
    • The theme.colors and theme.shadows objects are no longer available from the theme export. Use the useThemehook instead:
    - import {theme} from '@primer/react'
    + import {useTheme} from '@primer/react'
    
    function Example() {
    + const {theme} = useTheme()
      const myColor = theme.colors.text.primary
      ...
    }

Patch Changes

24.0.0

Major Changes

  • beef075e #1094 Thanks @colebemis! - Components no longer have a default theme prop. To ensure components still render correctly, you'll need pass the Primer theme to a styled-components <ThemeProvider> at the root of your application:

    import {ThemeProvider} from 'styled-components'
    import {theme} from '@primer/react'
    
    function App(props) {
      return (
        <div>
          <ThemeProvider theme={theme}>
            <div>your app here</div>
          </ThemeProvider>
        </div>
      )
    }

Patch Changes

  • e93cf268 #1092 Thanks @bscofield! - Use functional color variables in Caret, CircleBadge, Pagehead, ProgressBar, and Popover

23.2.1

Patch Changes

  • a42162c0 #1087 Thanks @emplums! - Fix up styles in TabNav allowing for items positioned on the right end of TabNav

23.2.0

Minor Changes

Patch Changes

23.1.0

Minor Changes

Patch Changes

23.0.4

Patch Changes

23.0.3

Patch Changes

23.0.2

Patch Changes