Add Navigation, NavigationItem components, storybook router and icons
This commit is contained in:
parent
b3b20de516
commit
e8d99ccf6f
@ -1,16 +1,15 @@
|
||||
module.exports = {
|
||||
"stories": [
|
||||
"../src/**/*.stories.mdx",
|
||||
"../src/**/*.stories.@(js|jsx|ts|tsx)"
|
||||
],
|
||||
"addons": [
|
||||
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-interactions"
|
||||
"@storybook/addon-interactions",
|
||||
"storybook-addon-next-router",
|
||||
],
|
||||
"framework": "@storybook/react",
|
||||
"core": {
|
||||
"builder": "@storybook/builder-webpack5",
|
||||
"disableTelemetry": true
|
||||
}
|
||||
}
|
||||
framework: "@storybook/react",
|
||||
core: {
|
||||
builder: "@storybook/builder-webpack5",
|
||||
disableTelemetry: true,
|
||||
},
|
||||
staticDirs: ["../public"],
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { RouterContext } from "next/dist/shared/lib/router-context"; // next 12
|
||||
|
||||
export const parameters = {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
@ -6,4 +8,12 @@ export const parameters = {
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
}
|
||||
nextRouter: {
|
||||
Provider: RouterContext.Provider,
|
||||
asPath: "/",
|
||||
pathname: "/",
|
||||
query: {},
|
||||
route: "/",
|
||||
push() {}
|
||||
},
|
||||
};
|
||||
|
@ -34,6 +34,7 @@
|
||||
"eslint-config-next": "12.2.0",
|
||||
"eslint-plugin-storybook": "^0.5.13",
|
||||
"prettier": "^2.7.1",
|
||||
"storybook-addon-next-router": "^4.0.0",
|
||||
"typescript": "4.7.4"
|
||||
}
|
||||
}
|
||||
|
11
public/icons/calendar.svg
Normal file
11
public/icons/calendar.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<rect x="4" y="5" width="16" height="16" rx="2" />
|
||||
<line x1="16" y1="3" x2="16" y2="7" />
|
||||
<line x1="8" y1="3" x2="8" y2="7" />
|
||||
<line x1="4" y1="11" x2="20" y2="11" />
|
||||
<line x1="11" y1="15" x2="12" y2="15" />
|
||||
<line x1="12" y1="15" x2="12" y2="18" />
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 552 B |
6
public/icons/check.svg
Normal file
6
public/icons/check.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-check" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M5 12l5 5l10 -10" />
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 320 B |
8
public/icons/home.svg
Normal file
8
public/icons/home.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<polyline points="5 12 3 12 12 3 21 12 19 12" />
|
||||
<path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7" />
|
||||
<path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6" />
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 453 B |
21
public/icons/icons-license.txt
Normal file
21
public/icons/icons-license.txt
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2022 Paweł Kuna
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -16,7 +16,9 @@ export function ExpressionCard({
|
||||
return (
|
||||
<article className="expression-card">
|
||||
<h2 className="expression-card-prompt">{prompt}</h2>
|
||||
<h3 className="expression-card-categories">{categories.join(", ")}</h3>
|
||||
<span className="expression-card-categories">
|
||||
{categories.join(", ")}
|
||||
</span>
|
||||
{show_description && (
|
||||
<div className="expression-card-details">{description}</div>
|
||||
)}
|
||||
|
16
src/components/Navigation/Navigation.stories.tsx
Normal file
16
src/components/Navigation/Navigation.stories.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import "../../styles/globals.css";
|
||||
import "../../styles/components.css";
|
||||
|
||||
import React from "react";
|
||||
import { ComponentStory, ComponentMeta } from "@storybook/react";
|
||||
|
||||
import { Navigation } from "./Navigation";
|
||||
|
||||
export default {
|
||||
title: "Components/Navigation",
|
||||
component: Navigation,
|
||||
} as ComponentMeta<typeof Navigation>;
|
||||
|
||||
export const Example: ComponentStory<typeof Navigation> = (args) => (
|
||||
<Navigation />
|
||||
);
|
19
src/components/Navigation/Navigation.tsx
Normal file
19
src/components/Navigation/Navigation.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { NavigationItem } from "./NavigationItem";
|
||||
|
||||
export function Navigation() {
|
||||
return (
|
||||
<nav className="navigation">
|
||||
<NavigationItem text="home" iconUrl="/icons/home.svg" href="/" />
|
||||
<NavigationItem
|
||||
text="practice"
|
||||
iconUrl="/icons/calendar.svg"
|
||||
href="/practice"
|
||||
/>
|
||||
<NavigationItem
|
||||
text="settings"
|
||||
iconUrl="/icons/check.svg"
|
||||
href="/check"
|
||||
/>
|
||||
</nav>
|
||||
);
|
||||
}
|
44
src/components/Navigation/NavigationItem.stories.tsx
Normal file
44
src/components/Navigation/NavigationItem.stories.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import "../../styles/globals.css";
|
||||
import "../../styles/components.css";
|
||||
|
||||
import React from "react";
|
||||
import { ComponentStory, ComponentMeta } from "@storybook/react";
|
||||
|
||||
import { NavigationItem } from "./NavigationItem";
|
||||
|
||||
export default {
|
||||
title: "Components/Navigation Item",
|
||||
component: NavigationItem,
|
||||
} as ComponentMeta<typeof NavigationItem>;
|
||||
|
||||
const Template: ComponentStory<typeof NavigationItem> = (args) => (
|
||||
<NavigationItem {...args} />
|
||||
);
|
||||
|
||||
export const TextItem = Template.bind({});
|
||||
TextItem.story = {
|
||||
args: {
|
||||
text: "Home",
|
||||
href: "/",
|
||||
},
|
||||
};
|
||||
|
||||
export const IconItem = Template.bind({});
|
||||
IconItem.args = {
|
||||
iconUrl: "/icons/home.svg",
|
||||
href: "/",
|
||||
};
|
||||
|
||||
export const TextAndIconItem = Template.bind({});
|
||||
TextAndIconItem.args = {
|
||||
text: "Home",
|
||||
iconUrl: "/icons/home.svg",
|
||||
href: "/",
|
||||
};
|
||||
|
||||
export const InactiveItem = Template.bind({});
|
||||
InactiveItem.args = {
|
||||
text: "Inactive",
|
||||
iconUrl: "/icons/home.svg",
|
||||
href: "current-path",
|
||||
};
|
26
src/components/Navigation/NavigationItem.tsx
Normal file
26
src/components/Navigation/NavigationItem.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { UrlObject } from "url";
|
||||
|
||||
export interface NavigationItemProps {
|
||||
text: string;
|
||||
iconUrl?: string;
|
||||
href: string | UrlObject;
|
||||
}
|
||||
|
||||
export function NavigationItem({ text, iconUrl, href }: NavigationItemProps) {
|
||||
const router = useRouter();
|
||||
const active = router.pathname === href;
|
||||
|
||||
return (
|
||||
<li className={active ? "navigation-item active" : "navigation-item"}>
|
||||
<Link href={href} passHref>
|
||||
<a>
|
||||
{iconUrl && <Image src={iconUrl} width="24" height="24" alt="" />}
|
||||
<span>{text}</span>
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
}
|
2
src/components/Navigation/index.tsx
Normal file
2
src/components/Navigation/index.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./Navigation";
|
||||
export * from "./NavigationItem";
|
@ -1 +1,2 @@
|
||||
export * from "./ExpressionCard";
|
||||
export * from "./Navigation";
|
||||
|
@ -1,3 +1,41 @@
|
||||
/* Navigation */
|
||||
|
||||
.navigation {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.navigation > .navigation-item {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.navigation-item {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.navigation-item > a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background-color: lavender;
|
||||
border: 1px solid darkslategray;
|
||||
font-weight: bold;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.navigation-item > a:hover {
|
||||
background-color: lavenderblush;
|
||||
}
|
||||
|
||||
.navigation-item.active > a {
|
||||
background-color: lightsteelblue;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Expression cards */
|
||||
|
||||
.expression-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -9690,6 +9690,13 @@ store2@^2.12.0:
|
||||
resolved "https://registry.yarnpkg.com/store2/-/store2-2.13.2.tgz#01ad8802ca5b445b9c316b55e72645c13a3cd7e3"
|
||||
integrity sha512-CMtO2Uneg3SAz/d6fZ/6qbqqQHi2ynq6/KzMD/26gTkiEShCcpqFfTHgOxsE0egAq6SX3FmN4CeSqn8BzXQkJg==
|
||||
|
||||
storybook-addon-next-router@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/storybook-addon-next-router/-/storybook-addon-next-router-4.0.0.tgz#d0719e6e27cbd2c374d23fad821157f2b053b045"
|
||||
integrity sha512-zaEo/RI9IXzxlaiWeFBMBkjxYabLZGFibD82xH9AcKYcN/5yZq7VKo+NckMuTVu2WBaCUR4jA/O+ftcrQEvvfA==
|
||||
dependencies:
|
||||
tslib "^2.3.0"
|
||||
|
||||
stream-browserify@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
|
||||
@ -10146,7 +10153,7 @@ tslib@^1.8.1, tslib@^1.9.3:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.4.0:
|
||||
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.3.0, tslib@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||
|
Loading…
Reference in New Issue
Block a user