Skip to content

Commit 93efa53

Browse files
committed
Merge branch 'main' of github.com:adobe/react-spectrum into usepress-refactor
# Conflicts: # packages/@react-aria/focus/src/FocusScope.tsx # packages/@react-aria/test-utils/src/table.ts
2 parents f7e4d9e + df3f1ea commit 93efa53

File tree

426 files changed

+10010
-5480
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

426 files changed

+10010
-5480
lines changed

.storybook-s2/docs/Icons.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {highlight} from './highlight' with {type: 'macro'};
66

77
export function Icons() {
88
return (
9-
<div className={style({marginX: 'auto'})}>
9+
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
1010
<div className={style({marginX: 48})}>
1111
<h1 className={style({font: 'heading-2xl', marginBottom: 48})}>
1212
Workflow icons

.storybook-s2/docs/Illustrations.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { useState } from 'react';
1111
export function Illustrations() {
1212
let [gradientStyle, setStyle] = useState('generic1');
1313
return (
14-
<div className={style({marginX: 'auto'})}>
14+
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
1515
<div className={style({marginX: 48})}>
1616
<h1 className={style({font: 'heading-2xl', marginBottom: 48})}>
1717
Illustrations

.storybook-s2/docs/Intro.jsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {H2, H3, H4, P, Pre, Code, Strong, Link} from './typography';
1313

1414
export function Docs() {
1515
return (
16-
<div className={style({marginX: 'auto', marginY: 48})}>
16+
<div className={'sb-unstyled ' + style({marginX: 'auto', marginY: 48})}>
1717
<header
1818
style={{
1919
backgroundImage: `url(${new URL('wallpaper_collaborative_S2_desktop.webp', import.meta.url).toString()})`,
@@ -228,7 +228,7 @@ import {ActionButton} from '@react-spectrum/s2';
228228
</ul>
229229
<H3>UNSAFE Style Overrides</H3>
230230
<P>We highly discourage overriding the styles of React Spectrum components because it may break at any time when we change our implementation, making it difficult for you to update in the future. Consider using <Link href="https://react-spectrum.adobe.com/react-aria/" target="_blank">React Aria Components</Link> with our <Link href="?path=/docs/style-macro--docs" target="_top">style macro</Link> to build a custom component with Spectrum styles instead.</P>
231-
<P>That said, just like in React Spectrum v3, the <Code>UNSAFE_className</Code> and <Code>UNSAFE_style</Code> props are supported on Spectrum 2 components as last-resort escape hatches. However, unlike in v3, UNSAFE_classNames must be placed in a special <Code>UNSAFE_overrides</Code> <Link href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers" target="_blank">CSS cascade layer</Link>. This guarentees that your overrides will always win over other styles on the page, no matter the order or specificity of the selector.</P>
231+
<P>That said, just like in React Spectrum v3, the <Code>UNSAFE_className</Code> and <Code>UNSAFE_style</Code> props are supported on Spectrum 2 components as last-resort escape hatches.</P>
232232
<Pre>{highlight(`/* YourComponent.tsx */
233233
import {Button} from '@react-spectrum/s2';
234234
import './YourComponent.css';
@@ -237,12 +237,10 @@ function YourComponent() {
237237
return <Button UNSAFE_className="your-unsafe-class">Button</Button>;
238238
}`)}</Pre>
239239
<Pre>{highlight(`/* YourComponent.css */
240-
@layer UNSAFE_overrides {
241-
/* Wrap all UNSAFE_className rules in this layer. */
242-
.your-unsafe-class {
243-
background: red;
244-
}
245-
}`, 'CSS')}</Pre>
240+
.your-unsafe-class {
241+
background: red;
242+
}
243+
`, 'CSS')}</Pre>
246244
</main>
247245
</div>
248246
)

.storybook-s2/docs/MDXLayout.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const mdxComponents = {
1919

2020
export function MDXLayout({children}) {
2121
return (
22-
<div className={style({marginX: 'auto'})}>
22+
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
2323
<main className={style({marginX: 48})}>
2424
<MDXProvider components={mdxComponents}>
2525
{children}

.storybook-s2/docs/Migrating.jsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {P, Code, Pre, H3, H2, Link} from './typography';
33

44
export function Migrating() {
55
return (
6-
<div className={style({marginX: 'auto', fontFamily: 'sans'})}>
6+
<div className={'sb-unstyled ' + style({marginX: 'auto', fontFamily: 'sans'})}>
77
<div className={style({marginX: 48})}>
88
<h1 className={style({font: 'heading-2xl', marginBottom: 48})}>
99
Migrating to Spectrum 2
@@ -44,6 +44,17 @@ export function Migrating() {
4444
<li className={style({font: 'body', marginY: 8})}>Add <Code>allowsMultipleExpanded</Code> to allow multiple <Code>Disclosure</Code> components to be expanded at once (previously default behavior)</li>
4545
</ul>
4646

47+
<H3>ActionBar</H3>
48+
<ul className="sb-unstyled">
49+
<li className={style({font: 'body', marginY: 8})}>Remove <Code>ActionBarContainer</Code> and move <Code>ActionBar</Code> to <Code>renderActionBar</Code> prop of <Code>TableView</Code> or <Code>CardView</Code></li>
50+
<li className={style({font: 'body', marginY: 8})}>Update <Code>Item</Code> to <Code>ActionButton</Code></li>
51+
<li className={style({font: 'body', marginY: 8})}>Update root level <Code>onAction</Code> to be called via <Code>onPress</Code> on each <Code>ActionButton</Code></li>
52+
<li className={style({font: 'body', marginY: 8})}>Apply <Code>isDisabled</Code> directly on each <Code>ActionButton</Code> or <Code>ToggleButton</Code> instead of root level <Code>disabledKeys</Code></li>
53+
<li className={style({font: 'body', marginY: 8})}>Update <Code>key</Code> to be <Code>id</Code> (and keep <Code>key</Code> if rendered inside <Code>array.map</Code>)</li>
54+
<li className={style({font: 'body', marginY: 8})}>Convert dynamic collections render function to <Code>items.map</Code></li>
55+
<li className={style({font: 'body', marginY: 8})}>[PENDING] Comment out <Code>buttonLabelBehavior</Code> (it has not been implemented yet)</li>
56+
</ul>
57+
4758
<H3>ActionButton</H3>
4859
<P>No updates needed.</P>
4960

@@ -338,6 +349,17 @@ export function Migrating() {
338349
<H3>Switch</H3>
339350
<P>No updates needed.</P>
340351

352+
<H3>TableView</H3>
353+
<ul className="sb-unstyled">
354+
<li className={style({font: 'body', marginY: 8})}>For <Code>Column</Code> and <Code>Row</Code>: Update <Code>key</Code> to be <Code>id</Code> (and keep <Code>key</Code> if rendered inside <Code>array.map</Code>)</li>
355+
<li className={style({font: 'body', marginY: 8})}>For dynamic tables, pass a <Code>columns</Code> prop into <Code>Row</Code></li>
356+
<li className={style({font: 'body', marginY: 8})}>For <Code>Row</Code>: Update dynamic render function to pass in <Code>column</Code> instead of <Code>columnKey</Code></li>
357+
<li className={style({font: 'body', marginY: 8})}>[PENDING] Comment out <Code>UNSTABLE_allowsExpandableRows</Code> (it has not been implemented yet)</li>
358+
<li className={style({font: 'body', marginY: 8})}>[PENDING] Comment out <Code>UNSTABLE_onExpandedChange</Code> (it has not been implemented yet)</li>
359+
<li className={style({font: 'body', marginY: 8})}>[PENDING] Comment out <Code>UNSTABLE_expandedKeys</Code> (it has not been implemented yet)</li>
360+
<li className={style({font: 'body', marginY: 8})}>[PENDING] Comment out <Code>UNSTABLE_defaultExpandedKeys</Code> (it has not been implemented yet)</li>
361+
</ul>
362+
341363
<H3>Tabs</H3>
342364
<ul className="sb-unstyled">
343365
<li className={style({font: 'body', marginY: 8})}>Inside <Code>TabList</Code>: Update <Code>Item</Code> to be <Code>Tab</Code></li>

.storybook-s2/docs/Release Notes.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@ export default MDXLayout;
44

55
# Release Notes
66

7+
## v0.6.0
8+
9+
### New Components
10+
11+
* [ActionBar](?path=/docs/actionbar--docs)
12+
13+
### Updates
14+
15+
* [Button](?path=/docs/button--docs): Add `genai` and `premium` gradient variants
16+
* [Menu](?path=/docs/menu--docs): Add `hideLinkOutIcon` prop, update alignment of items in different sections, and show checkmark on selected items that are links.
17+
* Added `staticColor="auto"` option to [ActionButton](?path=/docs/actionbutton--docs), [ToggleButton](?path=/docs/togglebutton--docs), [Divider](?path=/docs/divider--docs), [Meter](?path=/docs/meter--docs), [ProgressBar](?path=/docs/progressbar--docs), and [Link](?path=/docs/link--docs)
18+
* [ContextualHelp](?path=/docs/contextualhelp--docs): Fix alignment with field labels
19+
* [InlineAlert](?path=/docs/inlinealert--docs): Remove maximum width
20+
* [CheckboxGroup](?path=/docs/checkboxgroup--docs): Fix `isRequired` within a Form
21+
22+
### Codemods
23+
24+
* Added TableView codemods
25+
726
## v0.5.0
827

928
In this release we have updated our Dialog and DialogTrigger APIs to improve layout flexibility for custom dialogs and popovers. Dialog has been split into four components:

.storybook-s2/docs/StyleMacro.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {Colors} from './Colors';
66

77
export function StyleMacro() {
88
return (
9-
<div className={style({marginX: 'auto'})}>
9+
<div className={'sb-unstyled ' + style({marginX: 'auto'})}>
1010
<header
1111
className={style({
1212
paddingX: 48,

examples/rac-tailwind/src/App.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ArrowUpIcon, BellIcon, CheckCircleIcon, CheckIcon, ChevronUpDownIcon } from '@heroicons/react/20/solid';
22
import { ChatBubbleOvalLeftEllipsisIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';
33
import { useMemo, useState } from 'react';
4-
import { Button, Cell, Collection, Column, ComboBox, DateInput, DatePicker, DateSegment, Dialog, DialogTrigger, Group, Header, Heading, Input, Label, ListBox, ListBoxItem, Menu, MenuItem, MenuTrigger, Modal, ModalOverlay, OverlayArrow, Popover, ProgressBar, Radio, RadioGroup, Row, Section, Select, SelectValue, Separator, Slider, SliderOutput, SliderThumb, SliderTrack, Switch, Tab, Table, TableBody, TableHeader, TabList, TabPanel, Tabs, Text } from 'react-aria-components';
4+
import { UNSTABLE_Autocomplete as Autocomplete, Button, Cell, Collection, Column, ComboBox, DateInput, DatePicker, DateSegment, Dialog, DialogTrigger, Group, Header, Heading, Input, Label, ListBox, ListBoxItem, Menu, MenuItem, MenuTrigger, Modal, ModalOverlay, OverlayArrow, Popover, ProgressBar, Radio, RadioGroup, Row, SearchField, Section, Select, SelectValue, Separator, Slider, SliderOutput, SliderThumb, SliderTrack, Switch, Tab, Table, TableBody, TableHeader, TabList, TabPanel, Tabs, Text, useFilter} from 'react-aria-components';
55
import { useAsyncList } from 'react-stately';
66
import { people } from './people.js';
77
import stocks from './stocks.json';
@@ -29,6 +29,7 @@ export function App() {
2929
<ImageGridExample />
3030
<ComboBoxExample />
3131
<ProgressBarExample />
32+
<AutocompleteExample />
3233
</div>
3334
</>
3435
);
@@ -549,3 +550,31 @@ function StockRow(props) {
549550
function StockCell(props) {
550551
return <Cell {...props} className={`px-4 py-2 text-sm ${props.className} data-[focus-visible]:outline data-[focus-visible]:outline-2 data-[focus-visible]:outline-slate-600 data-[focus-visible]:-outline-offset-4 group-aria-selected:data-[focus-visible]:outline-white`} />;
551552
}
553+
554+
function AutocompleteExample() {
555+
let {contains} = useFilter({sensitivity: 'base'});
556+
return (
557+
<div className="bg-gradient-to-r from-sky-400 to-cyan-400 p-8 rounded-lg flex justify-center flex-col">
558+
<Autocomplete filter={contains} className="flex flex-col gap-1 w-5/6">
559+
<SearchField>
560+
<Label className="text-sm text-black">Contacts</Label>
561+
<div className="relative w-full cursor-default overflow-hidden rounded-lg bg-white bg-opacity-90 focus-within:bg-opacity-100 transition text-left shadow-md [&:has([data-focus-visible])]:ring-2 [&:has([data-focus-visible])]:ring-black sm:text-sm">
562+
<Input className="w-full border-none py-2 pl-3 pr-2 sm:text-sm leading-5 text-gray-900 bg-transparent outline-none" />
563+
</div>
564+
</SearchField>
565+
<div className="h-[300px] py-2 rounded-lg flex justify-center">
566+
<ListBox aria-label="Contacts" selectionMode="multiple" selectionBehavior="replace" className="w-72 max-h-[290px] overflow-auto outline-none bg-white text-gray-700 p-2 flex flex-col gap-2 rounded-lg shadow scroll-pb-2 scroll-pt-7">
567+
<ContactSection title="Favorites">
568+
<Contact id="wade" name="Tony Baldwin" handle="@tony" avatar="https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" />
569+
<Contact id="arelene" name="Julienne Langstrath" handle="@jlangstrath" avatar="https://images.unsplash.com/photo-1580489944761-15a19d654956?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" />
570+
<Contact id="tom" name="Roberto Gonzalez" handle="@rgonzalez" avatar="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" />
571+
</ContactSection>
572+
<ContactSection title="All Contacts" items={people}>
573+
{item => <Contact name={item.name} handle={item.username} avatar={item.avatar} />}
574+
</ContactSection>
575+
</ListBox>
576+
</div>
577+
</Autocomplete>
578+
</div>
579+
);
580+
}

examples/rsp-cra-18/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@types/react": "^18",
2222
"@types/react-dom": "^18",
2323
"react": "^18.1.0",
24+
"react-aria-components": "latest",
2425
"react-dom": "^18.1.0",
2526
"react-scripts": "5.0.1",
2627
"typescript": "5.0.4",

examples/rsp-cra-18/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import StatusExamples from './sections/StatusExamples';
1515
import ContentExamples from './sections/ContentExamples';
1616
import PickerExamples from './sections/PickerExamples';
1717
import DragAndDropExamples from './sections/DragAndDropExamples';
18+
import {AutocompleteExample} from './AutocompleteExample';
1819

1920
let columns = [
2021
{name: 'Foo', key: 'foo'},
@@ -61,6 +62,7 @@ function App() {
6162
}
6263
</TableBody>
6364
</TableView>
65+
<AutocompleteExample />
6466
<ButtonExamples />
6567
<CollectionExamples />
6668
<ColorExamples />
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {UNSTABLE_Autocomplete as Autocomplete, Input, Label, Menu, MenuItem, SearchField, Text, useFilter} from 'react-aria-components'
2+
import {classNames} from '@react-spectrum/utils';
3+
import styles from './autocomplete.css';
4+
5+
interface AutocompleteItem {
6+
id: string,
7+
name: string
8+
}
9+
10+
let items: AutocompleteItem[] = [{id: '1', name: 'Foo'}, {id: '2', name: 'Bar'}, {id: '3', name: 'Baz'}];
11+
12+
export function AutocompleteExample() {
13+
let {contains} = useFilter({sensitivity: 'base'});
14+
15+
return (
16+
<Autocomplete filter={contains}>
17+
<div>
18+
<SearchField autoFocus>
19+
<Label style={{display: 'block'}}>Test</Label>
20+
<Input />
21+
<Text style={{display: 'block'}} slot="description">Please select an option below.</Text>
22+
</SearchField>
23+
<Menu items={items} selectionMode="single">
24+
{item => (
25+
<MenuItem
26+
id={item.id}
27+
className={({isFocused, isSelected, isOpen}) => classNames(styles, 'item', {
28+
focused: isFocused,
29+
selected: isSelected,
30+
open: isOpen
31+
})}>
32+
{item.name}
33+
</MenuItem>
34+
)}
35+
</Menu>
36+
</div>
37+
</Autocomplete>
38+
);
39+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
.react-aria-Menu {
2+
display: block;
3+
min-width: 150px;
4+
width: fit-content;
5+
margin: 4px 0 0 0;
6+
border: 1px solid gray;
7+
background: lightgray;
8+
padding: 0;
9+
list-style: none;
10+
overflow-y: auto;
11+
height: 100px;
12+
}
13+
14+
.item {
15+
padding: 2px 5px;
16+
outline: none;
17+
cursor: default;
18+
color: black;
19+
background: transparent;
20+
}
21+
22+
.item[data-disabled] {
23+
opacity: 0.4;
24+
}
25+
26+
.item.focused {
27+
background: gray;
28+
color: white;
29+
}
30+
31+
.item.open:not(.focused) {
32+
background: lightslategray;
33+
color: white;
34+
}
35+
36+
.item.item.hovered {
37+
background: lightsalmon;
38+
color: white;
39+
}
40+
41+
.item.selected {
42+
background: purple;
43+
color: white;
44+
}

examples/rsp-cra-18/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"jsx": "react-jsx"
2222
},
2323
"include": [
24-
"src"
24+
"src",
25+
"typings.d.ts"
2526
]
2627
}

examples/rsp-cra-18/typings.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module "*.css";
1.04 MB
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {UNSTABLE_Autocomplete as Autocomplete, Input, Label, Menu, MenuItem, SearchField, Text, useFilter} from 'react-aria-components'
2+
import {classNames} from '@react-spectrum/utils';
3+
import React from 'react';
4+
import styles from './autocomplete.module.css';
5+
6+
interface AutocompleteItem {
7+
id: string,
8+
name: string
9+
}
10+
11+
let items: AutocompleteItem[] = [{id: '1', name: 'Foo'}, {id: '2', name: 'Bar'}, {id: '3', name: 'Baz'}];
12+
13+
export function AutocompleteExample() {
14+
let {contains} = useFilter({sensitivity: 'base'});
15+
16+
return (
17+
<Autocomplete filter={contains}>
18+
<div>
19+
<SearchField autoFocus>
20+
<Label style={{display: 'block'}}>Test</Label>
21+
<Input />
22+
<Text style={{display: 'block'}} slot="description">Please select an option below.</Text>
23+
</SearchField>
24+
<Menu items={items} className={styles.menu} selectionMode="single">
25+
{item => (
26+
<MenuItem
27+
id={item.id}
28+
className={({isFocused, isSelected, isOpen}) => classNames(styles, 'item', {
29+
focused: isFocused,
30+
selected: isSelected,
31+
open: isOpen
32+
})}>
33+
{item.name}
34+
</MenuItem>
35+
)}
36+
</Menu>
37+
</div>
38+
</Autocomplete>
39+
);
40+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
.menu {
2+
display: block;
3+
min-width: 150px;
4+
width: fit-content;
5+
margin: 4px 0 0 0;
6+
border: 1px solid gray;
7+
background: lightgray;
8+
padding: 0;
9+
list-style: none;
10+
overflow-y: auto;
11+
height: 100px;
12+
}
13+
14+
.item {
15+
padding: 2px 5px;
16+
outline: none;
17+
cursor: default;
18+
color: black;
19+
background: transparent;
20+
}
21+
22+
.item[data-disabled] {
23+
opacity: 0.4;
24+
}
25+
26+
.item.focused {
27+
background: gray;
28+
color: white;
29+
}
30+
31+
.item.open:not(.focused) {
32+
background: lightslategray;
33+
color: white;
34+
}
35+
36+
.item.item.hovered {
37+
background: lightsalmon;
38+
color: white;
39+
}
40+
41+
.item.selected {
42+
background: purple;
43+
color: white;
44+
}

0 commit comments

Comments
 (0)