Skip to content
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
2 changes: 1 addition & 1 deletion packages/@react-aria/button/docs/useToggleButtonGroup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ By default, toggle button groups are horizontally oriented. The orientation prop
</ToggleButtonGroup>
```

## Accessiblity
## Accessibility

A `ToggleButtonGroup` can be labeled using the `aria-label` or `aria-labelledby` props.

Expand Down
2 changes: 1 addition & 1 deletion packages/@react-aria/overlays/docs/usePopover.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ with <TypeLink links={dialogDocs.links} type={dialogDocs.exports.useDialog} />.

The `Popover` component uses an &lt;<TypeLink links={docs.links} type={docs.exports.Overlay} />&gt; to render its contents in a React [Portal](https://reactjs.org/docs/portals.html) at the end of the document body, which ensures it is not clipped by other elements. It also acts as a focus scope, containing focus within the popover and restoring it to the trigger when it unmounts. <TypeLink links={docs.links} type={docs.exports.usePopover} /> handles positioning the popover relative to the trigger element, and closing it when the user interacts outside or presses the <Keyboard>Escape</Keyboard> key.

<TypeLink links={docs.links} type={docs.exports.usePopover} /> also hides content outside the popover from screen readers, which is important since the surrounding content won't be in context of the original trigger due to the portal. To allow screen reader users to dismiss the popover without a keyboard (e.g. on mobile), visually hidden &lt;<TypeLink links={docs.links} type={docs.exports.DismissButton} />&gt; elements are added at the start and end of the popover. An underlay is also used to prevent scrolling and interacting with elements outside the popover with a pointer, to avoid unintentially repositioning or closing it.
<TypeLink links={docs.links} type={docs.exports.usePopover} /> also hides content outside the popover from screen readers, which is important since the surrounding content won't be in context of the original trigger due to the portal. To allow screen reader users to dismiss the popover without a keyboard (e.g. on mobile), visually hidden &lt;<TypeLink links={docs.links} type={docs.exports.DismissButton} />&gt; elements are added at the start and end of the popover. An underlay is also used to prevent scrolling and interacting with elements outside the popover with a pointer, to avoid unintentionally repositioning or closing it.

```tsx example export=true render=false
import type {AriaPopoverProps} from 'react-aria';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ See Icon's [labeling](workflow-icons.html#labeling) section and Avatar's [access
<Item textValue="Mail">
<Email size="S" />
<Text>Mail</Text>
<Text slot="description">Send and recieve emails</Text>
<Text slot="description">Send and receive emails</Text>
</Item>
<Item textValue="File Explorer">
<Folder size="S" />
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/filetrigger/docs/FileTrigger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ By default, the file trigger will accept any file type. To support only certain

## Multiple files

A file trigger can accept multiple files by passsing the `allowsMultiple` property.
A file trigger can accept multiple files by passing the `allowsMultiple` property.

```tsx example
<FileTrigger allowsMultiple>
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/icon/docs/custom-icons.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function CustomIcon(props) {
<CustomIcon aria-label="Star" />
```

Wrapping the SVG with Icon will ensure it recieves proper styling when used within React Spectrum components:
Wrapping the SVG with Icon will ensure it receives proper styling when used within React Spectrum components:

```tsx example
import {Button, Text} from '@adobe/react-spectrum';
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/progress/docs/ProgressCircle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ keywords: [progress circle]
## Value

ProgressCircles are controlled with the `value` prop.
By default, the `value` prop represents the current percentage of progress, as the minimum and maxiumum values default to 0 and 100, respectively.
By default, the `value` prop represents the current percentage of progress, as the minimum and maximum values default to 0 and 100, respectively.

```tsx example
<ProgressCircle aria-label="Loading…" value={25} />
Expand Down
6 changes: 3 additions & 3 deletions packages/@react-spectrum/tabs/stories/Tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,10 +374,10 @@ ChangingTabTitles.story = {
name: 'changing tab titles'
};

export const ChangingSelectionProgramatically: TabsStory = () => <ControlledSelection />;
export const ChangingSelectionProgrammatically: TabsStory = () => <ControlledSelection />;

ChangingSelectionProgramatically.story = {
name: 'changing selection programatically'
ChangingSelectionProgrammatically.story = {
name: 'changing selection programmatically'
};

export const Links: StoryFn<SpectrumTabsProps<unknown> & {collapsed?: boolean}> = (args) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/tabs/test/Tabs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ describe('Tabs', function () {
expect(onSelectionChange).toHaveBeenCalledWith(defaultItems[0].name);
});

it('updates the tab index of the selected tab if programatically changed', function () {
it('updates the tab index of the selected tab if programmatically changed', function () {
let Example = (props) => (
<Provider theme={theme}>
<Tabs aria-label="Test Tabs" items={defaultItems} selectedKey={props.selectedKey}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,6 @@ export const DisabledBehaviorAll: TreeViewStoryProps = () => (
<TestTree disabledBehavior="all" selectionMode="multiple" />
);

export const HiglightSelectionWithDisabledBehaviorAll: TreeViewStoryProps = () => (
export const HighlightSelectionWithDisabledBehaviorAll: TreeViewStoryProps = () => (
<TestTree selectionStyle="highlight" selectionMode="multiple" disabledBehavior="all" />
);
2 changes: 1 addition & 1 deletion packages/@react-types/calendar/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface CalendarPropsBase {
autoFocus?: boolean,
/** Controls the currently focused date within the calendar. */
focusedValue?: DateValue | null,
/** The date that is focused when the calendar first mounts (uncountrolled). */
/** The date that is focused when the calendar first mounts (uncontrolled). */
defaultFocusedValue?: DateValue | null,
/** Handler that is called when the focused date changes. */
onFocusChange?: (date: CalendarDate) => void,
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-types/card/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ interface LayoutOptions {
collator?: Intl.Collator,
// TODO: is this valid or is scale a spectrum specific thing that should be left out of the layouts?
// Added here so we can keep the default item padding options within the layouts instead of having to
// do extra work in CardView to accomodate different sizing for scales
// do extra work in CardView to accommodate different sizing for scales
scale?: Scale
}

Expand All @@ -51,7 +51,7 @@ export interface CardViewLayoutConstructor<T> {
}

interface CardViewProps<T> extends CollectionBase<T>, MultipleSelection, Omit<AsyncLoadable, 'isLoading'> {
// TODO: Does LayoutContructor and Layout give enough info for a user to know what to put in their own custom layout?
// TODO: Does LayoutConstructor and Layout give enough info for a user to know what to put in their own custom layout?
// Replaced with CardViewLayout so that they know they need to have keyboardDelegate stuff as well as collection, disabledKeys, etc
layout: CardViewLayoutConstructor<T> | CardViewLayout<T>,
// TODO: readd size when we get updated designs from spectrum
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/docs/pages/blog/building-a-button-part-3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ There are many nuances to this, however. For example, when clicking a text input

Another challenge is that focus events may occur without any preceding user event. For example, when navigating through a form with the next and previous buttons on the software keyboard in iOS, only a focus event is fired, with no keyboard or pointer events before it. This can also occur when navigating with an assistive technology like a screen reader. In these cases, we don’t know how the navigation occurred, so we default to showing the focus ring to ensure the user knows where focus went.

However, we do not want programmatic `focus()` calls to affect the current input modality. The user may click on an element with the mouse, and in response focus is moved somewhere else programatically. For example, when clicking on a button to open a menu, focus is typically moved to the first menu item. However, because `focus` events are still fired when focusing an element programmatically, we need to ignore these events to ensure the focus ring does not appear or disappear based on programatic focus movement.
However, we do not want programmatic `focus()` calls to affect the current input modality. The user may click on an element with the mouse, and in response focus is moved somewhere else programmatically. For example, when clicking on a button to open a menu, focus is typically moved to the first menu item. However, because `focus` events are still fired when focusing an element programmatically, we need to ignore these events to ensure the focus ring does not appear or disappear based on programmatic focus movement.

There are also various inconsistencies in the number and order of focus events across browsers. For example, Firefox fires two extra focus events when the user first clicks on any element in an iframe: first on the window, then on the document. Finally, it fires a focus event on the element itself. We need to ignore these extra focus events so they don’t unintentionally cause the focus ring to appear when using a mouse.

Expand All @@ -67,7 +67,7 @@ Unfortunately, Safari both on macOS and iOS reaaaally doesn’t want to do this.

Even with this setting turned on, however, Safari still does not focus buttons and other native form elements on mouse down or touch start. A [bug](https://bugs.webkit.org/show_bug.cgi?id=22261) for this has been open against WebKit since 2008, and it seems unlikely to be fixed any time soon. In this case, we do need to normalize this to ensure browsers are consistent. We can handle focusing the element programmatically on mouse down ourselves.

However, it gets even more tricky on iOS. While on macOS, Safari will respect our programatic focus, on iOS the browser attempts to forcibly blur the element *asynchronously* sometime after the `onClick` event is fired. This means that even programmatically, focusing the button will not work. 🤯
However, it gets even more tricky on iOS. While on macOS, Safari will respect our programmatic focus, on iOS the browser attempts to forcibly blur the element *asynchronously* sometime after the `onClick` event is fired. This means that even programmatically, focusing the button will not work. 🤯

The only solution is to call `event.preventDefault()` on all mouse and touch events on the element, and handle focusing ourselves. This ensures that the browser does not perform any of its default behavior, including this forced blur, but it means that we’ll have to handle all of the default browser behavior ourselves.

Expand Down
6 changes: 3 additions & 3 deletions packages/dev/docs/pages/blog/rtl-date-time.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Below is a simplified code example of how we utilize Unicode characters to enfor

## DateFields

Date fields, on the other hand, were much more complicated to solve in comparsion. Since we were relying on `display: flex` to format the date segments, the resulting format appeared to mirror the order in which the segments were stored, as returned by [DateFormatter](https://react-spectrum.adobe.com/internationalized/date/DateFormatter.html#dateformatter). This suggested that we could apply a similar approach to what we used for time fields — forcing a left-to-right direction on the date segments.
Date fields, on the other hand, were much more complicated to solve in comparison. Since we were relying on `display: flex` to format the date segments, the resulting format appeared to mirror the order in which the segments were stored, as returned by [DateFormatter](https://react-spectrum.adobe.com/internationalized/date/DateFormatter.html#dateformatter). This suggested that we could apply a similar approach to what we used for time fields — forcing a left-to-right direction on the date segments.

However, this assumption proved too broad. In some locales, such as Arabic (`ar-AE`), the date segments were already correctly formatted. In particular, we found that in Arabic, the separators between date segments contained [right-to-left marks](https://en.wikipedia.org/wiki/Implicit_directional_marks) which were returned by the `Intl.DateTimeFormat` API. This causes the separators to be positioned to the left of the preceding text. When we tried enforcing a left-to-right direction like we did in time field using the same solution, the date field was formatted as `2 2022/ 12/` instead of `2022/12/2` due to the presence of the right-to-left marks interfering with the LRI Unicode. In contrast, Hebrew did not have such markers. Therefore, we had to adopt a different approach that accounted for these variations.

Expand Down Expand Up @@ -111,7 +111,7 @@ However, this assumption proved too broad. In some locales, such as Arabic (`ar-
</div>
```

Through much trial and error, we discovered that appplying the [left-to-right embedding (LRE) Unicode](https://unicode.org/reports/tr9/#Explicit_Directional_Embeddings) on each date segment displayed date fields in Hebrew as left-to-right but also preserved the right-to-left marks on the separaters in Arabic, ensuring that dates in both languages were formatted correctly. While we could have added Unicode to the segments like we did with the time fields, we opted for the [equivalent CSS](https://unicode.org/reports/tr9/#Markup_And_Formatting) approach instead to avoid modifying the DOM. This CSS is applied on date segments with placeholder or actual values to avoid the behavior discussed earlier with shifting segments. Through additional testing, we found that we should only apply left-to-right embedding on numeric values. If the value was displayed as text (e.g. "November" instead of "11"), we did not apply this CSS.
Through much trial and error, we discovered that applying the [left-to-right embedding (LRE) Unicode](https://unicode.org/reports/tr9/#Explicit_Directional_Embeddings) on each date segment displayed date fields in Hebrew as left-to-right but also preserved the right-to-left marks on the separaters in Arabic, ensuring that dates in both languages were formatted correctly. While we could have added Unicode to the segments like we did with the time fields, we opted for the [equivalent CSS](https://unicode.org/reports/tr9/#Markup_And_Formatting) approach instead to avoid modifying the DOM. This CSS is applied on date segments with placeholder or actual values to avoid the behavior discussed earlier with shifting segments. Through additional testing, we found that we should only apply left-to-right embedding on numeric values. If the value was displayed as text (e.g. "November" instead of "11"), we did not apply this CSS.

## Keyboard Navigation

Expand All @@ -136,7 +136,7 @@ Below is an example of a date field in Hebrew with the correct date format but i

<Video alt="Demo of keyboard navigation prior to fixes" src={keyboardVideoURL} muted controls />

As a result, we updated the keyboard navigation in right-to-left langauges to calculate the distance between the currently focused segment and other segments to identify the closest node based on whether the left or right arrow key was pressed, rather than reying on the DOM order.
As a result, we updated the keyboard navigation in right-to-left languages to calculate the distance between the currently focused segment and other segments to identify the closest node based on whether the left or right arrow key was pressed, rather than reying on the DOM order.

## Conclusion

Expand Down
2 changes: 1 addition & 1 deletion packages/dev/docs/pages/react-aria/forms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ In addition to the built-in constraints, custom validation is supported by provi

By default, validation errors are displayed to the user after the value is committed (e.g. on blur), or when the form is submitted. This avoids confusing the user with irrelevant errors while they are still entering a value.

In some cases, validating in realtime can be desireable, such as when meeting password requirements. This can be accomplished by making the field value [controlled](#controlled-forms), and setting the `isInvalid` prop and `FieldError` children accordingly.
In some cases, validating in realtime can be desirable, such as when meeting password requirements. This can be accomplished by making the field value [controlled](#controlled-forms), and setting the `isInvalid` prop and `FieldError` children accordingly.

```tsx example
function Example() {
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/docs/pages/react-spectrum/forms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ In addition to the built-in constraints, custom validation is supported by provi

Usually, validation errors should be displayed to the user after the value is committed (e.g. on blur), or when the form is submitted. This avoids confusing the user with irrelevant errors while they are still entering a value.

In some cases, validating in realtime can be desireable, such as when meeting password requirements. This can be accomplished by making the field value [controlled](#controlled-forms), and setting the `validationState` and `errorMessage` props accordingly.
In some cases, validating in realtime can be desirable, such as when meeting password requirements. This can be accomplished by making the field value [controlled](#controlled-forms), and setting the `validationState` and `errorMessage` props accordingly.

```tsx example
function Example() {
Expand Down
3 changes: 3 additions & 0 deletions packages/dev/s2-docs/.parcelrc-s2-docs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"extends": "@parcel/config-default",
"resolvers": ["@react-aria/parcel-resolver-optimize-locales", "@parcel/resolver-glob", "./S2DocsResolver", "parcel-resolver-docs", "..."],
"optimizers": {
"*.html": []
},
"transformers": {
"docs:*.{js,ts,tsx,json}": ["parcel-transformer-docs", "@parcel/transformer-inline"],
"docs-json:*.{js,ts,tsx,json}": ["parcel-transformer-docs"],
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/s2-docs/pages/react-aria/CheckboxGroup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {InlineAlert, Heading, Content} from '@react-spectrum/s2'
export const tags = ['input'];
export const relatedPages = [
{title: 'useCheckboxGroup', url: 'https://react-spectrum.adobe.com/react-aria/useCheckboxGroup.html'},
{title: 'Testing', url: './CheckboxGroup/testing'}
{title: 'Testing CheckboxGroup', url: './CheckboxGroup/testing'}
];
export const description = 'Allows a user to select multiple items from a list of options.';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {InstallCommand} from '../../../src/InstallCommand';
import {PatternTestingFAQ} from '../../../src/PatternTestingFAQ';

export const isSubpage = true;
export const hideFromSearch = true;
export const tags = ['testing', 'checkboxgroup', 'test-utils'];
export const description = 'Testing CheckboxGroup with React Aria test utils';

Expand Down
2 changes: 1 addition & 1 deletion packages/dev/s2-docs/pages/react-aria/ComboBox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {InlineAlert, Heading, Content} from '@react-spectrum/s2'
export const tags = ['autocomplete', 'search', 'typeahead', 'input'];
export const relatedPages = [
{title: 'useComboBox', url: 'https://react-spectrum.adobe.com/react-aria/useComboBox.html'},
{title: 'Testing', url: './ComboBox/testing'}
{title: 'Testing ComboBox', url: './ComboBox/testing'}
];
export const description = 'Combines a text input with a listbox, allowing users to filter a list of options to items matching a query.';

Expand Down
1 change: 1 addition & 0 deletions packages/dev/s2-docs/pages/react-aria/ComboBox/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {InstallCommand} from '../../../src/InstallCommand';
import {PatternTestingFAQ} from '../../../src/PatternTestingFAQ';

export const isSubpage = true;
export const hideFromSearch = true;
export const tags = ['testing', 'combobox', 'test-utils'];
export const description = 'Testing ComboBox with React Aria test utils';

Expand Down
2 changes: 1 addition & 1 deletion packages/dev/s2-docs/pages/react-aria/GridList.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {InlineAlert, Heading, Content} from '@react-spectrum/s2'
export const tags = ['list view'];
export const relatedPages = [
{title: 'useGridList', url: 'https://react-spectrum.adobe.com/react-aria/useGridList.html'},
{title: 'Testing', url: './GridList/testing'}
{title: 'Testing GridList', url: './GridList/testing'}
];
export const description = 'Displays a list of interactive items, with support for keyboard navigation, selection, and actions.';

Expand Down
1 change: 1 addition & 0 deletions packages/dev/s2-docs/pages/react-aria/GridList/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {InstallCommand} from '../../../src/InstallCommand';
import {PatternTestingFAQ} from '../../../src/PatternTestingFAQ';

export const isSubpage = true;
export const hideFromSearch = true;
export const tags = ['testing', 'gridlist', 'test-utils'];
export const description = 'Testing GridList with React Aria test utils';

Expand Down
Loading
Loading