Skip to content

Commit

Permalink
Add new extra package docs to repo and update installation process …
Browse files Browse the repository at this point in the history
…docs (#257)

* move bottomSheet

* add categories

* Add new useCarousel doc

* switch to related guidelines

* Add Carousel docs

* update carousel guideline links

* update accessibilityActions type

* improved wording

* improved installation instructions

* update to Arguments for hook

* Add new useKeyboard doc
  • Loading branch information
JDMathew authored Oct 11, 2024
1 parent 9927eea commit 95e3cae
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 5 deletions.
File renamed without changes.
93 changes: 93 additions & 0 deletions packages/extras/docs/components/Carousel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { Required } from '@site/src/components';

# Carousel

AMA Provides an accessible Carousel component built on top
of [React Native FlatList](https://reactnative.dev/docs/flatlist)
using the [useCarousel](./../hooks/useCarousel.md) hook.

## Example

```tsx {2-15,22-23}
import { Carousel } from '@react-native-ama/extras';

const Component = () => {
const data = [
{ key: '1', image: image_1 },
{ key: '2', image: image_2 },
{ key: '3', image: image_3 },
];
const ref = React.useRef<FlatList<(typeof data)[number]>>(null);

const renderItem: ListRenderItem<(typeof data)[number]> = ({ item }) => {
return <Image source={item.image} resizeMode="cover" />;
};

return (
<Carousel
ref={ref}
accessibilityLabel="Carousel of dog portraits"
data={data}
renderItem={renderItem}
/>
);
};
```

## Accessibility

- Provides / abstracts `accessibilityActions` array to Carousel with `increment` and `decrement` actions
- Provides / abstracts `onAccessibilityAction` handler to Carousel to manage the `AccessibilityActionEvent` change and scroll to the new index in the FlatList
- Provides / abstracts `accessibilityRole` to Carousel as `adjustable`/ `slider`

## Props

### <Required /> `ref`

The carousel reference provides access to underlying `FlatList` methods and is required for accessibility actions to work on iOS.

| Type | Default |
| ------------------------------------ | --------- |
| React.RefObject\<FlatList\<ItemT\>\> | undefined |

### <Required /> `accessibilityLabel`

The `accessibilityLabel` is required and should describe what the carousel displays, this is announced by the screen reader when the element gains focus, then it announces its role ('adjustable').

| Type | Default |
| ------ | --------- |
| string | undefined |

### <Required /> `data` (Inherited from FlatList)

An array (or array-like list) of items to render. Other data types can be used by targeting VirtualizedList directly.

| Type | Default |
| --------------------------------------- | --------- |
| ArrayLike\<ItemT\> \| null \| undefined | undefined |

### <Required /> `renderItem` (Inherited from FlatList)

Takes an item from data and renders it into the list. Typical usage:

```tsx
const renderItem = ({item}) => (
<TouchableOpacity onPress={() => onPress(item)}>
<Text>{item.title}</Text>
</TouchableOpacity>
);

...

<FlatList data={[{title: 'Title Text', key: 'item1'}]} renderItem={renderItem} />
```

Provides additional metadata like `index` if you need it.

| Type | Default |
| -------------------------------------------- | --------- |
| ListRenderItem\<ItemT\> \| null \| undefined | undefined |

## Related guidelines

- [Carousel](/guidelines/carousel)
5 changes: 5 additions & 0 deletions packages/extras/docs/components/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"label": "Components",
"collapsible": true,
"collapsed": false
}
17 changes: 17 additions & 0 deletions packages/extras/docs/extras.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,20 @@ Install the `@react-native-ama/extras` package with your favourite package manag
```bash npm2yarn
npm install @react-native-ama/extras
```

### Dependencies

Some components rely on [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) and/or [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler),
so these dependencies are required for the extras package to function and should also be installed.

```bash npm2yarn
npm install react-native-reanimated
```

Follow the specific installation instructions for React Native Reanimated [here](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#installation).

```bash npm2yarn
npm install react-native-gesture-handler
```

Follow the specific installation instructions for React Native Gesture Handler [here](https://docs.swmansion.com/react-native-gesture-handler/docs/fundamentals/installation), specifically wrapping the entry point of the app in a `GestureHandlerRootView`.
5 changes: 5 additions & 0 deletions packages/extras/docs/hooks/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"label": "Hooks",
"collapsible": true,
"collapsed": false
}
49 changes: 49 additions & 0 deletions packages/extras/docs/hooks/useCarousel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Required } from '@site/src/components'

# useCarousel

`useCarousel` is a hook that provides `a11yProps` for creating carousels from FlatLists or ScrollViews.

:::info

`a11yProps` here is an object that contains all the necessary accessibility props to make an accessible carousel, those being the role, actions and the onAction handler. See [Carousel guidelines](/guidelines/carousel) for more information.

:::

## Usage

```tsx {2-4,8-10}
import { useCarousel } from '@react-native-ama/extras';

const ExampleCarousel = props => {
const ref = React.useRef<FlatList>(null);
const a11yProps = useCarousel({
data: props.data,
flatListRef: ref,
});

return <FlatList ref={ref} {...props} {...a11yProps} />;
};
```

## Arguments

### <Required /> `data`

The data passed to the Scrollable component, used to calculate the number of items in the carousel.

| Type | Default |
| ------------------------------------- | --------- |
| ArrayLike\<any\> \| null \| undefined | undefined |

### <Required /> `flatListRef`

The ref passed to the FlatList or ScrollView, used to scroll to index's when accessibility actions are performed.

| Type | Default |
| ------------------------------------ | --------- |
| React.Ref\<FlatList\<any\> \| null\> | undefined |

## Related guidelines

- [Carousel](/guidelines/carousel)
104 changes: 104 additions & 0 deletions packages/extras/docs/hooks/useKeyboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Required } from '@site/src/components'

# useKeyboard

`useKeyboard` is a hook that provides Reanimated shared values for the current and final heights of the keyboard, along with a boolean shared value indicating whether the keyboard is visible. These properties are `keyboardHeight`, `keyboardFinalHeight`, and `isKeyboardVisible` and can be utilized when building animations.

:::info

This hook is provided for convenience, however it is not necessary for accessibility or part of the official AMA guidelines.

:::

## Usage

```tsx {2-5,12-24}
import { useKeyboard } from '@react-native-ama/extras';
import Animated, {
useAnimatedStyle,
useDerivedValue,
} from 'react-native-reanimated';

const Example = props => {
const { keyboardHeight, keyboardFinalHeight, isKeyboardVisible } =
useKeyboard(props.shouldHandleKeyboardEvents);

// Do something with values
const maxHeightValue = useDerivedValue(() => {
return maxHeight - keyboardHeight.value;
}, [keyboardHeight, maxHeight]);

const animatedStyle = useAnimatedStyle(() => {
const keyboard = keyboardHeight.value;

return {
transform: [{ translateY: translateY.value - keyboard }],
maxHeight: maxHeightValue.value,
};
}, [maxHeightValue, translateY, keyboardHeight]);

return <Animated.View style={[animatedStyle]} />;
};
```

## Arguments

### `shouldHandleKeyboardEvents` _(optional)_

The data passed to the Scrollable component, used to calculate the number of items in the carousel.

| Type | Default |
| ------- | ------- |
| boolean | true |

## Returns

### `keyboardHeight`

A Reanimated shared value representing the current height of the keyboard.

| Type | Initial |
| --------------------- | ------- |
| SharedValue\<number\> | 0 |

> You can access data stored in the shared value with either its value property or get and set methods.
### `keyboardFinalHeight`

A Reanimated shared value representing the final height of the keyboard. When the keyboard is not visible, this value will be 0.

| Type | Initial |
| --------------------- | ------- |
| SharedValue\<number\> | 0 |

> You can access data stored in the shared value with either its value property or get and set methods.
### `isKeyboardVisible`

A Reanimated shared value representing whether the keyboard is visible.

| Type | Initial |
| ---------------------- | ------- |
| SharedValue\<boolean\> | false |

> You can access data stored in the shared value with either its value property or get and set methods.
### Related

:::note SharedValue type

```ts
interface SharedValue<Value = unknown> {
value: Value;
get(): Value;
set(value: Value | ((value: Value) => Value)): void;
addListener: (listenerID: number, listener: (value: Value) => void) => void;
removeListener: (listenerID: number) => void;
modify: (
modifier?: <T extends Value>(value: T) => T,
forceUpdate?: boolean,
) => void;
}
```

:::
6 changes: 4 additions & 2 deletions packages/extras/src/hooks/useCarousel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useRef } from 'react';
// import { FlatList } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import {
AccessibilityActionEvent,
Expand All @@ -15,7 +14,10 @@ export const useCarousel = <T = any>({ data, flatListRef }: UseCarousel<T>) => {
const carouselIndexForScreenReader = useRef(0);
const totalItems = data?.length || 0;

const accessibilityActions = [{ name: 'increment' }, { name: 'decrement' }];
const accessibilityActions = [
{ name: 'increment' },
{ name: 'decrement' },
] as const;

const onAccessibilityAction = (event: AccessibilityActionEvent) => {
const value = event.nativeEvent.actionName === 'increment' ? 1 : -1;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/docs/ExpandablePressable.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The component uses the [onLayout](https://reactnative.dev/docs/layoutevent) prop

### <Required /> `accessibilityLabel`

The `accessibilityLabel` for the expandable button, this is announced by the screen reader when the element gains focus, then it announces its role. The accessibilityLabel is a required properties as if it is omitted, the user will have no context for the purpose of the button.
The `accessibilityLabel` for the expandable button, this is announced by the screen reader when the element gains focus, then it announces its role. The accessibilityLabel is a required properties as if it is omitted, the user may have no context for the purpose of the button.

| Type | Default |
| ------ | --------- |
Expand Down
4 changes: 2 additions & 2 deletions website/guidelines/carousel.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,5 @@ To implement this navigation behavior in React Native when the Screen Reader is
### Related AMA utility
- [CarouseWrapper](/extras/docs/components/carouse-wrapper)
- [useCarousel](/extras/docs/hooks/use-carousel)
- [Carouse](/extras/components/Carousel)
- [useCarousel](/extras/hooks/useCarousel)

0 comments on commit 95e3cae

Please sign in to comment.