Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
10 changes: 6 additions & 4 deletions packages/@adobe/spectrum-css-temp/components/accordion/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ governing permissions and limitations under the License.
}

&.spectrum-Accordion-item--quiet, &.spectrum-Accordion-item--quiet:first-of-type {
border-radius: var(--spectrum-global-dimension-static-size-100);
border-color: transparent;
}
}
Expand Down Expand Up @@ -97,17 +98,18 @@ governing permissions and limitations under the License.
width: 100%;
border-style: solid;
border-color: transparent;
border-radius: var(--spectrum-global-dimension-static-size-100);

&.focus-ring {
border-radius: var(--spectrum-global-dimension-static-size-100);
outline: solid 2px var(--spectrum-accordion-item-focus-ring-color);
outline-offset: -4px;
}
}

.spectrum-Accordion-itemContent {
padding: 0 var(--spectrum-accordion-item-content-padding) var(--spectrum-accordion-item-content-padding) var(--spectrum-accordion-item-content-padding);
display: none;
.spectrum-Accordion-item.is-expanded {
.spectrum-Accordion-itemContent {
padding: 0 var(--spectrum-accordion-item-content-padding) var(--spectrum-accordion-item-content-padding) var(--spectrum-accordion-item-content-padding);
}
}

.spectrum-Accordion-item {
Expand Down
18 changes: 7 additions & 11 deletions packages/@adobe/spectrum-css-temp/components/accordion/skin.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ governing permissions and limitations under the License.

:root {
--spectrum-accordion-text-color-disabled: var(--spectrum-alias-text-color-disabled);
--spectrum-accordion-background-color-down: var(--spectrum-global-color-gray-300);
}

.spectrum-Accordion-item {
Expand All @@ -25,20 +26,14 @@ governing permissions and limitations under the License.
.spectrum-Accordion-itemHeader {
color: var(--spectrum-alias-text-color);

&:hover {
&:hover, &:focus-visible {
color: var(--spectrum-alias-text-color-hover);

background-color: var(--spectrum-accordion-background-color-hover);
}
}

.spectrum-Accordion-item {
&.is-expanded {
.spectrum-Accordion-itemHeader {
&:hover {
background-color: transparent;
}
}
&.is-pressed {
color: var(--spectrum-accordion-text-color-down);
background-color: var(--spectrum-accordion-background-color-down);
}
}

Expand All @@ -54,8 +49,9 @@ governing permissions and limitations under the License.
}
@media (forced-colors: active) {
.spectrum-Accordion-itemHeader {
border: none;
&:focus-visible {
outline: 3px solid CanvasText;
outline: 2px solid CanvasText;
}
}
}
3 changes: 2 additions & 1 deletion packages/@react-aria/disclosure/src/useDisclosure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export function useDisclosure(props: AriaDisclosureProps, state: DisclosureState
},
isDisabled,
onKeyDown(e) {
if (!isDisabled && (e.key === 'Enter' || e.key === ' ')) {
if (!isDisabled && !e.repeat && (e.key === 'Enter' || e.key === ' ')) {
e.preventDefault();
state.toggle();
}
Expand All @@ -114,6 +114,7 @@ export function useDisclosure(props: AriaDisclosureProps, state: DisclosureState
// This can be overridden at the panel element level.
role: 'group',
'aria-labelledby': triggerId,
'aria-hidden': !state.isExpanded,
hidden: supportsBeforeMatch ? true : !state.isExpanded
}
};
Expand Down
30 changes: 30 additions & 0 deletions packages/@react-aria/disclosure/test/useDisclosure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('useDisclosure', () => {

expect(buttonProps['aria-expanded']).toBe(false);
expect(panelProps.hidden).toBe(true);
expect(panelProps['aria-hidden']).toBe(true);
});

it('should return correct aria attributes when expanded', () => {
Expand Down Expand Up @@ -79,6 +80,35 @@ describe('useDisclosure', () => {
expect(result.current.state.isExpanded).toBe(true);
});

it('should not expand or collapse on repeat keydown event', () => {
let {result} = renderHook(() => {
let state = useDisclosureState({});
let disclosure = useDisclosure({}, state, ref);
return {state, disclosure};
});

let preventDefault = jest.fn();
let event = (e: Partial<KeyboardEvent>) => ({...e, preventDefault} as KeyboardEvent);

act(() => {
result.current.disclosure.buttonProps.onKeyDown?.(event({key: 'Enter', preventDefault}) as KeyboardEvent);
result.current.disclosure.buttonProps.onKeyDown?.(event({key: 'Enter', preventDefault, repeat: true}) as KeyboardEvent);
});

expect(preventDefault).toHaveBeenCalledTimes(1);

expect(result.current.state.isExpanded).toBe(true);

act(() => {
result.current.disclosure.buttonProps.onKeyDown?.(event({key: 'Enter', preventDefault}) as KeyboardEvent);
result.current.disclosure.buttonProps.onKeyDown?.(event({key: 'Enter', preventDefault, repeat: true}) as KeyboardEvent);
});

expect(preventDefault).toHaveBeenCalledTimes(2);

expect(result.current.state.isExpanded).toBe(false);
});

it('should not toggle when disabled', () => {
let {result} = renderHook(() => {
let state = useDisclosureState({});
Expand Down
5 changes: 3 additions & 2 deletions packages/@react-spectrum/accordion/src/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/

import {AriaLabelingProps, DOMProps, DOMRef, StyleProps} from '@react-types/shared';
import {Button, UNSTABLE_DisclosureGroup as DisclosureGroup, DisclosureGroupProps, DisclosurePanelProps, DisclosureProps, Heading, UNSTABLE_Disclosure as RACDisclosure, UNSTABLE_DisclosurePanel as RACDisclosurePanel} from 'react-aria-components';
import {Button, DisclosureGroup, DisclosureGroupProps, DisclosurePanelProps, DisclosureProps, Heading, Disclosure as RACDisclosure, DisclosurePanel as RACDisclosurePanel} from 'react-aria-components';
import ChevronLeftMedium from '@spectrum-icons/ui/ChevronLeftMedium';
import ChevronRightMedium from '@spectrum-icons/ui/ChevronRightMedium';
import {classNames, useDOMRef, useStyleProps} from '@react-spectrum/utils';
Expand Down Expand Up @@ -103,8 +103,9 @@ function DisclosureHeader(props: SpectrumDisclosureHeaderProps, ref: DOMRef<HTML
<Heading ref={domRef} level={level} className={classNames(styles, 'spectrum-Accordion-itemHeading')}>
<Button
slot="trigger"
className={({isHovered, isFocusVisible}) => classNames(styles, 'spectrum-Accordion-itemHeader', {
className={({isHovered, isFocusVisible, isPressed}) => classNames(styles, 'spectrum-Accordion-itemHeader', {
'is-hovered': isHovered,
'is-pressed': isPressed,
'focus-ring': isFocusVisible
})}>
{direction === 'ltr' ? (
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/s2/src/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import {ContextValue, UNSTABLE_DisclosureGroup as DisclosureGroup, DisclosureGroupProps, SlotProps} from 'react-aria-components';
import {ContextValue, DisclosureGroup, DisclosureGroupProps, SlotProps} from 'react-aria-components';
import {DisclosureContext} from './Disclosure';
import {DOMProps, DOMRef, DOMRefValue} from '@react-types/shared';
import {getAllowedOverrides, StylesPropWithHeight, UnsafeStyles} from './style-utils' with { type: 'macro' };
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-spectrum/s2/src/Disclosure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import {ActionButtonContext} from './ActionButton';
import {AriaLabelingProps, DOMProps, DOMRef, DOMRefValue, forwardRefType} from '@react-types/shared';
import {Button, ContextValue, DisclosureStateContext, Heading, Provider, UNSTABLE_Disclosure as RACDisclosure, UNSTABLE_DisclosurePanel as RACDisclosurePanel, DisclosurePanelProps as RACDisclosurePanelProps, DisclosureProps as RACDisclosureProps, useLocale, useSlottedContext} from 'react-aria-components';
import {Button, ContextValue, DisclosureStateContext, Heading, Provider, Disclosure as RACDisclosure, DisclosurePanel as RACDisclosurePanel, DisclosurePanelProps as RACDisclosurePanelProps, DisclosureProps as RACDisclosureProps, useLocale, useSlottedContext} from 'react-aria-components';
import {CenterBaseline} from './CenterBaseline';
import {centerPadding, getAllowedOverrides, StyleProps, UnsafeStyles} from './style-utils' with { type: 'macro' };
import Chevron from '../ui-icons/Chevron';
Expand Down Expand Up @@ -174,7 +174,7 @@ const buttonStyles = style({
default: 'transparent',
isFocusVisible: lightDark('transparent-black-100', 'transparent-white-100'),
isHovered: lightDark('transparent-black-100', 'transparent-white-100'),
isPressed: lightDark('transparent-black-100', 'transparent-white-100')
isPressed: lightDark('transparent-black-300', 'transparent-white-300')
},
transition: 'default',
borderWidth: 0,
Expand Down
19 changes: 18 additions & 1 deletion packages/@react-spectrum/s2/stories/Disclosure.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,24 @@ export const Controlled: Story = {

Controlled.parameters = {
docs: {
disable: true
source: {
transform: () => {
return `
function ControlledDisclosure(props) {
let [isExpanded, setExpanded] = React.useState(false);
return (
<Disclosure {...props} isExpanded={isExpanded} onExpandedChange={setExpanded}>
<DisclosureTitle>
Files
</DisclosureTitle>
<DisclosurePanel>
Files content
</DisclosurePanel>
</Disclosure>
);
}`;
}
}
}
};

Expand Down
12 changes: 6 additions & 6 deletions packages/react-aria-components/docs/Disclosure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ preRelease: alpha

# Disclosure

<PageDescription>{docs.exports.UNSTABLE_Disclosure.description}</PageDescription>
<PageDescription>{docs.exports.Disclosure.description}</PageDescription>

<HeaderInfo
packageData={packageData}
Expand All @@ -40,7 +40,7 @@ preRelease: alpha
## Example

```tsx example
import {UNSTABLE_Disclosure as Disclosure, Button, UNSTABLE_DisclosurePanel as DisclosurePanel, Heading} from 'react-aria-components';
import {Disclosure, Button, DisclosurePanel, Heading} from 'react-aria-components';

<Disclosure>
<Heading>
Expand Down Expand Up @@ -116,7 +116,7 @@ Custom styled disclosures can be difficult to build in an accessible way with th
A disclosure consists of a button and panel of content. The button contains the label representing content within the panel, and the panel is the section of content that is associated with the button which is either expanded or collapsed.

```tsx
import {Button, UNSTABLE_Disclosure as Disclosure, UNSTABLE_DisclosurePanel as DisclosurePanel, Heading} from 'react-aria-components';
import {Button, Disclosure, DisclosurePanel, Heading} from 'react-aria-components';

<Disclosure>
<Heading>
Expand Down Expand Up @@ -206,7 +206,7 @@ A Disclosure can be disabled using the `isDisabled` prop.

### Disclosure

<PropTable component={docs.exports.UNSTABLE_Disclosure} links={docs.links} />
<PropTable component={docs.exports.Disclosure} links={docs.links} />

### Button

Expand All @@ -222,7 +222,7 @@ A Disclosure can be disabled using the `isDisabled` prop.
<details>
<summary style={{fontWeight: 'bold'}}><ChevronRight size="S" /> Show props</summary>

<PropTable component={docs.exports.UNSTABLE_DisclosurePanel} links={docs.links} />
<PropTable component={docs.exports.DisclosurePanel} links={docs.links} />

</details>

Expand Down Expand Up @@ -284,7 +284,7 @@ A `DisclosurePanel` can be targeted with the `.react-aria-DisclosurePanel` CSS s

All React Aria Components export a corresponding context that can be used to send props to them from a parent element. This enables you to build your own compositional APIs similar to those found in React Aria Components itself. You can send any prop or ref via context that you could pass to the corresponding component. The local props and ref on the component are merged with the ones passed via context, with the local props taking precedence (following the rules documented in [mergeProps](mergeProps.html)).

<ContextTable components={['UNSTABLE_Disclosure']} docs={docs} />
<ContextTable components={['Disclosure']} docs={docs} />

This example shows a `DisclosureGroup` component that renders a group of disclosures. The entire group can be marked as disabled via the `isDisabled` prop, which is passed to all child disclosures via the `DisclosureContext` provider.

Expand Down
12 changes: 6 additions & 6 deletions packages/react-aria-components/docs/DisclosureGroup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ preRelease: alpha

# DisclosureGroup

<PageDescription>{docs.exports.UNSTABLE_DisclosureGroup.description}</PageDescription>
<PageDescription>{docs.exports.DisclosureGroup.description}</PageDescription>

<HeaderInfo
packageData={packageData}
Expand All @@ -42,7 +42,7 @@ preRelease: alpha
## Example

```tsx example
import {UNSTABLE_DisclosureGroup as DisclosureGroup, UNSTABLE_Disclosure as Disclosure, Button, UNSTABLE_DisclosurePanel as DisclosurePanel, Heading} from 'react-aria-components';
import {DisclosureGroup, Disclosure, Button, DisclosurePanel, Heading} from 'react-aria-components';

<DisclosureGroup defaultExpandedKeys={['personal']}>
<Disclosure id="personal">
Expand Down Expand Up @@ -95,7 +95,7 @@ Custom styled disclosure groups can be difficult to implement in an accessible w
A disclosure group consists of a set of disclosures. Each disclosure includes a button within a heading and panel of content that is either shown or hidden. Zero or more disclosures within a group can be expanded at the same time, however, by default, only one disclosure can be expanded at a time. Users may click or touch a disclosure to expand it, or use the <Keyboard>Tab</Keyboard> key to navigate between disclosures and the <Keyboard>Enter</Keyboard> or <Keyboard>Space</Keyboard> key to toggle it.

```tsx
import {UNSTABLE_DisclosureGroup as DisclosureGroup, UNSTABLE_Disclosure as Disclosure, Button, UNSTABLE_DisclosurePanel as DisclosurePanel, Heading} from 'react-aria-components';
import {DisclosureGroup, Disclosure, Button, DisclosurePanel, Heading} from 'react-aria-components';

<DisclosureGroup>
<Disclosure>
Expand Down Expand Up @@ -223,7 +223,7 @@ A DisclosureGroup can be disabled using the `isDisabled` prop.

### DisclosureGroup

<PropTable component={docs.exports.UNSTABLE_DisclosureGroup} links={docs.links} />
<PropTable component={docs.exports.DisclosureGroup} links={docs.links} />

### Disclosure

Expand All @@ -232,7 +232,7 @@ Within a `<DisclosureGroup>`, most `<Disclosure>` props are set automatically. T
<details>
<summary style={{fontWeight: 'bold'}}><ChevronRight size="S" /> Show props</summary>

<PropTable component={docs.exports.UNSTABLE_Disclosure} links={docs.links} />
<PropTable component={docs.exports.Disclosure} links={docs.links} />

</details>

Expand All @@ -250,7 +250,7 @@ Within a `<DisclosureGroup>`, most `<Disclosure>` props are set automatically. T
<details>
<summary style={{fontWeight: 'bold'}}><ChevronRight size="S" /> Show props</summary>

<PropTable component={docs.exports.UNSTABLE_DisclosurePanel} links={docs.links} />
<PropTable component={docs.exports.DisclosurePanel} links={docs.links} />

</details>

Expand Down
2 changes: 1 addition & 1 deletion packages/react-aria-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export {composeRenderProps, DEFAULT_SLOT, Provider, useContextProps, useSlottedC
export {DateField, DateInput, DateSegment, TimeField, DateFieldContext, TimeFieldContext, DateFieldStateContext, TimeFieldStateContext} from './DateField';
export {DatePicker, DateRangePicker, DatePickerContext, DateRangePickerContext, DatePickerStateContext, DateRangePickerStateContext} from './DatePicker';
export {DialogTrigger, Dialog, DialogContext, OverlayTriggerStateContext} from './Dialog';
export {Disclosure as UNSTABLE_Disclosure, DisclosureGroup as UNSTABLE_DisclosureGroup, DisclosureGroupStateContext, DisclosurePanel as UNSTABLE_DisclosurePanel, DisclosureStateContext, DisclosureContext} from './Disclosure';
export {Disclosure, DisclosureGroup, DisclosureGroupStateContext, DisclosurePanel, DisclosureStateContext, DisclosureContext} from './Disclosure';
export {DropZone, DropZoneContext} from './DropZone';
export {FieldError, FieldErrorContext} from './FieldError';
export {FileTrigger} from './FileTrigger';
Expand Down
2 changes: 1 addition & 1 deletion packages/react-aria-components/test/Disclosure.ssr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {screen, testSSR} from '@react-spectrum/test-utils-internal';
describe('Disclosure SSR', function () {
it('should render without errors', async function () {
await testSSR(__filename, `
import {UNSTABLE_DisclosureGroup as DisclosureGroup, UNSTABLE_Disclosure as Disclosure, UNSTABLE_DisclosurePanel as DisclosurePanel, Heading, Button} from '../';
import {DisclosureGroup, Disclosure, DisclosurePanel, Heading, Button} from '../';

<React.StrictMode>
<DisclosureGroup>
Expand Down
6 changes: 3 additions & 3 deletions packages/react-aria-components/test/Disclosure.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

import {
Button,
UNSTABLE_Disclosure as Disclosure,
UNSTABLE_DisclosureGroup as DisclosureGroup,
UNSTABLE_DisclosurePanel as DisclosurePanel,
Disclosure,
DisclosureGroup,
DisclosurePanel,
Heading,
Menu,
MenuItem,
Expand Down
6 changes: 3 additions & 3 deletions starters/tailwind/src/Disclosure.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useContext } from "react";
import {
UNSTABLE_Disclosure as AriaDisclosure,
UNSTABLE_DisclosureGroup as AriaDisclosureGroup,
Disclosure as AriaDisclosure,
DisclosureGroup as AriaDisclosureGroup,
DisclosureProps as AriaDisclosureProps,
DisclosureGroupProps as AriaDisclosureGroupProps,
UNSTABLE_DisclosurePanel as AriaDisclosurePanel,
DisclosurePanel as AriaDisclosurePanel,
DisclosurePanelProps as AriaDisclosurePanelProps,
composeRenderProps,
Heading,
Expand Down