Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(cauldron): Release 6.13.0 #1771

Merged
merged 13 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,10 @@ jobs:
NODE_ENV=production yarn --cwd packages/react build
NODE_ENV=production yarn --cwd packages/styles build
- run: yarn build:docs
- run: yarn test:a11y
# Newer versions of Ubuntu have increased security restrictions in which
# puppeteer is unable to launch without additional configuration
# See: https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md
- run: |
export CHROME_DEVEL_SANDBOX=/opt/google/chrome/chrome-sandbox
sudo chmod 4755 /opt/google/chrome/chrome-sandbox
yarn test:a11y
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [6.13.0](https://github.com/dequelabs/cauldron/compare/v6.12.0...v6.13.0) (2024-12-18)


### Features

* **react,style:** add AnchoredOverlay component, refactor Tooltip and Popover to use AnchoredOverlay ([#1760](https://github.com/dequelabs/cauldron/issues/1760)) ([6773975](https://github.com/dequelabs/cauldron/commit/67739754b0c6368ec1db878ace917730db102797))
* **react:** add max-width column configuration to Table grids ([#1770](https://github.com/dequelabs/cauldron/issues/1770)) ([dc7e4ac](https://github.com/dequelabs/cauldron/commit/dc7e4ac43be846ee6faa6b1cf878753aed1b6a31))
* **react:** add multiselect to Listbox component ([#1763](https://github.com/dequelabs/cauldron/issues/1763)) ([afa8fb4](https://github.com/dequelabs/cauldron/commit/afa8fb4f89d43e453eccfa2c39587e4fee0bc9cf))
* **react:** remove focus-trap-react replacing with internally managed focus traps ([#1730](https://github.com/dequelabs/cauldron/issues/1730)) ([775bed0](https://github.com/dequelabs/cauldron/commit/775bed0e4becc55af34e69495ee0b6e3db3a11be))


### Bug Fixes

* **react:** remove defaultProps from sidebar, use default parameters instead ([#1764](https://github.com/dequelabs/cauldron/issues/1764)) ([e4a3441](https://github.com/dequelabs/cauldron/commit/e4a3441d8497f656dbec6afa35a989a139d430e7))

## [6.12.0](https://github.com/dequelabs/cauldron/compare/v6.11.0...v6.12.0) (2024-12-04)


Expand Down
189 changes: 189 additions & 0 deletions docs/pages/components/AnchoredOverlay.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
---
title: AnchoredOverlay
description: A component that displays an anchored layered element relative to a target element.
source: https://github.com/dequelabs/cauldron/tree/develop/packages/react/src/components/AnchoredOverlay/index.tsx
---

import { useRef, useState } from 'react'
import { Select, Button, AnchoredOverlay } from '@deque/cauldron-react'
export const placements = [
'top',
'top-start',
'top-end',
'right',
'right-start',
'right-end',
'bottom',
'bottom-start',
'bottom-end',
'left',
'left-start',
'left-end',
'auto',
'auto-start',
'auto-end'
]

```jsx
import { AnchoredOverlay } from '@deque/cauldron-react'
```

Under the hood, `AnchoredOverlay` uses [floating-ui](https://floating-ui.com/) to dynamically position an overlay element relative to a target element. It is intentionally un-styled to be composed with other components, such as [Tooltip]('./Tooltip'), [Popover](./Popover), or via more complex overlay components.

<Note>
`AnchoredOverlay` is a positioning component and does not include built-in accessibility features like ARIA attributes, focus management, or keyboard interactions that would be needed for components like tooltips, dialogs, or popovers. When using `AnchoredOverlay`, you'll need to implement these accessibility patterns yourself based on your specific use case.
</Note>

## Examples

### Placement

By default, initial placement is set to `auto` when it is not set via props. However the placement can [dynamically change](https://floating-ui.com/docs/autoplacement) when using `auto` or [flip](https://floating-ui.com/docs/flip) when using positional placement.

If there are presentation elements that are dependent on the position of the `AnchoredOverlay`, you should use `onPlacementChange` to keep these presentation elements in sync with any updated placements.

```jsx example
function AnchoredOverlayExample() {
const [placement, setPlacement] = useState('top')
const [open, setOpen] = useState(false)
const targetRef = useRef()
const handlePlacementChange = ({ target }) => setPlacement(target.value);
const toggleOpen = () => setOpen(!open)
const handleClose = () => setOpen(false)

return (
<>
<Select
label="Placement"
options={placements.map(placement => ({ value: placement }))}
onChange={handlePlacementChange}
/>
<Button
ref={targetRef}
onFocus={toggleOpen}
onBlur={handleClose}
aria-describedby="anchored-overlay"
>
Anchor Element
</Button>
<AnchoredOverlay
id="anchored-overlay"
target={targetRef}
open={open}
placement={placement}
onOpenChange={openState => setOpen(openState)}
style={{
padding: 'var(--space-small)',
backgroundColor: 'var(--panel-background-color)',
display: open ? 'block' : 'none'
}}
>
Anchored Overlay Element with placement {placement}
</AnchoredOverlay>
</>
)
}
```

### Offset

Optionally, an `offset` value can be set which will offset the aligning edge of the overlay element relative to its anchor.

```jsx example
function AnchoredOverlayWithOffsetExample() {
const [placement, setPlacement] = useState('top')
const [open, setOpen] = useState(false)
const targetRef = useRef()
const handlePlacementChange = ({ target }) => setPlacement(target.value);
const toggleOpen = () => setOpen(!open)
const handleClose = () => setOpen(false)

return (
<>
<Select
label="Placement"
options={placements.map(placement => ({ value: placement }))}
onChange={handlePlacementChange}
/>
<Button
ref={targetRef}
onFocus={toggleOpen}
onBlur={handleClose}
aria-describedby="anchored-overlay-offset"
>
Anchor Element
</Button>
<AnchoredOverlay
id="anchored-overlay-offset"
target={targetRef}
open={open}
placement={placement}
onOpenChange={openState => setOpen(openState)}
offset={20}
style={{
padding: 'var(--space-small)',
backgroundColor: 'var(--panel-background-color)',
display: open ? 'block' : 'none'
}}
>
Anchored Overlay Element with offset placement {placement}
</AnchoredOverlay>
</>
)
}
```

## Props

<ComponentProps
children={true}
className={true}
refType="HTMLElement"
props={[
{
name: 'target',
type: ['HTMLElement', 'React.MutableRefObject<HTMLElement>', 'React.RefObject<HTMLElement>'],
required: true,
description: 'A target element or ref to attach the overlay anchor element.'
},
{
name: 'placement',
type: 'string',
defaultValue: 'auto',
description: 'Positional placement value to anchor the overlay element relative to its anchored target.'
},
{
name: 'open',
type: 'boolean',
defaultValue: 'false',
description: 'Determines if the overlay anchor is currently visible.'
},
{
name: 'onOpenChange',
type: '(open: boolean) => void',
description: 'A callback function that is called when the overlay state changes.'
},
{
name: 'onPlacementChange',
type: '(placement: Placement) => void',
description: 'A callback function that is called when the placement of the overlay changes.'
},
{
name: 'offset',
type: 'number',
description: 'An optional offset number to position the anchor element from its anchored target.'
},
{
name: 'as',
type: 'React.ElementType',
defaultValue: 'div',
description: 'The element type to render as.'
}
]}
/>

## Related Components

- [Tooltip](./Tooltip)
- [Popover](./Popover)

26 changes: 25 additions & 1 deletion docs/pages/components/Listbox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function ControlledListboxExample() {
<Listbox
aria-labelledby="listbox-controlled-example"
value={value}
onSelect={handleSelect}
onSelectionChange={handleSelect}
>
<ListboxOption>One</ListboxOption>
<ListboxOption>Two</ListboxOption>
Expand All @@ -128,6 +128,25 @@ Uncontrolled listboxes will automatically set `aria-selected="true"` for the sel
</>
```

### Multiselect

Listboxes can also support multiple selection of listbox options.

```jsx example
<>
<div id="listbox-multiselect-example">Multiselect Listbox</div>
<Listbox aria-labelledby="listbox-multiselect-example" multiselect>
<ListboxOption>One</ListboxOption>
<ListboxOption>Two</ListboxOption>
<ListboxOption>Three</ListboxOption>
</Listbox>
</>
```

<Note>
Multiselect Listbox components will pass in array values for the selected options in `onSelectionChange` and expect an array of values for `value` and `defaultValue` props.
</Note>

## Props

### Listbox
Expand Down Expand Up @@ -180,6 +199,11 @@ Uncontrolled listboxes will automatically set `aria-selected="true"` for the sel
type: 'boolean',
description: 'When set, sets the listbox option as "aria-disabled="true" and removes the element from key navigation.'
},
{
name: 'selected',
type: 'boolean',
description: 'When set, sets the listbox option as "aria-selected="true".'
},
{
name: 'activeClass',
type: 'string',
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/components/Popover.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Popover, Button } from '@deque/cauldron-react'

## Examples

Cauldron's tooltip relies on [Popper](https://popper.js.org/) to position tooltips dynamically. Popover can be triggered from any focusable element via a `target` attribute pointed to an HTMLElement or React ref object.
Cauldron's tooltip relies on [Floating UI](https://floating-ui.com/) to position tooltips dynamically. Popover can be triggered from any focusable element via a `target` attribute pointed to an HTMLElement or React ref object.

### Prompt Popover

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/components/Scrim.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Scrim } from '@deque/cauldron-react'
A scrim is a component that is a semi-transparent overlay over the viewport to provide emphasis, focus, or draw attention to certain information. This is most commonly used as a backdrop for dialogs, modals, and other elements that need primary focus on the page.

<Note>
It is recommended that a focus trap is used to contain keyboard focus within the element that has primary focus. [Alert](./Alert) and [Modal](./Modal) both use [react-focus-trap](https://www.npmjs.com/package/focus-trap-react) to manage focus. If `Scrim` is being used with other components, a focus trap may be needed to prevent certain keyboard accessibility issues.
It is recommended that a focus trap is used to contain keyboard focus within the element that has primary focus. If `Scrim` is being used with other components, a focus trap (among other AT considerations) may be needed to prevent certain keyboard accessibility issues.
</Note>

## Example
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/components/Table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,15 @@ function SortableTableExample() {

### Grid Layout

The Table component supports an optional css grid layout that can specify column alignment and width definitions per column.
The Table component supports an optional css grid layout that can specify column alignment and width and max-width definitions per column.

```jsx example
<Table
layout="grid"
columns={[
{ width: 'max-content', align: 'start' },
{ width: 'max-content', align: 'start' },
{ width: '1fr', align: 'end' }
{ width: 'auto', maxWidth: '250', align: 'end' }
]}>
<TableHead>
<TableRow>
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/components/Tooltip.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Tooltip } from '@deque/cauldron-react'

## Examples

Cauldron's tooltip relies on [Popper](https://popper.js.org/) to position tooltips dynamically. Tooltips can be triggered from any focusable element via a `target` attribute pointed to an HTMLElement or React ref object.
Cauldron's tooltip relies on [Floating UI](https://floating-ui.com/) to position tooltips dynamically. Tooltips can be triggered from any focusable element via a `target` attribute pointed to an HTMLElement or React ref object.

<Note>

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cauldron",
"private": true,
"version": "6.12.0",
"version": "6.13.0",
"license": "MPL-2.0",
"scripts": {
"clean": "rimraf dist docs/dist",
Expand Down
6 changes: 2 additions & 4 deletions packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@deque/cauldron-react",
"version": "6.12.0",
"version": "6.13.0",
"license": "MPL-2.0",
"description": "Fully accessible react components library for Deque Cauldron",
"homepage": "https://cauldron.dequelabs.com/",
Expand All @@ -23,13 +23,11 @@
"test": "jest --maxWorkers=1 --coverage"
},
"dependencies": {
"@popperjs/core": "^2.5.4",
"@floating-ui/react-dom": "^2.1.2",
"classnames": "^2.2.6",
"focus-trap-react": "^10.2.3",
"focusable": "^2.3.0",
"keyname": "^0.1.0",
"react-id-generator": "^3.0.1",
"react-popper": "^2.2.4",
"react-syntax-highlighter": "^15.5.0",
"tslib": "^2.4.0"
},
Expand Down
Loading
Loading