From 2f21bcd3b2fc6969a956737b23beda8a61b967e6 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 26 May 2023 12:31:15 +0200 Subject: [PATCH 1/9] wip --- apps/public-docsite-v9/.storybook/main.js | 1 + .../src/components/Tag/useTagStyles.styles.ts | 1 + .../TagGroup/TagGroupOverflow.stories.tsx | 155 ++++++++++++++++++ .../stories/TagGroup/index.stories.tsx | 1 + 4 files changed, 158 insertions(+) create mode 100644 packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx diff --git a/apps/public-docsite-v9/.storybook/main.js b/apps/public-docsite-v9/.storybook/main.js index a57e9a915e54d5..4baca4c684a251 100644 --- a/apps/public-docsite-v9/.storybook/main.js +++ b/apps/public-docsite-v9/.storybook/main.js @@ -15,6 +15,7 @@ module.exports = /** @type {Omit ({ + value: name.replace(' ', '_'), + children: name, + media: , +})); + +//----- OverflowMenuItem -----// + +type OverflowMenuItemProps = { + tag: TagButtonProps; + onClick: React.MouseEventHandler; +}; + +/** + * A menu item for an overflow menu that only displays when the tab is not visible + */ +const OverflowMenuItem = (props: OverflowMenuItemProps) => { + const { tag, onClick } = props; + const isVisible = useIsOverflowItemVisible(tag.value!); + + if (isVisible) { + return null; + } + + return ( + +
{tag.children}
+
+ ); +}; + +//----- OverflowMenu -----// + +type OverflowMenuProps = { + onDismissItem: TagGroupProps['onDismiss']; +}; + +/** + * A menu for selecting tabs that have overflowed and are not visible. + */ +const OverflowMenu = (props: OverflowMenuProps) => { + const { ref, isOverflowing, overflowCount } = useOverflowMenu(); + + // const onItemClick = (tabId: string) => { + // onTabSelect?.(tabId); + // }; + + if (!isOverflowing) { + return null; + } + + return ( + + + {`+${overflowCount}`} + + + + {defaultItems.map(item => ( + console.log('OverflowMenuItem', 'value', 'click')} + /> + ))} + + + + ); +}; + +//----- Stories -----// + +const useStyles = makeStyles({ + container: { + ...shorthands.overflow('hidden'), + ...shorthands.padding('5px'), + zIndex: 0, //stop the browser resize handle from piercing the overflow menu + height: 'fit-content', + minWidth: '150px', + resize: 'horizontal', + width: '600px', + }, + tagGroup: { + display: 'flex', // TagGroup is inline-flex by default, but we want it to be same width as the container + }, +}); + +export const HorizontalOverflow = () => { + const [items, setItems] = React.useState(defaultItems); + const removeItem: TagGroupProps['onDismiss'] = (_e, { dismissedTagValue }) => { + setItems([...items].filter(item => item.value !== dismissedTagValue)); + }; + + const styles = useStyles(); + + return ( +
+ + + {items.map(item => ( + + + + ))} + + + +
+ ); +}; + +HorizontalOverflow.storyName = 'Overflow'; +HorizontalOverflow.parameters = { + docs: { + description: { + story: 'A TagGroup can support overflow by using Overflow and OverflowItem.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx index 09880bb5bd4975..1eacab4632fbef 100644 --- a/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx @@ -6,6 +6,7 @@ import bestPracticesMd from './TagGroupBestPractices.md'; export { Default } from './TagGroupDefault.stories'; export { Dismiss } from './TagGroupDismiss.stories'; export { Sizes } from './TagGroupSizes.stories'; +export { HorizontalOverflow } from './TagGroupOverflow.stories'; export default { title: 'Preview Components/Tag/TagGroup', From 035eee065348fb80d3a2c124bf66dc0bf5a4d730 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 26 May 2023 12:44:01 +0200 Subject: [PATCH 2/9] nowrap --- .../react-tags/src/components/Tag/useTagStyles.styles.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts index b1a7903b25dcc9..edc4c3943ba06f 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts @@ -48,6 +48,7 @@ export const useTagBaseStyles = makeStyles({ paddingLeft: tokens.spacingHorizontalXXS, paddingRight: tokens.spacingHorizontalXXS, ...typographyStyles.caption2, + whiteSpace: 'nowrap', }, }); From c147dd7560f1c91adc7cd9e10ba9ad61d7336d66 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 5 Jun 2023 17:55:32 +0200 Subject: [PATCH 3/9] update --- .../react-tags/etc/react-tags.api.md | 2 +- .../src/components/Tag/Tag.types.ts | 2 +- .../TagGroup/TagGroupOverflow.stories.tsx | 94 ++++++++++++++----- .../stories/TagGroup/index.stories.tsx | 2 +- 4 files changed, 72 insertions(+), 28 deletions(-) diff --git a/packages/react-components/react-tags/etc/react-tags.api.md b/packages/react-components/react-tags/etc/react-tags.api.md index 2cdee8d68e5118..b731080fb1171a 100644 --- a/packages/react-components/react-tags/etc/react-tags.api.md +++ b/packages/react-components/react-tags/etc/react-tags.api.md @@ -84,7 +84,7 @@ export type TagProps = ComponentProps> & { // @public (undocumented) export type TagSlots = { - root: NonNullable>; + root: NonNullable>; media?: Slot<'span'>; icon?: Slot<'span'>; primaryText: Slot<'span'>; diff --git a/packages/react-components/react-tags/src/components/Tag/Tag.types.ts b/packages/react-components/react-tags/src/components/Tag/Tag.types.ts index 1869fb1368ec9f..2dd7710c60367c 100644 --- a/packages/react-components/react-tags/src/components/Tag/Tag.types.ts +++ b/packages/react-components/react-tags/src/components/Tag/Tag.types.ts @@ -11,7 +11,7 @@ export type TagContextValues = { }; export type TagSlots = { - root: NonNullable>; + root: NonNullable>; /** * Slot for an icon or other visual element diff --git a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx index 8398be54f805a4..2e5450c737c58a 100644 --- a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { TagGroup, TagButton, TagButtonProps, TagGroupProps } from '@fluentui/react-tags'; +import { TagGroup, Tag, TagProps } from '@fluentui/react-tags'; import { makeStyles, shorthands, @@ -13,6 +13,7 @@ import { Overflow, OverflowItem, Avatar, + tokens, } from '@fluentui/react-components'; const names = [ @@ -28,33 +29,51 @@ const names = [ 'Charlotte Waltson', 'Elliot Woodward', ]; -const defaultItems: TagButtonProps[] = names.map(name => ({ +const defaultItems: TagProps[] = names.map(name => ({ value: name.replace(' ', '_'), children: name, - media: , + media: ( + + ), + secondaryText: 'Available', })); //----- OverflowMenuItem -----// type OverflowMenuItemProps = { - tag: TagButtonProps; + tag: TagProps; onClick: React.MouseEventHandler; }; +const useMenuItemStyles = makeStyles({ + menuItem: shorthands.padding(tokens.spacingVerticalSNudge, tokens.spacingHorizontalSNudge), + tag: { + backgroundColor: 'transparent', + ...shorthands.borderColor('transparent'), + }, +}); + /** * A menu item for an overflow menu that only displays when the tab is not visible */ const OverflowMenuItem = (props: OverflowMenuItemProps) => { - const { tag, onClick } = props; + const { tag } = props; const isVisible = useIsOverflowItemVisible(tag.value!); + const styles = useMenuItemStyles(); + if (isVisible) { return null; } return ( - -
{tag.children}
+ + ); }; @@ -62,32 +81,27 @@ const OverflowMenuItem = (props: OverflowMenuItemProps) => { //----- OverflowMenu -----// type OverflowMenuProps = { - onDismissItem: TagGroupProps['onDismiss']; + onDismissItem?: TagGroupProps['onDismiss']; }; /** * A menu for selecting tabs that have overflowed and are not visible. */ -const OverflowMenu = (props: OverflowMenuProps) => { +const OverflowMenu = () => { const { ref, isOverflowing, overflowCount } = useOverflowMenu(); - // const onItemClick = (tabId: string) => { - // onTabSelect?.(tabId); - // }; - if (!isOverflowing) { return null; } + // const onItemClick = (tabId: string) => { + // onTabSelect?.(tabId); + // }; + return ( - + - {`+${overflowCount}`} + {`+${overflowCount}`} @@ -121,14 +135,33 @@ const useStyles = makeStyles({ }, }); -export const HorizontalOverflow = () => { +const OverflowExample = () => { + const styles = useStyles(); + + return ( +
+ + + {defaultItems.map(item => ( + + + + ))} + + + +
+ ); +}; + +const DismissibleOverflowExample = () => { + const styles = useStyles(); + const [items, setItems] = React.useState(defaultItems); const removeItem: TagGroupProps['onDismiss'] = (_e, { dismissedTagValue }) => { setItems([...items].filter(item => item.value !== dismissedTagValue)); }; - const styles = useStyles(); - return (
@@ -145,8 +178,19 @@ export const HorizontalOverflow = () => { ); }; -HorizontalOverflow.storyName = 'Overflow'; -HorizontalOverflow.parameters = { +export const WithOverflow = () => { + const styles = useStyles(); + + return ( +
+ + +
+ ); +}; + +WithOverflow.storyName = 'With Overflow'; +WithOverflow.parameters = { docs: { description: { story: 'A TagGroup can support overflow by using Overflow and OverflowItem.', diff --git a/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx index 1eacab4632fbef..a07a090b5f8563 100644 --- a/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/index.stories.tsx @@ -6,7 +6,7 @@ import bestPracticesMd from './TagGroupBestPractices.md'; export { Default } from './TagGroupDefault.stories'; export { Dismiss } from './TagGroupDismiss.stories'; export { Sizes } from './TagGroupSizes.stories'; -export { HorizontalOverflow } from './TagGroupOverflow.stories'; +export { WithOverflow } from './TagGroupOverflow.stories'; export default { title: 'Preview Components/Tag/TagGroup', From f6d50166de57f9fe859ea90f10ef6e994017dcf3 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 5 Jun 2023 17:56:48 +0200 Subject: [PATCH 4/9] update --- .../TagGroup/TagGroupOverflow.stories.tsx | 52 +------------------ 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx index 2e5450c737c58a..f6cab0be1a49cc 100644 --- a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx @@ -47,7 +47,6 @@ const defaultItems: TagProps[] = names.map(name => ({ type OverflowMenuItemProps = { tag: TagProps; - onClick: React.MouseEventHandler; }; const useMenuItemStyles = makeStyles({ @@ -80,10 +79,6 @@ const OverflowMenuItem = (props: OverflowMenuItemProps) => { //----- OverflowMenu -----// -type OverflowMenuProps = { - onDismissItem?: TagGroupProps['onDismiss']; -}; - /** * A menu for selecting tabs that have overflowed and are not visible. */ @@ -94,10 +89,6 @@ const OverflowMenu = () => { return null; } - // const onItemClick = (tabId: string) => { - // onTabSelect?.(tabId); - // }; - return ( @@ -106,11 +97,7 @@ const OverflowMenu = () => { {defaultItems.map(item => ( - console.log('OverflowMenuItem', 'value', 'click')} - /> + ))} @@ -135,7 +122,7 @@ const useStyles = makeStyles({ }, }); -const OverflowExample = () => { +export const WithOverflow = () => { const styles = useStyles(); return ( @@ -154,41 +141,6 @@ const OverflowExample = () => { ); }; -const DismissibleOverflowExample = () => { - const styles = useStyles(); - - const [items, setItems] = React.useState(defaultItems); - const removeItem: TagGroupProps['onDismiss'] = (_e, { dismissedTagValue }) => { - setItems([...items].filter(item => item.value !== dismissedTagValue)); - }; - - return ( -
- - - {items.map(item => ( - - - - ))} - - - -
- ); -}; - -export const WithOverflow = () => { - const styles = useStyles(); - - return ( -
- - -
- ); -}; - WithOverflow.storyName = 'With Overflow'; WithOverflow.parameters = { docs: { From 62594961b22c7886dc6ee64f6a6efb83ed4fd693 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 5 Jun 2023 17:59:25 +0200 Subject: [PATCH 5/9] fix comment --- .../react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx index f6cab0be1a49cc..927b05b54fc1d1 100644 --- a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx @@ -80,7 +80,7 @@ const OverflowMenuItem = (props: OverflowMenuItemProps) => { //----- OverflowMenu -----// /** - * A menu for selecting tabs that have overflowed and are not visible. + * A menu for viewing tags that have overflowed and are not visible. */ const OverflowMenu = () => { const { ref, isOverflowing, overflowCount } = useOverflowMenu(); @@ -111,7 +111,7 @@ const useStyles = makeStyles({ container: { ...shorthands.overflow('hidden'), ...shorthands.padding('5px'), - zIndex: 0, //stop the browser resize handle from piercing the overflow menu + zIndex: 0, // stop the browser resize handle from piercing the overflow menu height: 'fit-content', minWidth: '150px', resize: 'horizontal', From 0e0cc46700d55029c78ad7beec9b9495494bd6a3 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 5 Jun 2023 18:30:33 +0200 Subject: [PATCH 6/9] type update in test --- .../react-components/react-tags/src/components/Tag/Tag.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/Tag/Tag.test.tsx b/packages/react-components/react-tags/src/components/Tag/Tag.test.tsx index 174ddfaad88b70..ed002889a23df8 100644 --- a/packages/react-components/react-tags/src/components/Tag/Tag.test.tsx +++ b/packages/react-components/react-tags/src/components/Tag/Tag.test.tsx @@ -14,7 +14,7 @@ const requiredProps: TagProps = { }; describe('Tag', () => { - isConformant({ + isConformant({ Component: Tag, displayName: 'Tag', requiredProps, From 4c63eb0a1322acf5e782f6a51abd3e2193885d25 Mon Sep 17 00:00:00 2001 From: Amber Date: Tue, 6 Jun 2023 15:17:47 +0200 Subject: [PATCH 7/9] Update packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx Co-authored-by: ling1726 --- .../react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx index 927b05b54fc1d1..dd056fb40272fb 100644 --- a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx @@ -127,7 +127,7 @@ export const WithOverflow = () => { return (
- + {defaultItems.map(item => ( From 8333e2d7b571a4a22a557e5033da5575a1ecb2bd Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Wed, 7 Jun 2023 18:42:22 +0200 Subject: [PATCH 8/9] update spacing according to design --- .../react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx index dd056fb40272fb..8fbe1614c2caec 100644 --- a/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx +++ b/packages/react-components/react-tags/stories/TagGroup/TagGroupOverflow.stories.tsx @@ -50,7 +50,7 @@ type OverflowMenuItemProps = { }; const useMenuItemStyles = makeStyles({ - menuItem: shorthands.padding(tokens.spacingVerticalSNudge, tokens.spacingHorizontalSNudge), + menuItem: shorthands.padding(tokens.spacingVerticalSNudge, tokens.spacingHorizontalXS), tag: { backgroundColor: 'transparent', ...shorthands.borderColor('transparent'), @@ -115,7 +115,7 @@ const useStyles = makeStyles({ height: 'fit-content', minWidth: '150px', resize: 'horizontal', - width: '600px', + width: '100%', }, tagGroup: { display: 'flex', // TagGroup is inline-flex by default, but we want it to be same width as the container From 48a4b187ae513990743d9d9826ce01f2a9aa3242 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Wed, 14 Jun 2023 20:47:44 +0200 Subject: [PATCH 9/9] remove tag from doc --- apps/public-docsite-v9/.storybook/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/public-docsite-v9/.storybook/main.js b/apps/public-docsite-v9/.storybook/main.js index 4baca4c684a251..a57e9a915e54d5 100644 --- a/apps/public-docsite-v9/.storybook/main.js +++ b/apps/public-docsite-v9/.storybook/main.js @@ -15,7 +15,6 @@ module.exports = /** @type {Omit