Skip to content

Commit

Permalink
docs(react-keytips): improve keytips docs (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
mainframev authored Nov 5, 2024
1 parent 9c9ff0c commit 61dab23
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "docs(react-keytips): improve keytips docs",
"packageName": "@fluentui-contrib/react-keytips",
"email": "[email protected]",
"dependentChangeType": "patch"
}
71 changes: 0 additions & 71 deletions packages/react-keytips/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,75 +34,4 @@ export const App = () => {
};
```

### Handling keytips with dynamic content

If a Keytip triggers dynamic content that includes its own keytips, you must add the `hasDynamicChildren` prop to the `useKeytipRef` for the relevant component. Additionally, the child keytips should include the parent's key sequence in their key sequences.

Here's an example using a Tab component:

```tsx
import * as React from 'react';
import { Keytips, useKeytipRef } from '@fluentui-contrib/react-keytips';

const TabExample = () => {
const [selectedValue, setSelectedValue] = React.useState<TabValue>('1');

const onTabSelect = (_: SelectTabEvent, data: SelectTabData) => {
setSelectedValue(data.value);
};

const refFirstTab = useKeytipRef({
keySequences: ['a'],
content: 'A',
hasDynamicChildren: true,
onExecute: btnExecute,
});

const refSecondTab = useKeytipRef({
keySequences: ['b'],
content: 'B',
hasDynamicChildren: true,
onExecute: btnExecute,
});

const checkBoxRef = useKeytipRef<HTMLInputElement>({
keySequences: ['a', '1'],
content: '1',
onExecute: btnExecute,
});

const btnRef = useKeytipRef({
keySequences: ['b', '1'],
content: 'B1',
onExecute: btnExecute,
});

return (
<>
<Keytips {...props} />
<TabList onTabSelect={onTabSelect}>
<Tab id="1" ref={refFirstTab} value="1">
First Tab
</Tab>
<Tab id="2" ref={refSecondTab} value="2">
Second Tab
</Tab>
</TabList>
<div className={classes.panels}>
{selectedValue === '1' && (
<div role="tabpanel" className={classes.row}>
<Checkbox ref={checkBoxRef} label="Checkbox" />
</div>
)}
{selectedValue === '2' && (
<div role="tabpanel">
<Button ref={btnRef}>Button 2</Button>
</div>
)}
</div>
</>
);
};
```

Follow up on the [Storybook](https://microsoft.github.io/fluentui-contrib/react-keytips) for examples on how to use the components provided by this package.
1 change: 1 addition & 0 deletions packages/react-keytips/src/docs/Spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ The keytip is positioned below and centered to the target element by default.
| `onExitKeytipsMode` | `EventHandler<OnExitKeytipsModeData>` | | Callback function triggered when keytip mode is exited. |
| `onEnterKeytipsMode` | `EventHandler<OnEnterKeytipsModeData>` | | Callback function triggered when keytip mode is entered. |
| `startDelay` | `number` | `0` | Timeout in milliseconds for keytips enter mode to be on, use if you'd like to have a more clear intent that keytips need to be shown. Values < 0 disable the feature. |
| `invokeEvent` | `keydown \| keyup` | `keydown` | The event is responsible for invoking event. |

## useKeytipRef

Expand Down
28 changes: 28 additions & 0 deletions packages/react-keytips/stories/Default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
By default Keytips are shown for all target elements that have keytip attached via
`useKeytipRef`, except disabled elements.
When multiple Keytips start with the same character, typing that character will filter the visible keytips.
You can also use `positioning` to set an offset from the target element, or control [other positioning options](https://react.fluentui.dev/?path=/docs/concepts-developer-positioning-components--docs).

```tsx
export const DefaultStory = () => {
const normalKeytip = useKeytipRef({
keySequences: ['b1'],
content: 'B1',
onExecute,
});

const keytipWithOffset = useKeytipRef({
keySequences: ['b4'],
positioning: { offset: { crossAxis: -50, mainAxis: 5 } },
content: 'B4',
onExecute,
});

return (
<>
<Button ref={normalKeytip}>Normal Keytip</Button>
<Button ref={keytipWithOffset}>Keytip with offset</Button>
</>
);
};
```
9 changes: 9 additions & 0 deletions packages/react-keytips/stories/Default.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
MenuButtonProps,
useMergedRefs,
} from '@fluentui/react-components';
import description from './Default.md';

const useStyles = makeStyles({
splitButtonWrapper: {
Expand Down Expand Up @@ -162,3 +163,11 @@ export const DefaultStory = () => {
</>
);
};

DefaultStory.parameters = {
docs: {
description: {
story: description,
},
},
};
3 changes: 3 additions & 0 deletions packages/react-keytips/stories/Dynamic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
If a `Keytip` triggers dynamic content that includes its own keytips, you must add the `dynamic` prop to the `useKeytipRef` for the relevant component. Additionally, the child keytips should include the parents key sequence in their key sequences.

Take the case below; clicking Button 1 and Button 2 will update the text of Button3. Triggering the keytip for Button 1 or Button 2 will then also change the keytip sequence of Button 3, because it can be both a child of Button 1 or Button 2. For this to work fully, Button 1 and Button 2 should have `dynamic: true`.
9 changes: 9 additions & 0 deletions packages/react-keytips/stories/Dynamic.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
useKeytipRef,
} from '@fluentui-contrib/react-keytips';
import { makeStyles, Button } from '@fluentui/react-components';
import description from './Dynamic.md';

const useStyles = makeStyles({
column: {
Expand Down Expand Up @@ -76,3 +77,11 @@ export const DynamicStory = () => {
</>
);
};

DynamicStory.parameters = {
docs: {
description: {
story: description,
},
},
};
14 changes: 14 additions & 0 deletions packages/react-keytips/stories/OverflowMenu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Keytips with Overflow require `dynamic` prop to be passed with `useKeytipRef`. You can also register
a `persisted` keytip, that can be accessed from the top level as a shortcut. A shortcut to a normal Button
will trigger the Button, shortcut to a MenuButton will open a menu. In this example, firing `B` and `C`
will show this functionality.

```tsx
const subMenuRef = useKeytipRef<HTMLDivElement>({
keySequences: ['a', 'b'],
content: 'B',
dynamic: true,
persited: true,
onExecute,
});
```
15 changes: 12 additions & 3 deletions packages/react-keytips/stories/OverflowMenu.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import {
tokens,
mergeClasses,
Overflow,
OverflowItem,
OverflowItemProps,
OverflowItem,
useIsOverflowItemVisible,
useOverflowMenu,
useMergedRefs,
} from '@fluentui/react-components';
import description from './OverflowMenu.md';

const useStyles = makeStyles({
container: {
Expand Down Expand Up @@ -110,7 +111,7 @@ const SubMenu = () => {
);
};

const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = (props) => {
const OverflowMenuItem = (props: Pick<OverflowItemProps, 'id'>) => {
const { id } = props;
const isVisible = useIsOverflowItemVisible(id);

Expand All @@ -121,7 +122,7 @@ const OverflowMenuItem: React.FC<Pick<OverflowItemProps, 'id'>> = (props) => {
return <MenuItem>Item {id}</MenuItem>;
};

const OverflowMenu: React.FC<{ itemIds: string[] }> = ({ itemIds }) => {
const OverflowMenu = ({ itemIds }: { itemIds: string[] }) => {
const { ref, overflowCount, isOverflowing } =
useOverflowMenu<HTMLButtonElement>();

Expand Down Expand Up @@ -177,3 +178,11 @@ export const OverflowStory = () => {
</>
);
};

OverflowStory.parameters = {
docs: {
description: {
story: description,
},
},
};
31 changes: 31 additions & 0 deletions packages/react-keytips/stories/WithDelay.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react';
import {
ExecuteKeytipEventHandler,
useKeytipRef,
} from '@fluentui-contrib/react-keytips';

const onExecute: ExecuteKeytipEventHandler = (_, { targetElement }) => {
if (targetElement) targetElement.click();
};

export const DefaultStory = () => {
const normalButton = useKeytipRef({
keySequences: ['b1'],
content: 'B1',
onExecute,
});

return <Button ref={normalButton}>Delayed Start of Keytip Mode</Button>;
};

DefaultStory.parameters = {
docs: {
description: {
story: [
`By default Keytips are shown for all target elements that have keytip attached via
\`useKeytipRef\`, except disabled elements.`,
`When multiple Keytips start with the same character, typing that character will filter the visible keytips.`,
].join('\n'),
},
},
};
9 changes: 9 additions & 0 deletions packages/react-keytips/stories/WithTabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import {
ExecuteKeytipEventHandler,
useKeytipRef,
KeytipsProps,
} from '@fluentui-contrib/react-keytips';
import {
makeStyles,
Expand Down Expand Up @@ -139,3 +140,11 @@ export const WithTabsStory = () => {
</>
);
};

WithTabsStory.parameters = {
docs: {
description: {
story: `For Tabs, Keytips will first show keytip for each tab, after selecting a tab, the keytips foor it's content are shown.`,
},
},
};
2 changes: 1 addition & 1 deletion packages/react-keytips/stories/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react';
import description from '../README.md';

import { Meta } from '@storybook/react';
import { Keytips } from '@fluentui-contrib/react-keytips';
import description from '../README.md';
export { DefaultStory as Default } from './Default.stories';
export { WithTabsStory as WithTabs } from './WithTabs.stories';
export { DynamicStory as Dynamic } from './Dynamic.stories';
Expand Down

0 comments on commit 61dab23

Please sign in to comment.