From 607fb16f8c2695dfa10d283bc2d29d97ebe9a27a Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Tue, 28 Feb 2023 17:17:53 -0800 Subject: [PATCH 01/62] add raw html --- .../src/components/Tag/renderTag.tsx | 20 ++++++++++++++++++- .../components/TagButton/renderTagButton.tsx | 20 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx index 07a4f9804be21b..a6fa25c5e16188 100644 --- a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx @@ -9,5 +9,23 @@ export const renderTag_unstable = (state: TagState) => { const { slots, slotProps } = getSlots(state); // TODO Add additional slots in the appropriate place - return ; + return ( + + +
+ +
+
i
+
Primary Text
+
Secondary Text
+
+
+ +
+
+ ); }; diff --git a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx index b96dbec44bf5bb..0afd74b82e58b0 100644 --- a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx @@ -9,5 +9,23 @@ export const renderTagButton_unstable = (state: TagButtonState) => { const { slots, slotProps } = getSlots(state); // TODO Add additional slots in the appropriate place - return ; + return ( + + +
+ +
+
+ ); }; From b6bbff48d0ffca5f2002a2117aa4305cb687e2ef Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Thu, 2 Mar 2023 14:27:45 -0800 Subject: [PATCH 02/62] add types and update render to use slots --- .../react-components/react-tags/package.json | 1 + .../src/components/Tag/Tag.types.ts | 20 +++++++-- .../src/components/Tag/renderTag.tsx | 24 ++++------- .../react-tags/src/components/Tag/useTag.ts | 19 +++++--- .../src/components/Tag/useTagStyles.ts | 43 ++++++++++++++++--- .../stories/Tag/TagDefault.stories.tsx | 2 +- 6 files changed, 79 insertions(+), 30 deletions(-) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index 49d91c4fe08695..88e8ad5e0a237d 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -32,6 +32,7 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { + "@fluentui/react-persona": "9.1.13", "@fluentui/react-theme": "^9.1.5", "@fluentui/react-utilities": "^9.6.0", "@griffel/react": "^1.5.2", 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 2bb2b4b3227976..d2a3853ad2cc35 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 @@ -1,17 +1,29 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; +import { Persona } from '@fluentui/react-persona'; export type TagSlots = { - root: Slot<'div'>; + root: NonNullable>; + content?: Slot<'span'>; + persona?: Slot; + icon?: Slot<'span'>; + primaryText?: Slot<'span'>; + secondaryText?: Slot<'span'>; + dismiss?: Slot<'span'>; }; /** * Tag Props */ -export type TagProps = ComponentProps & {}; +export type TagProps = ComponentProps & { + size?: 'extra-small' | 'small' | 'medium'; + shape?: 'rounded' | 'circular'; + style?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; + disabled?: boolean; + checked?: boolean; + dismissible?: boolean; +}; /** * State used in rendering Tag */ export type TagState = ComponentState; -// TODO: Remove semicolon from previous line, uncomment next line, and provide union of props to pick from TagProps. -// & Required> diff --git a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx index a6fa25c5e16188..238bec8d0f4464 100644 --- a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx @@ -11,21 +11,15 @@ export const renderTag_unstable = (state: TagState) => { // TODO Add additional slots in the appropriate place return ( - -
- -
-
i
-
Primary Text
-
Secondary Text
-
-
- -
+ {slots.content && ( + + {slots.persona && } + {slots.icon && } + {slots.primaryText && } + {slots.secondaryText && } + + )} + {slots.dismiss && }
); }; diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.ts b/packages/react-components/react-tags/src/components/Tag/useTag.ts index 67bed0af432f4f..8117d194081f57 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTag.ts @@ -1,6 +1,7 @@ import * as React from 'react'; -import { getNativeElementProps } from '@fluentui/react-utilities'; +import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; import type { TagProps, TagState } from './Tag.types'; +import { Persona } from '@fluentui/react-persona'; /** * Create the state required to render Tag. @@ -13,16 +14,24 @@ import type { TagProps, TagState } from './Tag.types'; */ export const useTag_unstable = (props: TagProps, ref: React.Ref): TagState => { return { - // TODO add appropriate props/defaults components: { - // TODO add each slot's element type or component root: 'div', + content: 'span', + persona: Persona, + icon: 'span', + primaryText: 'span', + secondaryText: 'span', + dismiss: 'span', }, - // TODO add appropriate slots, for example: - // mySlot: resolveShorthand(props.mySlot), root: getNativeElementProps('div', { ref, ...props, }), + content: resolveShorthand(props.content, { required: true }), + persona: resolveShorthand(props.persona), + icon: resolveShorthand(props.icon), + primaryText: resolveShorthand(props.primaryText), + secondaryText: resolveShorthand(props.secondaryText), + dismiss: resolveShorthand(props.dismiss), }; }; diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 6faa08d90aaf48..8bf6367406649c 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -4,8 +4,12 @@ import type { SlotClassNames } from '@fluentui/react-utilities'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', - // TODO: add class names for all slots on TagSlots. - // Should be of the form `: 'fui-Tag__` + content: 'fui-Tag_content', + persona: 'fui-Tag_persona', + icon: 'fui-Tag_icon', + primaryText: 'fui-Tag_primaryText', + secondaryText: 'fui-Tag_secondaryText', + dismiss: 'fui-Tag_dismiss', }; /** @@ -15,6 +19,12 @@ const useStyles = makeStyles({ root: { // TODO Add default styles for the root element }, + content: {}, + persona: {}, + icon: {}, + primaryText: {}, + secondaryText: {}, + dismiss: {}, // TODO add additional classes for different states and/or slots }); @@ -25,9 +35,32 @@ const useStyles = makeStyles({ export const useTagStyles_unstable = (state: TagState): TagState => { const styles = useStyles(); state.root.className = mergeClasses(tagClassNames.root, styles.root, state.root.className); - - // TODO Add class names to slots, for example: - // state.mySlot.className = mergeClasses(styles.mySlot, state.mySlot.className); + if (state.content) { + state.content.className = mergeClasses(tagClassNames.content, styles.content, state.content.className); + } + if (state.persona) { + state.persona.className = mergeClasses(tagClassNames.persona, styles.persona, state.persona.className); + } + if (state.icon) { + state.icon.className = mergeClasses(tagClassNames.icon, styles.icon, state.icon.className); + } + if (state.primaryText) { + state.primaryText.className = mergeClasses( + tagClassNames.primaryText, + styles.primaryText, + state.primaryText.className, + ); + } + if (state.secondaryText) { + state.secondaryText.className = mergeClasses( + tagClassNames.secondaryText, + styles.secondaryText, + state.secondaryText.className, + ); + } + if (state.dismiss) { + state.dismiss.className = mergeClasses(tagClassNames.dismiss, styles.dismiss, state.dismiss.className); + } return state; }; diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index 342622eceed82b..f749d16b0a0182 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -1,4 +1,4 @@ import * as React from 'react'; import { Tag, TagProps } from '@fluentui/react-tags'; -export const Default = (props: Partial) => ; +export const Default = (props: Partial) => ; From fd1b1432ebe3bf84515733e69d9cbd48f61e9308 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Mon, 6 Mar 2023 15:04:33 -0800 Subject: [PATCH 03/62] init slots and layout setup for tag --- .../react-components/react-tags/package.json | 2 +- .../src/components/Tag/Tag.types.ts | 13 ++--- .../src/components/Tag/renderTag.tsx | 4 +- .../components/Tag/{useTag.ts => useTag.tsx} | 33 +++++++++++-- .../src/components/Tag/useTagStyles.ts | 48 +++++++++++++------ .../stories/Tag/TagDefault.stories.tsx | 18 ++++++- 6 files changed, 89 insertions(+), 29 deletions(-) rename packages/react-components/react-tags/src/components/Tag/{useTag.ts => useTag.tsx} (60%) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index 88e8ad5e0a237d..d15dce1c6901cb 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -32,7 +32,7 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react-persona": "9.1.13", + "@fluentui/react-avatar": "9.3.7", "@fluentui/react-theme": "^9.1.5", "@fluentui/react-utilities": "^9.6.0", "@griffel/react": "^1.5.2", 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 d2a3853ad2cc35..1b4d377c6d49e6 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 @@ -1,14 +1,14 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; -import { Persona } from '@fluentui/react-persona'; +import { Avatar } from '@fluentui/react-avatar'; export type TagSlots = { root: NonNullable>; content?: Slot<'span'>; - persona?: Slot; + avatar?: Slot; icon?: Slot<'span'>; primaryText?: Slot<'span'>; secondaryText?: Slot<'span'>; - dismiss?: Slot<'span'>; + dismissButton?: NonNullable>; }; /** @@ -17,13 +17,14 @@ export type TagSlots = { export type TagProps = ComponentProps & { size?: 'extra-small' | 'small' | 'medium'; shape?: 'rounded' | 'circular'; - style?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; + appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; disabled?: boolean; checked?: boolean; - dismissible?: boolean; + dismissable?: boolean; }; /** * State used in rendering Tag */ -export type TagState = ComponentState; +export type TagState = ComponentState & + Required>; diff --git a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx index 238bec8d0f4464..73293eca119e61 100644 --- a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx @@ -13,13 +13,13 @@ export const renderTag_unstable = (state: TagState) => { {slots.content && ( - {slots.persona && } + {slots.avatar && } {slots.icon && } {slots.primaryText && } {slots.secondaryText && } )} - {slots.dismiss && } + {slots.dismissButton && state.dismissable && } ); }; diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.ts b/packages/react-components/react-tags/src/components/Tag/useTag.tsx similarity index 60% rename from packages/react-components/react-tags/src/components/Tag/useTag.ts rename to packages/react-components/react-tags/src/components/Tag/useTag.tsx index 8117d194081f57..c80ea7f88f390f 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; import type { TagProps, TagState } from './Tag.types'; -import { Persona } from '@fluentui/react-persona'; +import { Dismiss16Filled } from '@fluentui/react-icons'; +import { Avatar } from '@fluentui/react-avatar'; /** * Create the state required to render Tag. @@ -13,25 +14,47 @@ import { Persona } from '@fluentui/react-persona'; * @param ref - reference to root HTMLElement of Tag */ export const useTag_unstable = (props: TagProps, ref: React.Ref): TagState => { + const { + checked = false, + disabled = false, + dismissable = false, + shape = 'rounded', + size = 'medium', + appearance = 'filled-lighter', + } = props; + return { components: { root: 'div', content: 'span', - persona: Persona, + avatar: Avatar, icon: 'span', primaryText: 'span', secondaryText: 'span', - dismiss: 'span', + dismissButton: 'button', }, + checked, + disabled, + dismissable, + shape, + size, + appearance, root: getNativeElementProps('div', { ref, ...props, }), content: resolveShorthand(props.content, { required: true }), - persona: resolveShorthand(props.persona), + avatar: resolveShorthand(props.avatar), icon: resolveShorthand(props.icon), primaryText: resolveShorthand(props.primaryText), secondaryText: resolveShorthand(props.secondaryText), - dismiss: resolveShorthand(props.dismiss), + dismissButton: resolveShorthand(props.dismissButton, { + required: true, + defaultProps: { + disabled: props.disabled, + type: 'button', + children: , + }, + }), }; }; diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 8bf6367406649c..590e8cdfcd83af 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -1,15 +1,15 @@ -import { makeStyles, mergeClasses } from '@griffel/react'; +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagSlots, TagState } from './Tag.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', content: 'fui-Tag_content', - persona: 'fui-Tag_persona', + avatar: 'fui-Tag_avatar', icon: 'fui-Tag_icon', primaryText: 'fui-Tag_primaryText', secondaryText: 'fui-Tag_secondaryText', - dismiss: 'fui-Tag_dismiss', + dismissButton: 'fui-Tag_dismissButton', }; /** @@ -17,14 +17,30 @@ export const tagClassNames: SlotClassNames = { */ const useStyles = makeStyles({ root: { - // TODO Add default styles for the root element + display: 'inline-flex', }, - content: {}, - persona: {}, - icon: {}, - primaryText: {}, - secondaryText: {}, - dismiss: {}, + content: { + display: 'inline-grid', + gridTemplateColumns: 'auto 8px auto auto 8px auto', + gridTemplateRows: '1fr auto auto 1fr', + gridTemplateAreas: ` + "avatar x icon . y" + "avatar x icon primary y" + "avatar x icon secondary y" + "avatar x icon . y" + `, + }, + avatar: { + alignSelf: 'center', + ...shorthands.gridArea('avatar'), + }, + icon: { + alignSelf: 'center', + ...shorthands.gridArea('icon'), + }, + primaryText: { ...shorthands.gridArea('primary') }, + secondaryText: { ...shorthands.gridArea('secondary') }, + dismissButton: {}, // TODO add additional classes for different states and/or slots }); @@ -38,8 +54,8 @@ export const useTagStyles_unstable = (state: TagState): TagState => { if (state.content) { state.content.className = mergeClasses(tagClassNames.content, styles.content, state.content.className); } - if (state.persona) { - state.persona.className = mergeClasses(tagClassNames.persona, styles.persona, state.persona.className); + if (state.avatar) { + state.avatar.className = mergeClasses(tagClassNames.avatar, styles.avatar, state.avatar.className); } if (state.icon) { state.icon.className = mergeClasses(tagClassNames.icon, styles.icon, state.icon.className); @@ -58,8 +74,12 @@ export const useTagStyles_unstable = (state: TagState): TagState => { state.secondaryText.className, ); } - if (state.dismiss) { - state.dismiss.className = mergeClasses(tagClassNames.dismiss, styles.dismiss, state.dismiss.className); + if (state.dismissButton) { + state.dismissButton.className = mergeClasses( + tagClassNames.dismissButton, + styles.dismissButton, + state.dismissButton.className, + ); } return state; diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index f749d16b0a0182..c6639a6746769a 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -1,4 +1,20 @@ import * as React from 'react'; import { Tag, TagProps } from '@fluentui/react-tags'; +import { Calendar3Day28Regular } from '@fluentui/react-icons'; -export const Default = (props: Partial) => ; +export const Default = (props: Partial) => ( + } + primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + /> +); From 6843d4c0abedeebd426e095be98c67f73d81e6b9 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Mon, 6 Mar 2023 15:12:19 -0800 Subject: [PATCH 04/62] init pass on Tag button --- .../components/TagButton/TagButton.types.ts | 23 ++++-- .../components/TagButton/renderTagButton.tsx | 26 +++---- .../src/components/TagButton/useTagButton.ts | 28 -------- .../src/components/TagButton/useTagButton.tsx | 60 ++++++++++++++++ .../TagButton/useTagButtonStyles.ts | 71 +++++++++++++++++-- .../TagButton/TagButtonDefault.stories.tsx | 18 ++++- 6 files changed, 169 insertions(+), 57 deletions(-) delete mode 100644 packages/react-components/react-tags/src/components/TagButton/useTagButton.ts create mode 100644 packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts b/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts index d8590ba8b3d3b4..2909aceadc7cc2 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts @@ -1,17 +1,30 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; +import { Avatar } from '@fluentui/react-avatar'; export type TagButtonSlots = { - root: Slot<'div'>; + root: NonNullable>; + contentButton?: Slot<'button'>; + avatar?: Slot; + icon?: Slot<'span'>; + primaryText?: Slot<'span'>; + secondaryText?: Slot<'span'>; + dismissButton?: NonNullable>; }; /** * TagButton Props */ -export type TagButtonProps = ComponentProps & {}; +export type TagButtonProps = ComponentProps & { + size?: 'extra-small' | 'small' | 'medium'; + shape?: 'rounded' | 'circular'; + appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; + disabled?: boolean; + checked?: boolean; + dismissable?: boolean; +}; /** * State used in rendering TagButton */ -export type TagButtonState = ComponentState; -// TODO: Remove semicolon from previous line, uncomment next line, and provide union of props to pick from TagButtonProps. -// & Required> +export type TagButtonState = ComponentState & + Required>; diff --git a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx index 0afd74b82e58b0..32503ddad727b8 100644 --- a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx @@ -3,7 +3,7 @@ import { getSlots } from '@fluentui/react-utilities'; import type { TagButtonState, TagButtonSlots } from './TagButton.types'; /** - * Render the final JSX of TagButton + * Render the final JSX of Tag */ export const renderTagButton_unstable = (state: TagButtonState) => { const { slots, slotProps } = getSlots(state); @@ -11,21 +11,15 @@ export const renderTagButton_unstable = (state: TagButtonState) => { // TODO Add additional slots in the appropriate place return ( - -
- -
+ {slots.contentButton && ( + + {slots.avatar && } + {slots.icon && } + {slots.primaryText && } + {slots.secondaryText && } + + )} + {slots.dismissButton && state.dismissable && }
); }; diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButton.ts deleted file mode 100644 index 912c9a85cc99f1..00000000000000 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { getNativeElementProps } from '@fluentui/react-utilities'; -import type { TagButtonProps, TagButtonState } from './TagButton.types'; - -/** - * Create the state required to render TagButton. - * - * The returned state can be modified with hooks such as useTagButtonStyles_unstable, - * before being passed to renderTagButton_unstable. - * - * @param props - props from this instance of TagButton - * @param ref - reference to root HTMLElement of TagButton - */ -export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { - return { - // TODO add appropriate props/defaults - components: { - // TODO add each slot's element type or component - root: 'div', - }, - // TODO add appropriate slots, for example: - // mySlot: resolveShorthand(props.mySlot), - root: getNativeElementProps('div', { - ref, - ...props, - }), - }; -}; diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx new file mode 100644 index 00000000000000..b4efff759239b0 --- /dev/null +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; +import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; +import type { TagButtonProps, TagButtonState } from './TagButton.types'; +import { Dismiss16Filled } from '@fluentui/react-icons'; +import { Avatar } from '@fluentui/react-avatar'; + +/** + * Create the state required to render TagButton. + * + * The returned state can be modified with hooks such as useTagButtonStyles_unstable, + * before being passed to renderTagButton_unstable. + * + * @param props - props from this instance of TagButton + * @param ref - reference to root HTMLElement of TagButton + */ +export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { + const { + checked = false, + disabled = false, + dismissable = false, + shape = 'rounded', + size = 'medium', + appearance = 'filled-lighter', + } = props; + + return { + components: { + root: 'div', + contentButton: 'button', + avatar: Avatar, + icon: 'span', + primaryText: 'span', + secondaryText: 'span', + dismissButton: 'button', + }, + checked, + disabled, + dismissable, + shape, + size, + appearance, + root: getNativeElementProps('div', { + ref, + ...props, + }), + contentButton: resolveShorthand(props.contentButton, { required: true }), + avatar: resolveShorthand(props.avatar), + icon: resolveShorthand(props.icon), + primaryText: resolveShorthand(props.primaryText), + secondaryText: resolveShorthand(props.secondaryText), + dismissButton: resolveShorthand(props.dismissButton, { + required: true, + defaultProps: { + disabled: props.disabled, + type: 'button', + children: , + }, + }), + }; +}; diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts index 64364e62d1d3c8..bed43ce7ffbca4 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts @@ -1,11 +1,15 @@ -import { makeStyles, mergeClasses } from '@griffel/react'; +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagButtonSlots, TagButtonState } from './TagButton.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; export const tagButtonClassNames: SlotClassNames = { root: 'fui-TagButton', - // TODO: add class names for all slots on TagButtonSlots. - // Should be of the form `: 'fui-TagButton__` + contentButton: 'fui-TagButton_contentButton', + avatar: 'fui-TagButton_avatar', + icon: 'fui-TagButton_icon', + primaryText: 'fui-TagButton_primaryText', + secondaryText: 'fui-TagButton_secondaryText', + dismissButton: 'fui-TagButton_dismissButton', }; /** @@ -13,8 +17,30 @@ export const tagButtonClassNames: SlotClassNames = { */ const useStyles = makeStyles({ root: { - // TODO Add default styles for the root element + display: 'inline-flex', }, + contentButton: { + display: 'inline-grid', + gridTemplateColumns: 'auto 8px auto auto 8px auto', + gridTemplateRows: '1fr auto auto 1fr', + gridTemplateAreas: ` + "avatar x icon . y" + "avatar x icon primary y" + "avatar x icon secondary y" + "avatar x icon . y" + `, + }, + avatar: { + alignSelf: 'center', + ...shorthands.gridArea('avatar'), + }, + icon: { + alignSelf: 'center', + ...shorthands.gridArea('icon'), + }, + primaryText: { ...shorthands.gridArea('primary') }, + secondaryText: { ...shorthands.gridArea('secondary') }, + dismissButton: {}, // TODO add additional classes for different states and/or slots }); @@ -25,9 +51,40 @@ const useStyles = makeStyles({ export const useTagButtonStyles_unstable = (state: TagButtonState): TagButtonState => { const styles = useStyles(); state.root.className = mergeClasses(tagButtonClassNames.root, styles.root, state.root.className); - - // TODO Add class names to slots, for example: - // state.mySlot.className = mergeClasses(styles.mySlot, state.mySlot.className); + if (state.contentButton) { + state.contentButton.className = mergeClasses( + tagButtonClassNames.contentButton, + styles.contentButton, + state.contentButton.className, + ); + } + if (state.avatar) { + state.avatar.className = mergeClasses(tagButtonClassNames.avatar, styles.avatar, state.avatar.className); + } + if (state.icon) { + state.icon.className = mergeClasses(tagButtonClassNames.icon, styles.icon, state.icon.className); + } + if (state.primaryText) { + state.primaryText.className = mergeClasses( + tagButtonClassNames.primaryText, + styles.primaryText, + state.primaryText.className, + ); + } + if (state.secondaryText) { + state.secondaryText.className = mergeClasses( + tagButtonClassNames.secondaryText, + styles.secondaryText, + state.secondaryText.className, + ); + } + if (state.dismissButton) { + state.dismissButton.className = mergeClasses( + tagButtonClassNames.dismissButton, + styles.dismissButton, + state.dismissButton.className, + ); + } return state; }; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx index 6956d82a32f358..08c2b41a875738 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx @@ -1,4 +1,20 @@ import * as React from 'react'; import { TagButton, TagButtonProps } from '@fluentui/react-tags'; +import { Calendar3Day28Regular } from '@fluentui/react-icons'; -export const Default = (props: Partial) => ; +export const Default = (props: Partial) => ( + } + primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + /> +); From c02029ce460f4e7b195a6eafa5c877e5df408087 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Mon, 6 Mar 2023 15:26:24 -0800 Subject: [PATCH 05/62] fix dep version --- packages/react-components/react-tags/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index d15dce1c6901cb..febdd0c2542314 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -32,7 +32,7 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react-avatar": "9.3.7", + "@fluentui/react-avatar": "^9.3.7", "@fluentui/react-theme": "^9.1.5", "@fluentui/react-utilities": "^9.6.0", "@griffel/react": "^1.5.2", From 1345a2e7dda3e76ec1dcb3705e3c6be3a35d9d62 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Tue, 7 Mar 2023 07:37:02 -0800 Subject: [PATCH 06/62] add icons to package.json --- packages/react-components/react-tags/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index febdd0c2542314..a51e00f9619f7c 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -34,6 +34,7 @@ "dependencies": { "@fluentui/react-avatar": "^9.3.7", "@fluentui/react-theme": "^9.1.5", + "@fluentui/react-icons": "^2.0.175", "@fluentui/react-utilities": "^9.6.0", "@griffel/react": "^1.5.2", "tslib": "^2.1.0" From 01d968e02e2d1c5b1c2537b98ee202f0b6d0dfa7 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Tue, 7 Mar 2023 07:50:57 -0800 Subject: [PATCH 07/62] api update --- .../react-tags/etc/react-tags.api.md | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 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 a96f539e01bfc4..749af6e50ff3d2 100644 --- a/packages/react-components/react-tags/etc/react-tags.api.md +++ b/packages/react-components/react-tags/etc/react-tags.api.md @@ -4,6 +4,9 @@ ```ts +/// + +import { Avatar } from '@fluentui/react-avatar'; import type { ComponentProps } from '@fluentui/react-utilities'; import type { ComponentState } from '@fluentui/react-utilities'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; @@ -27,29 +30,55 @@ export const TagButton: ForwardRefComponent; export const tagButtonClassNames: SlotClassNames; // @public -export type TagButtonProps = ComponentProps & {}; +export type TagButtonProps = ComponentProps & { + size?: 'extra-small' | 'small' | 'medium'; + shape?: 'rounded' | 'circular'; + appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; + disabled?: boolean; + checked?: boolean; + dismissable?: boolean; +}; // @public (undocumented) export type TagButtonSlots = { - root: Slot<'div'>; + root: NonNullable>; + contentButton?: Slot<'button'>; + avatar?: Slot; + icon?: Slot<'span'>; + primaryText?: Slot<'span'>; + secondaryText?: Slot<'span'>; + dismissButton?: NonNullable>; }; // @public -export type TagButtonState = ComponentState; +export type TagButtonState = ComponentState & Required>; // @public (undocumented) export const tagClassNames: SlotClassNames; // @public -export type TagProps = ComponentProps & {}; +export type TagProps = ComponentProps & { + size?: 'extra-small' | 'small' | 'medium'; + shape?: 'rounded' | 'circular'; + appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; + disabled?: boolean; + checked?: boolean; + dismissable?: boolean; +}; // @public (undocumented) export type TagSlots = { - root: Slot<'div'>; + root: NonNullable>; + content?: Slot<'span'>; + avatar?: Slot; + icon?: Slot<'span'>; + primaryText?: Slot<'span'>; + secondaryText?: Slot<'span'>; + dismissButton?: NonNullable>; }; // @public -export type TagState = ComponentState; +export type TagState = ComponentState & Required>; // @public export const useTag_unstable: (props: TagProps, ref: React_2.Ref) => TagState; From 33b2f8b0aa48e5079cdab7bafafd5e989ef064b0 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Tue, 7 Mar 2023 08:55:59 -0800 Subject: [PATCH 08/62] update tests --- .../src/components/Tag/Tag.test.tsx | 13 ++++- .../Tag/__snapshots__/Tag.test.tsx.snap | 52 ++++++++++++++++++- .../src/components/Tag/useTagStyles.ts | 12 ++--- .../components/TagButton/TagButton.test.tsx | 13 ++++- .../__snapshots__/TagButton.test.tsx.snap | 52 ++++++++++++++++++- .../TagButton/useTagButtonStyles.ts | 12 ++--- 6 files changed, 138 insertions(+), 16 deletions(-) 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 80af2199dba4ba..f883681c531f31 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 @@ -3,16 +3,27 @@ import { render } from '@testing-library/react'; import { Tag } from './Tag'; import { isConformant } from '../../testing/isConformant'; +const requiredProps = { + avatar: { + name: 'Katri Athokas', + }, + icon: 'i', + primaryText: 'Primary text', + secondaryText: 'Secondary text', + dismissable: true, +}; + describe('Tag', () => { isConformant({ Component: Tag, displayName: 'Tag', + requiredProps, }); // TODO add more tests here, and create visual regression tests in /apps/vr-tests it('renders a default state', () => { - const result = render(Default Tag); + const result = render(Default Tag); expect(result.container).toMatchSnapshot(); }); }); diff --git a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap index f2701f46afe480..30930745ddda77 100644 --- a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap +++ b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap @@ -5,7 +5,57 @@ exports[`Tag renders a default state 1`] = `
- Default Tag + + + + KA + + + + i + + + Primary text + + + Secondary text + + +
`; diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 590e8cdfcd83af..60988d1ec939fa 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -4,12 +4,12 @@ import type { SlotClassNames } from '@fluentui/react-utilities'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', - content: 'fui-Tag_content', - avatar: 'fui-Tag_avatar', - icon: 'fui-Tag_icon', - primaryText: 'fui-Tag_primaryText', - secondaryText: 'fui-Tag_secondaryText', - dismissButton: 'fui-Tag_dismissButton', + content: 'fui-Tag__content', + avatar: 'fui-Tag__avatar', + icon: 'fui-Tag__icon', + primaryText: 'fui-Tag__primaryText', + secondaryText: 'fui-Tag__secondaryText', + dismissButton: 'fui-Tag__dismissButton', }; /** diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx b/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx index a5257d7328b180..00568aabcc30d1 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx @@ -3,16 +3,27 @@ import { render } from '@testing-library/react'; import { TagButton } from './TagButton'; import { isConformant } from '../../testing/isConformant'; +const requiredProps = { + avatar: { + name: 'Katri Athokas', + }, + icon: 'i', + primaryText: 'Primary text', + secondaryText: 'Secondary text', + dismissable: true, +}; + describe('TagButton', () => { isConformant({ Component: TagButton, displayName: 'TagButton', + requiredProps, }); // TODO add more tests here, and create visual regression tests in /apps/vr-tests it('renders a default state', () => { - const result = render(Default TagButton); + const result = render(Default TagButton); expect(result.container).toMatchSnapshot(); }); }); diff --git a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap index 10f50a682bcb66..d6ab63bcb6107c 100644 --- a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap +++ b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap @@ -5,7 +5,57 @@ exports[`TagButton renders a default state 1`] = `
- Default TagButton + +
`; diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts index bed43ce7ffbca4..ceb61e20ce6047 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts @@ -4,12 +4,12 @@ import type { SlotClassNames } from '@fluentui/react-utilities'; export const tagButtonClassNames: SlotClassNames = { root: 'fui-TagButton', - contentButton: 'fui-TagButton_contentButton', - avatar: 'fui-TagButton_avatar', - icon: 'fui-TagButton_icon', - primaryText: 'fui-TagButton_primaryText', - secondaryText: 'fui-TagButton_secondaryText', - dismissButton: 'fui-TagButton_dismissButton', + contentButton: 'fui-TagButton__contentButton', + avatar: 'fui-TagButton__avatar', + icon: 'fui-TagButton__icon', + primaryText: 'fui-TagButton__primaryText', + secondaryText: 'fui-TagButton__secondaryText', + dismissButton: 'fui-TagButton__dismissButton', }; /** From bc7dff9ad229a65d9fe3285b73d35bd9554ff5de Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 08:09:39 -0800 Subject: [PATCH 09/62] Update packages/react-components/react-tags/src/components/Tag/Tag.types.ts Co-authored-by: Esteban Munoz Facusse --- .../react-components/react-tags/src/components/Tag/Tag.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1b4d377c6d49e6..8cffeea46be0d1 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 @@ -27,4 +27,4 @@ export type TagProps = ComponentProps & { * State used in rendering Tag */ export type TagState = ComponentState & - Required>; + Required>; From cb8b4f1bbaad16bc3311c715280a0d2ad69377f1 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 08:10:11 -0800 Subject: [PATCH 10/62] Update packages/react-components/react-tags/src/components/Tag/useTag.tsx Co-authored-by: Esteban Munoz Facusse --- .../react-components/react-tags/src/components/Tag/useTag.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index c80ea7f88f390f..1beed6165cd0a0 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; -import type { TagProps, TagState } from './Tag.types'; import { Dismiss16Filled } from '@fluentui/react-icons'; import { Avatar } from '@fluentui/react-avatar'; +import type { TagProps, TagState } from './Tag.types'; /** * Create the state required to render Tag. From ed79cd6b4a811f1a14a79a5c22a81d9e6c091e1d Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 08:13:46 -0800 Subject: [PATCH 11/62] Update packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts Co-authored-by: Esteban Munoz Facusse --- .../react-tags/src/components/TagButton/TagButton.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts b/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts index 2909aceadc7cc2..807800361a382e 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts @@ -27,4 +27,4 @@ export type TagButtonProps = ComponentProps & { * State used in rendering TagButton */ export type TagButtonState = ComponentState & - Required>; + Required>; From 30dcbe17ae7891287516d5b904fe29f0b29ed435 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 08:14:09 -0800 Subject: [PATCH 12/62] Update packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx Co-authored-by: Esteban Munoz Facusse --- .../react-tags/src/components/TagButton/renderTagButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx index 32503ddad727b8..935bdef3c636b4 100644 --- a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx @@ -3,7 +3,7 @@ import { getSlots } from '@fluentui/react-utilities'; import type { TagButtonState, TagButtonSlots } from './TagButton.types'; /** - * Render the final JSX of Tag + * Render the final JSX of TagButton */ export const renderTagButton_unstable = (state: TagButtonState) => { const { slots, slotProps } = getSlots(state); From e0fb356c0efc6ea183bbcff13fffea4752d29759 Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 08:21:49 -0800 Subject: [PATCH 13/62] remove unnecessary named columns --- .../react-tags/src/components/Tag/useTagStyles.ts | 8 ++++---- .../src/components/TagButton/useTagButtonStyles.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 60988d1ec939fa..d388013ad1ebeb 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -24,10 +24,10 @@ const useStyles = makeStyles({ gridTemplateColumns: 'auto 8px auto auto 8px auto', gridTemplateRows: '1fr auto auto 1fr', gridTemplateAreas: ` - "avatar x icon . y" - "avatar x icon primary y" - "avatar x icon secondary y" - "avatar x icon . y" + "avatar . icon . ." + "avatar . icon primary ." + "avatar . icon secondary ." + "avatar . icon . ." `, }, avatar: { diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts index ceb61e20ce6047..c03ad488ae53f5 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts @@ -24,10 +24,10 @@ const useStyles = makeStyles({ gridTemplateColumns: 'auto 8px auto auto 8px auto', gridTemplateRows: '1fr auto auto 1fr', gridTemplateAreas: ` - "avatar x icon . y" - "avatar x icon primary y" - "avatar x icon secondary y" - "avatar x icon . y" + "avatar . icon . ." + "avatar . icon primary ." + "avatar . icon secondary ." + "avatar . icon . ." `, }, avatar: { From 1248f0a4db16728311a9a09b34188b9048d9fc5b Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 15:51:47 -0800 Subject: [PATCH 14/62] Update packages/react-components/react-tags/src/components/Tag/useTag.tsx Co-authored-by: Sean Monahan --- .../react-components/react-tags/src/components/Tag/useTag.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index 1beed6165cd0a0..0965e8455d9712 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -51,7 +51,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T dismissButton: resolveShorthand(props.dismissButton, { required: true, defaultProps: { - disabled: props.disabled, + disabled, type: 'button', children: , }, From 0e2dcfb5e6f1761d012e74a4ecd75a01fd4be76f Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 8 Mar 2023 15:51:57 -0800 Subject: [PATCH 15/62] Update packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx Co-authored-by: Sean Monahan --- .../react-tags/src/components/TagButton/useTagButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx index b4efff759239b0..5a359ada2eec39 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -51,7 +51,7 @@ export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref, }, From fbe57979816793b2074cc081dd8386971f54362d Mon Sep 17 00:00:00 2001 From: Micah Godbolt Date: Wed, 15 Mar 2023 10:45:36 -0700 Subject: [PATCH 16/62] bmp react utils to match master --- packages/react-components/react-tags/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index a51e00f9619f7c..2c419a2617e9db 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -35,7 +35,7 @@ "@fluentui/react-avatar": "^9.3.7", "@fluentui/react-theme": "^9.1.5", "@fluentui/react-icons": "^2.0.175", - "@fluentui/react-utilities": "^9.6.0", + "@fluentui/react-utilities": "^9.7.0", "@griffel/react": "^1.5.2", "tslib": "^2.1.0" }, From 9cde259433bebae95f3244a04075316a3019c30d Mon Sep 17 00:00:00 2001 From: Amber Date: Thu, 27 Apr 2023 08:55:49 +0200 Subject: [PATCH 17/62] Update packages/react-components/react-tags/package.json --- packages/react-components/react-tags/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index e8004e3d527471..6df62172ac1f7f 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -32,8 +32,8 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react-avatar": "^9.3.7", - "@fluentui/react-icons": "^2.0.175", + "@fluentui/react-avatar": "^9.4.10", + "@fluentui/react-icons": "^2.0.196", "@fluentui/react-jsx-runtime": "9.0.0-alpha.2", "@fluentui/react-theme": "^9.1.7", "@fluentui/react-utilities": "^9.8.0", From 0e2b67623f8b9660094bb27f6ea93179c6d2bd32 Mon Sep 17 00:00:00 2001 From: Amber Date: Thu, 27 Apr 2023 09:31:10 +0200 Subject: [PATCH 18/62] Update api.md --- packages/react-components/react-tags/etc/react-tags.api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 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 749af6e50ff3d2..659e2b81f72266 100644 --- a/packages/react-components/react-tags/etc/react-tags.api.md +++ b/packages/react-components/react-tags/etc/react-tags.api.md @@ -51,7 +51,7 @@ export type TagButtonSlots = { }; // @public -export type TagButtonState = ComponentState & Required>; +export type TagButtonState = ComponentState & Required>; // @public (undocumented) export const tagClassNames: SlotClassNames; @@ -78,7 +78,7 @@ export type TagSlots = { }; // @public -export type TagState = ComponentState & Required>; +export type TagState = ComponentState & Required>; // @public export const useTag_unstable: (props: TagProps, ref: React_2.Ref) => TagState; From 57a0ed2b6d5e751c45406b836421a2baa532cfa7 Mon Sep 17 00:00:00 2001 From: Amber Date: Thu, 27 Apr 2023 10:00:49 +0200 Subject: [PATCH 19/62] Update test snapshot with react-icon update --- .../src/components/Tag/__snapshots__/Tag.test.tsx.snap | 2 +- .../components/TagButton/__snapshots__/TagButton.test.tsx.snap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap index 30930745ddda77..f66f95a0e95775 100644 --- a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap +++ b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap @@ -51,7 +51,7 @@ exports[`Tag renders a default state 1`] = ` xmlns="http://www.w3.org/2000/svg" > diff --git a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap index d6ab63bcb6107c..ad849b8d3f3003 100644 --- a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap +++ b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap @@ -51,7 +51,7 @@ exports[`TagButton renders a default state 1`] = ` xmlns="http://www.w3.org/2000/svg" > From aa38b3aeb0a548a7657d9e50156c02f56aea8702 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Thu, 27 Apr 2023 18:43:35 +0800 Subject: [PATCH 20/62] add avatar shape to avatar context --- .../react-avatar/etc/react-avatar.api.md | 4 +++- .../react-avatar/src/components/Avatar/Avatar.types.ts | 7 ++++++- .../react-avatar/src/components/Avatar/useAvatar.tsx | 4 ++-- .../react-avatar/src/contexts/AvatarContext.ts | 3 ++- packages/react-components/react-avatar/src/index.ts | 10 +++++++++- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/react-components/react-avatar/etc/react-avatar.api.md b/packages/react-components/react-avatar/etc/react-avatar.api.md index a0a6b609aa9e8a..0fa3e1b97b9fd8 100644 --- a/packages/react-components/react-avatar/etc/react-avatar.api.md +++ b/packages/react-components/react-avatar/etc/react-avatar.api.md @@ -32,6 +32,8 @@ export const AvatarContextProvider: React_2.Provider, 'color'> & { color?: 'neutral' | 'brand' | 'colorful' | AvatarNamedColor; idForColor?: string | undefined; name?: string; - shape?: 'circular' | 'square'; + shape?: AvatarShape; size?: AvatarSize; }; diff --git a/packages/react-components/react-avatar/src/components/Avatar/Avatar.types.ts b/packages/react-components/react-avatar/src/components/Avatar/Avatar.types.ts index d0b330cac4a85d..1f992919aa499a 100644 --- a/packages/react-components/react-avatar/src/components/Avatar/Avatar.types.ts +++ b/packages/react-components/react-avatar/src/components/Avatar/Avatar.types.ts @@ -11,6 +11,11 @@ export type AvatarSizes = AvatarSize; */ export type AvatarSize = 16 | 20 | 24 | 28 | 32 | 36 | 40 | 48 | 56 | 64 | 72 | 96 | 120 | 128; +/** + * Shape of the avatar + */ +export type AvatarShape = 'circular' | 'square'; + export type AvatarSlots = { root: Slot<'span'>; @@ -129,7 +134,7 @@ export type AvatarProps = Omit, 'color'> & { * The avatar can have a circular or square shape. * @default circular */ - shape?: 'circular' | 'square'; + shape?: AvatarShape; /** * Size of the avatar in pixels. diff --git a/packages/react-components/react-avatar/src/components/Avatar/useAvatar.tsx b/packages/react-components/react-avatar/src/components/Avatar/useAvatar.tsx index 1b165c7b50f957..731b0db1ab5b96 100644 --- a/packages/react-components/react-avatar/src/components/Avatar/useAvatar.tsx +++ b/packages/react-components/react-avatar/src/components/Avatar/useAvatar.tsx @@ -14,11 +14,11 @@ export const DEFAULT_STRINGS = { export const useAvatar_unstable = (props: AvatarProps, ref: React.Ref): AvatarState => { const { dir } = useFluent(); - const { size: contextSize } = useAvatarContext(); + const { size: contextSize, shape: contextShape } = useAvatarContext(); const { name, size = contextSize ?? (32 as const), - shape = 'circular', + shape = contextShape ?? 'circular', active = 'unset', activeAppearance = 'ring', idForColor, diff --git a/packages/react-components/react-avatar/src/contexts/AvatarContext.ts b/packages/react-components/react-avatar/src/contexts/AvatarContext.ts index 8ce68e20285f32..12e5b2bf57e9d7 100644 --- a/packages/react-components/react-avatar/src/contexts/AvatarContext.ts +++ b/packages/react-components/react-avatar/src/contexts/AvatarContext.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { AvatarSize } from '../components/Avatar/Avatar.types'; +import { AvatarSize, AvatarShape } from '../components/Avatar/Avatar.types'; const avatarContext = React.createContext(undefined); @@ -8,6 +8,7 @@ const avatarContext = React.createContext(undefi */ export interface AvatarContextValue { size?: AvatarSize; + shape?: AvatarShape; } const avatarContextDefaultValue: AvatarContextValue = {}; diff --git a/packages/react-components/react-avatar/src/index.ts b/packages/react-components/react-avatar/src/index.ts index 3093b679be158e..bf2090ee06055f 100644 --- a/packages/react-components/react-avatar/src/index.ts +++ b/packages/react-components/react-avatar/src/index.ts @@ -6,7 +6,15 @@ export { useAvatar_unstable, } from './Avatar'; // eslint-disable-next-line deprecation/deprecation -export type { AvatarNamedColor, AvatarProps, AvatarSlots, AvatarState, AvatarSizes, AvatarSize } from './Avatar'; +export type { + AvatarNamedColor, + AvatarProps, + AvatarSlots, + AvatarState, + AvatarSizes, + AvatarSize, + AvatarShape, +} from './Avatar'; export { getInitials, partitionAvatarGroupItems } from './utils/index'; export type { PartitionAvatarGroupItems, PartitionAvatarGroupItemsOptions } from './utils/index'; export { From 6c4d5f5180b8210b2b33183aa170bb8db6d49bee Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Thu, 27 Apr 2023 18:43:58 +0800 Subject: [PATCH 21/62] add bundle size tool to Tag --- .../react-components/react-tags/bundle-size/tag.fixture.js | 7 +++++++ packages/react-components/react-tags/package.json | 1 + 2 files changed, 8 insertions(+) create mode 100644 packages/react-components/react-tags/bundle-size/tag.fixture.js diff --git a/packages/react-components/react-tags/bundle-size/tag.fixture.js b/packages/react-components/react-tags/bundle-size/tag.fixture.js new file mode 100644 index 00000000000000..3e1a566ef404c8 --- /dev/null +++ b/packages/react-components/react-tags/bundle-size/tag.fixture.js @@ -0,0 +1,7 @@ +import { Tag } from '@fluentui/react-tags'; + +console.log(Tag); + +export default { + name: 'Tag', +}; diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index 6df62172ac1f7f..28e3173fe19978 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -14,6 +14,7 @@ "license": "MIT", "scripts": { "build": "just-scripts build", + "bundle-size": "bundle-size measure", "clean": "just-scripts clean", "code-style": "just-scripts code-style", "just": "just-scripts", From 8d5745eede53f9dfb4626d2cff8d507788994925 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Thu, 27 Apr 2023 21:22:24 +0800 Subject: [PATCH 22/62] add style for spacing --- .../react-components/react-tags/package.json | 1 + .../react-tags/src/components/Tag/Tag.tsx | 3 +- .../src/components/Tag/Tag.types.ts | 47 ++++- .../src/components/Tag/renderTag.tsx | 15 +- .../react-tags/src/components/Tag/useTag.tsx | 37 ++-- .../src/components/Tag/useTagContextValues.ts | 18 ++ .../src/components/Tag/useTagStyles.ts | 91 ++++++++-- .../stories/Tag/TagDefault.stories.tsx | 167 ++++++++++++++++-- .../stories/Tag/TagDismiss.stories.tsx | 26 +++ .../stories/Tag/TagIcon.stories.tsx | 14 ++ .../stories/Tag/TagMedia.stories.tsx | 15 ++ .../stories/Tag/TagSecondaryText.stories.tsx | 13 ++ .../stories/Tag/TagShape.stories.tsx | 33 ++++ .../react-tags/stories/Tag/index.stories.tsx | 5 + 14 files changed, 431 insertions(+), 54 deletions(-) create mode 100644 packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts create mode 100644 packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx create mode 100644 packages/react-components/react-tags/stories/Tag/TagIcon.stories.tsx create mode 100644 packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx create mode 100644 packages/react-components/react-tags/stories/Tag/TagSecondaryText.stories.tsx create mode 100644 packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index 28e3173fe19978..189b83ea66614f 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -34,6 +34,7 @@ }, "dependencies": { "@fluentui/react-avatar": "^9.4.10", + "@fluentui/react-button": "^9.3.10", "@fluentui/react-icons": "^2.0.196", "@fluentui/react-jsx-runtime": "9.0.0-alpha.2", "@fluentui/react-theme": "^9.1.7", diff --git a/packages/react-components/react-tags/src/components/Tag/Tag.tsx b/packages/react-components/react-tags/src/components/Tag/Tag.tsx index 12541970e70a05..eaeaa678d4430b 100644 --- a/packages/react-components/react-tags/src/components/Tag/Tag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/Tag.tsx @@ -4,6 +4,7 @@ import { renderTag_unstable } from './renderTag'; import { useTagStyles_unstable } from './useTagStyles'; import type { TagProps } from './Tag.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import { useTagContextValues_unstable } from './useTagContextValues'; /** * Tag component - TODO: add more docs @@ -12,7 +13,7 @@ export const Tag: ForwardRefComponent = React.forwardRef((props, ref) const state = useTag_unstable(props, ref); useTagStyles_unstable(state); - return renderTag_unstable(state); + return renderTag_unstable(state, useTagContextValues_unstable(state)); }); Tag.displayName = 'Tag'; 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 8cffeea46be0d1..45763b093eabd5 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 @@ -1,20 +1,46 @@ +import { AvatarSize, AvatarShape } from '@fluentui/react-avatar'; import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; -import { Avatar } from '@fluentui/react-avatar'; +import { Button } from '@fluentui/react-button'; + +export type TagContextValues = { + avatar: { + size?: AvatarSize; + shape?: AvatarShape; + }; +}; export type TagSlots = { root: NonNullable>; - content?: Slot<'span'>; - avatar?: Slot; + + /** + * Slot for an icon or other visual element + */ + media: Slot<'span'>; + + /** + * A layout wrapper for the icon slot, the primaryText and secondaryText slots + */ + content: Slot<'div'>; + icon?: Slot<'span'>; - primaryText?: Slot<'span'>; - secondaryText?: Slot<'span'>; - dismissButton?: NonNullable>; + + /** + * Main text for the Tag. Children of the root slot are automatically rendered here + */ + primaryText: Slot<'span'>; + + /** + * Secondary text that describes or complements the main text + */ + secondaryText: Slot<'span'>; + + dismissButton: Slot; }; /** * Tag Props */ -export type TagProps = ComponentProps & { +export type TagProps = ComponentProps> & { size?: 'extra-small' | 'small' | 'medium'; shape?: 'rounded' | 'circular'; appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; @@ -27,4 +53,9 @@ export type TagProps = ComponentProps & { * State used in rendering Tag */ export type TagState = ComponentState & - Required>; + Required< + Pick & { + avatarSize: AvatarSize | undefined; + avatarShape: AvatarShape | undefined; + } + >; diff --git a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx index ab3e1d6e61433b..9d63c4ba66cb6a 100644 --- a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx @@ -4,22 +4,29 @@ import { createElement } from '@fluentui/react-jsx-runtime'; import { getSlotsNext } from '@fluentui/react-utilities'; -import type { TagState, TagSlots } from './Tag.types'; +import type { TagState, TagSlots, TagContextValues } from './Tag.types'; +import { AvatarContextProvider } from '@fluentui/react-avatar'; /** * Render the final JSX of Tag */ -export const renderTag_unstable = (state: TagState) => { +export const renderTag_unstable = (state: TagState, contextValues: TagContextValues) => { const { slots, slotProps } = getSlotsNext(state); // TODO Add additional slots in the appropriate place return ( + {slots.media && ( + + + + )} {slots.content && ( - {slots.avatar && } {slots.icon && } - {slots.primaryText && } + {slots.primaryText && ( + {slotProps.root.children} + )} {slots.secondaryText && } )} diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index 0965e8455d9712..e36761d7a21d90 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -1,8 +1,20 @@ import * as React from 'react'; import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; -import { Dismiss16Filled } from '@fluentui/react-icons'; -import { Avatar } from '@fluentui/react-avatar'; +import { DismissRegular } from '@fluentui/react-icons'; import type { TagProps, TagState } from './Tag.types'; +import { Button } from '@fluentui/react-button'; + +// TODO verify map +const tagAvatarSizeMap = { + medium: 28, + small: 24, + 'extra-small': 20, +} as const; + +const tagAvatarShapeMap = { + rounded: 'square', + circular: 'circular', +} as const; /** * Create the state required to render Tag. @@ -26,12 +38,12 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T return { components: { root: 'div', - content: 'span', - avatar: Avatar, + content: 'div', + media: 'span', icon: 'span', primaryText: 'span', secondaryText: 'span', - dismissButton: 'button', + dismissButton: Button, }, checked, disabled, @@ -43,17 +55,22 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T ref, ...props, }), - content: resolveShorthand(props.content, { required: true }), - avatar: resolveShorthand(props.avatar), + avatarSize: tagAvatarSizeMap[size], + avatarShape: tagAvatarShapeMap[shape], + media: resolveShorthand(props.media), + + content: resolveShorthand(props.content, { required: !!props.primaryText || !!props.children }), icon: resolveShorthand(props.icon), - primaryText: resolveShorthand(props.primaryText), + primaryText: resolveShorthand(props.primaryText, { required: true }), secondaryText: resolveShorthand(props.secondaryText), + dismissButton: resolveShorthand(props.dismissButton, { - required: true, + required: props.dismissable, defaultProps: { disabled, + appearance: 'transparent', type: 'button', - children: , + icon: , }, }), }; diff --git a/packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts b/packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts new file mode 100644 index 00000000000000..d9ee8146af144a --- /dev/null +++ b/packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts @@ -0,0 +1,18 @@ +import * as React from 'react'; +import type { TagState, TagContextValues } from './Tag.types'; + +export function useTagContextValues_unstable(state: TagState): TagContextValues { + const { avatarSize, avatarShape } = state; + + const avatar = React.useMemo( + () => ({ + size: avatarSize, + shape: avatarShape, + }), + [avatarShape, avatarSize], + ); + + return { + avatar, + }; +} diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index d388013ad1ebeb..94a4177c9c3f0d 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -1,11 +1,12 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagSlots, TagState } from './Tag.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; +import { tokens, typographyStyles } from '@fluentui/react-theme'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', content: 'fui-Tag__content', - avatar: 'fui-Tag__avatar', + media: 'fui-Tag__media', icon: 'fui-Tag__icon', primaryText: 'fui-Tag__primaryText', secondaryText: 'fui-Tag__secondaryText', @@ -18,29 +19,74 @@ export const tagClassNames: SlotClassNames = { const useStyles = makeStyles({ root: { display: 'inline-flex', + height: '32px', + width: 'fit-content', + ...shorthands.borderRadius(tokens.borderRadiusMedium), + + ...shorthands.outline('1px', 'solid', 'red'), + + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForeground2, + }, + rootCircular: { + ...shorthands.borderRadius(tokens.borderRadiusCircular), }, + + media: { + alignSelf: 'center', + paddingLeft: tokens.spacingHorizontalXXS, + paddingRight: tokens.spacingHorizontalS, + }, + content: { display: 'inline-grid', - gridTemplateColumns: 'auto 8px auto auto 8px auto', gridTemplateRows: '1fr auto auto 1fr', gridTemplateAreas: ` - "avatar . icon . ." - "avatar . icon primary ." - "avatar . icon secondary ." - "avatar . icon . ." + "icon . " + "icon primary " + "icon secondary" + "icon . " `, + paddingRight: tokens.spacingHorizontalS, }, - avatar: { - alignSelf: 'center', - ...shorthands.gridArea('avatar'), + textOnlyContent: { + paddingLeft: tokens.spacingHorizontalS, + }, + dismissableContent: { + paddingRight: '2px', }, + icon: { + display: 'flex', alignSelf: 'center', ...shorthands.gridArea('icon'), + paddingLeft: '6px', + paddingRight: '2px', + }, + primaryText: { + gridColumnStart: 'primary', + gridRowStart: 'primary', + gridRowEnd: 'secondary', + ...typographyStyles.body1, + paddingLeft: tokens.spacingHorizontalXXS, + paddingRight: tokens.spacingHorizontalXXS, + }, + primaryTextWithSecondaryText: { + ...shorthands.gridArea('primary'), + ...typographyStyles.caption1, + }, + secondaryText: { + ...shorthands.gridArea('secondary'), + paddingLeft: tokens.spacingHorizontalXXS, + paddingRight: tokens.spacingHorizontalXXS, + ...typographyStyles.caption2, + }, + + dismissButton: { + ...shorthands.padding('0px'), + marginRight: '6px', + minWidth: '20px', }, - primaryText: { ...shorthands.gridArea('primary') }, - secondaryText: { ...shorthands.gridArea('secondary') }, - dismissButton: {}, // TODO add additional classes for different states and/or slots }); @@ -50,12 +96,24 @@ const useStyles = makeStyles({ */ export const useTagStyles_unstable = (state: TagState): TagState => { const styles = useStyles(); - state.root.className = mergeClasses(tagClassNames.root, styles.root, state.root.className); + state.root.className = mergeClasses( + tagClassNames.root, + styles.root, + state.shape === 'circular' && styles.rootCircular, + state.root.className, + ); if (state.content) { - state.content.className = mergeClasses(tagClassNames.content, styles.content, state.content.className); + state.content.className = mergeClasses( + tagClassNames.content, + styles.content, + !state.media && !state.icon && styles.textOnlyContent, + state.dismissButton && styles.dismissableContent, + state.content.className, + ); } - if (state.avatar) { - state.avatar.className = mergeClasses(tagClassNames.avatar, styles.avatar, state.avatar.className); + + if (state.media) { + state.media.className = mergeClasses(tagClassNames.media, styles.media, state.media.className); } if (state.icon) { state.icon.className = mergeClasses(tagClassNames.icon, styles.icon, state.icon.className); @@ -64,6 +122,7 @@ export const useTagStyles_unstable = (state: TagState): TagState => { state.primaryText.className = mergeClasses( tagClassNames.primaryText, styles.primaryText, + state.secondaryText && styles.primaryTextWithSecondaryText, state.primaryText.className, ); } diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index c6639a6746769a..651ae411b46802 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -1,20 +1,157 @@ import * as React from 'react'; import { Tag, TagProps } from '@fluentui/react-tags'; -import { Calendar3Day28Regular } from '@fluentui/react-icons'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; +import { Avatar } from '@fluentui/react-avatar'; export const Default = (props: Partial) => ( - } - primaryText="Primary text" - secondaryText="Secondary text" - dismissable={true} - {...props} - /> +
+
+ + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + > + Primary text + + + } + dismissable={true} + {...props} + > + Primary text + + + } + {...props} + > + Primary text + + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + {...props} + > + Primary text + + } dismissable={true} {...props}> + Primary text + + } {...props}> + Primary text + + Primary text +
+
+ + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + > + Primary text + + + } + dismissable={true} + {...props} + > + Primary text + + + } + {...props} + > + Primary text + + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + {...props} + > + Primary text + + } dismissable={true} {...props}> + Primary text + + } {...props}> + Primary text + + + Primary text + +
+
); diff --git a/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx new file mode 100644 index 00000000000000..874b5780cd21a1 --- /dev/null +++ b/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { Avatar } from '@fluentui/react-avatar'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; + +import { Tag } from '@fluentui/react-tags'; + +export const Dismiss = () => ( +
+ Primary text + }> + Primary text + + } secondaryText="Secondary text"> + Primary text + +
+); + +Dismiss.storyName = 'Dismiss'; +Dismiss.parameters = { + docs: { + description: { + story: 'A tag can have a button that dismisses it', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/Tag/TagIcon.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagIcon.stories.tsx new file mode 100644 index 00000000000000..28e79a1dc3e3f4 --- /dev/null +++ b/packages/react-components/react-tags/stories/Tag/TagIcon.stories.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; +import { Tag } from '@fluentui/react-tags'; + +export const Icon = () => }>Primary text; + +Icon.storyName = 'Icon'; +Icon.parameters = { + docs: { + description: { + story: 'A Tag can render a custom icon if provided.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx new file mode 100644 index 00000000000000..45d655fc8ef955 --- /dev/null +++ b/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import { Avatar } from '@fluentui/react-avatar'; + +import { Tag } from '@fluentui/react-tags'; + +export const Media = () => }>Primary text; + +Media.storyName = 'Media'; +Media.parameters = { + docs: { + description: { + story: 'A tag can render a media, for example an Avatar.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/Tag/TagSecondaryText.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagSecondaryText.stories.tsx new file mode 100644 index 00000000000000..1f16e2b7b0815d --- /dev/null +++ b/packages/react-components/react-tags/stories/Tag/TagSecondaryText.stories.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import { Tag } from '@fluentui/react-tags'; + +export const SecondaryText = () => Primary text; + +SecondaryText.storyName = 'SecondaryText'; +SecondaryText.parameters = { + docs: { + description: { + story: 'A Tag can have a secondary text.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx new file mode 100644 index 00000000000000..54205219a6a802 --- /dev/null +++ b/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import { Avatar } from '@fluentui/react-avatar'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; + +import { Tag } from '@fluentui/react-tags'; + +export const Shape = () => ( +
+
+ }>Rounded + }> + Circular + +
+
+ } secondaryText="Secondary text"> + Rounded + + } secondaryText="Secondary text"> + Circular + +
+
+); + +Shape.storyName = 'Shape'; +Shape.parameters = { + docs: { + description: { + story: 'A tag can be rounded or circular,', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/Tag/index.stories.tsx b/packages/react-components/react-tags/stories/Tag/index.stories.tsx index e0fb64458e077f..2aea59a32ff446 100644 --- a/packages/react-components/react-tags/stories/Tag/index.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/index.stories.tsx @@ -4,6 +4,11 @@ import descriptionMd from './TagDescription.md'; import bestPracticesMd from './TagBestPractices.md'; export { Default } from './TagDefault.stories'; +export { Icon } from './TagIcon.stories'; +export { Media } from './TagMedia.stories'; +export { SecondaryText } from './TagSecondaryText.stories'; +export { Dismiss } from './TagDismiss.stories'; +export { Shape } from './TagShape.stories'; export default { title: 'Preview Components/Tag', From a606ec2f7777dcf18fa466767bb57e3de90de5d3 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Thu, 27 Apr 2023 23:58:25 +0800 Subject: [PATCH 23/62] fix after merge --- .../src/components/Tag/useTagStyles.ts | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 146c862ecb24cd..94a4177c9c3f0d 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -87,28 +87,6 @@ const useStyles = makeStyles({ marginRight: '6px', minWidth: '20px', }, - content: { - display: 'inline-grid', - gridTemplateColumns: 'auto 8px auto auto 8px auto', - gridTemplateRows: '1fr auto auto 1fr', - gridTemplateAreas: ` - "avatar . icon . ." - "avatar . icon primary ." - "avatar . icon secondary ." - "avatar . icon . ." - `, - }, - avatar: { - alignSelf: 'center', - ...shorthands.gridArea('avatar'), - }, - icon: { - alignSelf: 'center', - ...shorthands.gridArea('icon'), - }, - primaryText: { ...shorthands.gridArea('primary') }, - secondaryText: { ...shorthands.gridArea('secondary') }, - dismissButton: {}, // TODO add additional classes for different states and/or slots }); From 756122b055be87a9c364325a43d61c3698c85b64 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 00:20:37 +0800 Subject: [PATCH 24/62] put media in content --- .../react-tags/src/components/Tag/Tag.types.ts | 2 +- .../react-tags/src/components/Tag/renderTag.tsx | 10 +++++----- .../react-tags/src/components/Tag/useTag.tsx | 3 --- .../react-tags/src/components/Tag/useTagStyles.ts | 9 +++++---- 4 files changed, 11 insertions(+), 13 deletions(-) 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 45763b093eabd5..79ba7a1595ffed 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 @@ -22,7 +22,7 @@ export type TagSlots = { */ content: Slot<'div'>; - icon?: Slot<'span'>; + icon: Slot<'span'>; /** * Main text for the Tag. Children of the root slot are automatically rendered here diff --git a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx index 9d63c4ba66cb6a..d8dc70d2f516e3 100644 --- a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx @@ -16,13 +16,13 @@ export const renderTag_unstable = (state: TagState, contextValues: TagContextVal // TODO Add additional slots in the appropriate place return ( - {slots.media && ( - - - - )} {slots.content && ( + {slots.media && ( + + + + )} {slots.icon && } {slots.primaryText && ( {slotProps.root.children} diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index e36761d7a21d90..a6418e1845a3fe 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -4,7 +4,6 @@ import { DismissRegular } from '@fluentui/react-icons'; import type { TagProps, TagState } from './Tag.types'; import { Button } from '@fluentui/react-button'; -// TODO verify map const tagAvatarSizeMap = { medium: 28, small: 24, @@ -67,9 +66,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T dismissButton: resolveShorthand(props.dismissButton, { required: props.dismissable, defaultProps: { - disabled, appearance: 'transparent', - type: 'button', icon: , }, }), diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 94a4177c9c3f0d..7d67ffcdb55f10 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -33,6 +33,7 @@ const useStyles = makeStyles({ }, media: { + ...shorthands.gridArea('media'), alignSelf: 'center', paddingLeft: tokens.spacingHorizontalXXS, paddingRight: tokens.spacingHorizontalS, @@ -42,10 +43,10 @@ const useStyles = makeStyles({ display: 'inline-grid', gridTemplateRows: '1fr auto auto 1fr', gridTemplateAreas: ` - "icon . " - "icon primary " - "icon secondary" - "icon . " + "media icon . " + "media icon primary " + "media icon secondary" + "media icon . " `, paddingRight: tokens.spacingHorizontalS, }, From 6bb2bcd4a04ac117a598a74efa29855fae3d8ead Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:20:50 +0800 Subject: [PATCH 25/62] try content as button on tag and it works fine --- .../src/components/Tag/Tag.types.ts | 3 +- .../react-tags/src/components/Tag/useTag.tsx | 11 +++- .../src/components/Tag/useTagStyles.ts | 55 +++++++++++++++++++ .../stories/Tag/TagDefault.stories.tsx | 22 ++++++-- 4 files changed, 83 insertions(+), 8 deletions(-) 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 79ba7a1595ffed..32b4846203c205 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 @@ -47,6 +47,7 @@ export type TagProps = ComponentProps> & { disabled?: boolean; checked?: boolean; dismissable?: boolean; + contentAsButton?: boolean; }; /** @@ -54,7 +55,7 @@ export type TagProps = ComponentProps> & { */ export type TagState = ComponentState & Required< - Pick & { + Pick & { avatarSize: AvatarSize | undefined; avatarShape: AvatarShape | undefined; } diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index a6418e1845a3fe..d987bd87765756 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -32,6 +32,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T shape = 'rounded', size = 'medium', appearance = 'filled-lighter', + contentAsButton = false, } = props; return { @@ -50,6 +51,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T shape, size, appearance, + contentAsButton, root: getNativeElementProps('div', { ref, ...props, @@ -58,7 +60,14 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T avatarShape: tagAvatarShapeMap[shape], media: resolveShorthand(props.media), - content: resolveShorthand(props.content, { required: !!props.primaryText || !!props.children }), + content: resolveShorthand(props.content, { + required: !!props.primaryText || !!props.children, + defaultProps: contentAsButton + ? { + tabIndex: 0, + } + : undefined, + }), icon: resolveShorthand(props.icon), primaryText: resolveShorthand(props.primaryText, { required: true }), secondaryText: resolveShorthand(props.secondaryText), diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 7d67ffcdb55f10..09bd858eb5a2c1 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -2,6 +2,7 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagSlots, TagState } from './Tag.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; import { tokens, typographyStyles } from '@fluentui/react-theme'; +import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', @@ -92,11 +93,56 @@ const useStyles = makeStyles({ // TODO add additional classes for different states and/or slots }); +/** + * Styles for focus indicator when the content of tag is a focusable button + */ +const useFocusIndicatorStyles = makeStyles({ + contentAsButton: { + paddingRight: tokens.spacingHorizontalS, + position: 'relative', + ...createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorTransparentStroke), + ...shorthands.borderRadius(tokens.borderRadiusMedium), + ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorTransparentStroke), + boxShadow: ` + ${tokens.shadow4}, + 0 0 0 2px ${tokens.colorStrokeFocus2} + `, + zIndex: 1, + }), + }, + circular: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular)), + dismissable: createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusNone, + borderBottomRightRadius: tokens.borderRadiusNone, + }), + + dismissButton: { + marginRight: '0px', + paddingLeft: '6px', + paddingRight: '6px', + borderLeftColor: tokens.colorNeutralStroke1, + borderTopLeftRadius: tokens.borderRadiusNone, + borderBottomLeftRadius: tokens.borderRadiusNone, + + ...createCustomFocusIndicatorStyle({ + borderTopLeftRadius: tokens.borderRadiusNone, + borderBottomLeftRadius: tokens.borderRadiusNone, + }), + }, + dismissButtonCircular: createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusCircular, + borderBottomRightRadius: tokens.borderRadiusCircular, + }), +}); + /** * Apply styling to the Tag slots based on the state */ export const useTagStyles_unstable = (state: TagState): TagState => { const styles = useStyles(); + const focusStyles = useFocusIndicatorStyles(); + state.root.className = mergeClasses( tagClassNames.root, styles.root, @@ -109,6 +155,11 @@ export const useTagStyles_unstable = (state: TagState): TagState => { styles.content, !state.media && !state.icon && styles.textOnlyContent, state.dismissButton && styles.dismissableContent, + + state.contentAsButton && focusStyles.contentAsButton, + state.contentAsButton && state.shape === 'circular' && focusStyles.circular, + state.contentAsButton && state.dismissButton && focusStyles.dismissable, + state.content.className, ); } @@ -138,6 +189,10 @@ export const useTagStyles_unstable = (state: TagState): TagState => { state.dismissButton.className = mergeClasses( tagClassNames.dismissButton, styles.dismissButton, + + state.contentAsButton && focusStyles.dismissButton, + state.contentAsButton && state.shape === 'circular' && focusStyles.dismissButtonCircular, + state.dismissButton.className, ); } diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index 651ae411b46802..7aead879b9edec 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -7,6 +7,7 @@ export const Default = (props: Partial) => (
) => ( Primary text ) => ( Primary text ) => ( Primary text } // primaryText="Primary text" secondaryText="Secondary text" @@ -68,16 +72,19 @@ export const Default = (props: Partial) => ( > Primary text - } dismissable={true} {...props}> + } dismissable={true} {...props}> Primary text - } {...props}> + } {...props}> + Primary text + + Primary text - Primary text
) => ( Primary text ) => ( Primary text ) => ( Primary text } // primaryText="Primary text" @@ -143,13 +153,13 @@ export const Default = (props: Partial) => ( > Primary text - } dismissable={true} {...props}> + } dismissable={true} {...props}> Primary text - } {...props}> + } {...props}> Primary text - + Primary text
From 2849eeb3e68fde67b1a987407365ba3ff89eef2f Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:39:38 +0800 Subject: [PATCH 26/62] Revert "try content as button on tag and it works fine" This reverts commit 6bb2bcd4a04ac117a598a74efa29855fae3d8ead. --- .../src/components/Tag/Tag.types.ts | 3 +- .../react-tags/src/components/Tag/useTag.tsx | 11 +--- .../src/components/Tag/useTagStyles.ts | 55 ------------------- .../stories/Tag/TagDefault.stories.tsx | 22 ++------ 4 files changed, 8 insertions(+), 83 deletions(-) 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 32b4846203c205..79ba7a1595ffed 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 @@ -47,7 +47,6 @@ export type TagProps = ComponentProps> & { disabled?: boolean; checked?: boolean; dismissable?: boolean; - contentAsButton?: boolean; }; /** @@ -55,7 +54,7 @@ export type TagProps = ComponentProps> & { */ export type TagState = ComponentState & Required< - Pick & { + Pick & { avatarSize: AvatarSize | undefined; avatarShape: AvatarShape | undefined; } diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index d987bd87765756..a6418e1845a3fe 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -32,7 +32,6 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T shape = 'rounded', size = 'medium', appearance = 'filled-lighter', - contentAsButton = false, } = props; return { @@ -51,7 +50,6 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T shape, size, appearance, - contentAsButton, root: getNativeElementProps('div', { ref, ...props, @@ -60,14 +58,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T avatarShape: tagAvatarShapeMap[shape], media: resolveShorthand(props.media), - content: resolveShorthand(props.content, { - required: !!props.primaryText || !!props.children, - defaultProps: contentAsButton - ? { - tabIndex: 0, - } - : undefined, - }), + content: resolveShorthand(props.content, { required: !!props.primaryText || !!props.children }), icon: resolveShorthand(props.icon), primaryText: resolveShorthand(props.primaryText, { required: true }), secondaryText: resolveShorthand(props.secondaryText), diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 09bd858eb5a2c1..7d67ffcdb55f10 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -2,7 +2,6 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagSlots, TagState } from './Tag.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; import { tokens, typographyStyles } from '@fluentui/react-theme'; -import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', @@ -93,56 +92,11 @@ const useStyles = makeStyles({ // TODO add additional classes for different states and/or slots }); -/** - * Styles for focus indicator when the content of tag is a focusable button - */ -const useFocusIndicatorStyles = makeStyles({ - contentAsButton: { - paddingRight: tokens.spacingHorizontalS, - position: 'relative', - ...createCustomFocusIndicatorStyle({ - ...shorthands.borderColor(tokens.colorTransparentStroke), - ...shorthands.borderRadius(tokens.borderRadiusMedium), - ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorTransparentStroke), - boxShadow: ` - ${tokens.shadow4}, - 0 0 0 2px ${tokens.colorStrokeFocus2} - `, - zIndex: 1, - }), - }, - circular: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular)), - dismissable: createCustomFocusIndicatorStyle({ - borderTopRightRadius: tokens.borderRadiusNone, - borderBottomRightRadius: tokens.borderRadiusNone, - }), - - dismissButton: { - marginRight: '0px', - paddingLeft: '6px', - paddingRight: '6px', - borderLeftColor: tokens.colorNeutralStroke1, - borderTopLeftRadius: tokens.borderRadiusNone, - borderBottomLeftRadius: tokens.borderRadiusNone, - - ...createCustomFocusIndicatorStyle({ - borderTopLeftRadius: tokens.borderRadiusNone, - borderBottomLeftRadius: tokens.borderRadiusNone, - }), - }, - dismissButtonCircular: createCustomFocusIndicatorStyle({ - borderTopRightRadius: tokens.borderRadiusCircular, - borderBottomRightRadius: tokens.borderRadiusCircular, - }), -}); - /** * Apply styling to the Tag slots based on the state */ export const useTagStyles_unstable = (state: TagState): TagState => { const styles = useStyles(); - const focusStyles = useFocusIndicatorStyles(); - state.root.className = mergeClasses( tagClassNames.root, styles.root, @@ -155,11 +109,6 @@ export const useTagStyles_unstable = (state: TagState): TagState => { styles.content, !state.media && !state.icon && styles.textOnlyContent, state.dismissButton && styles.dismissableContent, - - state.contentAsButton && focusStyles.contentAsButton, - state.contentAsButton && state.shape === 'circular' && focusStyles.circular, - state.contentAsButton && state.dismissButton && focusStyles.dismissable, - state.content.className, ); } @@ -189,10 +138,6 @@ export const useTagStyles_unstable = (state: TagState): TagState => { state.dismissButton.className = mergeClasses( tagClassNames.dismissButton, styles.dismissButton, - - state.contentAsButton && focusStyles.dismissButton, - state.contentAsButton && state.shape === 'circular' && focusStyles.dismissButtonCircular, - state.dismissButton.className, ); } diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index 7aead879b9edec..651ae411b46802 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -7,7 +7,6 @@ export const Default = (props: Partial) => (
) => ( Primary text ) => ( Primary text ) => ( Primary text } // primaryText="Primary text" secondaryText="Secondary text" @@ -72,19 +68,16 @@ export const Default = (props: Partial) => ( > Primary text - } dismissable={true} {...props}> + } dismissable={true} {...props}> Primary text - } {...props}> - Primary text - - + } {...props}> Primary text + Primary text
) => ( Primary text ) => ( Primary text ) => ( Primary text } // primaryText="Primary text" @@ -153,13 +143,13 @@ export const Default = (props: Partial) => ( > Primary text - } dismissable={true} {...props}> + } dismissable={true} {...props}> Primary text - } {...props}> + } {...props}> Primary text - + Primary text
From 2e19dca36ad1ebe345a98ebbef148633203aa3fb Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:41:12 +0800 Subject: [PATCH 27/62] TagButton implementation --- .../react-tags/src/components/Tag/Tag.tsx | 2 +- .../src/components/TagButton/TagButton.tsx | 3 +- .../components/TagButton/TagButton.types.ts | 27 +-- .../components/TagButton/renderTagButton.tsx | 21 ++- .../src/components/TagButton/useTagButton.tsx | 54 +----- .../TagButton/useTagButtonStyles.ts | 131 +++++++++++--- .../Tag => utils}/useTagContextValues.ts | 2 +- .../TagButton/TagButtonDefault.stories.tsx | 169 ++++++++++++++++-- 8 files changed, 296 insertions(+), 113 deletions(-) rename packages/react-components/react-tags/src/{components/Tag => utils}/useTagContextValues.ts (82%) diff --git a/packages/react-components/react-tags/src/components/Tag/Tag.tsx b/packages/react-components/react-tags/src/components/Tag/Tag.tsx index eaeaa678d4430b..37f7399ec8b019 100644 --- a/packages/react-components/react-tags/src/components/Tag/Tag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/Tag.tsx @@ -4,7 +4,7 @@ import { renderTag_unstable } from './renderTag'; import { useTagStyles_unstable } from './useTagStyles'; import type { TagProps } from './Tag.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; -import { useTagContextValues_unstable } from './useTagContextValues'; +import { useTagContextValues_unstable } from '../../utils/useTagContextValues'; /** * Tag component - TODO: add more docs diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx index aa55c30c625e33..d00f55a703b037 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx @@ -4,6 +4,7 @@ import { renderTagButton_unstable } from './renderTagButton'; import { useTagButtonStyles_unstable } from './useTagButtonStyles'; import type { TagButtonProps } from './TagButton.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import { useTagContextValues_unstable } from '../../utils/useTagContextValues'; /** * TagButton component - TODO: add more docs @@ -12,7 +13,7 @@ export const TagButton: ForwardRefComponent = React.forwardRef(( const state = useTagButton_unstable(props, ref); useTagButtonStyles_unstable(state); - return renderTagButton_unstable(state); + return renderTagButton_unstable(state, useTagContextValues_unstable(state)); }); TagButton.displayName = 'TagButton'; diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts b/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts index 807800361a382e..ae5531c83167e0 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.types.ts @@ -1,30 +1,15 @@ -import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; -import { Avatar } from '@fluentui/react-avatar'; +import { TagContextValues, TagProps, TagSlots, TagState } from '../Tag/index'; -export type TagButtonSlots = { - root: NonNullable>; - contentButton?: Slot<'button'>; - avatar?: Slot; - icon?: Slot<'span'>; - primaryText?: Slot<'span'>; - secondaryText?: Slot<'span'>; - dismissButton?: NonNullable>; -}; +export type TagButtonContextValues = TagContextValues; + +export type TagButtonSlots = TagSlots; /** * TagButton Props */ -export type TagButtonProps = ComponentProps & { - size?: 'extra-small' | 'small' | 'medium'; - shape?: 'rounded' | 'circular'; - appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; - disabled?: boolean; - checked?: boolean; - dismissable?: boolean; -}; +export type TagButtonProps = TagProps; /** * State used in rendering TagButton */ -export type TagButtonState = ComponentState & - Required>; +export type TagButtonState = TagState; diff --git a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx index 17836bf23f9c6d..797c3e5301c11b 100644 --- a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx @@ -4,24 +4,31 @@ import { createElement } from '@fluentui/react-jsx-runtime'; import { getSlotsNext } from '@fluentui/react-utilities'; -import type { TagButtonState, TagButtonSlots } from './TagButton.types'; +import type { TagButtonState, TagButtonSlots, TagButtonContextValues } from './TagButton.types'; +import { AvatarContextProvider } from '@fluentui/react-avatar'; /** * Render the final JSX of TagButton */ -export const renderTagButton_unstable = (state: TagButtonState) => { +export const renderTagButton_unstable = (state: TagButtonState, contextValues: TagButtonContextValues) => { const { slots, slotProps } = getSlotsNext(state); // TODO Add additional slots in the appropriate place return ( - {slots.contentButton && ( - - {slots.avatar && } + {slots.content && ( + + {slots.media && ( + + + + )} {slots.icon && } - {slots.primaryText && } + {slots.primaryText && ( + {slotProps.root.children} + )} {slots.secondaryText && } - + )} {slots.dismissButton && state.dismissable && } diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx index 5a359ada2eec39..8308983b37ae1d 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -1,8 +1,7 @@ import * as React from 'react'; -import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; +import { resolveShorthand } from '@fluentui/react-utilities'; import type { TagButtonProps, TagButtonState } from './TagButton.types'; -import { Dismiss16Filled } from '@fluentui/react-icons'; -import { Avatar } from '@fluentui/react-avatar'; +import { useTag_unstable } from '../Tag/index'; /** * Create the state required to render TagButton. @@ -14,47 +13,12 @@ import { Avatar } from '@fluentui/react-avatar'; * @param ref - reference to root HTMLElement of TagButton */ export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { - const { - checked = false, - disabled = false, - dismissable = false, - shape = 'rounded', - size = 'medium', - appearance = 'filled-lighter', - } = props; - - return { - components: { - root: 'div', - contentButton: 'button', - avatar: Avatar, - icon: 'span', - primaryText: 'span', - secondaryText: 'span', - dismissButton: 'button', + const state = useTag_unstable(props, ref); + state.content = resolveShorthand(props.content, { + required: !!props.primaryText || !!props.children, + defaultProps: { + tabIndex: 0, }, - checked, - disabled, - dismissable, - shape, - size, - appearance, - root: getNativeElementProps('div', { - ref, - ...props, - }), - contentButton: resolveShorthand(props.contentButton, { required: true }), - avatar: resolveShorthand(props.avatar), - icon: resolveShorthand(props.icon), - primaryText: resolveShorthand(props.primaryText), - secondaryText: resolveShorthand(props.secondaryText), - dismissButton: resolveShorthand(props.dismissButton, { - required: true, - defaultProps: { - disabled, - type: 'button', - children: , - }, - }), - }; + }); + return state; }; diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts index c03ad488ae53f5..24ea9dc57035a6 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts @@ -1,11 +1,13 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagButtonSlots, TagButtonState } from './TagButton.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; +import { createCustomFocusIndicatorStyle } from '../../../../react-tabster/src/index'; +import { tokens, typographyStyles } from '../../../../react-theme/src/index'; export const tagButtonClassNames: SlotClassNames = { root: 'fui-TagButton', - contentButton: 'fui-TagButton__contentButton', - avatar: 'fui-TagButton__avatar', + content: 'fui-TagButton__content', + media: 'fui-TagButton__media', icon: 'fui-TagButton__icon', primaryText: 'fui-TagButton__primaryText', secondaryText: 'fui-TagButton__secondaryText', @@ -18,29 +20,100 @@ export const tagButtonClassNames: SlotClassNames = { const useStyles = makeStyles({ root: { display: 'inline-flex', + height: '32px', + width: 'fit-content', + ...shorthands.borderRadius(tokens.borderRadiusMedium), + + ...shorthands.outline('1px', 'solid', 'red'), + + backgroundColor: tokens.colorNeutralBackground3, + color: tokens.colorNeutralForeground2, + }, + rootCircular: { + ...shorthands.borderRadius(tokens.borderRadiusCircular), + }, + + media: { + ...shorthands.gridArea('media'), + alignSelf: 'center', + paddingLeft: tokens.spacingHorizontalXXS, + paddingRight: tokens.spacingHorizontalS, }, - contentButton: { + + content: { display: 'inline-grid', - gridTemplateColumns: 'auto 8px auto auto 8px auto', gridTemplateRows: '1fr auto auto 1fr', gridTemplateAreas: ` - "avatar . icon . ." - "avatar . icon primary ." - "avatar . icon secondary ." - "avatar . icon . ." + "media icon . " + "media icon primary " + "media icon secondary" + "media icon . " + `, + paddingRight: tokens.spacingHorizontalS, + + position: 'relative', + ...createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorTransparentStroke), + ...shorthands.borderRadius(tokens.borderRadiusMedium), + ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorTransparentStroke), + boxShadow: ` + ${tokens.shadow4}, + 0 0 0 2px ${tokens.colorStrokeFocus2} `, + zIndex: 1, + }), }, - avatar: { - alignSelf: 'center', - ...shorthands.gridArea('avatar'), + textOnlyContent: { + paddingLeft: tokens.spacingHorizontalS, }, + circularContent: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular)), + dismissableContent: createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusNone, + borderBottomRightRadius: tokens.borderRadiusNone, + }), + icon: { + display: 'flex', alignSelf: 'center', ...shorthands.gridArea('icon'), + paddingLeft: '6px', + paddingRight: '2px', }, - primaryText: { ...shorthands.gridArea('primary') }, - secondaryText: { ...shorthands.gridArea('secondary') }, - dismissButton: {}, + primaryText: { + gridColumnStart: 'primary', + gridRowStart: 'primary', + gridRowEnd: 'secondary', + ...typographyStyles.body1, + paddingLeft: tokens.spacingHorizontalXXS, + paddingRight: tokens.spacingHorizontalXXS, + }, + primaryTextWithSecondaryText: { + ...shorthands.gridArea('primary'), + ...typographyStyles.caption1, + }, + secondaryText: { + ...shorthands.gridArea('secondary'), + paddingLeft: tokens.spacingHorizontalXXS, + paddingRight: tokens.spacingHorizontalXXS, + ...typographyStyles.caption2, + }, + + dismissButton: { + minWidth: '20px', + ...shorthands.padding('0px', '6px'), + borderLeftColor: tokens.colorNeutralStroke1, + borderTopLeftRadius: tokens.borderRadiusNone, + borderBottomLeftRadius: tokens.borderRadiusNone, + + ...createCustomFocusIndicatorStyle({ + borderTopLeftRadius: tokens.borderRadiusNone, + borderBottomLeftRadius: tokens.borderRadiusNone, + }), + }, + dismissButtonCircular: createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusCircular, + borderBottomRightRadius: tokens.borderRadiusCircular, + }), // TODO add additional classes for different states and/or slots }); @@ -50,16 +123,28 @@ const useStyles = makeStyles({ */ export const useTagButtonStyles_unstable = (state: TagButtonState): TagButtonState => { const styles = useStyles(); - state.root.className = mergeClasses(tagButtonClassNames.root, styles.root, state.root.className); - if (state.contentButton) { - state.contentButton.className = mergeClasses( - tagButtonClassNames.contentButton, - styles.contentButton, - state.contentButton.className, + + state.root.className = mergeClasses( + tagButtonClassNames.root, + styles.root, + state.shape === 'circular' && styles.rootCircular, + state.root.className, + ); + if (state.content) { + state.content.className = mergeClasses( + tagButtonClassNames.content, + styles.content, + !state.media && !state.icon && styles.textOnlyContent, + + state.shape === 'circular' && styles.circularContent, + state.dismissButton && styles.dismissableContent, + + state.content.className, ); } - if (state.avatar) { - state.avatar.className = mergeClasses(tagButtonClassNames.avatar, styles.avatar, state.avatar.className); + + if (state.media) { + state.media.className = mergeClasses(tagButtonClassNames.media, styles.media, state.media.className); } if (state.icon) { state.icon.className = mergeClasses(tagButtonClassNames.icon, styles.icon, state.icon.className); @@ -68,6 +153,7 @@ export const useTagButtonStyles_unstable = (state: TagButtonState): TagButtonSta state.primaryText.className = mergeClasses( tagButtonClassNames.primaryText, styles.primaryText, + state.secondaryText && styles.primaryTextWithSecondaryText, state.primaryText.className, ); } @@ -82,6 +168,7 @@ export const useTagButtonStyles_unstable = (state: TagButtonState): TagButtonSta state.dismissButton.className = mergeClasses( tagButtonClassNames.dismissButton, styles.dismissButton, + state.shape === 'circular' && styles.dismissButtonCircular, state.dismissButton.className, ); } diff --git a/packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts b/packages/react-components/react-tags/src/utils/useTagContextValues.ts similarity index 82% rename from packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts rename to packages/react-components/react-tags/src/utils/useTagContextValues.ts index d9ee8146af144a..d394a39d56c331 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagContextValues.ts +++ b/packages/react-components/react-tags/src/utils/useTagContextValues.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { TagState, TagContextValues } from './Tag.types'; +import { TagContextValues, TagState } from '../components/Tag/index'; export function useTagContextValues_unstable(state: TagState): TagContextValues { const { avatarSize, avatarShape } = state; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx index 08c2b41a875738..88a684498b7dc5 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx @@ -1,20 +1,159 @@ import * as React from 'react'; import { TagButton, TagButtonProps } from '@fluentui/react-tags'; -import { Calendar3Day28Regular } from '@fluentui/react-icons'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; +import { Avatar } from '@fluentui/react-avatar'; export const Default = (props: Partial) => ( - } - primaryText="Primary text" - secondaryText="Secondary text" - dismissable={true} - {...props} - /> +
+
+ + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + > + Primary text + + + } + dismissable={true} + {...props} + > + Primary text + + + } + {...props} + > + Primary text + + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + {...props} + > + Primary text + + } dismissable={true} {...props}> + Primary text + + } {...props}> + Primary text + + + Primary text + +
+
+ + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + > + Primary text + + + } + dismissable={true} + {...props} + > + Primary text + + + } + {...props} + > + Primary text + + } + // primaryText="Primary text" + secondaryText="Secondary text" + dismissable={true} + {...props} + {...props} + > + Primary text + + } dismissable={true} {...props}> + Primary text + + } {...props}> + Primary text + + + Primary text + +
+
); From c5b1b4b9c1119795608c91de109ecb369fcefa6d Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:41:38 +0800 Subject: [PATCH 28/62] add tabster to dependency --- packages/react-components/react-tags/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index 189b83ea66614f..7f627eb3eca864 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -37,6 +37,7 @@ "@fluentui/react-button": "^9.3.10", "@fluentui/react-icons": "^2.0.196", "@fluentui/react-jsx-runtime": "9.0.0-alpha.2", + "@fluentui/react-tabster": "^9.6.5", "@fluentui/react-theme": "^9.1.7", "@fluentui/react-utilities": "^9.8.0", "@griffel/react": "^1.5.2", From 2cf6e73eef190f3a471b960a3a4e6de281aad01c Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:45:05 +0800 Subject: [PATCH 29/62] TagButton stories --- .../TagButton/TagButtonDismiss.stories.tsx | 30 +++++++++++++++++ .../TagButton/TagButtonIcon.stories.tsx | 14 ++++++++ .../TagButton/TagButtonMedia.stories.tsx | 17 ++++++++++ .../TagButtonSecondaryText.stories.tsx | 13 ++++++++ .../TagButton/TagButtonShape.stories.tsx | 33 +++++++++++++++++++ .../stories/TagButton/index.stories.tsx | 5 +++ 6 files changed, 112 insertions(+) create mode 100644 packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx create mode 100644 packages/react-components/react-tags/stories/TagButton/TagButtonIcon.stories.tsx create mode 100644 packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx create mode 100644 packages/react-components/react-tags/stories/TagButton/TagButtonSecondaryText.stories.tsx create mode 100644 packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx new file mode 100644 index 00000000000000..81b96cd176151e --- /dev/null +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import { Avatar } from '@fluentui/react-avatar'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; + +import { TagButton } from '@fluentui/react-tags'; + +export const Dismiss = () => ( +
+ Primary text + }> + Primary text + + } + secondaryText="Secondary text" + > + Primary text + +
+); + +Dismiss.storyName = 'Dismiss'; +Dismiss.parameters = { + docs: { + description: { + story: 'A TagButton can have a button that dismisses it', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonIcon.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonIcon.stories.tsx new file mode 100644 index 00000000000000..621e32e4db1c0e --- /dev/null +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonIcon.stories.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; +import { TagButton } from '@fluentui/react-tags'; + +export const Icon = () => }>Primary text; + +Icon.storyName = 'Icon'; +Icon.parameters = { + docs: { + description: { + story: 'A TagButton can render a custom icon if provided.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx new file mode 100644 index 00000000000000..11158694b62336 --- /dev/null +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { Avatar } from '@fluentui/react-avatar'; + +import { TagButton } from '@fluentui/react-tags'; + +export const Media = () => ( + }>Primary text +); + +Media.storyName = 'Media'; +Media.parameters = { + docs: { + description: { + story: 'A tag can render a media, for example an Avatar.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonSecondaryText.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonSecondaryText.stories.tsx new file mode 100644 index 00000000000000..26f4145b44d28c --- /dev/null +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonSecondaryText.stories.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import { TagButton } from '@fluentui/react-tags'; + +export const SecondaryText = () => Primary text; + +SecondaryText.storyName = 'SecondaryText'; +SecondaryText.parameters = { + docs: { + description: { + story: 'A TagButton can have a secondary text.', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx new file mode 100644 index 00000000000000..d1a59d7f5fd62a --- /dev/null +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import { Avatar } from '@fluentui/react-avatar'; +import { Calendar3Day20Regular } from '@fluentui/react-icons'; + +import { TagButton } from '@fluentui/react-tags'; + +export const Shape = () => ( +
+
+ }>Rounded + }> + Circular + +
+
+ } secondaryText="Secondary text"> + Rounded + + } secondaryText="Secondary text"> + Circular + +
+
+); + +Shape.storyName = 'Shape'; +Shape.parameters = { + docs: { + description: { + story: 'A TagButton can be rounded or circular,', + }, + }, +}; diff --git a/packages/react-components/react-tags/stories/TagButton/index.stories.tsx b/packages/react-components/react-tags/stories/TagButton/index.stories.tsx index 29de0d16523bf6..38b25718ef37c5 100644 --- a/packages/react-components/react-tags/stories/TagButton/index.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/index.stories.tsx @@ -4,6 +4,11 @@ import descriptionMd from './TagButtonDescription.md'; import bestPracticesMd from './TagButtonBestPractices.md'; export { Default } from './TagButtonDefault.stories'; +export { Icon } from './TagButtonIcon.stories'; +export { Media } from './TagButtonMedia.stories'; +export { SecondaryText } from './TagButtonSecondaryText.stories'; +export { Dismiss } from './TagButtonDismiss.stories'; +export { Shape } from './TagButtonShape.stories'; export default { title: 'Preview Components/TagButton', From 2d35934cf4f4aee27f956876a15de323c1102968 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:49:02 +0800 Subject: [PATCH 30/62] cleanup TODO and remove debug styles --- .../react-tags/src/components/Tag/renderTag.tsx | 1 - .../react-tags/src/components/Tag/useTagStyles.ts | 4 +--- .../react-tags/src/components/TagButton/renderTagButton.tsx | 1 - .../react-tags/src/components/TagButton/useTagButtonStyles.ts | 4 +--- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx index d8dc70d2f516e3..6e382ca446cb48 100644 --- a/packages/react-components/react-tags/src/components/Tag/renderTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/renderTag.tsx @@ -13,7 +13,6 @@ import { AvatarContextProvider } from '@fluentui/react-avatar'; export const renderTag_unstable = (state: TagState, contextValues: TagContextValues) => { const { slots, slotProps } = getSlotsNext(state); - // TODO Add additional slots in the appropriate place return ( {slots.content && ( diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts index 7d67ffcdb55f10..7dc652db7e381e 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts +++ b/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts @@ -23,8 +23,6 @@ const useStyles = makeStyles({ width: 'fit-content', ...shorthands.borderRadius(tokens.borderRadiusMedium), - ...shorthands.outline('1px', 'solid', 'red'), - backgroundColor: tokens.colorNeutralBackground3, color: tokens.colorNeutralForeground2, }, @@ -89,7 +87,7 @@ const useStyles = makeStyles({ minWidth: '20px', }, - // TODO add additional classes for different states and/or slots + // TODO add additional classes for fill/outline appearance, different sizes, and state }); /** diff --git a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx index 797c3e5301c11b..1d358dcaa60b5d 100644 --- a/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/renderTagButton.tsx @@ -13,7 +13,6 @@ import { AvatarContextProvider } from '@fluentui/react-avatar'; export const renderTagButton_unstable = (state: TagButtonState, contextValues: TagButtonContextValues) => { const { slots, slotProps } = getSlotsNext(state); - // TODO Add additional slots in the appropriate place return ( {slots.content && ( diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts index 24ea9dc57035a6..55fc0dc2005423 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts @@ -24,8 +24,6 @@ const useStyles = makeStyles({ width: 'fit-content', ...shorthands.borderRadius(tokens.borderRadiusMedium), - ...shorthands.outline('1px', 'solid', 'red'), - backgroundColor: tokens.colorNeutralBackground3, color: tokens.colorNeutralForeground2, }, @@ -115,7 +113,7 @@ const useStyles = makeStyles({ borderBottomRightRadius: tokens.borderRadiusCircular, }), - // TODO add additional classes for different states and/or slots + // TODO add additional classes for fill/outline appearance, different sizes, and state }); /** From b938f677fdcde44e5df3c8283c871ad27363f92c Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 12:58:35 +0800 Subject: [PATCH 31/62] add TODO --- .../react-tags/stories/Tag/TagDefault.stories.tsx | 1 + .../react-tags/stories/TagButton/TagButtonDefault.stories.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index 651ae411b46802..51866a2418f9ef 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -3,6 +3,7 @@ import { Tag, TagProps } from '@fluentui/react-tags'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { Avatar } from '@fluentui/react-avatar'; +// TODO I added many examples here for easier implementation. This story will be simplified to keep only the default example export const Default = (props: Partial) => (
diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx index 88a684498b7dc5..0956509a567da9 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx @@ -3,6 +3,7 @@ import { TagButton, TagButtonProps } from '@fluentui/react-tags'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { Avatar } from '@fluentui/react-avatar'; +// TODO I added many examples here for easier implementation. This story will be simplified to keep only the default example export const Default = (props: Partial) => (
From f67a4764f5ffbf8b27854a7869eae0754b640854 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 13:04:19 +0800 Subject: [PATCH 32/62] change --- ...-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json diff --git a/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json b/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json new file mode 100644 index 00000000000000..c12caf9cff69bd --- /dev/null +++ b/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: add `shape` to AvatarContext", + "packageName": "@fluentui/react-avatar", + "email": "yuanboxue@microsoft.com", + "dependentChangeType": "patch" +} From c8d157c2e955ffe1ef7ae28eeeadc209b7a145a6 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 13:07:26 +0800 Subject: [PATCH 33/62] default story cleanup --- .../stories/Tag/TagDefault.stories.tsx | 12 +----------- .../TagButton/TagButtonDefault.stories.tsx | 18 ++++++------------ 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index 51866a2418f9ef..573c5d95d6428d 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -19,7 +19,6 @@ export const Default = (props: Partial) => ( }} /> } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} @@ -59,14 +58,7 @@ export const Default = (props: Partial) => ( > Primary text - } - // primaryText="Primary text" - secondaryText="Secondary text" - dismissable={true} - {...props} - {...props} - > + } secondaryText="Secondary text" dismissable={true} {...props} {...props}> Primary text } dismissable={true} {...props}> @@ -91,7 +83,6 @@ export const Default = (props: Partial) => ( }} /> } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} @@ -136,7 +127,6 @@ export const Default = (props: Partial) => ( } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx index 0956509a567da9..d723f6e759abf9 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx @@ -19,7 +19,6 @@ export const Default = (props: Partial) => ( }} /> } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} @@ -61,7 +60,6 @@ export const Default = (props: Partial) => ( } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} @@ -69,15 +67,13 @@ export const Default = (props: Partial) => ( > Primary text - } dismissable={true} {...props}> + } dismissable={true} {...props}> Primary text - } {...props}> - Primary text - - + } {...props}> Primary text + Primary text
) => ( }} /> } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} @@ -138,7 +133,6 @@ export const Default = (props: Partial) => ( } - // primaryText="Primary text" secondaryText="Secondary text" dismissable={true} {...props} @@ -146,13 +140,13 @@ export const Default = (props: Partial) => ( > Primary text - } dismissable={true} {...props}> + } dismissable={true} {...props}> Primary text - } {...props}> + } {...props}> Primary text - + Primary text
From 4d2f0d7dce608a7be56bb1a982bcc245e1035d2c Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 13:21:21 +0800 Subject: [PATCH 34/62] update import from react-avatar to react-components in stories --- .../react-tags/stories/Tag/TagDefault.stories.tsx | 2 +- .../react-tags/stories/Tag/TagDismiss.stories.tsx | 2 +- .../react-tags/stories/Tag/TagMedia.stories.tsx | 2 +- .../react-tags/stories/Tag/TagShape.stories.tsx | 2 +- .../react-tags/stories/TagButton/TagButtonDefault.stories.tsx | 2 +- .../react-tags/stories/TagButton/TagButtonDismiss.stories.tsx | 2 +- .../react-tags/stories/TagButton/TagButtonMedia.stories.tsx | 2 +- .../react-tags/stories/TagButton/TagButtonShape.stories.tsx | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx index 573c5d95d6428d..85917d78a12326 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDefault.stories.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Tag, TagProps } from '@fluentui/react-tags'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; // TODO I added many examples here for easier implementation. This story will be simplified to keep only the default example export const Default = (props: Partial) => ( diff --git a/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx index 874b5780cd21a1..a57af0bc76c09b 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { Tag } from '@fluentui/react-tags'; diff --git a/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx index 45d655fc8ef955..941fbec7e0262a 100644 --- a/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagMedia.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; import { Tag } from '@fluentui/react-tags'; diff --git a/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx index 54205219a6a802..baca77e3be1f84 100644 --- a/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { Tag } from '@fluentui/react-tags'; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx index d723f6e759abf9..a9ef63153070a5 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDefault.stories.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { TagButton, TagButtonProps } from '@fluentui/react-tags'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; // TODO I added many examples here for easier implementation. This story will be simplified to keep only the default example export const Default = (props: Partial) => ( diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx index 81b96cd176151e..5793eafb7c1016 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { TagButton } from '@fluentui/react-tags'; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx index 11158694b62336..93db18c6b107ba 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonMedia.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; import { TagButton } from '@fluentui/react-tags'; diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx index d1a59d7f5fd62a..3c840f2e1b77c3 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-avatar'; +import { Avatar } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { TagButton } from '@fluentui/react-tags'; From af6fe3ed68fa524b0aae4fd6452f41e8f56e6cc5 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 13:32:29 +0800 Subject: [PATCH 35/62] fix crud --- packages/react-components/react-avatar/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-avatar/src/index.ts b/packages/react-components/react-avatar/src/index.ts index bf2090ee06055f..a7938b4eba2292 100644 --- a/packages/react-components/react-avatar/src/index.ts +++ b/packages/react-components/react-avatar/src/index.ts @@ -5,12 +5,12 @@ export { useAvatarStyles_unstable, useAvatar_unstable, } from './Avatar'; -// eslint-disable-next-line deprecation/deprecation export type { AvatarNamedColor, AvatarProps, AvatarSlots, AvatarState, + // eslint-disable-next-line deprecation/deprecation AvatarSizes, AvatarSize, AvatarShape, From 6846a7ad5089f8f15ad2c453085541533326535e Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 13:45:08 +0800 Subject: [PATCH 36/62] avatar api.md --- packages/react-components/react-avatar/etc/react-avatar.api.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-components/react-avatar/etc/react-avatar.api.md b/packages/react-components/react-avatar/etc/react-avatar.api.md index 0fa3e1b97b9fd8..b7208720df6341 100644 --- a/packages/react-components/react-avatar/etc/react-avatar.api.md +++ b/packages/react-components/react-avatar/etc/react-avatar.api.md @@ -137,6 +137,9 @@ export type AvatarProps = Omit, 'color'> & { size?: AvatarSize; }; +// @public +export type AvatarShape = 'circular' | 'square'; + // @public export type AvatarSize = 16 | 20 | 24 | 28 | 32 | 36 | 40 | 48 | 56 | 64 | 72 | 96 | 120 | 128; From 5c267fe6a9f77793d2559b77675772603e30c7d6 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 13:46:05 +0800 Subject: [PATCH 37/62] tags api.md --- .../react-tags/etc/react-tags.api.md | 48 ++++++++----------- 1 file changed, 19 insertions(+), 29 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 659e2b81f72266..088d4e3b1e4e62 100644 --- a/packages/react-components/react-tags/etc/react-tags.api.md +++ b/packages/react-components/react-tags/etc/react-tags.api.md @@ -6,7 +6,9 @@ /// -import { Avatar } from '@fluentui/react-avatar'; +import { AvatarShape } from '@fluentui/react-avatar'; +import { AvatarSize } from '@fluentui/react-avatar'; +import { Button } from '@fluentui/react-button'; import type { ComponentProps } from '@fluentui/react-utilities'; import type { ComponentState } from '@fluentui/react-utilities'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; @@ -15,10 +17,10 @@ import type { Slot } from '@fluentui/react-utilities'; import type { SlotClassNames } from '@fluentui/react-utilities'; // @public -export const renderTag_unstable: (state: TagState) => JSX.Element; +export const renderTag_unstable: (state: TagState, contextValues: TagContextValues) => JSX.Element; // @public -export const renderTagButton_unstable: (state: TagButtonState) => JSX.Element; +export const renderTagButton_unstable: (state: TagButtonState, contextValues: TagButtonContextValues) => JSX.Element; // @public export const Tag: ForwardRefComponent; @@ -30,34 +32,19 @@ export const TagButton: ForwardRefComponent; export const tagButtonClassNames: SlotClassNames; // @public -export type TagButtonProps = ComponentProps & { - size?: 'extra-small' | 'small' | 'medium'; - shape?: 'rounded' | 'circular'; - appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; - disabled?: boolean; - checked?: boolean; - dismissable?: boolean; -}; +export type TagButtonProps = TagProps; // @public (undocumented) -export type TagButtonSlots = { - root: NonNullable>; - contentButton?: Slot<'button'>; - avatar?: Slot; - icon?: Slot<'span'>; - primaryText?: Slot<'span'>; - secondaryText?: Slot<'span'>; - dismissButton?: NonNullable>; -}; +export type TagButtonSlots = TagSlots; // @public -export type TagButtonState = ComponentState & Required>; +export type TagButtonState = TagState; // @public (undocumented) export const tagClassNames: SlotClassNames; // @public -export type TagProps = ComponentProps & { +export type TagProps = ComponentProps> & { size?: 'extra-small' | 'small' | 'medium'; shape?: 'rounded' | 'circular'; appearance?: 'filled-darker' | 'filled-lighter' | 'tint' | 'outline'; @@ -69,16 +56,19 @@ export type TagProps = ComponentProps & { // @public (undocumented) export type TagSlots = { root: NonNullable>; - content?: Slot<'span'>; - avatar?: Slot; - icon?: Slot<'span'>; - primaryText?: Slot<'span'>; - secondaryText?: Slot<'span'>; - dismissButton?: NonNullable>; + media: Slot<'span'>; + content: Slot<'div'>; + icon: Slot<'span'>; + primaryText: Slot<'span'>; + secondaryText: Slot<'span'>; + dismissButton: Slot; }; // @public -export type TagState = ComponentState & Required>; +export type TagState = ComponentState & Required & { + avatarSize: AvatarSize | undefined; + avatarShape: AvatarShape | undefined; +}>; // @public export const useTag_unstable: (props: TagProps, ref: React_2.Ref) => TagState; From 4c2908a83535093489207e08ebd17df46874909e Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 14:53:11 +0800 Subject: [PATCH 38/62] fix import --- .../react-tags/src/components/TagButton/useTagButtonStyles.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts index 55fc0dc2005423..5ca3a2c19fd4b9 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts @@ -1,8 +1,8 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagButtonSlots, TagButtonState } from './TagButton.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; -import { createCustomFocusIndicatorStyle } from '../../../../react-tabster/src/index'; -import { tokens, typographyStyles } from '../../../../react-theme/src/index'; +import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; +import { tokens, typographyStyles } from '@fluentui/react-theme'; export const tagButtonClassNames: SlotClassNames = { root: 'fui-TagButton', From 211dc741d7fae7f09967e82eb6ec5f05520e039f Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 15:14:42 +0800 Subject: [PATCH 39/62] add bundle icon and update test --- .../src/components/Tag/Tag.test.tsx | 4 +- .../Tag/__snapshots__/Tag.test.tsx.snap | 62 ++++++++++-------- .../react-tags/src/components/Tag/useTag.tsx | 6 +- .../components/TagButton/TagButton.test.tsx | 4 +- .../__snapshots__/TagButton.test.tsx.snap | 65 +++++++++++-------- 5 files changed, 80 insertions(+), 61 deletions(-) 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 f883681c531f31..d408c6f4614f60 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 @@ -4,9 +4,7 @@ import { Tag } from './Tag'; import { isConformant } from '../../testing/isConformant'; const requiredProps = { - avatar: { - name: 'Katri Athokas', - }, + media: 'media', icon: 'i', primaryText: 'Primary text', secondaryText: 'Secondary text', diff --git a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap index f66f95a0e95775..c472374ae88eda 100644 --- a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap +++ b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap @@ -5,21 +5,13 @@ exports[`Tag renders a default state 1`] = `
- - - KA - + media - Primary text + Default Tag Secondary text - +
diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index a6418e1845a3fe..f33ea6761a8cc6 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; -import { DismissRegular } from '@fluentui/react-icons'; +import { DismissRegular, bundleIcon, DismissFilled } from '@fluentui/react-icons'; import type { TagProps, TagState } from './Tag.types'; import { Button } from '@fluentui/react-button'; @@ -15,6 +15,8 @@ const tagAvatarShapeMap = { circular: 'circular', } as const; +const DismissIcon = bundleIcon(DismissFilled, DismissRegular); + /** * Create the state required to render Tag. * @@ -67,7 +69,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T required: props.dismissable, defaultProps: { appearance: 'transparent', - icon: , + icon: , }, }), }; diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx b/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx index 00568aabcc30d1..dd4b83857158a2 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx @@ -4,9 +4,7 @@ import { TagButton } from './TagButton'; import { isConformant } from '../../testing/isConformant'; const requiredProps = { - avatar: { - name: 'Katri Athokas', - }, + media: 'media', icon: 'i', primaryText: 'Primary text', secondaryText: 'Secondary text', diff --git a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap index ad849b8d3f3003..632a3183d9f062 100644 --- a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap +++ b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap @@ -5,21 +5,14 @@ exports[`TagButton renders a default state 1`] = `
- +
From be0cf254834dc40ce852dbc9fcc8fbd3f0ea5364 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 28 Apr 2023 17:54:03 +0800 Subject: [PATCH 40/62] Hack to build tag in PR docsite --- apps/public-docsite-v9/.storybook/main.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/public-docsite-v9/.storybook/main.js b/apps/public-docsite-v9/.storybook/main.js index a57e9a915e54d5..7a5ef6eac316b8 100644 --- a/apps/public-docsite-v9/.storybook/main.js +++ b/apps/public-docsite-v9/.storybook/main.js @@ -15,6 +15,8 @@ module.exports = /** @type {Omit Date: Fri, 28 Apr 2023 19:01:28 +0800 Subject: [PATCH 41/62] add styles suffix --- packages/react-components/react-tags/src/components/Tag/Tag.tsx | 2 +- .../react-components/react-tags/src/components/Tag/index.ts | 2 +- .../components/Tag/{useTagStyles.ts => useTagStyles.styles.ts} | 0 .../react-tags/src/components/TagButton/TagButton.tsx | 2 +- .../react-tags/src/components/TagButton/index.ts | 2 +- .../{useTagButtonStyles.ts => useTagButtonStyles.styles.ts} | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename packages/react-components/react-tags/src/components/Tag/{useTagStyles.ts => useTagStyles.styles.ts} (100%) rename packages/react-components/react-tags/src/components/TagButton/{useTagButtonStyles.ts => useTagButtonStyles.styles.ts} (100%) diff --git a/packages/react-components/react-tags/src/components/Tag/Tag.tsx b/packages/react-components/react-tags/src/components/Tag/Tag.tsx index 37f7399ec8b019..30cded29f93faa 100644 --- a/packages/react-components/react-tags/src/components/Tag/Tag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/Tag.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { useTag_unstable } from './useTag'; import { renderTag_unstable } from './renderTag'; -import { useTagStyles_unstable } from './useTagStyles'; +import { useTagStyles_unstable } from './useTagStyles.styles'; import type { TagProps } from './Tag.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; import { useTagContextValues_unstable } from '../../utils/useTagContextValues'; diff --git a/packages/react-components/react-tags/src/components/Tag/index.ts b/packages/react-components/react-tags/src/components/Tag/index.ts index 142ad9d5c187af..a44c9ce425d76c 100644 --- a/packages/react-components/react-tags/src/components/Tag/index.ts +++ b/packages/react-components/react-tags/src/components/Tag/index.ts @@ -2,4 +2,4 @@ export * from './Tag'; export * from './Tag.types'; export * from './renderTag'; export * from './useTag'; -export * from './useTagStyles'; +export * from './useTagStyles.styles'; diff --git a/packages/react-components/react-tags/src/components/Tag/useTagStyles.ts b/packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts similarity index 100% rename from packages/react-components/react-tags/src/components/Tag/useTagStyles.ts rename to packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx index d00f55a703b037..aff06a81252e8d 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { useTagButton_unstable } from './useTagButton'; import { renderTagButton_unstable } from './renderTagButton'; -import { useTagButtonStyles_unstable } from './useTagButtonStyles'; +import { useTagButtonStyles_unstable } from './useTagButtonStyles.styles'; import type { TagButtonProps } from './TagButton.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; import { useTagContextValues_unstable } from '../../utils/useTagContextValues'; diff --git a/packages/react-components/react-tags/src/components/TagButton/index.ts b/packages/react-components/react-tags/src/components/TagButton/index.ts index 722687cc27a851..42382817cf40b7 100644 --- a/packages/react-components/react-tags/src/components/TagButton/index.ts +++ b/packages/react-components/react-tags/src/components/TagButton/index.ts @@ -2,4 +2,4 @@ export * from './TagButton'; export * from './TagButton.types'; export * from './renderTagButton'; export * from './useTagButton'; -export * from './useTagButtonStyles'; +export * from './useTagButtonStyles.styles'; diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts similarity index 100% rename from packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.ts rename to packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts From e46a4d42a8e346317c946d941d87fd2a0e68006d Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 11:36:35 +0800 Subject: [PATCH 42/62] make content slot required --- .../react-components/react-tags/src/components/Tag/useTag.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index f33ea6761a8cc6..2b0f02c5a28466 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -60,7 +60,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T avatarShape: tagAvatarShapeMap[shape], media: resolveShorthand(props.media), - content: resolveShorthand(props.content, { required: !!props.primaryText || !!props.children }), + content: resolveShorthand(props.content, { required: true }), icon: resolveShorthand(props.icon), primaryText: resolveShorthand(props.primaryText, { required: true }), secondaryText: resolveShorthand(props.secondaryText), From e585b1ec1ecf5417a665d3689dd0ea18f7a968c0 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 11:39:47 +0800 Subject: [PATCH 43/62] update useTagButton_unstable --- .../src/components/TagButton/useTagButton.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx index 8308983b37ae1d..c3d2d8a70b64b2 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { resolveShorthand } from '@fluentui/react-utilities'; import type { TagButtonProps, TagButtonState } from './TagButton.types'; import { useTag_unstable } from '../Tag/index'; @@ -13,12 +12,5 @@ import { useTag_unstable } from '../Tag/index'; * @param ref - reference to root HTMLElement of TagButton */ export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { - const state = useTag_unstable(props, ref); - state.content = resolveShorthand(props.content, { - required: !!props.primaryText || !!props.children, - defaultProps: { - tabIndex: 0, - }, - }); - return state; + return useTag_unstable({ ...props, content: { tabIndex: 0, ...props.content } }, ref); }; From cfa336fdec4cf124140972f400e028e923206488 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 11:56:05 +0800 Subject: [PATCH 44/62] use makeStyles for stories --- .../stories/Tag/TagDismiss.stories.tsx | 39 +++++++++++------ .../stories/Tag/TagShape.stories.tsx | 25 +++++++---- .../TagButton/TagButtonDismiss.stories.tsx | 43 ++++++++++++------- .../TagButton/TagButtonShape.stories.tsx | 25 +++++++---- 4 files changed, 88 insertions(+), 44 deletions(-) diff --git a/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx index a57af0bc76c09b..c5b805116d96d4 100644 --- a/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagDismiss.stories.tsx @@ -1,20 +1,35 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-components'; +import { Avatar, makeStyles } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { Tag } from '@fluentui/react-tags'; -export const Dismiss = () => ( -
- Primary text - }> - Primary text - - } secondaryText="Secondary text"> - Primary text - -
-); +const useContainerStyles = makeStyles({ + root: { + display: 'flex', + flexDirection: 'column', + rowGap: '10px', + }, +}); + +export const Dismiss = () => { + const containerStyles = useContainerStyles(); + return ( +
+ Primary text + }> + Primary text + + } + secondaryText="Secondary text" + > + Primary text + +
+ ); +}; Dismiss.storyName = 'Dismiss'; Dismiss.parameters = { diff --git a/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx b/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx index baca77e3be1f84..620b4001ce5e12 100644 --- a/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx +++ b/packages/react-components/react-tags/stories/Tag/TagShape.stories.tsx @@ -1,18 +1,27 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-components'; +import { Avatar, makeStyles } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { Tag } from '@fluentui/react-tags'; -export const Shape = () => ( -
-
+const useContainerStyles = makeStyles({ + root: { + display: 'grid', + rowGap: '10px', + columnGap: '10px', + gridTemplateColumns: 'auto 1fr', + }, +}); + +export const Shape = () => { + const containerStyles = useContainerStyles(); + return ( +
}>Rounded }> Circular -
-
+ } secondaryText="Secondary text"> Rounded @@ -20,8 +29,8 @@ export const Shape = () => ( Circular
-
-); + ); +}; Shape.storyName = 'Shape'; Shape.parameters = { diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx index 5793eafb7c1016..f10a12d9b45e1e 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonDismiss.stories.tsx @@ -1,24 +1,35 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-components'; +import { Avatar, makeStyles } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { TagButton } from '@fluentui/react-tags'; -export const Dismiss = () => ( -
- Primary text - }> - Primary text - - } - secondaryText="Secondary text" - > - Primary text - -
-); +const useContainerStyles = makeStyles({ + root: { + display: 'flex', + flexDirection: 'column', + rowGap: '10px', + }, +}); + +export const Dismiss = () => { + const containerStyles = useContainerStyles(); + return ( +
+ Primary text + }> + Primary text + + } + secondaryText="Secondary text" + > + Primary text + +
+ ); +}; Dismiss.storyName = 'Dismiss'; Dismiss.parameters = { diff --git a/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx b/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx index 3c840f2e1b77c3..3f45196559c4b0 100644 --- a/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx +++ b/packages/react-components/react-tags/stories/TagButton/TagButtonShape.stories.tsx @@ -1,18 +1,27 @@ import * as React from 'react'; -import { Avatar } from '@fluentui/react-components'; +import { Avatar, makeStyles } from '@fluentui/react-components'; import { Calendar3Day20Regular } from '@fluentui/react-icons'; import { TagButton } from '@fluentui/react-tags'; -export const Shape = () => ( -
-
+const useContainerStyles = makeStyles({ + root: { + display: 'grid', + rowGap: '10px', + columnGap: '10px', + gridTemplateColumns: 'auto 1fr', + }, +}); + +export const Shape = () => { + const containerStyles = useContainerStyles(); + return ( +
}>Rounded }> Circular -
-
+ } secondaryText="Secondary text"> Rounded @@ -20,8 +29,8 @@ export const Shape = () => ( Circular
-
-); + ); +}; Shape.storyName = 'Shape'; Shape.parameters = { From 262cee1a8582e7d514ca31e7336060b5ac985314 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 12:03:53 +0800 Subject: [PATCH 45/62] remove snapshot test --- .../src/components/Tag/Tag.test.tsx | 9 --- .../Tag/__snapshots__/Tag.test.tsx.snap | 71 ------------------ .../components/TagButton/TagButton.test.tsx | 9 --- .../__snapshots__/TagButton.test.tsx.snap | 72 ------------------- 4 files changed, 161 deletions(-) delete mode 100644 packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap delete mode 100644 packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap 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 d408c6f4614f60..480342e78bece2 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 @@ -1,5 +1,3 @@ -import * as React from 'react'; -import { render } from '@testing-library/react'; import { Tag } from './Tag'; import { isConformant } from '../../testing/isConformant'; @@ -17,11 +15,4 @@ describe('Tag', () => { displayName: 'Tag', requiredProps, }); - - // TODO add more tests here, and create visual regression tests in /apps/vr-tests - - it('renders a default state', () => { - const result = render(Default Tag); - expect(result.container).toMatchSnapshot(); - }); }); diff --git a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap b/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap deleted file mode 100644 index c472374ae88eda..00000000000000 --- a/packages/react-components/react-tags/src/components/Tag/__snapshots__/Tag.test.tsx.snap +++ /dev/null @@ -1,71 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Tag renders a default state 1`] = ` -
-
-
- - media - - - i - - - Default Tag - - - Secondary text - -
- -
-
-`; diff --git a/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx b/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx index dd4b83857158a2..74dd557f5f6efd 100644 --- a/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/TagButton.test.tsx @@ -1,5 +1,3 @@ -import * as React from 'react'; -import { render } from '@testing-library/react'; import { TagButton } from './TagButton'; import { isConformant } from '../../testing/isConformant'; @@ -17,11 +15,4 @@ describe('TagButton', () => { displayName: 'TagButton', requiredProps, }); - - // TODO add more tests here, and create visual regression tests in /apps/vr-tests - - it('renders a default state', () => { - const result = render(Default TagButton); - expect(result.container).toMatchSnapshot(); - }); }); diff --git a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap b/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap deleted file mode 100644 index 632a3183d9f062..00000000000000 --- a/packages/react-components/react-tags/src/components/TagButton/__snapshots__/TagButton.test.tsx.snap +++ /dev/null @@ -1,72 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TagButton renders a default state 1`] = ` -
-
-
- - media - - - i - - - Default TagButton - - - Secondary text - -
- -
-
-`; From ef6d38662c3e00d89f1fcecd5f864ebbf1ee5478 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 12:22:17 +0800 Subject: [PATCH 46/62] revert change in useTagButton_unstable --- .../src/components/TagButton/useTagButton.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx index c3d2d8a70b64b2..78b065e9c6722c 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { resolveShorthand } from '@fluentui/react-utilities'; import type { TagButtonProps, TagButtonState } from './TagButton.types'; import { useTag_unstable } from '../Tag/index'; @@ -12,5 +13,12 @@ import { useTag_unstable } from '../Tag/index'; * @param ref - reference to root HTMLElement of TagButton */ export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { - return useTag_unstable({ ...props, content: { tabIndex: 0, ...props.content } }, ref); + const state = useTag_unstable(props, ref); + state.content = resolveShorthand(props.content, { + required: true, + defaultProps: { + tabIndex: 0, + }, + }); + return state; }; From 7918b421a8c3fb5d769fc3838707ced8c855773d Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 16:59:17 +0800 Subject: [PATCH 47/62] change Button into button --- .../react-tags/etc/react-tags.api.md | 3 +-- packages/react-components/react-tags/package.json | 2 +- .../react-tags/src/components/Tag/Tag.types.ts | 3 +-- .../react-tags/src/components/Tag/useTag.tsx | 11 ++++++----- .../src/components/Tag/useTagStyles.styles.ts | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 10 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 088d4e3b1e4e62..c8e561dc6958cd 100644 --- a/packages/react-components/react-tags/etc/react-tags.api.md +++ b/packages/react-components/react-tags/etc/react-tags.api.md @@ -8,7 +8,6 @@ import { AvatarShape } from '@fluentui/react-avatar'; import { AvatarSize } from '@fluentui/react-avatar'; -import { Button } from '@fluentui/react-button'; import type { ComponentProps } from '@fluentui/react-utilities'; import type { ComponentState } from '@fluentui/react-utilities'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; @@ -61,7 +60,7 @@ export type TagSlots = { icon: Slot<'span'>; primaryText: Slot<'span'>; secondaryText: Slot<'span'>; - dismissButton: Slot; + dismissButton: Slot<'button'>; }; // @public diff --git a/packages/react-components/react-tags/package.json b/packages/react-components/react-tags/package.json index 7f627eb3eca864..0fa7345db834d9 100644 --- a/packages/react-components/react-tags/package.json +++ b/packages/react-components/react-tags/package.json @@ -33,8 +33,8 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { + "@fluentui/react-aria": "^9.3.18", "@fluentui/react-avatar": "^9.4.10", - "@fluentui/react-button": "^9.3.10", "@fluentui/react-icons": "^2.0.196", "@fluentui/react-jsx-runtime": "9.0.0-alpha.2", "@fluentui/react-tabster": "^9.6.5", 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 79ba7a1595ffed..9d130328b633c0 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 @@ -1,6 +1,5 @@ import { AvatarSize, AvatarShape } from '@fluentui/react-avatar'; import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; -import { Button } from '@fluentui/react-button'; export type TagContextValues = { avatar: { @@ -34,7 +33,7 @@ export type TagSlots = { */ secondaryText: Slot<'span'>; - dismissButton: Slot; + dismissButton: Slot<'button'>; }; /** diff --git a/packages/react-components/react-tags/src/components/Tag/useTag.tsx b/packages/react-components/react-tags/src/components/Tag/useTag.tsx index 2b0f02c5a28466..35f804d5c4c2a5 100644 --- a/packages/react-components/react-tags/src/components/Tag/useTag.tsx +++ b/packages/react-components/react-tags/src/components/Tag/useTag.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities'; import { DismissRegular, bundleIcon, DismissFilled } from '@fluentui/react-icons'; import type { TagProps, TagState } from './Tag.types'; -import { Button } from '@fluentui/react-button'; +import { useARIAButtonShorthand } from '@fluentui/react-aria'; const tagAvatarSizeMap = { medium: 28, @@ -44,7 +44,7 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T icon: 'span', primaryText: 'span', secondaryText: 'span', - dismissButton: Button, + dismissButton: 'button', }, checked, disabled, @@ -65,11 +65,12 @@ export const useTag_unstable = (props: TagProps, ref: React.Ref): T primaryText: resolveShorthand(props.primaryText, { required: true }), secondaryText: resolveShorthand(props.secondaryText), - dismissButton: resolveShorthand(props.dismissButton, { + dismissButton: useARIAButtonShorthand(props.dismissButton, { required: props.dismissable, defaultProps: { - appearance: 'transparent', - icon: , + disabled, + type: 'button', + children: , }, }), }; 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 7dc652db7e381e..49e3398db40f50 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 @@ -81,10 +81,23 @@ const useStyles = makeStyles({ ...typographyStyles.caption2, }, + resetButton: { + boxSizing: 'content-box', + backgroundColor: 'inherit', + color: 'inherit', + fontFamily: 'inherit', + lineHeight: 'normal', + ...shorthands.overflow('visible'), + ...shorthands.padding(0), + ...shorthands.borderStyle('none'), + WebkitAppearance: 'button', + textAlign: 'unset', + }, dismissButton: { ...shorthands.padding('0px'), marginRight: '6px', minWidth: '20px', + fontSize: '20px', }, // TODO add additional classes for fill/outline appearance, different sizes, and state @@ -135,6 +148,7 @@ export const useTagStyles_unstable = (state: TagState): TagState => { if (state.dismissButton) { state.dismissButton.className = mergeClasses( tagClassNames.dismissButton, + styles.resetButton, styles.dismissButton, state.dismissButton.className, ); From 9c19d79b718ed6d76c0951cc1ff91ff7c2cc136a Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 17:39:26 +0800 Subject: [PATCH 48/62] reuse styles --- .../src/components/Tag/useTagStyles.styles.ts | 60 ++++++++---- .../TagButton/useTagButtonStyles.styles.ts | 98 +++++-------------- 2 files changed, 65 insertions(+), 93 deletions(-) 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 49e3398db40f50..1e7dca36c1997b 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 @@ -2,6 +2,7 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagSlots, TagState } from './Tag.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; import { tokens, typographyStyles } from '@fluentui/react-theme'; +import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; export const tagClassNames: SlotClassNames = { root: 'fui-Tag', @@ -16,7 +17,7 @@ export const tagClassNames: SlotClassNames = { /** * Styles for the root slot */ -const useStyles = makeStyles({ +export const useTagBaseStyles = makeStyles({ root: { display: 'inline-flex', height: '32px', @@ -51,9 +52,6 @@ const useStyles = makeStyles({ textOnlyContent: { paddingLeft: tokens.spacingHorizontalS, }, - dismissableContent: { - paddingRight: '2px', - }, icon: { display: 'flex', @@ -83,7 +81,6 @@ const useStyles = makeStyles({ resetButton: { boxSizing: 'content-box', - backgroundColor: 'inherit', color: 'inherit', fontFamily: 'inherit', lineHeight: 'normal', @@ -95,60 +92,87 @@ const useStyles = makeStyles({ }, dismissButton: { ...shorthands.padding('0px'), - marginRight: '6px', - minWidth: '20px', + backgroundColor: 'transparent', + width: '20px', + display: 'flex', + alignItems: 'center', fontSize: '20px', + + ...createCustomFocusIndicatorStyle({ + ...shorthands.borderColor(tokens.colorTransparentStroke), + ...shorthands.borderRadius(tokens.borderRadiusMedium), + ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorTransparentStroke), + boxShadow: ` + ${tokens.shadow4}, + 0 0 0 2px ${tokens.colorStrokeFocus2} + `, + zIndex: 1, + }), }, // TODO add additional classes for fill/outline appearance, different sizes, and state }); +const useTagStyles = makeStyles({ + dismissableContent: { + paddingRight: '2px', + }, + dismissButton: { + marginRight: '6px', + }, +}); + /** * Apply styling to the Tag slots based on the state */ export const useTagStyles_unstable = (state: TagState): TagState => { - const styles = useStyles(); + const baseStyles = useTagBaseStyles(); + const styles = useTagStyles(); + state.root.className = mergeClasses( tagClassNames.root, - styles.root, - state.shape === 'circular' && styles.rootCircular, + baseStyles.root, + state.shape === 'circular' && baseStyles.rootCircular, state.root.className, ); if (state.content) { state.content.className = mergeClasses( tagClassNames.content, - styles.content, - !state.media && !state.icon && styles.textOnlyContent, + baseStyles.content, + !state.media && !state.icon && baseStyles.textOnlyContent, + state.dismissButton && styles.dismissableContent, state.content.className, ); } if (state.media) { - state.media.className = mergeClasses(tagClassNames.media, styles.media, state.media.className); + state.media.className = mergeClasses(tagClassNames.media, baseStyles.media, state.media.className); } if (state.icon) { - state.icon.className = mergeClasses(tagClassNames.icon, styles.icon, state.icon.className); + state.icon.className = mergeClasses(tagClassNames.icon, baseStyles.icon, state.icon.className); } if (state.primaryText) { state.primaryText.className = mergeClasses( tagClassNames.primaryText, - styles.primaryText, - state.secondaryText && styles.primaryTextWithSecondaryText, + baseStyles.primaryText, + state.secondaryText && baseStyles.primaryTextWithSecondaryText, state.primaryText.className, ); } if (state.secondaryText) { state.secondaryText.className = mergeClasses( tagClassNames.secondaryText, - styles.secondaryText, + baseStyles.secondaryText, state.secondaryText.className, ); } if (state.dismissButton) { state.dismissButton.className = mergeClasses( tagClassNames.dismissButton, - styles.resetButton, + baseStyles.resetButton, + baseStyles.dismissButton, + styles.dismissButton, state.dismissButton.className, ); diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts index 5ca3a2c19fd4b9..b5c33afdc88fb4 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts @@ -2,7 +2,8 @@ import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; import type { TagButtonSlots, TagButtonState } from './TagButton.types'; import type { SlotClassNames } from '@fluentui/react-utilities'; import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster'; -import { tokens, typographyStyles } from '@fluentui/react-theme'; +import { tokens } from '@fluentui/react-theme'; +import { useTagBaseStyles } from '../Tag/index'; export const tagButtonClassNames: SlotClassNames = { root: 'fui-TagButton', @@ -18,37 +19,7 @@ export const tagButtonClassNames: SlotClassNames = { * Styles for the root slot */ const useStyles = makeStyles({ - root: { - display: 'inline-flex', - height: '32px', - width: 'fit-content', - ...shorthands.borderRadius(tokens.borderRadiusMedium), - - backgroundColor: tokens.colorNeutralBackground3, - color: tokens.colorNeutralForeground2, - }, - rootCircular: { - ...shorthands.borderRadius(tokens.borderRadiusCircular), - }, - - media: { - ...shorthands.gridArea('media'), - alignSelf: 'center', - paddingLeft: tokens.spacingHorizontalXXS, - paddingRight: tokens.spacingHorizontalS, - }, - content: { - display: 'inline-grid', - gridTemplateRows: '1fr auto auto 1fr', - gridTemplateAreas: ` - "media icon . " - "media icon primary " - "media icon secondary" - "media icon . " - `, - paddingRight: tokens.spacingHorizontalS, - position: 'relative', ...createCustomFocusIndicatorStyle({ ...shorthands.borderColor(tokens.colorTransparentStroke), @@ -61,48 +32,20 @@ const useStyles = makeStyles({ zIndex: 1, }), }, - textOnlyContent: { - paddingLeft: tokens.spacingHorizontalS, - }, - circularContent: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular)), - dismissableContent: createCustomFocusIndicatorStyle({ - borderTopRightRadius: tokens.borderRadiusNone, - borderBottomRightRadius: tokens.borderRadiusNone, - }), - icon: { - display: 'flex', - alignSelf: 'center', - ...shorthands.gridArea('icon'), - paddingLeft: '6px', - paddingRight: '2px', - }, - primaryText: { - gridColumnStart: 'primary', - gridRowStart: 'primary', - gridRowEnd: 'secondary', - ...typographyStyles.body1, - paddingLeft: tokens.spacingHorizontalXXS, - paddingRight: tokens.spacingHorizontalXXS, - }, - primaryTextWithSecondaryText: { - ...shorthands.gridArea('primary'), - ...typographyStyles.caption1, - }, - secondaryText: { - ...shorthands.gridArea('secondary'), - paddingLeft: tokens.spacingHorizontalXXS, - paddingRight: tokens.spacingHorizontalXXS, - ...typographyStyles.caption2, + circularContent: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular)), + dismissableContent: { + ...createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusNone, + borderBottomRightRadius: tokens.borderRadiusNone, + }), }, dismissButton: { - minWidth: '20px', ...shorthands.padding('0px', '6px'), - borderLeftColor: tokens.colorNeutralStroke1, + ...shorthands.borderLeft(tokens.strokeWidthThin, 'solid', tokens.colorNeutralStroke1), borderTopLeftRadius: tokens.borderRadiusNone, borderBottomLeftRadius: tokens.borderRadiusNone, - ...createCustomFocusIndicatorStyle({ borderTopLeftRadius: tokens.borderRadiusNone, borderBottomLeftRadius: tokens.borderRadiusNone, @@ -120,20 +63,22 @@ const useStyles = makeStyles({ * Apply styling to the TagButton slots based on the state */ export const useTagButtonStyles_unstable = (state: TagButtonState): TagButtonState => { + const baseStyles = useTagBaseStyles(); const styles = useStyles(); state.root.className = mergeClasses( tagButtonClassNames.root, - styles.root, - state.shape === 'circular' && styles.rootCircular, + baseStyles.root, + state.shape === 'circular' && baseStyles.rootCircular, state.root.className, ); if (state.content) { state.content.className = mergeClasses( tagButtonClassNames.content, - styles.content, - !state.media && !state.icon && styles.textOnlyContent, + baseStyles.content, + !state.media && !state.icon && baseStyles.textOnlyContent, + styles.content, state.shape === 'circular' && styles.circularContent, state.dismissButton && styles.dismissableContent, @@ -142,29 +87,32 @@ export const useTagButtonStyles_unstable = (state: TagButtonState): TagButtonSta } if (state.media) { - state.media.className = mergeClasses(tagButtonClassNames.media, styles.media, state.media.className); + state.media.className = mergeClasses(tagButtonClassNames.media, baseStyles.media, state.media.className); } if (state.icon) { - state.icon.className = mergeClasses(tagButtonClassNames.icon, styles.icon, state.icon.className); + state.icon.className = mergeClasses(tagButtonClassNames.icon, baseStyles.icon, state.icon.className); } if (state.primaryText) { state.primaryText.className = mergeClasses( tagButtonClassNames.primaryText, - styles.primaryText, - state.secondaryText && styles.primaryTextWithSecondaryText, + baseStyles.primaryText, + state.secondaryText && baseStyles.primaryTextWithSecondaryText, state.primaryText.className, ); } if (state.secondaryText) { state.secondaryText.className = mergeClasses( tagButtonClassNames.secondaryText, - styles.secondaryText, + baseStyles.secondaryText, state.secondaryText.className, ); } if (state.dismissButton) { state.dismissButton.className = mergeClasses( tagButtonClassNames.dismissButton, + baseStyles.resetButton, + baseStyles.dismissButton, + styles.dismissButton, state.shape === 'circular' && styles.dismissButtonCircular, state.dismissButton.className, From cae86d7bd30d19f182e428063a01cff365b0e4e2 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 17:42:20 +0800 Subject: [PATCH 49/62] fix HC border --- .../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 1e7dca36c1997b..0cc7f1445b7d99 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 @@ -26,6 +26,7 @@ export const useTagBaseStyles = makeStyles({ backgroundColor: tokens.colorNeutralBackground3, color: tokens.colorNeutralForeground2, + ...shorthands.border(tokens.strokeWidthThin, 'solid', tokens.colorTransparentStroke), }, rootCircular: { ...shorthands.borderRadius(tokens.borderRadiusCircular), From 3ed9d8ca7e0c551d2aaeeb6f0945285c58e3af20 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 2 May 2023 17:46:55 +0800 Subject: [PATCH 50/62] add makeResetStyle todo --- .../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 0cc7f1445b7d99..182eed5930b92d 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 @@ -19,6 +19,7 @@ export const tagClassNames: SlotClassNames = { */ export const useTagBaseStyles = makeStyles({ root: { + // TODO use makeResetStyle when styles are settled display: 'inline-flex', height: '32px', width: 'fit-content', From fc477a79e548270662a16ad710a2e10a2ecc8e12 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Wed, 3 May 2023 11:40:05 +0800 Subject: [PATCH 51/62] update useTagButton_unstable again --- .../src/components/TagButton/useTagButton.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx index 78b065e9c6722c..a06e0785fab519 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -13,12 +13,6 @@ import { useTag_unstable } from '../Tag/index'; * @param ref - reference to root HTMLElement of TagButton */ export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { - const state = useTag_unstable(props, ref); - state.content = resolveShorthand(props.content, { - required: true, - defaultProps: { - tabIndex: 0, - }, - }); - return state; + const content = resolveShorthand(props.content, { defaultProps: { tabIndex: 0 } }); + return useTag_unstable({ ...props, content }, ref); }; From d69816083b8605f236711482d58cc4149453db38 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Wed, 3 May 2023 11:45:24 +0800 Subject: [PATCH 52/62] remove weird stuff from merging --- .../react-components/react-avatar/src/contexts/AvatarContext.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-components/react-avatar/src/contexts/AvatarContext.ts b/packages/react-components/react-avatar/src/contexts/AvatarContext.ts index 2e3731494f5795..cb8e8fa15943f1 100644 --- a/packages/react-components/react-avatar/src/contexts/AvatarContext.ts +++ b/packages/react-components/react-avatar/src/contexts/AvatarContext.ts @@ -9,7 +9,6 @@ const avatarContext = React.createContext(undefi export interface AvatarContextValue { shape?: AvatarShape; size?: AvatarSize; - shape?: AvatarShape; } const avatarContextDefaultValue: AvatarContextValue = {}; From e21532074fa0535a0ff25a389b177866a3ed2b3f Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Wed, 3 May 2023 11:46:03 +0800 Subject: [PATCH 53/62] remove weird stuff from merging --- .../src/components/DonutChart/DonutChart.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-charting/src/components/DonutChart/DonutChart.test.tsx b/packages/react-charting/src/components/DonutChart/DonutChart.test.tsx index b98dee9948175b..bb7efc643b61fb 100644 --- a/packages/react-charting/src/components/DonutChart/DonutChart.test.tsx +++ b/packages/react-charting/src/components/DonutChart/DonutChart.test.tsx @@ -38,7 +38,7 @@ const points: IChartDataPoint[] = [ const chartTitle = 'Stacked Bar chart example'; export const chartPoints: IChartProps = { - chartTitle, + chartTitle: chartTitle, chartData: points, }; From 70aff78bb192f7d8272b8af85347c9085e32c5cd Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Wed, 3 May 2023 11:48:39 +0800 Subject: [PATCH 54/62] add required on tagButton content --- .../react-tags/src/components/TagButton/useTagButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx index a06e0785fab519..8d5bfe1d9d8dff 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButton.tsx @@ -13,6 +13,6 @@ import { useTag_unstable } from '../Tag/index'; * @param ref - reference to root HTMLElement of TagButton */ export const useTagButton_unstable = (props: TagButtonProps, ref: React.Ref): TagButtonState => { - const content = resolveShorthand(props.content, { defaultProps: { tabIndex: 0 } }); + const content = resolveShorthand(props.content, { required: true, defaultProps: { tabIndex: 0 } }); return useTag_unstable({ ...props, content }, ref); }; From 7a4f8ff3b544b2444b375c6e87f064b0d82f2b40 Mon Sep 17 00:00:00 2001 From: Amber Date: Thu, 4 May 2023 10:27:04 +0200 Subject: [PATCH 55/62] Update packages/react-components/react-tags/src/components/Tag/useTagStyles.styles.ts Co-authored-by: Sean Monahan --- .../react-tags/src/components/Tag/useTagStyles.styles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 182eed5930b92d..3bc1eea9a72435 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 @@ -89,7 +89,7 @@ export const useTagBaseStyles = makeStyles({ ...shorthands.overflow('visible'), ...shorthands.padding(0), ...shorthands.borderStyle('none'), - WebkitAppearance: 'button', + appearance: 'button', textAlign: 'unset', }, dismissButton: { From 7646ef59ae3db6765995f1b11682c526a7c2de57 Mon Sep 17 00:00:00 2001 From: Lingfan Gao Date: Thu, 4 May 2023 11:10:48 +0200 Subject: [PATCH 56/62] fix focus outline --- .../src/components/Tag/useTagStyles.styles.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) 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 3bc1eea9a72435..a71563aba9426b 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 @@ -100,16 +100,13 @@ export const useTagBaseStyles = makeStyles({ alignItems: 'center', fontSize: '20px', - ...createCustomFocusIndicatorStyle({ - ...shorthands.borderColor(tokens.colorTransparentStroke), - ...shorthands.borderRadius(tokens.borderRadiusMedium), - ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorTransparentStroke), - boxShadow: ` - ${tokens.shadow4}, - 0 0 0 2px ${tokens.colorStrokeFocus2} - `, - zIndex: 1, - }), + ...createCustomFocusIndicatorStyle( + { + ...shorthands.borderRadius(tokens.borderRadiusMedium), + ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorStrokeFocus2), + }, + { enableOutline: true }, + ), }, // TODO add additional classes for fill/outline appearance, different sizes, and state From 068f23617d3e2838abf146f1bc97a2e50e00995a Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Thu, 4 May 2023 19:56:15 +0800 Subject: [PATCH 57/62] simplify focus indicator --- .../TagButton/useTagButtonStyles.styles.ts | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts index b5c33afdc88fb4..f2baeed63be4ac 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts @@ -21,24 +21,26 @@ export const tagButtonClassNames: SlotClassNames = { const useStyles = makeStyles({ content: { position: 'relative', - ...createCustomFocusIndicatorStyle({ - ...shorthands.borderColor(tokens.colorTransparentStroke), - ...shorthands.borderRadius(tokens.borderRadiusMedium), - ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorTransparentStroke), - boxShadow: ` - ${tokens.shadow4}, - 0 0 0 2px ${tokens.colorStrokeFocus2} - `, - zIndex: 1, - }), + ...createCustomFocusIndicatorStyle( + { + ...shorthands.borderRadius(tokens.borderRadiusMedium), + ...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorStrokeFocus2), + }, + { enableOutline: true }, + ), }, - circularContent: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular)), + circularContent: createCustomFocusIndicatorStyle(shorthands.borderRadius(tokens.borderRadiusCircular), { + enableOutline: true, + }), dismissableContent: { - ...createCustomFocusIndicatorStyle({ - borderTopRightRadius: tokens.borderRadiusNone, - borderBottomRightRadius: tokens.borderRadiusNone, - }), + ...createCustomFocusIndicatorStyle( + { + borderTopRightRadius: tokens.borderRadiusNone, + borderBottomRightRadius: tokens.borderRadiusNone, + }, + { enableOutline: true }, + ), }, dismissButton: { @@ -46,15 +48,21 @@ const useStyles = makeStyles({ ...shorthands.borderLeft(tokens.strokeWidthThin, 'solid', tokens.colorNeutralStroke1), borderTopLeftRadius: tokens.borderRadiusNone, borderBottomLeftRadius: tokens.borderRadiusNone, - ...createCustomFocusIndicatorStyle({ - borderTopLeftRadius: tokens.borderRadiusNone, - borderBottomLeftRadius: tokens.borderRadiusNone, - }), + ...createCustomFocusIndicatorStyle( + { + borderTopLeftRadius: tokens.borderRadiusNone, + borderBottomLeftRadius: tokens.borderRadiusNone, + }, + { enableOutline: true }, + ), }, - dismissButtonCircular: createCustomFocusIndicatorStyle({ - borderTopRightRadius: tokens.borderRadiusCircular, - borderBottomRightRadius: tokens.borderRadiusCircular, - }), + dismissButtonCircular: createCustomFocusIndicatorStyle( + { + borderTopRightRadius: tokens.borderRadiusCircular, + borderBottomRightRadius: tokens.borderRadiusCircular, + }, + { enableOutline: true }, + ), // TODO add additional classes for fill/outline appearance, different sizes, and state }); From 901b8addb820e848953fdc37da4b6360a1e639ec Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 5 May 2023 00:56:16 +0800 Subject: [PATCH 58/62] use one gridArea for media and icon --- .../src/components/Tag/useTagStyles.styles.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 a71563aba9426b..1edf60c2352c94 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 @@ -44,10 +44,10 @@ export const useTagBaseStyles = makeStyles({ display: 'inline-grid', gridTemplateRows: '1fr auto auto 1fr', gridTemplateAreas: ` - "media icon . " - "media icon primary " - "media icon secondary" - "media icon . " + "media . " + "media primary " + "media secondary" + "media . " `, paddingRight: tokens.spacingHorizontalS, }, @@ -58,7 +58,7 @@ export const useTagBaseStyles = makeStyles({ icon: { display: 'flex', alignSelf: 'center', - ...shorthands.gridArea('icon'), + ...shorthands.gridArea('media'), paddingLeft: '6px', paddingRight: '2px', }, From 43f1b6d22ea875218b71c51e05381668ec53337c Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 9 May 2023 11:00:51 +0800 Subject: [PATCH 59/62] remove extra { enableOutline: true } after merge master fix --- .../TagButton/useTagButtonStyles.styles.ts | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts index f2baeed63be4ac..fb28d8ef924084 100644 --- a/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts +++ b/packages/react-components/react-tags/src/components/TagButton/useTagButtonStyles.styles.ts @@ -34,13 +34,10 @@ const useStyles = makeStyles({ enableOutline: true, }), dismissableContent: { - ...createCustomFocusIndicatorStyle( - { - borderTopRightRadius: tokens.borderRadiusNone, - borderBottomRightRadius: tokens.borderRadiusNone, - }, - { enableOutline: true }, - ), + ...createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusNone, + borderBottomRightRadius: tokens.borderRadiusNone, + }), }, dismissButton: { @@ -48,21 +45,15 @@ const useStyles = makeStyles({ ...shorthands.borderLeft(tokens.strokeWidthThin, 'solid', tokens.colorNeutralStroke1), borderTopLeftRadius: tokens.borderRadiusNone, borderBottomLeftRadius: tokens.borderRadiusNone, - ...createCustomFocusIndicatorStyle( - { - borderTopLeftRadius: tokens.borderRadiusNone, - borderBottomLeftRadius: tokens.borderRadiusNone, - }, - { enableOutline: true }, - ), + ...createCustomFocusIndicatorStyle({ + borderTopLeftRadius: tokens.borderRadiusNone, + borderBottomLeftRadius: tokens.borderRadiusNone, + }), }, - dismissButtonCircular: createCustomFocusIndicatorStyle( - { - borderTopRightRadius: tokens.borderRadiusCircular, - borderBottomRightRadius: tokens.borderRadiusCircular, - }, - { enableOutline: true }, - ), + dismissButtonCircular: createCustomFocusIndicatorStyle({ + borderTopRightRadius: tokens.borderRadiusCircular, + borderBottomRightRadius: tokens.borderRadiusCircular, + }), // TODO add additional classes for fill/outline appearance, different sizes, and state }); From 48ddb75a0febde01c2eb132ec8a86213b32518f7 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 9 May 2023 11:03:22 +0800 Subject: [PATCH 60/62] remove temp change that publishes tag in storybook --- apps/public-docsite-v9/.storybook/main.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/public-docsite-v9/.storybook/main.js b/apps/public-docsite-v9/.storybook/main.js index 7a5ef6eac316b8..a57e9a915e54d5 100644 --- a/apps/public-docsite-v9/.storybook/main.js +++ b/apps/public-docsite-v9/.storybook/main.js @@ -15,8 +15,6 @@ module.exports = /** @type {Omit Date: Tue, 9 May 2023 11:04:13 +0800 Subject: [PATCH 61/62] cleanup change file --- ...-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json diff --git a/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json b/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json deleted file mode 100644 index c12caf9cff69bd..00000000000000 --- a/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minor", - "comment": "feat: add `shape` to AvatarContext", - "packageName": "@fluentui/react-avatar", - "email": "yuanboxue@microsoft.com", - "dependentChangeType": "patch" -} From 22734e496b236322ab38f92daae82c6d425c8bf3 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 9 May 2023 11:05:07 +0800 Subject: [PATCH 62/62] Revert "cleanup change file" This reverts commit ba61dc37c9260f3abf3dcd4ca5cd075854e42c75. --- ...-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json diff --git a/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json b/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json new file mode 100644 index 00000000000000..c12caf9cff69bd --- /dev/null +++ b/change/@fluentui-react-avatar-beee81db-4a4e-458f-a4bf-e9d4624a0356.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: add `shape` to AvatarContext", + "packageName": "@fluentui/react-avatar", + "email": "yuanboxue@microsoft.com", + "dependentChangeType": "patch" +}