chore: Secondary sidebar nav

---

Co-authored-by: Subir <subir@viabl.ventures>
This commit is contained in:
Ahmed Bouhuolia 2022-05-06 13:29:08 +02:00 committed by GitHub
parent 5460d3afae
commit ce81d96bd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 280 additions and 0 deletions

View File

@ -0,0 +1,60 @@
// =============================================================================
// Copyright 2022 Haveno
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
import type { ComponentStory, ComponentMeta } from "@storybook/react";
import { SecondarySidebar } from "./SecondarySidebar";
import { SecondarySidebarItem } from "./SecondarySidebarItem";
export default {
title: "atoms/SecondarySidebar",
component: SecondarySidebar,
} as ComponentMeta<typeof SecondarySidebar>;
const menu = [
{
label: "Payment Accounts",
isActive: true,
},
{
label: "Node Settings",
},
{
label: "Security",
},
{
label: "Wallet",
},
{
label: "Back",
},
];
const Template: ComponentStory<typeof SecondarySidebar> = () => {
return (
<SecondarySidebar>
{menu.map((item) => (
<SecondarySidebarItem
key={item.label}
label={item.label}
isActive={item.isActive}
/>
))}
</SecondarySidebar>
);
};
export const Default = Template.bind({});
Default.args = {};

View File

@ -0,0 +1,35 @@
// =============================================================================
// Copyright 2022 Haveno
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
import { describe, expect, it } from "vitest";
import { render } from "@testing-library/react";
import { SecondarySidebar, SecondarySidebarItem } from "./";
import { ThemeProvider } from "@atoms/AppProviders/ThemeProvider";
describe("molecules::SecondarySidebar", () => {
it("renders without exploding", () => {
const { asFragment } = render(
<ThemeProvider>
<SecondarySidebar>
<SecondarySidebarItem label={"Active item"} isActive={true} />
<SecondarySidebarItem label={"Inactive item"} isActive={false} />
<SecondarySidebarItem label={"Active item"} isActive={true} />
</SecondarySidebar>
</ThemeProvider>
);
expect(asFragment()).toMatchSnapshot();
});
});

View File

@ -0,0 +1,34 @@
// =============================================================================
// Copyright 2022 Haveno
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
import { Stack, Navbar } from "@mantine/core";
interface SecondarySidebarProps {
children: Array<JSX.Element>;
}
/**
* Secondary sidebar.
* @param {SecondarySidebarProps}
* @returns {JSX.Element}
*/
export function SecondarySidebar({ children }: SecondarySidebarProps) {
return (
<Stack>
<Navbar>{children}</Navbar>
</Stack>
);
}

View File

@ -0,0 +1,77 @@
// =============================================================================
// Copyright 2022 Haveno
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
import { UnstyledButton, Group, Text, createStyles } from "@mantine/core";
interface SecondarySidebarItemProps {
isActive?: boolean;
label: string;
}
/**
* Secondary sidebar menu item.
* @param {SecondarySidebarItemProps}
* @returns {JSX.Element}
*/
export function SecondarySidebarItem({
isActive = false,
label,
}: SecondarySidebarItemProps) {
const { classes } = useStyles({ isActive });
return (
<UnstyledButton className={classes.button}>
<Group className={classes.group}>
<Text className={classes.text}>{label}</Text>
</Group>
</UnstyledButton>
);
}
const useStyles = createStyles<string, { isActive: boolean }>(
(theme, { isActive }) => ({
button: {
padding: `${theme.spacing.lg}px 0`,
color: isActive ? theme.colors.dark[9] : theme.colors.gray[6],
transition: "color 0.1s ease-in-out",
"&:hover": {
color: theme.colors.dark[9],
},
},
group: {
position: "relative",
},
text: {
textTransform: "uppercase",
fontSize: theme.fontSizes.xs,
fontWeight: 700,
paddingLeft: isActive ? 20 : "0",
"&:before": {
content: '""',
display: "inline-block",
width: isActive ? "12px" : "0",
height: 3,
backgroundColor: theme.colors.blue[6],
position: "absolute",
top: "50%",
marginTop: "-1.5px",
left: 0,
borderRadius: 3,
},
},
})
);

View File

@ -0,0 +1,56 @@
// Vitest Snapshot v1
exports[`molecules::SecondarySidebar > renders without exploding 1`] = `
<DocumentFragment>
<div
class="mantine-Stack-root mantine-lfk3cq"
>
<nav
class="mantine-Navbar-root mantine-1tps18r"
>
<button
class="mantine-UnstyledButton-root mantine-8x6xy1"
type="button"
>
<div
class="mantine-Group-root mantine-2jlg77"
>
<div
class="mantine-Text-root mantine-Group-child mantine-1ga3coc"
>
Active item
</div>
</div>
</button>
<button
class="mantine-UnstyledButton-root mantine-1us1eqc"
type="button"
>
<div
class="mantine-Group-root mantine-2jlg77"
>
<div
class="mantine-Text-root mantine-Group-child mantine-govdvw"
>
Inactive item
</div>
</div>
</button>
<button
class="mantine-UnstyledButton-root mantine-8x6xy1"
type="button"
>
<div
class="mantine-Group-root mantine-2jlg77"
>
<div
class="mantine-Text-root mantine-Group-child mantine-1ga3coc"
>
Active item
</div>
</div>
</button>
</nav>
</div>
</DocumentFragment>
`;

View File

@ -0,0 +1,18 @@
// =============================================================================
// Copyright 2022 Haveno
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
export * from "./SecondarySidebar";
export * from "./SecondarySidebarItem";