Skip to content

Commit e89b9bc

Browse files
authored
Add data-selection-mode attribute (#5018)
1 parent 07260d1 commit e89b9bc

File tree

9 files changed

+25
-75
lines changed

9 files changed

+25
-75
lines changed

packages/react-aria-components/docs/Menu.mdx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,15 @@ import {MenuTrigger, Button, Popover, Menu, Item} from 'react-aria-components';
161161
text-align: end;
162162
}
163163

164-
&[data-selected] {
164+
&[data-selection-mode] {
165165
padding-left: 24px;
166+
&::before {
167+
position: absolute;
168+
left: 4px;
169+
font-weight: 600;
170+
}
166171

167-
&[data-selected]::before {
172+
&[data-selection-mode=multiple][data-selected]::before {
168173
content: '';
169174
content: '' / '';
170175
alt: ' ';
@@ -173,7 +178,7 @@ import {MenuTrigger, Button, Popover, Menu, Item} from 'react-aria-components';
173178
font-weight: 600;
174179
}
175180

176-
&[role=menuitemradio][data-selected]::before {
181+
&[data-selection-mode=single][data-selected]::before {
177182
content: '';
178183
content: '' / '';
179184
transform: scale(0.7)
@@ -791,7 +796,7 @@ A `Header` within a `Section` can be targeted with the `.react-aria-Header` CSS
791796

792797
An `Item` can be targeted with the `.react-aria-Item` CSS selector, or by overriding with a custom `className`. It supports the following states and render props:
793798

794-
<StateTable properties={docs.exports.MenuItemRenderProps.properties} />
799+
<StateTable properties={docs.exports.ItemRenderProps.properties} />
795800

796801
Items also support two slots: a label, and a description. When provided using the `<Text>` element, the item will have `aria-labelledby` and `aria-describedby` attributes pointing to these slots, improving screen reader announcement. See [complex items](#complex-items) for an example.
797802

packages/react-aria-components/docs/Table.mdx

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,22 +1311,6 @@ function Example() {
13111311
box-sizing: border-box;
13121312
outline: none;
13131313

1314-
.react-aria-Section:not(:first-child) {
1315-
margin-top: 12px;
1316-
}
1317-
1318-
.react-aria-Header {
1319-
font-size: 1.143rem;
1320-
font-weight: bold;
1321-
padding: 0 0.714rem;
1322-
}
1323-
1324-
[role=separator] {
1325-
height: 1px;
1326-
background: var(--separator-color);
1327-
margin: 2px 4px;
1328-
}
1329-
13301314
.react-aria-Item {
13311315
margin: 2px;
13321316
padding: 0.286rem 0.571rem;
@@ -1346,45 +1330,6 @@ function Example() {
13461330
background: var(--highlight-background);
13471331
color: var(--highlight-foreground);
13481332
}
1349-
1350-
&[data-disabled] {
1351-
color: var(--text-color-disabled);
1352-
}
1353-
1354-
[slot=label] {
1355-
font-weight: bold;
1356-
grid-area: label;
1357-
}
1358-
1359-
[slot=description] {
1360-
font-size: small;
1361-
grid-area: desc;
1362-
}
1363-
1364-
& kbd {
1365-
grid-area: kbd;
1366-
font-family: monospace;
1367-
text-align: end;
1368-
}
1369-
1370-
&[data-checked] {
1371-
padding-left: 24px;
1372-
1373-
&[data-checked=true]::before {
1374-
content: '';
1375-
content: '' / '';
1376-
alt: ' ';
1377-
position: absolute;
1378-
left: 4px;
1379-
font-weight: 600;
1380-
}
1381-
1382-
&[role=menuitemradio][data-checked=true]::before {
1383-
content: '';
1384-
content: '' / '';
1385-
transform: scale(0.7)
1386-
}
1387-
}
13881333
}
13891334
}
13901335

packages/react-aria-components/src/Collection.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,10 @@ export interface ItemRenderProps {
814814
* @selector [data-disabled]
815815
*/
816816
isDisabled: boolean,
817-
/** The type of selection that is allowed in the collection. */
817+
/**
818+
* The type of selection that is allowed in the collection.
819+
* @selector [data-selection-mode="single | multiple"]
820+
*/
818821
selectionMode: SelectionMode,
819822
/** The selection behavior for the collection. */
820823
selectionBehavior: SelectionBehavior,

packages/react-aria-components/src/GridList.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ function GridListItem({item}) {
341341
data-pressed={states.isPressed || undefined}
342342
data-allows-dragging={!!dragState || undefined}
343343
data-dragging={isDragging || undefined}
344-
data-drop-target={dropIndicator?.isDropTarget || undefined}>
344+
data-drop-target={dropIndicator?.isDropTarget || undefined}
345+
data-selection-mode={state.selectionManager.selectionMode === 'none' ? undefined : state.selectionManager.selectionMode}>
345346
<div {...gridCellProps}>
346347
<Provider
347348
values={[

packages/react-aria-components/src/ListBox.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ function Option<T>({item}: OptionProps<T>) {
410410
data-focus-visible={states.isFocusVisible || undefined}
411411
data-pressed={states.isPressed || undefined}
412412
data-dragging={isDragging || undefined}
413-
data-drop-target={droppableItem?.isDropTarget || undefined}>
413+
data-drop-target={droppableItem?.isDropTarget || undefined}
414+
data-selection-mode={state.selectionManager.selectionMode === 'none' ? undefined : state.selectionManager.selectionMode}>
414415
<Provider
415416
values={[
416417
[TextContext, {

packages/react-aria-components/src/Menu.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
import {AriaMenuProps, mergeProps, useFocusRing, useMenu, useMenuItem, useMenuSection, useMenuTrigger} from 'react-aria';
15-
import {BaseCollection, CollectionProps, ItemProps, ItemRenderProps, useCachedChildren, useCollection} from './Collection';
15+
import {BaseCollection, CollectionProps, ItemProps, useCachedChildren, useCollection} from './Collection';
1616
import {MenuTriggerProps as BaseMenuTriggerProps, Node, TreeState, useMenuTriggerState, useTreeState} from 'react-stately';
1717
import {ButtonContext} from './Button';
1818
import {ContextValue, forwardRefType, Provider, SlotProps, StyleProps, useContextProps, useRenderProps, useSlot} from './utils';
@@ -169,14 +169,6 @@ function MenuSection<T>({section, className, style, ...otherProps}: MenuSectionP
169169
);
170170
}
171171

172-
export interface MenuItemRenderProps extends ItemRenderProps {
173-
/**
174-
* Whether the item is currently selected.
175-
* @selector [data-selected]
176-
*/
177-
isSelected: boolean
178-
}
179-
180172
interface MenuItemProps<T> {
181173
item: Node<T>
182174
}
@@ -215,7 +207,8 @@ function MenuItem<T>({item}: MenuItemProps<T>) {
215207
data-focused={states.isFocused || undefined}
216208
data-focus-visible={isFocusVisible || undefined}
217209
data-pressed={states.isPressed || undefined}
218-
data-selected={states.isSelected || undefined}>
210+
data-selected={states.isSelected || undefined}
211+
data-selection-mode={state.selectionManager.selectionMode === 'none' ? undefined : state.selectionManager.selectionMode}>
219212
<Provider
220213
values={[
221214
[TextContext, {

packages/react-aria-components/src/Table.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,8 @@ function TableRow<T>({item}: {item: GridNode<T>}) {
10811081
data-focus-visible={isFocusVisible || undefined}
10821082
data-pressed={states.isPressed || undefined}
10831083
data-dragging={isDragging || undefined}
1084-
data-drop-target={dropIndicator?.isDropTarget || undefined}>
1084+
data-drop-target={dropIndicator?.isDropTarget || undefined}
1085+
data-selection-mode={state.selectionManager.selectionMode === 'none' ? undefined : state.selectionManager.selectionMode}>
10851086
<Provider
10861087
values={[
10871088
[CheckboxContext, {

packages/react-aria-components/src/TagGroup.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ function TagItem({item}) {
245245
data-focused={states.isFocused || undefined}
246246
data-focus-visible={isFocusVisible || undefined}
247247
data-pressed={states.isPressed || undefined}
248-
data-allows-removing={states.allowsRemoving || undefined}>
248+
data-allows-removing={states.allowsRemoving || undefined}
249+
data-selection-mode={state.selectionManager.selectionMode === 'none' ? undefined : state.selectionManager.selectionMode}>
249250
<div {...gridCellProps}>
250251
<Provider
251252
values={[

packages/react-aria-components/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export type {LabelProps} from './Label';
7474
export type {LinkProps} from './Link';
7575
export type {LinkRenderProps} from './Link';
7676
export type {ListBoxProps, ListBoxRenderProps} from './ListBox';
77-
export type {MenuItemRenderProps, MenuProps, MenuTriggerProps} from './Menu';
77+
export type {MenuProps, MenuTriggerProps} from './Menu';
7878
export type {MeterProps, MeterRenderProps} from './Meter';
7979
export type {ModalOverlayProps, ModalRenderProps} from './Modal';
8080
export type {NumberFieldProps, NumberFieldRenderProps} from './NumberField';

0 commit comments

Comments
 (0)