Skip to content

Commit

Permalink
feat(react-nav-preview): Applying styles to NavCategoryItem and NavSu…
Browse files Browse the repository at this point in the history
…bItem (microsoft#31019)
  • Loading branch information
mltejera authored Apr 16, 2024
1 parent d38059f commit 25cfd4d
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export type NavCategoryItemProps = ComponentProps<Partial<NavCategoryItemSlots>>

// @public (undocumented)
export type NavCategoryItemSlots = {
root: Slot<'button'>;
root: NonNullable<Slot<'button'>>;
icon?: Slot<'span'>;
expandIcon: NonNullable<Slot<'span'>>;
};

Expand Down Expand Up @@ -110,7 +111,6 @@ export type NavItemRegisterData = {
export type NavItemSlots = {
root: NonNullable<Slot<'a'>>;
icon?: Slot<'span'>;
content: NonNullable<Slot<'span'>>;
};

// @public
Expand Down Expand Up @@ -177,7 +177,6 @@ export type NavSubItemProps = ComponentProps<Partial<NavSubItemSlots>> & {
// @public (undocumented)
export type NavSubItemSlots = {
root: Slot<'a'>;
content: NonNullable<Slot<'span'>>;
};

// @public
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { NavCategoryItemContextValue } from '../NavCategoryItemContext';

import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';

export type NavCategoryItemContextValues = {
Expand All @@ -10,20 +9,18 @@ export type NavCategoryItemSlots = {
/**
* The root element
*/
root: Slot<'button'>;
root: NonNullable<Slot<'button'>>;

/**
* The component to be used as button in heading
* Icon that renders before the content.
* Should be specific to each Category
*/
// button: NonNullable<Slot<ARIAButtonSlotProps<'a'>>>;
icon?: Slot<'span'>;

/**
* Expand icon slot rendered before (or after) children content in heading.
* Expand icon slot rendered after the content to indicate an open and closed state.
*/
expandIcon: NonNullable<Slot<'span'>>;
// /**
// * Expand icon slot rendered before (or after) children content in heading.
// */
// icon?: Slot<'div'>;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ export const renderNavCategoryItem_unstable = (
return (
<NavCategoryItemProvider value={contextValues.navCategoryItem}>
<state.root>
{/* TODO: These were copied from AccordionHeader.
We need to decide if they are still applicable
in our scenario and how to adapt them. */}
{/* <state.button> */}
{/* Todo: {state.icon && <state.icon />} */}
{state.icon && <state.icon />}
{state.root.children}
{state.expandIcon && <state.expandIcon />} {/* </state.button> */}
{state.expandIcon && <state.expandIcon />}
</state.root>
</NavCategoryItemProvider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,77 @@
import { makeResetStyles, mergeClasses, makeStyles } from '@griffel/react';
import { typographyStyles } from '@fluentui/react-theme';
import { makeStyles, mergeClasses } from '@griffel/react';
import { SlotClassNames } from '@fluentui/react-utilities';
import { typographyStyles } from '@fluentui/react-theme';
import {
useContentStyles,
useIconStyles,
useIndicatorStyles,
useRootDefaultClassName,
} from '../sharedNavStyles.styles';

import type { NavCategoryItemSlots, NavCategoryItemState } from './NavCategoryItem.types';

export const navCategoryItemClassNames: SlotClassNames<NavCategoryItemSlots> = {
root: 'fui-NavCategoryItem',
icon: 'fui-NavCategoryItem__icon',
expandIcon: 'fui-NavCategoryItem__expandIcon',
};

/**
* Styles for the root slot
*/
const useRootStyles = makeResetStyles({
display: 'flex',
...typographyStyles.body1,
});

const useContentStyles = makeStyles({
icon: {
display: 'flex',
const useExpandIconStyles = makeStyles({
base: {
marginInlineStart: 'auto',
},
open: {
transform: 'rotate(-90deg)',
},
closed: {
transform: 'rotate(90deg)',
},
selected: typographyStyles.body1Strong,
});

/**
* Styles for the root slot
*/
export const useRootStyles = makeStyles({
base: {
width: '100%',
},
});

/**
* Apply styling to the NavCategoryItem slots based on the state
*/
export const useNavCategoryItemStyles_unstable = (state: NavCategoryItemState): NavCategoryItemState => {
const defaultRootStyles = useRootStyles();
const rootStyles = useRootStyles();
const defaultRootClassName = useRootDefaultClassName();
const contentStyles = useContentStyles();
const indicatorStyles = useIndicatorStyles();
const iconStyles = useIconStyles();
const expandIconStyles = useExpandIconStyles();

const { selected } = state;
const { selected, open } = state;

state.root.className = mergeClasses(
navCategoryItemClassNames.root,
defaultRootStyles,
defaultRootClassName,
rootStyles.base,
selected && open === false && indicatorStyles.base,
selected && open === false && contentStyles.selected,
state.root.className,
selected && state.open === false && contentStyles.selected,
);

state.expandIcon.className = mergeClasses(
navCategoryItemClassNames.expandIcon,
contentStyles.icon,
state.open ? contentStyles.open : contentStyles.closed,
expandIconStyles.base,
state.open && expandIconStyles.open,
state.expandIcon.className,
);

if (state.icon) {
state.icon.className = mergeClasses(
navCategoryItemClassNames.icon,
iconStyles.base,
selected && iconStyles.selected,
state.icon.className,
);
}

return state;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const useNavCategoryItem_unstable = (
props: NavCategoryItemProps,
ref: React.Ref<HTMLButtonElement>,
): NavCategoryItemState => {
const { onClick, expandIcon } = props;
const { onClick, expandIcon, icon } = props;

const { open, value } = useNavCategoryContext_unstable();

Expand All @@ -30,41 +30,14 @@ export const useNavCategoryItem_unstable = (

const selected = selectedCategoryValue === value;

// TODO - these are copied from AccordionHeader.
// We need to figure out if they are applicable to this
// scenario and adapt them accordingly.

// const buttonSlot = slot.always(button, {
// elementType: 'button',
// defaultProps: {
// // we may decide to light these up later
// // disabled,
// // disabledFocusable,
// 'aria-expanded': open,
// type: 'button',
// onClick: onNavCategoryItemClick,
// },
// });

// buttonSlot.onClick = useEventCallback(event => {
// if (isResolvedShorthand(button)) {
// button.onClick?.(event);
// }
// if (!event.defaultPrevented) {
// onRequestNavCategoryItemToggle(event, { value, event }); //({ value, event });
// }
// });

return {
open,
value,
selected,
// TODO add appropriate props/defaults
components: {
root: 'button',
// button: 'div',
icon: 'span',
expandIcon: 'span',
// icon: 'div',
},
root: slot.always(
getIntrinsicElementProps('button', {
Expand All @@ -83,15 +56,8 @@ export const useNavCategoryItem_unstable = (
},
elementType: 'span',
}),
// button: useARIAButtonProps(buttonSlot.as, buttonSlot),
// button: slot.always(
// getIntrinsicElementProps('button', {
// ref,
// role: 'button',
// type: 'button',
// onClick: onNavCategoryItemClick,
// }),
// { elementType: 'button' },
// ),
icon: slot.optional(icon, {
elementType: 'span',
}),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ describe('NavItem', () => {
props: { icon: 'Test Icon', content: 'Some Content' },
expectedClassNames: {
root: navItemClassNames.root,
content: navItemClassNames.content,
icon: navItemClassNames.icon,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ export type NavItemSlots = {
* Icon that renders before the content.
*/
icon?: Slot<'span'>;

/**
* Component children are placed in this slot
* Avoid using the `children` property in this slot in favour of Component children whenever possible.
*/
content: NonNullable<Slot<'span'>>;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const renderNavItem_unstable = (state: NavItemState) => {
return (
<state.root>
{state.icon && <state.icon />}
<state.content />
{state.root.children}
</state.root>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { NavItemProps, NavItemState } from './NavItem.types';
* @param ref - reference to root HTMLAnchorElement of NavItem
*/
export const useNavItem_unstable = (props: NavItemProps, ref: React.Ref<HTMLAnchorElement>): NavItemState => {
const { content, onClick, value, icon } = props;
const { onClick, value, icon } = props;

const { selectedValue, onRegister, onUnregister, onSelect } = useNavContext_unstable();

Expand All @@ -36,13 +36,8 @@ export const useNavItem_unstable = (props: NavItemProps, ref: React.Ref<HTMLAnch
};
}, [onRegister, onUnregister, innerRef, value]);

const contentSlot = slot.always(content, {
defaultProps: { children: props.children },
elementType: 'span',
});

return {
components: { root: 'a', content: 'span', icon: 'span' },
components: { root: 'a', icon: 'span' },
root: slot.always(
getIntrinsicElementProps('a', {
ref,
Expand All @@ -56,7 +51,6 @@ export const useNavItem_unstable = (props: NavItemProps, ref: React.Ref<HTMLAnch
icon: slot.optional(icon, {
elementType: 'span',
}),
content: contentSlot,
selected,
value,
};
Expand Down
Loading

0 comments on commit 25cfd4d

Please sign in to comment.