Add Navigation, NavigationItem components, storybook router and icons
This commit is contained in:
parent
b3b20de516
commit
e8d99ccf6f
@ -1,16 +1,15 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"stories": [
|
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||||
"../src/**/*.stories.mdx",
|
addons: [
|
||||||
"../src/**/*.stories.@(js|jsx|ts|tsx)"
|
|
||||||
],
|
|
||||||
"addons": [
|
|
||||||
"@storybook/addon-links",
|
"@storybook/addon-links",
|
||||||
"@storybook/addon-essentials",
|
"@storybook/addon-essentials",
|
||||||
"@storybook/addon-interactions"
|
"@storybook/addon-interactions",
|
||||||
|
"storybook-addon-next-router",
|
||||||
],
|
],
|
||||||
"framework": "@storybook/react",
|
framework: "@storybook/react",
|
||||||
"core": {
|
core: {
|
||||||
"builder": "@storybook/builder-webpack5",
|
builder: "@storybook/builder-webpack5",
|
||||||
"disableTelemetry": true
|
disableTelemetry: true,
|
||||||
}
|
},
|
||||||
}
|
staticDirs: ["../public"],
|
||||||
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { RouterContext } from "next/dist/shared/lib/router-context"; // next 12
|
||||||
|
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
controls: {
|
controls: {
|
||||||
@ -6,4 +8,12 @@ export const parameters = {
|
|||||||
date: /Date$/,
|
date: /Date$/,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
nextRouter: {
|
||||||
|
Provider: RouterContext.Provider,
|
||||||
|
asPath: "/",
|
||||||
|
pathname: "/",
|
||||||
|
query: {},
|
||||||
|
route: "/",
|
||||||
|
push() {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
"eslint-config-next": "12.2.0",
|
"eslint-config-next": "12.2.0",
|
||||||
"eslint-plugin-storybook": "^0.5.13",
|
"eslint-plugin-storybook": "^0.5.13",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
|
"storybook-addon-next-router": "^4.0.0",
|
||||||
"typescript": "4.7.4"
|
"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 (
|
return (
|
||||||
<article className="expression-card">
|
<article className="expression-card">
|
||||||
<h2 className="expression-card-prompt">{prompt}</h2>
|
<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 && (
|
{show_description && (
|
||||||
<div className="expression-card-details">{description}</div>
|
<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 "./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 {
|
.expression-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -9690,6 +9690,13 @@ store2@^2.12.0:
|
|||||||
resolved "https://registry.yarnpkg.com/store2/-/store2-2.13.2.tgz#01ad8802ca5b445b9c316b55e72645c13a3cd7e3"
|
resolved "https://registry.yarnpkg.com/store2/-/store2-2.13.2.tgz#01ad8802ca5b445b9c316b55e72645c13a3cd7e3"
|
||||||
integrity sha512-CMtO2Uneg3SAz/d6fZ/6qbqqQHi2ynq6/KzMD/26gTkiEShCcpqFfTHgOxsE0egAq6SX3FmN4CeSqn8BzXQkJg==
|
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:
|
stream-browserify@^2.0.1:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
|
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"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
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"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||||
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||||
|
Loading…
Reference in New Issue
Block a user