From 8506c117c51567b6dbf80c7e607873eb73de6452 Mon Sep 17 00:00:00 2001 From: Mason Tejera <17346018+mltejera@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:01:49 -0700 Subject: [PATCH] [BREAKING] feat(react-nav-preview): Allow controlled behavior for nav categories, add controlled example and other cleanup (#32489) Co-authored-by: Mitch-At-Work --- ...-d9b041fc-d874-467e-a484-d42072027c4a.json | 7 + .../library/etc/react-nav-preview.api.md | 15 +- .../library/src/components/Nav/Nav.types.ts | 40 ++- .../library/src/components/Nav/useNav.ts | 95 +++--- .../src/components/NavCategoryContext.ts | 2 +- .../NavCategoryItem/useNavCategoryItem.tsx | 7 +- .../library/src/components/NavContext.ts | 1 - .../src/components/NavContext.types.ts | 7 +- .../src/components/NavSubItemContext.ts | 2 +- .../NavSubItemGroup/NavSubItemGroup.test.tsx | 2 +- .../react-nav-preview/library/src/index.ts | 2 +- .../src/AppItem/AppItemBestPractices.md | 5 - .../src/AppItem/AppItemDefault.stories.tsx | 4 - .../stories/src/AppItem/AppItemDescription.md | 0 .../stories/src/AppItem/index.stories.tsx | 18 -- .../AppItemStaticBestPractices.md | 5 - .../AppItemStaticDefault.stories.tsx | 4 - .../AppItemStatic/AppItemStaticDescription.md | 0 .../src/AppItemStatic/index.stories.tsx | 18 -- .../src/Hamburger/HamburgerBestPractices.md | 5 - .../Hamburger/HamburgerDefault.stories.tsx | 4 - .../src/Hamburger/HamburgerDescription.md | 0 .../stories/src/Hamburger/index.stories.tsx | 18 -- .../stories/src/Nav/NavDefault.stories.tsx | 12 - .../Nav/NavWithDefaultSelection.stories.tsx | 12 - .../src/Nav/NavWithNestedSubItems.stories.tsx | 28 -- ...edSubItemsWithDefaultSelection.stories.tsx | 52 --- ...DefaultSelectionSingleCategory.stories.tsx | 28 -- .../stories/src/Nav/index.stories.tsx | 8 +- .../NavCategory/NavCategoryBestPractices.md | 5 - .../NavCategoryDefault.stories.tsx | 19 -- .../src/NavCategory/NavCategoryDescription.md | 0 .../stories/src/NavCategory/index.stories.tsx | 18 -- .../src/NavDivider/NavDividerBestPractices.md | 5 - .../NavDivider/NavDividerDefault.stories.tsx | 4 - .../src/NavDivider/NavDividerDescription.md | 0 .../stories/src/NavDivider/index.stories.tsx | 18 -- .../NavDrawer/NavDrawerControlled.stories.tsx | 296 ++++++++++++++++++ .../NavDrawer/NavDrawerDefault.stories.tsx | 17 +- .../src/NavDrawer/NavDrawerSize.stories.tsx | 24 +- .../stories/src/NavDrawer/index.stories.tsx | 8 - .../NavDrawerBodyBestPractices.md | 5 - .../NavDrawerBodyDefault.stories.tsx | 4 - .../NavDrawerBody/NavDrawerBodyDescription.md | 0 .../src/NavDrawerBody/index.stories.tsx | 18 -- .../NavDrawerFooterBestPractices.md | 5 - .../NavDrawerFooterDefault.stories.tsx | 4 - .../NavDrawerFooterDescription.md | 0 .../src/NavDrawerFooter/index.stories.tsx | 18 -- .../NavDrawerHeaderBestPractices.md | 5 - .../NavDrawerHeaderDefault.stories.tsx | 4 - .../NavDrawerHeaderDescription.md | 0 .../src/NavDrawerHeader/index.stories.tsx | 18 -- .../src/NavItem/NavItemBestPractices.md | 5 - .../src/NavItem/NavItemDefault.stories.tsx | 46 --- .../stories/src/NavItem/NavItemDescription.md | 0 .../stories/src/NavItem/index.stories.tsx | 18 -- .../NavSectionHeaderBestPractices.md | 5 - .../NavSectionHeaderDefault.stories.tsx | 4 - .../NavSectionHeaderDescription.md | 0 .../src/NavSectionHeader/index.stories.tsx | 18 -- .../src/NavSubItem/NavSubItemBestPractices.md | 5 - .../NavSubItem/NavSubItemDefault.stories.tsx | 5 - .../src/NavSubItem/NavSubItemDescription.md | 0 .../stories/src/NavSubItem/index.stories.tsx | 18 -- .../NavSubItemGroupBestPractices.md | 5 - .../NavSubItemGroupDefault.stories.tsx | 5 - .../NavSubItemGroupDescription.md | 0 .../src/NavSubItemGroup/index.stories.tsx | 18 -- 69 files changed, 430 insertions(+), 618 deletions(-) create mode 100644 change/@fluentui-react-nav-preview-d9b041fc-d874-467e-a484-d42072027c4a.json delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItem/AppItemBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItem/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/AppItemStatic/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/Hamburger/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Nav/NavDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Nav/NavWithDefaultSelection.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItems.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelection.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelectionSingleCategory.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavCategory/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDivider/index.stories.tsx create mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerControlled.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawer/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerBody/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavItem/NavItemBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavItem/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSectionHeader/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItem/index.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupBestPractices.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDefault.stories.tsx delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDescription.md delete mode 100644 packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/index.stories.tsx diff --git a/change/@fluentui-react-nav-preview-d9b041fc-d874-467e-a484-d42072027c4a.json b/change/@fluentui-react-nav-preview-d9b041fc-d874-467e-a484-d42072027c4a.json new file mode 100644 index 0000000000000..06c9ed333dd1e --- /dev/null +++ b/change/@fluentui-react-nav-preview-d9b041fc-d874-467e-a484-d42072027c4a.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": " [BREAKING] Removed non functional reserveSelectedNavItemSpace prop. Added defaultOpenCategories and openCategories prop and example. Updated icon selection logic for NavCategoryItem. Exports OnNavItemSelectData.", + "packageName": "@fluentui/react-nav-preview", + "email": "matejera@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-nav-preview/library/etc/react-nav-preview.api.md b/packages/react-components/react-nav-preview/library/etc/react-nav-preview.api.md index 124c289c56091..88aea57efec56 100644 --- a/packages/react-components/react-nav-preview/library/etc/react-nav-preview.api.md +++ b/packages/react-components/react-nav-preview/library/etc/react-nav-preview.api.md @@ -130,7 +130,7 @@ export type NavCategoryState = NavCategoryContextValue & Required; // @public (undocumented) -export type NavContextValue = Pick & { +export type NavContextValue = Pick & { onRegister: RegisterNavItemEventHandler; onUnregister: RegisterNavItemEventHandler; onSelect: EventHandler; @@ -253,13 +253,14 @@ export type NavItemState = ComponentState & Pick & { - reserveSelectedNavItemSpace?: boolean; defaultSelectedValue?: NavItemValue; defaultSelectedCategoryValue?: NavItemValue; + defaultOpenCategories?: NavItemValue[]; + openCategories?: NavItemValue[]; onNavItemSelect?: EventHandler; selectedValue?: NavItemValue; selectedCategoryValue?: NavItemValue; @@ -288,7 +289,7 @@ export type NavSectionHeaderSlots = { // @public export type NavSectionHeaderState = ComponentState; -// @public (undocumented) +// @public export type NavSize = 'small' | 'medium'; // @public (undocumented) @@ -341,6 +342,12 @@ export type NavSubItemState = ComponentState & Pick> & { + value: NavItemValue; + categoryValue?: NavItemValue; +}; + // @public (undocumented) export type RegisterNavItemEventHandler = (data: NavItemRegisterData) => void; diff --git a/packages/react-components/react-nav-preview/library/src/components/Nav/Nav.types.ts b/packages/react-components/react-nav-preview/library/src/components/Nav/Nav.types.ts index 4b6a85459a002..2c454797acdba 100644 --- a/packages/react-components/react-nav-preview/library/src/components/Nav/Nav.types.ts +++ b/packages/react-components/react-nav-preview/library/src/components/Nav/Nav.types.ts @@ -7,50 +7,60 @@ export type NavSlots = { root: NonNullable>; }; +/*** + * Indicates the vertical size of the Nav content. + */ export type NavSize = 'small' | 'medium'; /** * Nav Props */ export type NavProps = ComponentProps & { - /** - * Nav size may change between unselected and selected states. - * The default scenario is a selected NavItem has bold text. - * - * When true, this property requests navItems be the same size whether unselected or selected. - * @default true - */ - reserveSelectedNavItemSpace?: boolean; - /** * The value of the navItem to be selected by default. * Typically useful when the selectedValue is uncontrolled. - * Mutually exclusive with selectedValue. + * Mutually exclusive with selectedValue. + * Empty string indicates no selection. */ defaultSelectedValue?: NavItemValue; /** * The value of the navCategory to be selected by default. * Typically useful when the selectedValue is uncontrolled. - * Mutually exclusive with selectedValue. + * Mutually exclusive with selectedValue. + * Empty string indicates no selection. */ defaultSelectedCategoryValue?: NavItemValue; + /** + * Set of categories that are opened by default. + * Typically useful when the openCategories is uncontrolled. + */ + defaultOpenCategories?: NavItemValue[]; + + /** + * Controls the open categories. + * For use in controlled scenarios. + */ + openCategories?: NavItemValue[]; + /** * Raised when a navItem is selected. + * If the navItem is child of a category, the categoryValue will be provided */ onNavItemSelect?: EventHandler; /** * The value of the currently selected navItem. * Mutually exclusive with defaultSelectedValue. + * @default undefined */ selectedValue?: NavItemValue; /** * Indicates a category that has a selected child * Will show the category as selected if it is closed. - * Null otherwise + * @default undefined */ selectedCategoryValue?: NavItemValue; @@ -61,13 +71,12 @@ export type NavProps = ComponentProps & { multiple?: boolean; /** - * Callback used by NavCategoryItem to request a change on it's own opened state + * Callback raised when a NavCategoryItem is toggled. */ onNavCategoryItemToggle?: EventHandler; /** * The size and density of the Nav and it's children - * * @default 'medium' */ size?: NavSize; @@ -76,11 +85,12 @@ export type NavProps = ComponentProps & { export type OnNavItemSelectData = EventData<'click', React.MouseEvent> & { /** * The value of the selected navItem. + * In the case of a category selection, this will be the value of the selected category. */ value: NavItemValue; /** - * The parent value of the selected navItem + * The parent value of the selected navSubItem * Null if not a child of a category */ categoryValue?: NavItemValue; diff --git a/packages/react-components/react-nav-preview/library/src/components/Nav/useNav.ts b/packages/react-components/react-nav-preview/library/src/components/Nav/useNav.ts index 59ee4dd527efb..83a8bc502be0a 100644 --- a/packages/react-components/react-nav-preview/library/src/components/Nav/useNav.ts +++ b/packages/react-components/react-nav-preview/library/src/components/Nav/useNav.ts @@ -11,33 +11,21 @@ import { import type { NavProps, NavState, OnNavItemSelectData } from './Nav.types'; import type { NavItemRegisterData, NavItemValue } from '../NavContext.types'; -// /** -// * Initial value for the uncontrolled case of the list of open indexes -// */ -// function initializeUncontrolledOpenItems({ defaultOpenItems }: Pick): NavItemValue[] { -// if (defaultOpenItems !== undefined) { -// if (Array.isArray(defaultOpenItems)) { -// return [defaultOpenItems[0]]; -// } -// return [defaultOpenItems]; -// } -// return []; -// } - -// /** -// * Normalizes Accordion index into an array of indexes -// */ -// function normalizeValues(index?: NavItemValue | NavItemValue[]): NavItemValue[] | undefined { -// if (index === undefined) { -// return undefined; -// } -// return Array.isArray(index) ? index : [index]; -// } - -// temp implementation of the above function. -const normalizeValues = (index?: NavItemValue | NavItemValue[]): NavItemValue[] | undefined => { +/** + * Initial value for the uncontrolled case of the list of open indexes + */ +function initializeUncontrolledOpenCategories({ + defaultOpenCategories, + multiple, +}: Pick): NavItemValue[] | undefined { + if (defaultOpenCategories !== undefined) { + if (Array.isArray(defaultOpenCategories)) { + return multiple ? defaultOpenCategories : [defaultOpenCategories[0]]; + } + return [defaultOpenCategories]; + } return undefined; -}; +} /** * Updates the list of open indexes based on an index that changes @@ -45,7 +33,7 @@ const normalizeValues = (index?: NavItemValue | NavItemValue[]): NavItemValue[] * @param previousOpenItems - list of current open indexes * @param multiple - if Nav supports open categories at the same time */ -const updateOpenItems = (value: NavItemValue, previousOpenItems: NavItemValue[], multiple: boolean) => { +const updateOpenCategories = (value: NavItemValue, previousOpenItems: NavItemValue[], multiple: boolean) => { if (multiple) { if (previousOpenItems.includes(value)) { return previousOpenItems.filter(i => i !== value); @@ -67,31 +55,36 @@ const updateOpenItems = (value: NavItemValue, previousOpenItems: NavItemValue[], * @param ref - reference to root HTMLDivElement of Nav */ export const useNav_unstable = (props: NavProps, ref: React.Ref): NavState => { - const { onNavItemSelect, onNavCategoryItemToggle, multiple = true, size = 'medium' } = props; + const { + onNavItemSelect, + onNavCategoryItemToggle, + multiple = true, + size = 'medium', + openCategories: controlledOpenCategoryItems, + selectedCategoryValue: controlledSelectedCategoryValue, + selectedValue: controlledSelectedValue, + defaultOpenCategories, + defaultSelectedValue, + defaultSelectedCategoryValue, + } = props; const innerRef = React.useRef(null); const [openCategories, setOpenCategories] = useControllableState({ - // normalizeValues(controlledOpenItems), [controlledOpenItems]) - state: React.useMemo(() => normalizeValues(), []), - defaultState: () => [], // initializeUncontrolledOpenItems({ defaultOpenItems }), + state: controlledOpenCategoryItems, + defaultState: initializeUncontrolledOpenCategories({ defaultOpenCategories, multiple }), initialState: [], }); - const onRequestNavCategoryItemToggle: EventHandler = useEventCallback((event, data) => { - const nextOpenItems = updateOpenItems(data.value, openCategories, multiple); - onNavCategoryItemToggle?.(event, data); - setOpenCategories(nextOpenItems); - }); - const [selectedCategoryValue, setSelectedCategoryValue] = useControllableState({ - state: props.selectedCategoryValue, - defaultState: props.defaultSelectedCategoryValue, + state: controlledSelectedCategoryValue, + defaultState: defaultSelectedCategoryValue, initialState: undefined, }); + const [selectedValue, setSelectedValue] = useControllableState({ - state: props.selectedValue, - defaultState: props.defaultSelectedValue, + state: controlledSelectedValue, + defaultState: defaultSelectedValue, initialState: undefined, }); @@ -105,20 +98,32 @@ export const useNav_unstable = (props: NavProps, ref: React.Ref) const currentSelectedCategoryValue = React.useRef(undefined); const previousSelectedCategoryValue = React.useRef(undefined); - React.useEffect(() => { + if (currentSelectedValue.current !== selectedValue) { previousSelectedValue.current = currentSelectedValue.current; currentSelectedValue.current = selectedValue; + } + if (currentSelectedCategoryValue.current !== selectedCategoryValue) { previousSelectedCategoryValue.current = currentSelectedCategoryValue.current; currentSelectedCategoryValue.current = selectedCategoryValue; - }, [selectedValue, selectedCategoryValue]); + } + // used for NavItems and NavSubItems const onSelect: EventHandler = useEventCallback((event, data) => { setSelectedValue(data.value); - setSelectedCategoryValue(data.categoryValue); + setSelectedCategoryValue(data.categoryValue ? data.categoryValue : ''); onNavItemSelect?.(event, data); }); + // used for NavCategoryItems + const onRequestNavCategoryItemToggle: EventHandler = useEventCallback((event, data) => { + if (data.categoryValue !== undefined) { + const nextOpenCategories = updateOpenCategories(data.categoryValue, openCategories ?? [], multiple); + onNavCategoryItemToggle?.(event, data); + setOpenCategories(nextOpenCategories); + } + }); + const registeredNavItems = React.useRef>({}); const onRegister = React.useCallback((data: NavItemRegisterData) => { @@ -150,6 +155,7 @@ export const useNav_unstable = (props: NavProps, ref: React.Ref) }), { elementType: 'div' }, ), + openCategories, selectedValue, selectedCategoryValue, onRegister, @@ -157,7 +163,6 @@ export const useNav_unstable = (props: NavProps, ref: React.Ref) onSelect, getRegisteredNavItems, onRequestNavCategoryItemToggle, - openCategories, multiple, size, }; diff --git a/packages/react-components/react-nav-preview/library/src/components/NavCategoryContext.ts b/packages/react-components/react-nav-preview/library/src/components/NavCategoryContext.ts index dd390af5e5c75..32e2d90ac997d 100644 --- a/packages/react-components/react-nav-preview/library/src/components/NavCategoryContext.ts +++ b/packages/react-components/react-nav-preview/library/src/components/NavCategoryContext.ts @@ -18,7 +18,7 @@ const NavCategoryContext = React.createContext onRequestNavCategoryItemToggle(event, { type: 'click', event, value })), + mergeCallbacks(onClick, event => + onRequestNavCategoryItemToggle(event, { type: 'click', event, value: '', categoryValue: value }), + ), ); - const selected = selectedCategoryValue === value; + // don't fill the icon when it's open + const selected = selectedCategoryValue === value && !open; // there's more than 2 possible values for aria-current, but this is the only one that's used in this component const validAriaCurrent: 'page' | 'false' = selected && !open ? 'page' : 'false'; diff --git a/packages/react-components/react-nav-preview/library/src/components/NavContext.ts b/packages/react-components/react-nav-preview/library/src/components/NavContext.ts index 55a21b462711d..f0cb4b5af7a71 100644 --- a/packages/react-components/react-nav-preview/library/src/components/NavContext.ts +++ b/packages/react-components/react-nav-preview/library/src/components/NavContext.ts @@ -2,7 +2,6 @@ import * as React from 'react'; import { NavContextValue } from './NavContext.types'; const navContextDefaultValue: NavContextValue = { - reserveSelectedNavItemSpace: true, selectedValue: undefined, selectedCategoryValue: undefined, onRegister: () => { diff --git a/packages/react-components/react-nav-preview/library/src/components/NavContext.types.ts b/packages/react-components/react-nav-preview/library/src/components/NavContext.types.ts index f78be285b1951..41beee99b9aa0 100644 --- a/packages/react-components/react-nav-preview/library/src/components/NavContext.types.ts +++ b/packages/react-components/react-nav-preview/library/src/components/NavContext.types.ts @@ -3,10 +3,7 @@ import { EventHandler } from '@fluentui/react-utilities'; import type { NavProps, OnNavItemSelectData } from './Nav/Nav.types'; -export type NavContextValue = Pick< - NavProps, - 'onNavItemSelect' | 'selectedValue' | 'selectedCategoryValue' | 'reserveSelectedNavItemSpace' | 'size' -> & { +export type NavContextValue = Pick & { /** A callback to allow a navItem to register itself with the navItem list. */ onRegister: RegisterNavItemEventHandler; @@ -46,7 +43,7 @@ export type NavContextValue = Pick< /** * Any value that identifies a specific Item. */ -export type NavItemValue = unknown; +export type NavItemValue = string; /** * Context values used in rendering navItemList. diff --git a/packages/react-components/react-nav-preview/library/src/components/NavSubItemContext.ts b/packages/react-components/react-nav-preview/library/src/components/NavSubItemContext.ts index c8e1c9049f635..1c154b01e8e9e 100644 --- a/packages/react-components/react-nav-preview/library/src/components/NavSubItemContext.ts +++ b/packages/react-components/react-nav-preview/library/src/components/NavSubItemContext.ts @@ -14,7 +14,7 @@ const NavSubItemContext = React.createContext): NavCategoryContextValue { return { open: false, - value: undefined, + value: '', ...partialValue, }; } diff --git a/packages/react-components/react-nav-preview/library/src/index.ts b/packages/react-components/react-nav-preview/library/src/index.ts index 7fe002336ab23..9553e114fb735 100644 --- a/packages/react-components/react-nav-preview/library/src/index.ts +++ b/packages/react-components/react-nav-preview/library/src/index.ts @@ -1,5 +1,5 @@ export { Nav, renderNav_unstable, useNav_unstable, useNavStyles_unstable, navClassNames } from './components/Nav/index'; -export type { NavProps, NavSlots, NavState, NavSize } from './components/Nav/index'; +export type { NavProps, NavSlots, NavState, NavSize, OnNavItemSelectData } from './components/Nav/index'; export { NavCategory, renderNavCategory_unstable, useNavCategory_unstable } from './components/NavCategory/index'; export type { NavCategoryProps, NavCategoryState } from './components/NavCategory/index'; diff --git a/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemBestPractices.md b/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDefault.stories.tsx deleted file mode 100644 index 55bca0eec037c..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { AppItem, AppItemProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDescription.md b/packages/react-components/react-nav-preview/stories/src/AppItem/AppItemDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/AppItem/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/AppItem/index.stories.tsx deleted file mode 100644 index 24450a5411f82..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/AppItem/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { AppItem } from '@fluentui/react-nav-preview'; - -import descriptionMd from './AppItemDescription.md'; -import bestPracticesMd from './AppItemBestPractices.md'; - -// export { Default } from './AppItemDefault.stories'; - -export default { - title: 'Preview Components/AppItem', - component: AppItem, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticBestPractices.md b/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDefault.stories.tsx deleted file mode 100644 index fd303f2e86b71..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { AppItemStatic, AppItemStaticProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDescription.md b/packages/react-components/react-nav-preview/stories/src/AppItemStatic/AppItemStaticDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/AppItemStatic/index.stories.tsx deleted file mode 100644 index 2fc6005290372..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/AppItemStatic/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { AppItemStatic } from '@fluentui/react-nav-preview'; - -import descriptionMd from './AppItemStaticDescription.md'; -import bestPracticesMd from './AppItemStaticBestPractices.md'; - -// export { Default } from './AppItemStaticDefault.stories'; - -export default { - title: 'Preview Components/AppItemStatic', - component: AppItemStatic, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerBestPractices.md b/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDefault.stories.tsx deleted file mode 100644 index 79910fa5513fd..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { Hamburger, HamburgerProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: HamburgerProps) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDescription.md b/packages/react-components/react-nav-preview/stories/src/Hamburger/HamburgerDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/Hamburger/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Hamburger/index.stories.tsx deleted file mode 100644 index 586670d14d9c0..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Hamburger/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Hamburger } from '@fluentui/react-nav-preview'; - -import descriptionMd from './HamburgerDescription.md'; -import bestPracticesMd from './HamburgerBestPractices.md'; - -// export { Default } from './HamburgerDefault.stories'; - -export default { - title: 'Preview Components/Hamburger', - component: Hamburger, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Nav/NavDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Nav/NavDefault.stories.tsx deleted file mode 100644 index 17f47882f483a..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Nav/NavDefault.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -import { Nav, NavItem } from '@fluentui/react-nav-preview'; - -export const Default = () => { - return ( - - ); -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithDefaultSelection.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Nav/NavWithDefaultSelection.stories.tsx deleted file mode 100644 index 13288b31446c9..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithDefaultSelection.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -import { Nav, NavItem } from '@fluentui/react-nav-preview'; - -export const WithDefaultSelection = () => { - return ( - - ); -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItems.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItems.stories.tsx deleted file mode 100644 index d95644e3932f7..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItems.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { Nav, NavCategory, NavCategoryItem, NavItem, NavSubItem, NavSubItemGroup } from '@fluentui/react-nav-preview'; - -export const WithNestedSubItems = () => { - return ( - - ); -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelection.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelection.stories.tsx deleted file mode 100644 index 7949f72cb2f43..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelection.stories.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from 'react'; -import { Nav, NavCategory, NavCategoryItem, NavItem, NavSubItem, NavSubItemGroup } from '@fluentui/react-nav-preview'; - -export const WithNestedSubItemsDefaultSelection = () => { - const someClickHandler = () => { - console.log('someClickHandler'); - }; - - return ( - - ); -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelectionSingleCategory.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelectionSingleCategory.stories.tsx deleted file mode 100644 index 315d34ebef455..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/Nav/NavWithNestedSubItemsWithDefaultSelectionSingleCategory.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { Nav, NavCategory, NavCategoryItem, NavItem, NavSubItem, NavSubItemGroup } from '@fluentui/react-nav-preview'; - -export const WithNestedSubItemsWithDefaultSelectionSingleCategory = () => { - return ( - - ); -}; diff --git a/packages/react-components/react-nav-preview/stories/src/Nav/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/Nav/index.stories.tsx index 536441a647513..2b325469d66ef 100644 --- a/packages/react-components/react-nav-preview/stories/src/Nav/index.stories.tsx +++ b/packages/react-components/react-nav-preview/stories/src/Nav/index.stories.tsx @@ -1,16 +1,12 @@ import { Nav } from '@fluentui/react-nav-preview'; +// Todo: light these up // import descriptionMd from './NavDescription.md'; // import bestPracticesMd from './NavBestPractices.md'; -// export { Default } from './NavDefault.stories'; -// export { WithDefaultSelection } from './NavWithDefaultSelection.stories'; -// export { WithNestedSubItems } from './NavWithNestedSubItems.stories'; -// export { WithNestedSubItemsDefaultSelection } from './NavWithNestedSubItemsWithDefaultSelection.stories'; -// export { WithNestedSubItemsWithDefaultSelectionSingleCategory } from './NavWithNestedSubItemsWithDefaultSelectionSingleCategory.stories'; - export { NavDrawerDefault } from '../NavDrawer/NavDrawerDefault.stories'; export { NavDrawerSize } from '../NavDrawer/NavDrawerSize.stories'; +export { NavDrawerControlled } from '../NavDrawer/NavDrawerControlled.stories'; export default { title: 'Preview Components/Nav', diff --git a/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDefault.stories.tsx deleted file mode 100644 index 6775632953382..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDefault.stories.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; -import { Nav, NavCategory, NavCategoryItem, NavSubItemGroup } from '@fluentui/react-nav-preview'; - -export const Default = () => ( - -); diff --git a/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDescription.md b/packages/react-components/react-nav-preview/stories/src/NavCategory/NavCategoryDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavCategory/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavCategory/index.stories.tsx deleted file mode 100644 index 9cab67460bc8a..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavCategory/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavCategory } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavCategoryDescription.md'; -import bestPracticesMd from './NavCategoryBestPractices.md'; - -// export { Default } from './NavCategoryDefault.stories'; - -export default { - title: 'Preview Components/NavCategory', - component: NavCategory, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDefault.stories.tsx deleted file mode 100644 index da3701f4b14f0..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { NavDivider, NavDividerProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDescription.md b/packages/react-components/react-nav-preview/stories/src/NavDivider/NavDividerDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavDivider/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDivider/index.stories.tsx deleted file mode 100644 index bc578c1e772b7..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDivider/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavDivider } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavDividerDescription.md'; -import bestPracticesMd from './NavDividerBestPractices.md'; - -// export { Default } from './NavDividerDefault.stories'; - -export default { - title: 'Preview Components/NavDivider', - component: NavDivider, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerControlled.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerControlled.stories.tsx new file mode 100644 index 0000000000000..77fd944465474 --- /dev/null +++ b/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerControlled.stories.tsx @@ -0,0 +1,296 @@ +import * as React from 'react'; +import { + AppItem, + Hamburger, + NavCategory, + NavCategoryItem, + NavDivider, + NavDrawer, + NavDrawerBody, + NavDrawerHeader, + NavDrawerProps, + NavItem, + NavItemValue, + NavSectionHeader, + NavSubItem, + NavSubItemGroup, + OnNavItemSelectData, +} from '@fluentui/react-nav-preview'; +import { Button, Label, Switch, Tooltip, makeStyles, tokens, useId } from '@fluentui/react-components'; +import { + Board20Filled, + Board20Regular, + BoxMultiple20Filled, + BoxMultiple20Regular, + DataArea20Filled, + DataArea20Regular, + DocumentBulletListMultiple20Filled, + DocumentBulletListMultiple20Regular, + HeartPulse20Filled, + HeartPulse20Regular, + MegaphoneLoud20Filled, + MegaphoneLoud20Regular, + NotePin20Filled, + NotePin20Regular, + People20Filled, + People20Regular, + PeopleStar20Filled, + PeopleStar20Regular, + Person20Filled, + PersonLightbulb20Filled, + PersonLightbulb20Regular, + Person20Regular, + PersonSearch20Filled, + PersonSearch20Regular, + PreviewLink20Filled, + PreviewLink20Regular, + bundleIcon, + PersonCircle32Regular, +} from '@fluentui/react-icons'; + +const useStyles = makeStyles({ + root: { + overflow: 'hidden', + display: 'flex', + height: '600px', + }, + content: { + flex: '1', + padding: '16px', + display: 'grid', + justifyContent: 'flex-start', + alignItems: 'flex-start', + }, + field: { + display: 'flex', + marginTop: '4px', + marginLeft: '8px', + flexDirection: 'column', + gridRowGap: tokens.spacingVerticalS, + }, +}); + +const Person = bundleIcon(Person20Filled, Person20Regular); +const Dashboard = bundleIcon(Board20Filled, Board20Regular); +const Announcements = bundleIcon(MegaphoneLoud20Filled, MegaphoneLoud20Regular); +const EmployeeSpotlight = bundleIcon(PersonLightbulb20Filled, PersonLightbulb20Regular); +const Search = bundleIcon(PersonSearch20Filled, PersonSearch20Regular); +const PerformanceReviews = bundleIcon(PreviewLink20Filled, PreviewLink20Regular); +const JobPostings = bundleIcon(NotePin20Filled, NotePin20Regular); +const Interviews = bundleIcon(People20Filled, People20Regular); +const HealthPlans = bundleIcon(HeartPulse20Filled, HeartPulse20Regular); +const TrainingPrograms = bundleIcon(BoxMultiple20Filled, BoxMultiple20Regular); +const CareerDevelopment = bundleIcon(PeopleStar20Filled, PeopleStar20Regular); +const Analytics = bundleIcon(DataArea20Filled, DataArea20Regular); +const Reports = bundleIcon(DocumentBulletListMultiple20Filled, DocumentBulletListMultiple20Regular); + +// A type that represents a navItemValue and its potential children. +// An empty children array indicates a Single top level NavItem. +// A hydrated children array indicates a NavCategoryItem with children. +type NavItemValueCombo = { parent: string; children: string[] }; + +// This is a list of navItemValues and their potential children +// Ite exactly matches the NavDrawer in the story below +// This is how a consumer might store them in their app +const navItemValueList: NavItemValueCombo[] = [ + { parent: '1', children: [] }, + { parent: '2', children: [] }, + { parent: '3', children: [] }, + { parent: '4', children: [] }, + { parent: '5', children: [] }, + { parent: '6', children: ['7', '8'] }, + { parent: '9', children: [] }, + { parent: '10', children: [] }, + { parent: '11', children: ['12', '13'] }, + { parent: '14', children: [] }, + { parent: '15', children: [] }, + { parent: '16', children: ['17', '18'] }, + { parent: '19', children: [] }, + { parent: '20', children: [] }, +]; + +type SelectedPage = { + newSelectedCategory: string | undefined; + newSelectedValue: string; +}; + +const getRandomPage = (): SelectedPage => { + const randomIndex = Math.floor(Math.random() * navItemValueList.length); + const randomItem = navItemValueList[randomIndex]; + + // there are no children, so we're selecting a top level item + if (randomItem.children.length === 0) { + return { newSelectedCategory: undefined, newSelectedValue: randomItem.parent }; + } else { + // there are children, so we're including a category and it's child as the selectedValue + const randomChildIndex = Math.floor(Math.random() * randomItem.children.length); + return { newSelectedCategory: randomItem.parent, newSelectedValue: randomItem.children[randomChildIndex] }; + } +}; + +export const NavDrawerControlled = (props: Partial) => { + const styles = useStyles(); + + const multipleLabelId = useId('multiple-label'); + + const [openCategories, setOpenCategories] = React.useState(['6', '11']); + const [selectedCategoryValue, setSelectedCategoryValue] = React.useState('6'); + const [selectedValue, setSelectedValue] = React.useState('7'); + const [isMultiple, setIsMultiple] = React.useState(true); + + const handleCategoryToggle = (ev: Event | React.SyntheticEvent, data: OnNavItemSelectData) => { + if (data.value === undefined && data.categoryValue) { + // we're just opening it, + setOpenCategories([data.categoryValue as string]); + } + + if (isMultiple) { + // if it's already open, remove it from the list + if (openCategories.includes(data.categoryValue as string)) { + setOpenCategories([...openCategories.filter(category => category !== data.categoryValue)]); + } else { + // otherwise add it + setOpenCategories([...openCategories, data.categoryValue as string]); + } + } else { + // if it's already open, remove it from the list + if (openCategories.includes(data.categoryValue as string)) { + setOpenCategories([]); + } else { + // otherwise add it + setOpenCategories([data.categoryValue as string]); + } + } + }; + + const handleItemSelect = (ev: Event | React.SyntheticEvent, data: OnNavItemSelectData) => { + setSelectedCategoryValue(data.categoryValue as string); + setSelectedValue(data.value as string); + }; + + const renderHamburgerWithToolTip = () => { + return ( + + + + ); + }; + + const handleNavigationClick = () => { + const { newSelectedCategory, newSelectedValue } = getRandomPage(); + + setSelectedCategoryValue(newSelectedCategory); + setSelectedValue(newSelectedValue); + }; + + const handleMultipleChange = (ev: Event | React.SyntheticEvent, data: { checked: boolean }) => { + setIsMultiple(data.checked); + + if (data.checked) { + setOpenCategories(['6', '11']); + } else { + setOpenCategories(['6']); + } + }; + + return ( +
+ + {renderHamburgerWithToolTip()} + + + } as="a"> + Contoso HR + + } value="1"> + Dashboard + + } value="2"> + Announcements + + } value="3"> + Employee Spotlight + + } value="4"> + Profile Search + + } value="5"> + Performance Reviews + + Employee Management + + }>Job Postings + + Openings + Submissions + + + } value="9"> + Interviews + + + Benefits + } value="10"> + Health Plans + + + } value="12"> + Retirement + + + Plan Information + Fund Performance + + + + Learning + } value="15"> + Training Programs + + + }>Career Development + + Career Paths + Planning + + + + } value="19"> + Workforce Data + + } value="20"> + Reports + + + +
+
+ + + handleMultipleChange(_, data)} + label={isMultiple ? 'Multiple' : 'Single'} + aria-labelledby={multipleLabelId} + /> +
+
+
+ ); +}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerDefault.stories.tsx index 61b973927fdb6..2acd6b95715d0 100644 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerDefault.stories.tsx +++ b/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerDefault.stories.tsx @@ -90,10 +90,12 @@ export const NavDrawerDefault = (props: Partial) => { const typeLableId = useId('type-label'); const linkLabelId = useId('link-label'); + const multipleLabelId = useId('multiple-label'); const [isOpen, setIsOpen] = React.useState(true); const [enabledLinks, setEnabledLinks] = React.useState(true); const [type, setType] = React.useState('inline'); + const [isMultiple, setIsMultiple] = React.useState(true); const linkDestination = enabledLinks ? 'https://www.bing.com' : ''; @@ -107,7 +109,13 @@ export const NavDrawerDefault = (props: Partial) => { return (
- + {renderHamburgerWithToolTip()} @@ -206,6 +214,13 @@ export const NavDrawerDefault = (props: Partial) => { label={enabledLinks ? 'Enabled' : 'Disabled'} aria-labelledby={linkLabelId} /> + + setIsMultiple(!!data.checked)} + label={isMultiple ? 'Multiple' : 'Single'} + aria-labelledby={multipleLabelId} + />
diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerSize.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerSize.stories.tsx index 3d04d07d9af6f..4e06a52ef48b4 100644 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerSize.stories.tsx +++ b/packages/react-components/react-nav-preview/stories/src/NavDrawer/NavDrawerSize.stories.tsx @@ -126,19 +126,19 @@ export const NavDrawerSize = (props: Partial) => { {appItem} - } value="1"> + } value="1"> Dashboard - } value="2"> + } value="2"> Announcements - } value="3"> + } value="3"> Employee Spotlight - } href="https://www.bing.com" value="4"> + } href={linkDestination} value="4"> Profile Search - } href="https://www.bing.com" value="5"> + } href={linkDestination} value="5"> Performance Reviews @@ -146,10 +146,10 @@ export const NavDrawerSize = (props: Partial) => { }>Job Postings - + Openings - + Submissions @@ -167,10 +167,10 @@ export const NavDrawerSize = (props: Partial) => { Retirement - + Plan Information - + Fund Performance @@ -183,10 +183,10 @@ export const NavDrawerSize = (props: Partial) => { }>Career Development - + Career Paths - + Planning @@ -194,7 +194,7 @@ export const NavDrawerSize = (props: Partial) => { } value="19"> Workforce Data - } value="20"> + } value="20"> Reports diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawer/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawer/index.stories.tsx deleted file mode 100644 index 13763daa3a7fd..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawer/index.stories.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { NavDrawer } from '@fluentui/react-nav-preview'; - -// export { NavDrawerDefault } from './NavDrawerDefault.stories'; - -export default { - title: 'Preview Components/NavDrawer', - component: NavDrawer, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDefault.stories.tsx deleted file mode 100644 index c4722cd32e9bd..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { NavDrawerBody, NavDrawerBodyProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDescription.md b/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/NavDrawerBodyDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/index.stories.tsx deleted file mode 100644 index 2e23c9ba90f1d..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerBody/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavDrawerBody } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavDrawerBodyDescription.md'; -import bestPracticesMd from './NavDrawerBodyBestPractices.md'; - -// export { Default } from './NavDrawerBodyDefault.stories'; - -export default { - title: 'Preview Components/NavDrawerBody', - component: NavDrawerBody, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDefault.stories.tsx deleted file mode 100644 index 547f662b8a7b5..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { NavDrawerFooter, NavDrawerFooterProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDescription.md b/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/NavDrawerFooterDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/index.stories.tsx deleted file mode 100644 index 64cfc0f558cf5..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerFooter/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavDrawerFooter } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavDrawerFooterDescription.md'; -import bestPracticesMd from './NavDrawerFooterBestPractices.md'; - -// export { Default } from './NavDrawerFooterDefault.stories'; - -export default { - title: 'Preview Components/NavDrawerFooter', - component: NavDrawerFooter, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDefault.stories.tsx deleted file mode 100644 index fd88b2e44a994..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { NavDrawerHeader, NavDrawerHeaderProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDescription.md b/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/NavDrawerHeaderDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/index.stories.tsx deleted file mode 100644 index 328f26534b6e4..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavDrawerHeader/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavDrawerHeader } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavDrawerHeaderDescription.md'; -import bestPracticesMd from './NavDrawerHeaderBestPractices.md'; - -// export { Default } from './NavDrawerHeaderDefault.stories'; - -export default { - title: 'Preview Components/NavDrawerHeader', - component: NavDrawerHeader, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDefault.stories.tsx deleted file mode 100644 index 96c47a911aec1..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDefault.stories.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; -import { Nav, NavItem, NavItemProps } from '@fluentui/react-nav-preview'; -import { Folder20Regular, Folder20Filled, bundleIcon } from '@fluentui/react-icons'; -import { makeStyles, tokens } from '@fluentui/react-components'; - -const Folder = bundleIcon(Folder20Filled, Folder20Regular); - -const useStyles = makeStyles({ - root: { - display: 'flex', - flexDirection: 'column', - maxWidth: '260px', - rowGap: '60px', - padding: '40px', - backgroundColor: tokens.colorNeutralBackground4, - }, -}); - -export const Default = (props: Partial) => { - const classes = useStyles(); - - const someClickHandler = () => { - console.log('someClickHandler'); - }; - - return ( -
- - -
- ); -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDescription.md b/packages/react-components/react-nav-preview/stories/src/NavItem/NavItemDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavItem/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavItem/index.stories.tsx deleted file mode 100644 index c5518d297ff7f..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavItem/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavItem } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavItemDescription.md'; -import bestPracticesMd from './NavItemBestPractices.md'; - -// export { Default } from './NavItemDefault.stories'; - -export default { - title: 'Preview Components/NavItem', - component: NavItem, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDefault.stories.tsx deleted file mode 100644 index 8dfdc3f8e191d..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDefault.stories.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import * as React from 'react'; -import { NavSectionHeader, NavSectionHeaderProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDescription.md b/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/NavSectionHeaderDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/index.stories.tsx deleted file mode 100644 index 4e7d17b746c0c..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSectionHeader/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavSectionHeader } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavSectionHeaderDescription.md'; -import bestPracticesMd from './NavSectionHeaderBestPractices.md'; - -// export { Default } from './NavSectionHeaderDefault.stories'; - -export default { - title: 'Preview Components/NavSectionHeader', - component: NavSectionHeader, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDefault.stories.tsx deleted file mode 100644 index fcfd503434c98..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDefault.stories.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import * as React from 'react'; -import { NavSubItem } from '@fluentui/react-nav-preview'; -import type { NavSubItemProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: NavSubItemProps) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDescription.md b/packages/react-components/react-nav-preview/stories/src/NavSubItem/NavSubItemDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItem/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavSubItem/index.stories.tsx deleted file mode 100644 index c8ceb0663f77b..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSubItem/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavSubItem } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavSubItemDescription.md'; -import bestPracticesMd from './NavSubItemBestPractices.md'; - -// export { Default } from './NavSubItemDefault.stories'; - -export default { - title: 'Preview Components/NavSubItem', - component: NavSubItem, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -}; diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupBestPractices.md b/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupBestPractices.md deleted file mode 100644 index 08ff8ddeeb5f8..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupBestPractices.md +++ /dev/null @@ -1,5 +0,0 @@ -## Best practices - -### Do - -### Don't diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDefault.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDefault.stories.tsx deleted file mode 100644 index 6eec96f4c7e13..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDefault.stories.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import * as React from 'react'; -import { NavSubItemGroup } from '@fluentui/react-nav-preview'; -import type { NavSubItemGroupProps } from '@fluentui/react-nav-preview'; - -export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDescription.md b/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/NavSubItemGroupDescription.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/index.stories.tsx b/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/index.stories.tsx deleted file mode 100644 index b44e18b5a2062..0000000000000 --- a/packages/react-components/react-nav-preview/stories/src/NavSubItemGroup/index.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { NavSubItemGroup } from '@fluentui/react-nav-preview'; - -import descriptionMd from './NavSubItemGroupDescription.md'; -import bestPracticesMd from './NavSubItemGroupBestPractices.md'; - -// export { Default } from './NavSubItemGroupDefault.stories'; - -export default { - title: 'Preview Components/NavSubItemGroup', - component: NavSubItemGroup, - parameters: { - docs: { - description: { - component: [descriptionMd, bestPracticesMd].join('\n'), - }, - }, - }, -};