Skip to content

Commit 7ae14af

Browse files
cogwizzlenkrantz
andauthored
Sidebar disclosure color (#4011)
* refactor: extract NavigationDisclosure props into interface * fix: fixing type issue * fix: fixing header for unselected navigation header * refactor: adding a styles for the unselected disclosure heading * refactor: extracting style computation logic into a custom hook * refactor: renaming variable * fix: removing change * chore: adding changeset * chore: formatting * feat: adding sidebar navigation item unselected styles * feat: updating the computed styles * chore: updating changeset message * feat: adjusting the icon color in sidebar navigation disclosure heading * chore: reverting changes * chore: small changes for merging --------- Co-authored-by: “nora <[email protected]> Co-authored-by: Nora Krantz <[email protected]>
1 parent df4ffd6 commit 7ae14af

File tree

3 files changed

+73
-11
lines changed

3 files changed

+73
-11
lines changed

.changeset/long-moons-worry.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@twilio-paste/sidebar": patch
3+
"@twilio-paste/core": patch
4+
---
5+
6+
[Sidebar] Updating the unselected Sidebar Disclosure Header and SidebarNavigationItems.

packages/paste-core/components/sidebar/src/navigation/SidebarNavigationDisclosureHeading.tsx

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,55 @@ export interface SidebarNavigationDisclosureHeadingProps extends HTMLPasteProps<
4040
icon?: React.ReactNode;
4141
}
4242

43+
interface UseComputeDisclosureHeadingStylesArgs {
44+
/** Whether the heading is selected */
45+
selected?: boolean;
46+
/** Whether the heading is nested within another heading */
47+
nested: boolean;
48+
}
49+
50+
/**
51+
* Small hook that abstracts the logic of computing styles for the SidebarNavigationDisclosureHeading component.
52+
*/
53+
const useComputeDisclosureHeadingStyles = ({ nested, selected }: UseComputeDisclosureHeadingStylesArgs): BoxProps => {
54+
let styles: BoxProps = {};
55+
if (nested) {
56+
styles = sidebarNavigationLabelNestedStyles;
57+
} else {
58+
styles = sidebarNavigationLabelStyles;
59+
}
60+
if (selected) {
61+
styles = { ...styles, ...sidebarNavigationLabelSelectedStyles };
62+
}
63+
return styles;
64+
};
65+
66+
interface UseAdjustIconColorArgs {
67+
/** Icon to be displayed within the Heading. */
68+
icon: React.ReactNode;
69+
/** Whether the heading is selected. */
70+
selected?: boolean;
71+
}
72+
73+
/**
74+
* Adjust the color on the icon if it is not selected. It accomplishes this by cloning the icon node and applying the colorTextIconInverse color.
75+
* Memoized to reduce the number of times the icon is cloned.
76+
*/
77+
const useAdjustIconColor = ({ icon, selected }: UseAdjustIconColorArgs): Required<React.ReactNode> => {
78+
return React.useMemo(() => {
79+
if (!icon) {
80+
return null;
81+
}
82+
if (icon && React.isValidElement(icon) && !selected) {
83+
const iconElement = icon as React.ReactElement;
84+
return React.cloneElement(iconElement, {
85+
color: "colorTextIconInverse",
86+
});
87+
}
88+
return icon;
89+
}, [icon, selected]);
90+
};
91+
4392
const StyledDisclosureHeading = React.forwardRef<HTMLDivElement, SidebarNavigationDisclosureHeadingProps>(
4493
({ children, element = "SIDEBAR_NAVIGATION_DISCLOSURE_HEADING", selected, icon, ...props }, ref) => {
4594
const { collapsed, variant } = React.useContext(SidebarContext);
@@ -63,15 +112,17 @@ const StyledDisclosureHeading = React.forwardRef<HTMLDivElement, SidebarNavigati
63112
}, 120);
64113
}, [collapsed, isCompact]);
65114

115+
const disclosureHeadingStyles = useComputeDisclosureHeadingStyles({ nested, selected });
116+
const adjustedIcon = useAdjustIconColor({ icon, selected });
117+
66118
return (
67119
<Box
68120
{...safelySpreadBoxProps(props)}
69121
ref={ref}
70122
element={element}
71123
onMouseEnter={() => setShouldIconMove(true)}
72124
onMouseLeave={() => setShouldIconMove(false)}
73-
{...(nested ? sidebarNavigationLabelNestedStyles : sidebarNavigationLabelStyles)}
74-
{...(selected && sidebarNavigationLabelSelectedStyles)}
125+
{...disclosureHeadingStyles}
75126
>
76127
<Box
77128
as="span"
@@ -87,7 +138,7 @@ const StyledDisclosureHeading = React.forwardRef<HTMLDivElement, SidebarNavigati
87138
>
88139
<ChevronDisclosureIcon color="inherit" decorative size="sizeIcon20" />
89140
</Box>
90-
{icon ? icon : null}
141+
{adjustedIcon}
91142
<Box
92143
as="span"
93144
display="block"

packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@ import { SidebarAnchor } from "./SidebarAnchor";
2323

2424
const CY_BASE = "sidebar-disclosure";
2525

26-
const NavigationDisclosure: React.FC<
27-
React.PropsWithChildren<{
28-
children: SidebarNavigationDisclosureContentProps["children"];
29-
categoryRoute: typeof SidebarCategoryRoutes[keyof typeof SidebarCategoryRoutes];
30-
buttonText: string;
31-
onClick?: SidebarNavigationDisclosureHeadingProps["onClick"];
32-
}>
33-
> = ({ children, categoryRoute, buttonText, onClick }) => {
26+
interface NavigationDisclosureProps {
27+
buttonText: string;
28+
categoryRoute: typeof SidebarCategoryRoutes[keyof typeof SidebarCategoryRoutes];
29+
children: SidebarNavigationDisclosureContentProps["children"];
30+
onClick?: SidebarNavigationDisclosureHeadingProps["onClick"];
31+
}
32+
33+
const NavigationDisclosure: React.FC<React.PropsWithChildren<NavigationDisclosureProps>> = ({
34+
children,
35+
categoryRoute,
36+
buttonText,
37+
onClick,
38+
}) => {
3439
const pathname = useLocationPathname();
3540
const disclosure = useSidebarNavigationDisclosureState({
3641
visible: pathname.startsWith(categoryRoute),

0 commit comments

Comments
 (0)