Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new extra package docs to repo and update installation process docs #257

Merged
merged 11 commits into from
Oct 11, 2024
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)
Loading