diff --git a/modules/react/collection/lib/useOverflowListItemMeasure.tsx b/modules/react/collection/lib/useOverflowListItemMeasure.tsx index ad5c02d4c8..a1772ad17c 100644 --- a/modules/react/collection/lib/useOverflowListItemMeasure.tsx +++ b/modules/react/collection/lib/useOverflowListItemMeasure.tsx @@ -31,10 +31,9 @@ export const useOverflowListItemMeasure = createElemPropsHook(useOverflowListMod width: localRef.current.offsetWidth + parseFloat(styles.marginLeft) + - parseFloat(styles.marginLeft) + parseFloat(styles.marginRight), height: - localRef.current.offsetWidth + + localRef.current.offsetHeight + parseFloat(styles.marginTop) + parseFloat(styles.marginBottom), }); diff --git a/modules/react/collection/lib/useOverflowListModel.tsx b/modules/react/collection/lib/useOverflowListModel.tsx index 956de41a7f..bf40c23b72 100644 --- a/modules/react/collection/lib/useOverflowListModel.tsx +++ b/modules/react/collection/lib/useOverflowListModel.tsx @@ -54,6 +54,9 @@ export function getHiddenIds( for (const key in itemSizeCache) { if (key !== selectedKey) { itemSize += itemSizeCache[key] + (shouldAddGap ? containerGap : 0); + console.log('itemSizeCache[key]', itemSizeCache[key]); + console.log('itemSize', itemSize); + console.log('containerSize', containerSize); shouldAddGap = true; if (itemSize > containerSize) { hiddenIds.push(key); @@ -105,13 +108,13 @@ export const useOverflowListModel = createModelHook({ hiddenIds: internalHiddenIds, itemSizeCache, /** - * @deprecated Use `itemSizeCache` instead - */ + * @deprecated Use `itemSizeCache` instead + */ itemWidthCache: itemSizeCache, containerSize, /** - * @deprecated Use `containerSize` instead - */ + * @deprecated Use `containerSize` instead + */ containerWidth: containerSize, containerGap, overflowTargetWidth, @@ -137,7 +140,8 @@ export const useOverflowListModel = createModelHook({ containerSizeRef.current = model.state.orientation === 'horizontal' ? data.width || 0 : data.height || 0; setContainerSize(containerSizeRef.current); - // setContainerGap(containerSizeRef.current); + console.log(containerSizeRef.current); + console.log(containerGap); const ids = getHiddenIds( containerSizeRef.current, containerGap, @@ -149,8 +153,8 @@ export const useOverflowListModel = createModelHook({ setHiddenIds(ids); }, /** - * @deprecated Use `setContainerSize` instead and pass both `width` and `height` - */ + * @deprecated Use `setContainerSize` instead and pass both `width` and `height` + */ setContainerWidth(data: {width?: number}) { events.setContainerSize({width: data.width, height: 0}); }, @@ -196,6 +200,9 @@ export const useOverflowListModel = createModelHook({ [data.id]: model.state.orientation === 'horizontal' ? data.width : data.height, }; + console.log('>>>size cache ref', data.height); + console.log('>>>size cache ref', data.width); + setItemSizeCache(itemSizeCacheRef.current); const ids = getHiddenIds( diff --git a/modules/react/collection/stories/mdx/examples/OverflowVerticalList.tsx b/modules/react/collection/stories/mdx/examples/OverflowVerticalList.tsx index 3cd7112e4c..f95fa08a7a 100644 --- a/modules/react/collection/stories/mdx/examples/OverflowVerticalList.tsx +++ b/modules/react/collection/stories/mdx/examples/OverflowVerticalList.tsx @@ -1,298 +1,73 @@ -import * as React from 'react'; -import { - composeHooks, - createContainer, - createElemPropsHook, - createModelHook, - createSubcomponent, - createSubModelElemPropsHook, - ExtractProps, -} from '@workday/canvas-kit-react/common'; - -import { - relatedActionsIcon, - homeIcon, - gearIcon, - userIcon, - viewTeamIcon, - linkIcon, - mediaMylearningIcon, -} from '@workday/canvas-system-icons-web'; -import { - defaultGetId, - useListItemRegister, - useListRenderItems, - useOverflowListItemMeasure, - useOverflowListMeasure, - useOverflowListModel, - useOverflowListTarget, -} from '@workday/canvas-kit-react/collection'; -import {Menu, useMenuModel, useMenuTarget} from '@workday/canvas-kit-react/menu'; -import {SecondaryButton, TertiaryButton} from '@workday/canvas-kit-react/button'; - -import {createStyles, CSProps, cssVar, handleCsProp} from '@workday/canvas-kit-styling'; -import {Tooltip} from '@workday/canvas-kit-react/tooltip'; -import {system} from '@workday/canvas-tokens-web'; - -const sidebarItems = [ - {id: '1', text: 'Home', icon: homeIcon}, - {id: '2', text: 'Profile', icon: userIcon}, - {id: '3', text: 'My Team', icon: viewTeamIcon}, - {id: '4', text: 'External Links', icon: linkIcon}, - {id: '5', text: 'Saved', icon: mediaMylearningIcon}, - {id: '6', text: 'Settings', icon: gearIcon}, -]; - -const useOverflowSidebar = createModelHook({ - defaultConfig: { - ...useOverflowListModel.defaultConfig, - /** - * Optional id for the whole `ActionBar` group. If not provided, a unique id will be created. - * @default useUniqueId() - */ - id: '', - - orientation: 'vertical' as typeof useOverflowListModel.defaultConfig.orientation, - menuConfig: {} as Partial, - /** - * The maximum number of actions that can be visible. - * Must be greater than 1 and less than items.length. - * @default 3 - */ - maximumVisible: 3, - }, - requiredConfig: useOverflowListModel.requiredConfig, -})(config => { - const getId = config.getId || defaultGetId; - - const items = config.items; - - const model = useOverflowListModel( - useOverflowListModel.mergeConfig(config, { - orientation: 'vertical', - items, - shouldVirtualize: false, - }) - ); - - let hiddenIds = model.state.hiddenIds; - let nonInteractiveIds = model.state.nonInteractiveIds; - const totalSize = model.state.items.length; - - // Only show maximumVisible buttons - const maximumVisible: number = - !config.maximumVisible || config.maximumVisible < 1 - ? 3 // should fallback to default value - : config.maximumVisible > totalSize - ? totalSize - : config.maximumVisible; - - if (totalSize - hiddenIds.length >= maximumVisible) { - hiddenIds = items.slice(maximumVisible, totalSize).map(getId); - } - - // Always show the first button and make sure it is interactive - if (totalSize - hiddenIds.length === 0) { - hiddenIds = items.slice(1, totalSize).map(getId); - } - - nonInteractiveIds = hiddenIds; - - const state = { - ...model.state, - hiddenIds, - nonInteractiveIds, - orientation: config.orientation || 'horizontal', - }; - - const overflowItems = React.useMemo( - () => (items ? items.filter(item => state.hiddenIds.includes(getId(item))) : undefined), - // eslint-disable-next-line react-hooks/exhaustive-deps - [state.hiddenIds, items] - ); - - const events = { - ...model.events, - }; - - const menu = useMenuModel( - useMenuModel.mergeConfig(config.menuConfig as Required, { - id: `act-bar-menu-${model.state.id}`, - items: overflowItems, - nonInteractiveIds: state.nonInteractiveIds.filter(key => !state.hiddenIds.includes(key)), - onSelect() { - menu.events.hide(); - }, - onShow() { - // Always select the first item when the menu is opened - menu.events.goToFirst(); - }, - }) - ); - - return { - ...model, - state, - events, - menu, - }; -}); - -interface SidebarItemProps { - children?: React.ReactNode; - 'data-id'?: string; -} - -const useSidebarItem = composeHooks(useOverflowListItemMeasure, useListItemRegister); - -const SidebarItem = createSubcomponent(TertiaryButton)({ - displayName: 'Sidebar.Item', - modelHook: useOverflowSidebar, - elemPropsHook: useSidebarItem, -})(({...elemProps}, Element) => { - return ; -}); - -const useSidebarOverflowButton = composeHooks( - createElemPropsHook(useOverflowSidebar)(() => ({ - 'aria-haspopup': true, - })), - useOverflowListTarget, - createSubModelElemPropsHook(useOverflowSidebar)(m => m.menu, useMenuTarget) -); - -const SidebarOverflowButton = createSubcomponent('button')({ - displayName: 'Sidebar.OverflowButton', - modelHook: useOverflowSidebar, - elemPropsHook: useSidebarOverflowButton, -})>(({...elemProps}, Element) => { - return ( - - ); -}); - -interface SidebarListProps extends CSProps { - children: ((item: T, index: number) => React.ReactNode) | React.ReactNode; - - overflowButton?: React.ReactNode; -} +import React from 'react'; +import {ActionBar, useActionBarModel} from '@workday/canvas-kit-react/action-bar'; +import {PrimaryButton} from '@workday/canvas-kit-react/button'; +import {Box} from '@workday/canvas-kit-react/layout'; +import styled from '@emotion/styled'; +import {StyledType} from '@workday/canvas-kit-react/common'; + +type MyActionItem = { + id: string; + text: React.ReactNode; +}; -const resposiveListStyles = createStyles({ - display: 'flex', - gap: system.space.x3, - depth: system.depth[1], - background: system.color.bg.default, - border: `solid 1px ${cssVar(system.color.border.container)}`, - position: 'relative', - bottom: 0, - left: 0, - flexDirection: 'column', - width: '60px', - alignItems: 'center', - right: 0, +const StyledActionbarList = styled(ActionBar.List)({ '> *': { flex: '0 0 auto', }, }); -const useSidebarList = useOverflowListMeasure; - -const SidebarList = createSubcomponent('div')({ - displayName: 'Sidebar.List', - modelHook: useOverflowSidebar, - elemPropsHook: useSidebarList, -})(({children, overflowButton, ...elemProps}, Element, model) => { - return ( - - {useListRenderItems(model, children)} - {overflowButton} - - ); -}); - -interface SidebarProps { - /** - * The contents of the ActionBar. Can be `ActionBar` children or any valid elements. - */ - children: React.ReactNode; -} - -const Sidebar = createContainer()({ - displayName: 'ActionBar', - modelHook: useOverflowSidebar, - subComponents: { - List: SidebarList, - Item: SidebarItem, - OverflowButton: SidebarOverflowButton, - Menu, - }, -})(({children}, _, model) => { - return {children}; -}); - -const containerStyles = createStyles({ - boxSizing: 'border-box', - maxHeight: '100%', - display: 'flex', - flexDirection: 'row', - height: '90vh', -}); - -const menuCardStyles = createStyles({ - maxHeight: 200, - maxWidth: 300, -}); - export const OverflowVerticalList = () => { - // useTheme is filling in the Canvas theme object if any keys are missing - - const model = useOverflowSidebar({ - items: sidebarItems, - getId: item => item.id, - getTextValue: item => item.text, - maximumVisible: 5, - }); + const [items] = React.useState([ + {id: 'first', text: 'First Action'}, + {id: 'second', text: 'Second Action'}, + {id: 'third', text: 'Third Action'}, + {id: 'fourth', text: 'Fourth Action'}, + {id: 'fifth', text: 'Fifth Action'}, + {id: 'sixth', text: 'Sixth Action'}, + {id: 'seventh', text: 'Seventh Action'}, + ]); + + const model = useActionBarModel({items, orientation: 'vertical', maximumVisible: 4}); return ( <> -
- - + + - - + } > - {(item: any, index) => ( - - console.log(item.id)} - > - + {(item: MyActionItem, index) => ( + console.log(item.id)} + > + {item.text} + )} - - - - - {(item: any) => ( - console.log(item.id)}> + + + + + {(item: MyActionItem) => ( + console.log(item.id)}> {item.text} - + )} - - - - -
+ + + + + ); };