Skip to content

Commit

Permalink
Merge branch 'main' into kh-fix-5566
Browse files Browse the repository at this point in the history
  • Loading branch information
khiga8 authored Jan 22, 2025
2 parents 81bae6b + 20788da commit 83be114
Show file tree
Hide file tree
Showing 33 changed files with 565 additions and 259 deletions.
5 changes: 5 additions & 0 deletions .changeset/gentle-stingrays-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": minor
---

Update FormControl to use CSS Modules behind feature flag
5 changes: 5 additions & 0 deletions .changeset/selfish-taxis-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Promote ActionList to staff
6 changes: 6 additions & 0 deletions .changeset/shy-carpets-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@primer/react": minor
---

- Convert ActionBar to CSS Modules
- Add new padding prop for container padding
5 changes: 5 additions & 0 deletions .changeset/swift-baboons-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Hide NavList sub items if collapsed
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ jobs:
run: npx tsx script/components-json/build.ts --storybook-data 'storybook-static/index.json'
working-directory: packages/react
- name: Build hooks.json
run: npx tsx script/hooks-json/build.ts'
run: npx tsx script/hooks-json/build.ts
working-directory: packages/react

sizes:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 8 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"@github/tab-container-element": "^4.8.0",
"@lit-labs/react": "1.2.1",
"@oddbird/popover-polyfill": "^0.4.4",
"@primer/behaviors": "^1.7.2",
"@primer/behaviors": "^1.8.0",
"@primer/live-region-element": "^0.7.1",
"@primer/octicons-react": "^19.13.0",
"@primer/primitives": "9.x || 10.x",
Expand Down
14 changes: 14 additions & 0 deletions packages/react/src/ActionBar/ActionBar.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@
"required": false,
"description": "Size of the action bar",
"defaultValue": ""
},
{
"name": "flush",
"type": "boolean",
"required": false,
"description": "Allows ActionBar to be flush with the container",
"defaultValue": "false"
},
{
"name": "className",
"type": "string",
"required": false,
"description": "Custom className",
"defaultValue": ""
}
],
"subcomponents": [
Expand Down
35 changes: 35 additions & 0 deletions packages/react/src/ActionBar/ActionBar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.List {
position: relative;
display: flex;
min-width: 0;

/* wonder why this is here */
/* stylelint-disable-next-line primer/spacing */
margin-bottom: -1px;
white-space: nowrap;
list-style: none;
align-items: center;
gap: var(--base-size-8);
}

.Nav {
display: flex;
padding-inline: var(--base-size-16);
justify-content: flex-end;
align-items: center;

&:where([data-flush='true']) {
padding-inline: 0;
}
}

.Divider {
&::before {
display: block;
width: var(--borderWidth-thin);
height: var(--base-size-20);
content: '';
/* stylelint-disable-next-line primer/colors */
background: var(--borderColor-muted);
}
}
35 changes: 33 additions & 2 deletions packages/react/src/ActionBar/ActionBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react'
import type {Meta} from '@storybook/react'
import ActionBar from '.'
import {
BoldIcon,
Expand All @@ -13,11 +12,43 @@ import {
ListOrderedIcon,
TasklistIcon,
} from '@primer/octicons-react'
import type {Meta, StoryObj} from '@storybook/react'

export default {
const meta: Meta<typeof ActionBar> = {
title: 'Experimental/Components/ActionBar',
} as Meta<typeof ActionBar>

export default meta
type Story = StoryObj<typeof ActionBar>

export const Playground: Story = {
render: args => (
<ActionBar {...args}>
<ActionBar.IconButton icon={BoldIcon} aria-label="Bold"></ActionBar.IconButton>
<ActionBar.IconButton icon={ItalicIcon} aria-label="Italic"></ActionBar.IconButton>
<ActionBar.Divider />
<ActionBar.IconButton icon={CodeIcon} aria-label="Code"></ActionBar.IconButton>
</ActionBar>
),
}
Playground.argTypes = {
size: {
control: {
type: 'radio',
},
options: ['small', 'medium', 'large'],
},
flush: {
control: {
type: 'boolean',
},
},
}
Playground.args = {
size: 'medium',
flush: false,
}

export const Default = () => (
<ActionBar aria-label="Toolbar">
<ActionBar.IconButton icon={BoldIcon} aria-label="Bold"></ActionBar.IconButton>
Expand Down
101 changes: 16 additions & 85 deletions packages/react/src/ActionBar/ActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ import React, {useState, useCallback, useRef, forwardRef} from 'react'
import {KebabHorizontalIcon} from '@primer/octicons-react'
import {ActionList} from '../ActionList'
import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect'
import styled from 'styled-components'
import sx from '../sx'
import {useOnEscapePress} from '../hooks/useOnEscapePress'
import type {ResizeObserverEntry} from '../hooks/useResizeObserver'
import {useResizeObserver} from '../hooks/useResizeObserver'

import {useOnOutsideClick} from '../hooks/useOnOutsideClick'
import type {IconButtonProps} from '../Button'
import {IconButton} from '../Button'
import Box from '../Box'
import {ActionMenu} from '../ActionMenu'
import {useFocusZone, FocusKeys} from '../hooks/useFocusZone'
import styles from './ActionBar.module.css'
import {clsx} from 'clsx'

type ChildSize = {
text: string
Expand Down Expand Up @@ -43,54 +42,13 @@ type A11yProps =
export type ActionBarProps = {
size?: Size
children: React.ReactNode
flush?: boolean
className?: string
} & A11yProps

export type ActionBarIconButtonProps = IconButtonProps

const NavigationList = styled.div`
${sx};
`

const GAP = 8

const listStyles = {
display: 'flex',
minWidth: 0,
listStyle: 'none',
whiteSpace: 'nowrap',
paddingY: 0,
paddingX: 0,
margin: 0,
marginBottom: '-1px',
alignItems: 'center',
gap: `${GAP}px`,
position: 'relative',
}

const MORE_BTN_WIDTH = 86
const navStyles = {
display: 'flex',
paddingX: 3,
justifyContent: 'flex-end',
align: 'row',
alignItems: 'center',
maxHeight: '32px',
}

const menuItemStyles = {
textDecoration: 'none',
}

const moreBtnStyles = {
//set margin 0 here because safari puts extra margin around the button, rest is to reset style to make it look like a list element
margin: 0,
border: 0,
background: 'transparent',
fontWeight: 'normal',
boxShadow: 'none',
paddingY: 1,
paddingX: 2,
}

const getValidChildren = (children: React.ReactNode) => {
return React.Children.toArray(children).filter(child => {
Expand Down Expand Up @@ -168,7 +126,7 @@ const overflowEffect = (
}

export const ActionBar: React.FC<React.PropsWithChildren<ActionBarProps>> = props => {
const {size = 'medium', children, 'aria-label': ariaLabel} = props
const {size = 'medium', children, 'aria-label': ariaLabel, flush = false, className} = props
const [childWidthArray, setChildWidthArray] = useState<ChildWidthArray>([])
const setChildrenWidth = useCallback((size: ChildSize) => {
setChildWidthArray(arr => {
Expand Down Expand Up @@ -243,34 +201,25 @@ export const ActionBar: React.FC<React.PropsWithChildren<ActionBarProps>> = prop

return (
<ActionBarContext.Provider value={{size, setChildrenWidth}}>
<Box ref={navRef} sx={navStyles}>
<NavigationList sx={listStyles} ref={listRef} role="toolbar">
<div ref={navRef} className={clsx(className, styles.Nav)} data-flush={flush}>
<div ref={listRef} role="toolbar" className={styles.List}>
{listItems}
{menuItems.length > 0 && (
<ActionMenu>
<ActionMenu.Anchor>
<IconButton sx={moreBtnStyles} aria-label={`More ${ariaLabel} items`} icon={KebabHorizontalIcon} />
<IconButton variant="invisible" aria-label={`More ${ariaLabel} items`} icon={KebabHorizontalIcon} />
</ActionMenu.Anchor>
<ActionMenu.Overlay>
<ActionList>
{menuItems.map((menuItem, index) => {
if (menuItem.type === ActionList.Divider) {
return <ActionList.Divider key={index} />
} else {
const {
children: menuItemChildren,
//'aria-current': ariaCurrent,
onClick,
icon: Icon,
'aria-label': ariaLabel,
} = menuItem.props
const {children: menuItemChildren, onClick, icon: Icon, 'aria-label': ariaLabel} = menuItem.props
return (
<ActionList.LinkItem
<ActionList.Item
key={menuItemChildren}
sx={menuItemStyles}
onClick={(
event: React.MouseEvent<HTMLAnchorElement> | React.KeyboardEvent<HTMLAnchorElement>,
) => {
onClick={(event: React.MouseEvent<HTMLLIElement, MouseEvent>) => {
closeOverlay()
focusOnMoreMenuBtn()
typeof onClick === 'function' && onClick(event)
Expand All @@ -282,16 +231,16 @@ export const ActionBar: React.FC<React.PropsWithChildren<ActionBarProps>> = prop
</ActionList.LeadingVisual>
) : null}
{ariaLabel}
</ActionList.LinkItem>
</ActionList.Item>
)
}
})}
</ActionList>
</ActionMenu.Overlay>
</ActionMenu>
)}
</NavigationList>
</Box>
</div>
</div>
</ActionBarContext.Provider>
)
}
Expand All @@ -308,31 +257,13 @@ export const ActionBarIconButton = forwardRef((props: ActionBarIconButtonProps,
return <IconButton ref={ref} size={size} {...props} variant="invisible" />
})

const sizeToHeight = {
small: '24px',
medium: '28px',
large: '32px',
}
export const VerticalDivider = () => {
const ref = useRef<HTMLDivElement>(null)
const {size, setChildrenWidth} = React.useContext(ActionBarContext)
const {setChildrenWidth} = React.useContext(ActionBarContext)
useIsomorphicLayoutEffect(() => {
const text = 'divider'
const domRect = (ref as MutableRefObject<HTMLElement>).current.getBoundingClientRect()
setChildrenWidth({text, width: domRect.width})
}, [ref, setChildrenWidth])
return (
<Box
ref={ref}
data-component="ActionBar.VerticalDivider"
aria-hidden="true"
sx={{
display: 'inline-block',
borderLeft: '1px solid',
borderColor: 'actionListItem.inlineDivider',
height: sizeToHeight[size],
mx: 2,
}}
/>
)
return <div ref={ref} data-component="ActionBar.VerticalDivider" aria-hidden="true" className={styles.Divider} />
}
4 changes: 4 additions & 0 deletions packages/react/src/ActionList/ActionList.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@
transform: scaleY(1);
}

& + .SubGroup {
display: none;
}

/* show active indicator on parent collapse if child is active */
&:has(+ .SubGroup [data-active='true']) {
background: var(--control-transparent-bgColor-selected);
Expand Down
Loading

0 comments on commit 83be114

Please sign in to comment.