Skip to content

Commit

Permalink
Aligned text over multiple lines and improved auto-size. (#173)
Browse files Browse the repository at this point in the history
* Aligned text over multiple lines and improved auto-size.
* Improved spacing in menu and changed color of section icon
* Better alignment of elements in menu when some have an icon while others do not.
* Implemented max and min width for menu.
  • Loading branch information
rubenthoms authored Oct 7, 2021
1 parent 83e3bc4 commit c67f634
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 78 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [UNRELEASED] - YYYY-MM-DD

### Changed
- [#161](https://github.com/equinor/webviz-core-components/pull/161) - Updated to `Dash 2.0`.

- [#161](https://github.com/equinor/webviz-core-components/pull/161) - Updated to `Dash 2.0`.
- [#173](https://github.com/equinor/webviz-core-components/pull/173) - Improved menu layout and auto-width.

### Fixed

Expand All @@ -19,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#172](https://github.com/equinor/webviz-core-components/pull/172) - Bug fix: No margin between plugins.

### Added

- [#154](https://github.com/equinor/webviz-core-components/pull/154) - Implemented new menu component.

## [0.5.1] - 2021-07-12
Expand Down
2 changes: 1 addition & 1 deletion react/src/demo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const App: React.FC = () => {
content: [
{
type: "group",
title: "Group",
title: "Demos",
content: [
{
type: "page",
Expand Down
21 changes: 21 additions & 0 deletions react/src/lib/components/Menu/Menu.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

.Menu__Ruler {
font-family: sans-serif;
white-space: nowrap;
}

.Menu__Icon {
Expand All @@ -19,3 +20,23 @@
.Menu__disabled {
cursor: not-allowed;
}

.Menu__Item {
display: flex;
flex-direction: row;
align-items: center;
}

.Menu__Item > span {
display: inline-block;
white-space: pre-wrap;
word-wrap: break-word;
}

.Menu__Item > span.Icon {
max-width: calc(100% - 40px);
}

.Menu__Item > span.IconPlaceholder {
padding-left: 40px;
}
49 changes: 30 additions & 19 deletions react/src/lib/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,33 @@ const getNavigationMaxWidth = (
navigationItems: PropertyNavigationType
): number => {
const recursivelyParseItems = (
item: PropertyPageType | PropertyGroupType | PropertySectionType,
items: (PropertyPageType | PropertyGroupType | PropertySectionType)[],
iconAtParentLevel?: boolean,
depth = 0
) => {
let maxWidth = depth * 16 + calculateTextWidth(item.title);
if (item.type !== "page") {
item.content.forEach(
(el) =>
(maxWidth = Math.max(
maxWidth,
recursivelyParseItems(el, depth + 1)
))
let maxWidth = 0;
const atLeastOneIconUsed = items.some((el) => el.icon !== undefined);
items.forEach((item) => {
maxWidth = Math.max(
maxWidth,
depth * 16 +
calculateTextWidth(item.title) +
(item.icon || iconAtParentLevel ? 40 : 0)
);
}
if (item.type !== "page") {
maxWidth = Math.max(
maxWidth,
recursivelyParseItems(
item.content,
atLeastOneIconUsed,
depth + 1
)
);
}
});
return maxWidth;
};
let maxWidth = 0;
navigationItems.forEach(
(el: PropertyPageType | PropertyGroupType | PropertySectionType) =>
(maxWidth = Math.max(recursivelyParseItems(el), maxWidth))
);
return maxWidth;
return recursivelyParseItems(navigationItems);
};

/**
Expand Down Expand Up @@ -166,15 +172,20 @@ export const Menu: React.FC<MenuProps> = (props) => {
const windowSize = useWindowSize();

const menuContentSpacing = 50;
const menuPadding = 32;

React.useEffect(() => {
setNavigationsItemsWithAssignedIds(
makeNavigationItemsWithAssignedIds(props.navigationItems)
);
setMenuWidth(
Math.min(
getNavigationMaxWidth(props.navigationItems) * 1.1 + 40,
windowSize.width / 2
Math.max(
250,
Math.min(
getNavigationMaxWidth(props.navigationItems) + menuPadding,
windowSize.width / 4,
400
)
)
);
}, [props.navigationItems, windowSize.width]);
Expand Down
16 changes: 14 additions & 2 deletions react/src/lib/components/Menu/components/Group/Group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type GroupProps = {
title: string;
level: number;
icon?: string;
applyIconIndentation: boolean;
forceOpen?: boolean;
children?: React.ReactNode;
};
Expand Down Expand Up @@ -41,13 +42,23 @@ export const Group: React.FC<GroupProps> = (props) => {
}}
>
<div
className="Menu__GroupTitle"
className="Menu__GroupTitle Menu__Item"
style={{ paddingLeft: 16 * props.level }}
>
{props.icon && (
<Icon className="Menu__Icon" icon={props.icon} />
)}
{props.title}
<span
className={
props.icon
? "Icon"
: props.applyIconIndentation
? "IconPlaceholder"
: ""
}
>
{props.title}
</span>
</div>
<div
className={props.forceOpen ? "Menu__disabled" : ""}
Expand Down Expand Up @@ -86,6 +97,7 @@ Group.propTypes = {
title: PropTypes.string.isRequired,
level: PropTypes.number.isRequired,
icon: PropTypes.string,
applyIconIndentation: PropTypes.bool.isRequired,
forceOpen: PropTypes.bool,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
Expand Down
113 changes: 65 additions & 48 deletions react/src/lib/components/Menu/components/MenuContent/MenuContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,55 +116,72 @@ const makeNavigation = (
): JSX.Element => {
const recursivelyMakeNavigation = (
items: NavigationItemType[],
iconAtParentLevel?: boolean,
level = 1
): JSX.Element => (
<>
{items.map((item) => {
if (item.type === "section") {
return (
<Section
key={item.id}
title={item.title}
icon={item.icon}
>
{recursivelyMakeNavigation(
(item as SectionType).content
)}
</Section>
);
} else if (item.type === "group") {
return (
<Group
id={item.id}
key={item.id}
level={level}
title={item.title}
icon={item.icon}
forceOpen={filtered}
>
{recursivelyMakeNavigation(
(item as GroupType).content,
level + 1
)}
</Group>
);
} else if (item.type === "page") {
return (
<Page
key={item.id}
level={level}
{...(item as PageType)}
onClick={() =>
onPageChange((item as PageType).href)
}
/>
);
} else {
return null;
}
})}
</>
);
): JSX.Element => {
const atLeastOneIconUsed = items.some((el) => el.icon !== undefined);
return (
<>
{items.map((item) => {
if (item.type === "section") {
return (
<Section
key={item.id}
title={item.title}
icon={item.icon}
applyIconIndentation={atLeastOneIconUsed}
>
{recursivelyMakeNavigation(
(item as SectionType).content,
atLeastOneIconUsed
)}
</Section>
);
} else if (item.type === "group") {
return (
<Group
id={item.id}
key={item.id}
level={level}
title={item.title}
icon={item.icon}
forceOpen={filtered}
applyIconIndentation={
atLeastOneIconUsed ||
iconAtParentLevel ||
false
}
>
{recursivelyMakeNavigation(
(item as GroupType).content,
atLeastOneIconUsed,
level + 1
)}
</Group>
);
} else if (item.type === "page") {
return (
<Page
key={item.id}
level={level}
applyIconIndentation={
atLeastOneIconUsed ||
iconAtParentLevel ||
false
}
{...(item as PageType)}
onClick={() =>
onPageChange((item as PageType).href)
}
/>
);
} else {
return null;
}
})}
</>
);
};
return recursivelyMakeNavigation(navigation);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
width: fit-content;
z-index: 1001;
display: inline-block;
max-width: 300px;
}

.Menu__MenuDrawerContentWrapper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export const MenuDrawer = React.forwardRef<HTMLDivElement, MenuDrawerProps>(
right: position.right,
bottom: position.bottom,
width: props.maxWidth + "px",
maxWidth: props.maxWidth + "px",
}}
>
{props.pinned && (
Expand Down
1 change: 0 additions & 1 deletion react/src/lib/components/Menu/components/Page/Page.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
padding: 16px;
padding-left: 40px;
text-decoration: none;
display: block;
color: black;
}

Expand Down
18 changes: 16 additions & 2 deletions react/src/lib/components/Menu/components/Page/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type PageProps = {
href: string;
level: number;
icon?: string;
applyIconIndentation: boolean;
onClick: () => void;
};

Expand All @@ -19,7 +20,9 @@ export const Page: React.FC<PageProps> = (props) => {

return (
<a
className={`Menu__Page${active ? " Menu__CurrentPage" : ""}`}
className={`Menu__Page${
active ? " Menu__CurrentPage" : ""
} Menu__Item`}
href={props.href}
onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {
props.onClick();
Expand All @@ -34,7 +37,17 @@ export const Page: React.FC<PageProps> = (props) => {
active={active}
/>
)}
{props.title}
<span
className={
props.icon
? "Icon"
: props.applyIconIndentation
? "IconPlaceholder"
: ""
}
>
{props.title}
</span>
</a>
);
};
Expand All @@ -44,5 +57,6 @@ Page.propTypes = {
href: PropTypes.string.isRequired,
level: PropTypes.number.isRequired,
icon: PropTypes.string,
applyIconIndentation: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
};
4 changes: 4 additions & 0 deletions react/src/lib/components/Menu/components/Section/Section.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
flex-direction: row;
}

.Menu__SectionTitle > svg * {
fill: #007079;
}

.Menu__Section {
padding-bottom: 24px;
margin-top: 24px;
Expand Down
Loading

0 comments on commit c67f634

Please sign in to comment.