From 9b6024400d34652994697607113f669eae18e1af Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Mon, 12 Aug 2024 14:35:33 -0700 Subject: [PATCH 01/11] make TagGroup disable-able --- .../components/InteractionTag/useInteractionTag.tsx | 9 +++++++-- .../react-tags/library/src/components/Tag/useTag.tsx | 3 ++- .../library/src/components/TagGroup/TagGroup.types.ts | 9 ++++++++- .../library/src/components/TagGroup/useTagGroup.ts | 11 ++++++++++- .../components/TagGroup/useTagGroupContextValues.ts | 6 +++--- .../library/src/contexts/tagGroupContext.tsx | 2 +- .../react-tags/stories/src/TagGroup/index.stories.tsx | 1 + 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx b/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx index 38ec4e9da28fb..4d4b5c4aec1e7 100644 --- a/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx +++ b/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx @@ -16,7 +16,12 @@ export const useInteractionTag_unstable = ( props: InteractionTagProps, ref: React.Ref, ): InteractionTagState => { - const { handleTagDismiss, size: contextSize, appearance: contextAppearance } = useTagGroupContext_unstable(); + const { + handleTagDismiss, + size: contextSize, + disabled: contextDisabled, + appearance: contextAppearance, + } = useTagGroupContext_unstable(); const id = useId('fui-InteractionTag-', props.id); @@ -24,7 +29,7 @@ export const useInteractionTag_unstable = ( const { appearance = contextAppearance ?? 'filled', - disabled = false, + disabled = contextDisabled ?? false, shape = 'rounded', size = contextSize, value = id, diff --git a/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx index 154c39bbae46f..8a4f79ec8f62c 100644 --- a/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx @@ -29,6 +29,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref = ComponentProps & { // eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback onDismiss?: TagDismissHandler; + /** + * A TagGroup can show that it cannot be interacted with. + * + * @default false + */ + disabled?: boolean; + size?: TagSize; appearance?: TagAppearance; dismissible?: boolean; @@ -30,7 +37,7 @@ export type TagGroupProps = ComponentProps & { * State used in rendering TagGroup */ export type TagGroupState = ComponentState & - Required> & { + Required> & { handleTagDismiss: TagDismissHandler; role?: React.AriaRole; }; diff --git a/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroup.ts b/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroup.ts index d04edd443bc3b..bb9cf04706bd8 100644 --- a/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroup.ts +++ b/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroup.ts @@ -15,7 +15,14 @@ import { interactionTagSecondaryClassNames } from '../InteractionTagSecondary/us * @param ref - reference to root HTMLDivElement of TagGroup */ export const useTagGroup_unstable = (props: TagGroupProps, ref: React.Ref): TagGroupState => { - const { onDismiss, size = 'medium', appearance = 'filled', dismissible = false, role = 'toolbar' } = props; + const { + onDismiss, + disabled = false, + size = 'medium', + appearance = 'filled', + dismissible = false, + role = 'toolbar', + } = props; const innerRef = React.useRef(); const { targetDocument } = useFluent(); @@ -55,6 +62,7 @@ export const useTagGroup_unstable = (props: TagGroupProps, ref: React.Ref, role, + 'aria-disabled': disabled, ...arrowNavigationProps, ...props, }), diff --git a/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroupContextValues.ts b/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroupContextValues.ts index c424568a0e146..706babd1c0484 100644 --- a/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroupContextValues.ts +++ b/packages/react-components/react-tags/library/src/components/TagGroup/useTagGroupContextValues.ts @@ -2,11 +2,11 @@ import * as React from 'react'; import type { TagGroupContextValues, TagGroupState } from './TagGroup.types'; export function useTagGroupContextValues_unstable(state: TagGroupState): TagGroupContextValues { - const { handleTagDismiss, size, appearance, dismissible, role } = state; + const { handleTagDismiss, size, disabled, appearance, dismissible, role } = state; return { tagGroup: React.useMemo( - () => ({ handleTagDismiss, size, appearance, dismissible, role }), - [handleTagDismiss, size, appearance, dismissible, role], + () => ({ handleTagDismiss, size, disabled, appearance, dismissible, role }), + [handleTagDismiss, size, disabled, appearance, dismissible, role], ), }; } diff --git a/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx b/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx index 8901c8ac7a61d..16ffd69af6757 100644 --- a/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx +++ b/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx @@ -13,7 +13,7 @@ const tagGroupContextDefaultValue: TagGroupContextValue = { * Context shared between TagGroup and its children components */ export type TagGroupContextValue = Required> & - Partial>; + Partial>; export const TagGroupContextProvider = TagGroupContext.Provider; diff --git a/packages/react-components/react-tags/stories/src/TagGroup/index.stories.tsx b/packages/react-components/react-tags/stories/src/TagGroup/index.stories.tsx index e2f77c70cf6ed..9c27ceb03acf7 100644 --- a/packages/react-components/react-tags/stories/src/TagGroup/index.stories.tsx +++ b/packages/react-components/react-tags/stories/src/TagGroup/index.stories.tsx @@ -7,6 +7,7 @@ export { Default } from './TagGroupDefault.stories'; export { Dismiss } from './TagGroupDismiss.stories'; export { Sizes } from './TagGroupSizes.stories'; export { WithOverflow } from './TagGroupOverflow.stories'; +export { Disabled } from './TagGroupDisabled.stories'; export default { title: 'Components/Tag/TagGroup', From 1a45470dbbeb11ca70dd160f0af5611553c4c28e Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Mon, 12 Aug 2024 14:35:48 -0700 Subject: [PATCH 02/11] add story for disabled TagGroup --- .../src/TagGroup/TagGroupDisabled.stories.tsx | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 packages/react-components/react-tags/stories/src/TagGroup/TagGroupDisabled.stories.tsx diff --git a/packages/react-components/react-tags/stories/src/TagGroup/TagGroupDisabled.stories.tsx b/packages/react-components/react-tags/stories/src/TagGroup/TagGroupDisabled.stories.tsx new file mode 100644 index 0000000000000..79118ea403ca7 --- /dev/null +++ b/packages/react-components/react-tags/stories/src/TagGroup/TagGroupDisabled.stories.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import { TagGroup, InteractionTag, InteractionTagPrimary, Tag, makeStyles } from '@fluentui/react-components'; + +const WithTags = () => ( + + Tag 1 + Tag 2 + Tag 3 + +); + +const WithInteractionTags = () => ( + + + Tag 1 + + + Tag 2 + + + Tag 3 + + +); + +const useStyles = makeStyles({ + container: { + display: 'flex', + flexDirection: 'column', + rowGap: '10px', + }, +}); + +export const Disabled = () => { + const styles = useStyles(); + return ( +
+ Disabled example with Tag: + + Disabled example with InteractionTag: + +
+ ); +}; + +Disabled.storyName = 'Disabled'; +Disabled.parameters = { + docs: { + description: { + story: 'A TagGroup can be disabled. The collection of Tag/InteractionTag will also be disabled.', + }, + }, +}; From 759e1920b4f4abc8662557e2e724ddbf45a4ae21 Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Mon, 12 Aug 2024 14:38:42 -0700 Subject: [PATCH 03/11] disable TagPickerGroup if TagPicker is disabled --- .../library/src/components/TagPickerGroup/useTagPickerGroup.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPickerGroup/useTagPickerGroup.ts b/packages/react-components/react-tag-picker/library/src/components/TagPickerGroup/useTagPickerGroup.ts index ce929680d6b12..c2cd563fc5b41 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPickerGroup/useTagPickerGroup.ts +++ b/packages/react-components/react-tag-picker/library/src/components/TagPickerGroup/useTagPickerGroup.ts @@ -27,6 +27,7 @@ export const useTagPickerGroup_unstable = ( const selectOption = useTagPickerContext_unstable(ctx => ctx.selectOption); const size = useTagPickerContext_unstable(ctx => tagPickerSizeToTagSize(ctx.size)); const appearance = useTagPickerContext_unstable(ctx => ctx.appearance); + const disabled = useTagPickerContext_unstable(ctx => ctx.disabled); const arrowNavigationProps = useArrowNavigationGroup({ circular: false, @@ -37,6 +38,7 @@ export const useTagPickerGroup_unstable = ( const state = useTagGroup_unstable( { role: 'listbox', + disabled, ...props, ...arrowNavigationProps, size, From fc0e91791ede9ff22e23b62750ccb159da115b7f Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Thu, 15 Aug 2024 09:28:45 -0700 Subject: [PATCH 04/11] changefiles --- ...ct-tag-picker-9be006cd-1c03-46c8-a255-b35dd8971bee.json | 7 +++++++ ...ui-react-tags-85ae0473-8232-428f-b0a7-cdb10bbd84df.json | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 change/@fluentui-react-tag-picker-9be006cd-1c03-46c8-a255-b35dd8971bee.json create mode 100644 change/@fluentui-react-tags-85ae0473-8232-428f-b0a7-cdb10bbd84df.json diff --git a/change/@fluentui-react-tag-picker-9be006cd-1c03-46c8-a255-b35dd8971bee.json b/change/@fluentui-react-tag-picker-9be006cd-1c03-46c8-a255-b35dd8971bee.json new file mode 100644 index 0000000000000..c80020a4e2f72 --- /dev/null +++ b/change/@fluentui-react-tag-picker-9be006cd-1c03-46c8-a255-b35dd8971bee.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix(react-tag-picker): allows TagPickerGroup to be disabled", + "packageName": "@fluentui/react-tag-picker", + "email": "jiangemma@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-tags-85ae0473-8232-428f-b0a7-cdb10bbd84df.json b/change/@fluentui-react-tags-85ae0473-8232-428f-b0a7-cdb10bbd84df.json new file mode 100644 index 0000000000000..d38069dcc85c3 --- /dev/null +++ b/change/@fluentui-react-tags-85ae0473-8232-428f-b0a7-cdb10bbd84df.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix(react-tags): allows TagGroup to be disabled", + "packageName": "@fluentui/react-tags", + "email": "jiangemma@microsoft.com", + "dependentChangeType": "patch" +} From 1ade5750f4b18793f2429a9caf0f9e37244334ae Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Thu, 15 Aug 2024 09:49:08 -0700 Subject: [PATCH 05/11] Update react-tags.api.md --- .../react-components/react-tags/library/etc/react-tags.api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/library/etc/react-tags.api.md b/packages/react-components/react-tags/library/etc/react-tags.api.md index d1d51b4a98e4f..6644658a93d13 100644 --- a/packages/react-components/react-tags/library/etc/react-tags.api.md +++ b/packages/react-components/react-tags/library/etc/react-tags.api.md @@ -133,6 +133,7 @@ export type TagGroupContextValues = { // @public export type TagGroupProps = ComponentProps & { onDismiss?: TagDismissHandler; + disabled?: boolean; size?: TagSize; appearance?: TagAppearance; dismissible?: boolean; @@ -144,7 +145,7 @@ export type TagGroupSlots = { }; // @public -export type TagGroupState = ComponentState & Required> & { +export type TagGroupState = ComponentState & Required> & { handleTagDismiss: TagDismissHandler; role?: React_2.AriaRole; }; From 7834d5feea648ab94e3c534c0ce60543c2ca407b Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Thu, 15 Aug 2024 10:57:18 -0700 Subject: [PATCH 06/11] fix back tick --- .../react-tags/library/src/contexts/tagGroupContext.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx b/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx index 16ffd69af6757..98b824d953b1f 100644 --- a/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx +++ b/packages/react-components/react-tags/library/src/contexts/tagGroupContext.tsx @@ -13,7 +13,7 @@ const tagGroupContextDefaultValue: TagGroupContextValue = { * Context shared between TagGroup and its children components */ export type TagGroupContextValue = Required> & - Partial>; + Partial>; export const TagGroupContextProvider = TagGroupContext.Provider; From 870b6313ccdec67ed0e75631c51b353b6485cf7f Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Fri, 16 Aug 2024 09:24:25 -0700 Subject: [PATCH 07/11] update TagPicker to use disabled on TagGroup instead of individual tags --- .../stories/src/TagPicker/TagPickerDisabled.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerDisabled.stories.tsx b/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerDisabled.stories.tsx index b2a33b577b206..7eb52b5995d4d 100644 --- a/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerDisabled.stories.tsx +++ b/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerDisabled.stories.tsx @@ -35,7 +35,6 @@ export const Disabled = () => { {selectedOptions.map(option => ( } From 14df212db2a89ec7621a4274bb006680dd22a61b Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Fri, 16 Aug 2024 09:33:48 -0700 Subject: [PATCH 08/11] force tag/interactionTag to be disabled always when tagGroup is disabled --- .../src/components/InteractionTag/useInteractionTag.tsx | 4 ++-- .../react-tags/library/src/components/Tag/useTag.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx b/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx index 4d4b5c4aec1e7..996fba85c0e78 100644 --- a/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx +++ b/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx @@ -29,7 +29,7 @@ export const useInteractionTag_unstable = ( const { appearance = contextAppearance ?? 'filled', - disabled = contextDisabled ?? false, + disabled = false, shape = 'rounded', size = contextSize, value = id, @@ -37,7 +37,7 @@ export const useInteractionTag_unstable = ( return { appearance, - disabled, + disabled: contextDisabled ? true : disabled, handleTagDismiss, interactionTagPrimaryId, shape, diff --git a/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx index 8a4f79ec8f62c..3eba5560cd9b8 100644 --- a/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx @@ -39,7 +39,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref Date: Fri, 16 Aug 2024 10:51:50 -0700 Subject: [PATCH 09/11] add override to Tag props if TagGroup is disabled --- .../library/src/components/InteractionTag/useInteractionTag.tsx | 1 + .../react-tags/library/src/components/Tag/useTag.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx b/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx index 996fba85c0e78..aef03bd7f2cec 100644 --- a/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx +++ b/packages/react-components/react-tags/library/src/components/InteractionTag/useInteractionTag.tsx @@ -52,6 +52,7 @@ export const useInteractionTag_unstable = ( getIntrinsicElementProps('div', { ref, ...props, + disabled: contextDisabled ? true : disabled, id, }), { elementType: 'div' }, diff --git a/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx index 3eba5560cd9b8..3f0cc40daf686 100644 --- a/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/library/src/components/Tag/useTag.tsx @@ -85,6 +85,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref Date: Fri, 16 Aug 2024 10:52:18 -0700 Subject: [PATCH 10/11] add unit test for disabling TagGroup children --- .../src/components/TagGroup/TagGroup.test.tsx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx b/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx index e10c37da9b7a0..d4ce6bbb09386 100644 --- a/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx +++ b/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx @@ -1,8 +1,10 @@ +import '@testing-library/jest-dom'; import * as React from 'react'; import { TagGroup } from './TagGroup'; import { isConformant } from '../../testing/isConformant'; import { render, fireEvent } from '@testing-library/react'; import { Tag } from '../Tag/index'; +import { InteractionTag } from '../InteractionTag/index'; describe('TagGroup', () => { isConformant({ @@ -35,4 +37,24 @@ describe('TagGroup', () => { expect(onDismiss).toHaveBeenCalledWith(expect.anything(), { value: '1' }); }); + + it('if disabled, should disable children Tags', () => { + const { getByRole } = render( + + + , + ); + + expect(getByRole('button')).toBeDisabled(); + }); + + it('if disabled, should override children Tags disabled prop', () => { + const { getByRole } = render( + + + , + ); + + expect(getByRole('button')).toBeDisabled(); + }); }); From de69681be47b1cd6a419570175afe3ee86c29ca0 Mon Sep 17 00:00:00 2001 From: Emma Jiang Date: Fri, 16 Aug 2024 11:09:04 -0700 Subject: [PATCH 11/11] remove unnecessary imports --- .../react-tags/library/src/components/TagGroup/TagGroup.test.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx b/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx index d4ce6bbb09386..8bd1042b5bc15 100644 --- a/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx +++ b/packages/react-components/react-tags/library/src/components/TagGroup/TagGroup.test.tsx @@ -4,7 +4,6 @@ import { TagGroup } from './TagGroup'; import { isConformant } from '../../testing/isConformant'; import { render, fireEvent } from '@testing-library/react'; import { Tag } from '../Tag/index'; -import { InteractionTag } from '../InteractionTag/index'; describe('TagGroup', () => { isConformant({