import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks'
import * as UseSubNavigationStories from './use-sub-navigation.stories.tsx'

<Meta
    title="pv-grid/Hooks/useSubNavigation"
    parameters={{
        viewMode: 'docs',
        previewTabs: {
            canvas: { hidden: true },
        },
    }}
/>

# useSubNavigation

This hook let's you opt-in to in-cell navigation.

`import { useSubNavigation } from '@planview/pv-grid'`

### Overview

The hook can be used within the `Renderer` -function of the column definition (or any component rendered within) to opt in to in-cell keyboard navigation.
The usage of the hook let's the grid know there are multiple tab stops within a single grid cell and prevents navigation from leaving the cell until that last/first index has been passed when navigating the grid using arrow-keys.

### How does it work:

The hook is used to retrieve the index (`currentSubFocusIndex`) of the item that should have `tabIndex="0"` among the focusable items inside the cell.
The `currentSubFocusIndex` will be `-1` until the cell get's focused, after that the value will be `0` or greater.

`0` means that the first item should have `tabIndex="0"`, the rest of the items should have `tabIndex="-1"`, `1` means the second item and so on.

On every navigation state change, this will be picked up by the grid navigation and used to determine where to put focus when navigating using keyboard.

The `tabIndex` passed from the `Renderer` will always be `-1` if there are any registered indexes in the cell.
This means that you can conditionally use the `tabIndex` if there is no in-cell tabbable content and you wish to focus the entire cell.

### Definition

```jsx
const useSubNavigation: ({ indexes, inlineFocusStylingEnabled, }: UseSubNavigationProps) => {
    currentSubFocusIndex: number;
    setCurrentSubFocusIndex: (index: number | "first" | "last") => void;
}
```

### Usage

```jsx
const teams: Team[] = [
    {
        id: '123',
        name: 'Everyone',
        description: 'Everyone in your organization',
        privacy: 'public',
        createdOn: new Date(2020, 0, 5),
        tags: [
            { label: '#Everyone', color: color.red200 },
            { label: '#Team', color: color.blue200 },
            { label: '#InThisTogether', color: color.yellow200 },
        ],
    },
    {
        id: '234',
        name: 'External',
        description: 'Everyone outside your organization',
        privacy: 'public',
        createdOn: new Date(2020, 0, 5),
        tags: [{ label: '#StakeHolders', color: color.red500 }],
    },
    {
        id: '345',
        name: 'Engineering',
        privacy: 'private',
        createdOn: new Date(2022, 7, 19),
        tags: [
            { label: '#WeBuildTogether', color: color.navy600 },
            { label: '#Team', color: color.blue200 },
        ],
    },
    {
        id: '3451',
        name: 'Design',
        privacy: 'private',
        createdOn: new Date(2023, 2, 10),
        tags: [
            { label: '#Team', color: color.blue200 },
            { label: '#DesignLove', color: color.purple500 },
            { label: '#DesignSystem', color: color.purple500 },
        ],
    },
]
const columns: Column<Team>[] = [
    {
        id: 'name',
        label: 'Team Name',
        width: 300,
    },

    {
        id: 'tags',
        label: 'Tags',
        width: 400,
        cell: {
            Renderer({ value, tabIndex }) {
                const tags = value as Team['tags']
                const cellNavigationEnabled = !!tags.length

                const { currentSubFocusIndex, setCurrentSubFocusIndex } =
                    useSubNavigation({
                        indexes: tags.length,
                        inlineFocusStylingEnabled: cellNavigationEnabled,//If there are no tags; give control of focus styling back to grid
                    })

                return (
                    <GridCellBase tabIndex={tabIndex}>
                        {tags.map((tag, i) => (
                            <div
                                role="button"
                                key={tag.label}
                                onClick={() => setCurrentSubFocusIndex(i)}
                                tabIndex={currentSubFocusIndex === i ? 0 : -1}
                            >
                                <Chip
                                    label={tag.label}
                                    color={tag.color}
                                    focusable
                                />
                            </div>
                        ))}
                    </GridCellBase>
                )
            },
        },
    },
]
return <Grid columns={columns} rows={teams} selectionMode="none" />
```

_Note: In this example one cell is empty (has no tags).
In this case controlling the focus styles is handed back to the grid by setting `inlineFocusStylingEnabled` to false.
This is not enforced by the grid but up to the consumer to decide_

<Story of={UseSubNavigationStories.UseSubNavigation} />
