@feminab/box-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +15 -0
- package/.storybook/main.ts +20 -0
- package/.storybook/preview.ts +15 -0
- package/README.md +46 -0
- package/dist/@interfaces/Badge.d.d.ts +12 -0
- package/dist/@interfaces/Badge.d.d.ts.map +1 -0
- package/dist/@interfaces/Button.d.d.ts +15 -0
- package/dist/@interfaces/Button.d.d.ts.map +1 -0
- package/dist/@interfaces/Color.d.d.ts +6 -0
- package/dist/@interfaces/Color.d.d.ts.map +1 -0
- package/dist/@interfaces/IButtonItem.d.d.ts +6 -0
- package/dist/@interfaces/IButtonItem.d.d.ts.map +1 -0
- package/dist/@interfaces/ISubNavItem.d.d.ts +9 -0
- package/dist/@interfaces/ISubNavItem.d.d.ts.map +1 -0
- package/dist/@interfaces/MobileNavProps.d.d.ts +5 -0
- package/dist/@interfaces/MobileNavProps.d.d.ts.map +1 -0
- package/dist/@interfaces/NavItem.d.d.ts +22 -0
- package/dist/@interfaces/NavItem.d.d.ts.map +1 -0
- package/dist/@interfaces/Pagination.d.d.ts +8 -0
- package/dist/@interfaces/Pagination.d.d.ts.map +1 -0
- package/dist/@interfaces/Select.d.d.ts +14 -0
- package/dist/@interfaces/Select.d.d.ts.map +1 -0
- package/dist/@interfaces/SideNavProps.d.d.ts +11 -0
- package/dist/@interfaces/SideNavProps.d.d.ts.map +1 -0
- package/dist/@interfaces/TextInput.d.d.ts +15 -0
- package/dist/@interfaces/TextInput.d.d.ts.map +1 -0
- package/dist/@interfaces/index.d.ts +12 -0
- package/dist/@interfaces/index.d.ts.map +1 -0
- package/dist/Badge.d.ts +4 -0
- package/dist/Badge.d.ts.map +1 -0
- package/dist/Button.d.ts +4 -0
- package/dist/Button.d.ts.map +1 -0
- package/dist/ButtonGroup.d.ts +9 -0
- package/dist/ButtonGroup.d.ts.map +1 -0
- package/dist/ColorBox.d.ts +4 -0
- package/dist/ColorBox.d.ts.map +1 -0
- package/dist/Header.d.ts +13 -0
- package/dist/Header.d.ts.map +1 -0
- package/dist/Nav/MobileNav.d.ts +4 -0
- package/dist/Nav/MobileNav.d.ts.map +1 -0
- package/dist/Nav/NavItem.d.ts +4 -0
- package/dist/Nav/NavItem.d.ts.map +1 -0
- package/dist/Nav/SideNav.d.ts +5 -0
- package/dist/Nav/SideNav.d.ts.map +1 -0
- package/dist/Nav/SubNavItem.d.ts +4 -0
- package/dist/Nav/SubNavItem.d.ts.map +1 -0
- package/dist/Page.d.ts +3 -0
- package/dist/Page.d.ts.map +1 -0
- package/dist/Paginate.d.ts +4 -0
- package/dist/Paginate.d.ts.map +1 -0
- package/dist/Select.d.ts +4 -0
- package/dist/Select.d.ts.map +1 -0
- package/dist/StoryLayout.d.ts +9 -0
- package/dist/StoryLayout.d.ts.map +1 -0
- package/dist/TextInput.d.ts +4 -0
- package/dist/TextInput.d.ts.map +1 -0
- package/dist/Typography.d.ts +14 -0
- package/dist/Typography.d.ts.map +1 -0
- package/dist/box-ui.cjs.development.js +1122 -0
- package/dist/box-ui.cjs.development.js.map +1 -0
- package/dist/box-ui.cjs.production.min.js +2 -0
- package/dist/box-ui.cjs.production.min.js.map +1 -0
- package/dist/box-ui.esm.js +1096 -0
- package/dist/box-ui.esm.js.map +1 -0
- package/dist/data/colors.d.ts +3 -0
- package/dist/data/colors.d.ts.map +1 -0
- package/dist/data/countries.d.ts +3 -0
- package/dist/data/countries.d.ts.map +1 -0
- package/dist/data/images/index.d.ts +5 -0
- package/dist/data/images/index.d.ts.map +1 -0
- package/dist/data/index.d.ts +6 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/navItems.d.ts +4 -0
- package/dist/data/navItems.d.ts.map +1 -0
- package/dist/data/options.d.ts +5 -0
- package/dist/data/options.d.ts.map +1 -0
- package/dist/data/prices.d.ts +3 -0
- package/dist/data/prices.d.ts.map +1 -0
- package/dist/hooks/useIconClassName.d.ts +5 -0
- package/dist/hooks/useIconClassName.d.ts.map +1 -0
- package/dist/hooks/useIconProps.d.ts +5 -0
- package/dist/hooks/useIconProps.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/reportWebVitals.d.ts +4 -0
- package/dist/reportWebVitals.d.ts.map +1 -0
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/stories/Badge.stories.d.ts +13 -0
- package/dist/stories/Badge.stories.d.ts.map +1 -0
- package/dist/stories/Button.stories.d.ts +16 -0
- package/dist/stories/Button.stories.d.ts.map +1 -0
- package/dist/stories/ButtonGroup.stories.d.ts +11 -0
- package/dist/stories/ButtonGroup.stories.d.ts.map +1 -0
- package/dist/stories/Colors.stories.d.ts +8 -0
- package/dist/stories/Colors.stories.d.ts.map +1 -0
- package/dist/stories/Header.stories.d.ts +20 -0
- package/dist/stories/Header.stories.d.ts.map +1 -0
- package/dist/stories/MobileNav.stories.d.ts +10 -0
- package/dist/stories/MobileNav.stories.d.ts.map +1 -0
- package/dist/stories/Page.stories.d.ts +14 -0
- package/dist/stories/Page.stories.d.ts.map +1 -0
- package/dist/stories/Paginate.stories.d.ts +11 -0
- package/dist/stories/Paginate.stories.d.ts.map +1 -0
- package/dist/stories/Select.stories.d.ts +11 -0
- package/dist/stories/Select.stories.d.ts.map +1 -0
- package/dist/stories/SideNav.stories.d.ts +10 -0
- package/dist/stories/SideNav.stories.d.ts.map +1 -0
- package/dist/stories/TextInput.stories.d.ts +11 -0
- package/dist/stories/TextInput.stories.d.ts.map +1 -0
- package/dist/stories/Typography.stories.d.ts +11 -0
- package/dist/stories/Typography.stories.d.ts.map +1 -0
- package/output.css +639 -0
- package/package.json +91 -0
- package/postcss.config.js +6 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +43 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/src/@interfaces/Badge.d.tsx +13 -0
- package/src/@interfaces/Button.d.tsx +17 -0
- package/src/@interfaces/Color.d.tsx +5 -0
- package/src/@interfaces/IButtonItem.d.tsx +6 -0
- package/src/@interfaces/ISubNavItem.d.tsx +10 -0
- package/src/@interfaces/MobileNavProps.d.tsx +4 -0
- package/src/@interfaces/NavItem.d.tsx +22 -0
- package/src/@interfaces/Pagination.d.tsx +7 -0
- package/src/@interfaces/Select.d.tsx +12 -0
- package/src/@interfaces/SideNavProps.d.tsx +11 -0
- package/src/@interfaces/TextInput.d.tsx +13 -0
- package/src/@interfaces/index.tsx +11 -0
- package/src/Badge.tsx +44 -0
- package/src/Button.tsx +132 -0
- package/src/ButtonGroup.tsx +37 -0
- package/src/ColorBox.tsx +15 -0
- package/src/Header.tsx +55 -0
- package/src/Nav/MobileNav.tsx +35 -0
- package/src/Nav/NavItem.tsx +101 -0
- package/src/Nav/SideNav.tsx +165 -0
- package/src/Nav/SubNavItem.tsx +39 -0
- package/src/Page.tsx +72 -0
- package/src/Paginate.tsx +102 -0
- package/src/Select.tsx +102 -0
- package/src/StoryLayout.tsx +17 -0
- package/src/TextInput.tsx +103 -0
- package/src/Typography.tsx +81 -0
- package/src/data/colors.tsx +279 -0
- package/src/data/countries.tsx +57 -0
- package/src/data/images/be.svg +1 -0
- package/src/data/images/de.svg +1 -0
- package/src/data/images/fr.svg +1 -0
- package/src/data/images/in.svg +1 -0
- package/src/data/images/index.tsx +33 -0
- package/src/data/images/it.svg +1 -0
- package/src/data/images/logo.svg +23 -0
- package/src/data/images/nl.svg +1 -0
- package/src/data/images/ru.svg +1 -0
- package/src/data/images/us.svg +1 -0
- package/src/data/index.tsx +5 -0
- package/src/data/navItems.tsx +109 -0
- package/src/data/options.tsx +51 -0
- package/src/data/prices.tsx +36 -0
- package/src/hooks/useIconClassName.tsx +14 -0
- package/src/hooks/useIconProps.tsx +19 -0
- package/src/index.js +15 -0
- package/src/react-app-env.d.ts +1 -0
- package/src/reportWebVitals.ts +15 -0
- package/src/setupTests.ts +5 -0
- package/src/stories/Badge.stories.tsx +86 -0
- package/src/stories/Button.stories.tsx +104 -0
- package/src/stories/ButtonGroup.stories.tsx +83 -0
- package/src/stories/Colors.stories.tsx +31 -0
- package/src/stories/Configure.mdx +364 -0
- package/src/stories/Header.stories.ts +33 -0
- package/src/stories/MobileNav.stories.tsx +60 -0
- package/src/stories/Page.stories.ts +32 -0
- package/src/stories/Paginate.stories.tsx +64 -0
- package/src/stories/Select.stories.tsx +77 -0
- package/src/stories/SideNav.stories.tsx +38 -0
- package/src/stories/TextInput.stories.tsx +100 -0
- package/src/stories/Typography.stories.tsx +115 -0
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +1 -0
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/avif-test-image.avif +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +1 -0
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +1 -0
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +1 -0
- package/src/stories/assets/youtube.svg +1 -0
- package/src/styles/global.css +367 -0
- package/storybook-static/125.65b26339.iframe.bundle.js +405 -0
- package/storybook-static/125.65b26339.iframe.bundle.js.LICENSE.txt +9 -0
- package/storybook-static/125.65b26339.iframe.bundle.js.map +1 -0
- package/storybook-static/13.0638081a.iframe.bundle.js +2 -0
- package/storybook-static/13.0638081a.iframe.bundle.js.LICENSE.txt +9 -0
- package/storybook-static/161.a19908ac.iframe.bundle.js +2 -0
- package/storybook-static/161.a19908ac.iframe.bundle.js.LICENSE.txt +9 -0
- package/storybook-static/161528bb6c25115b3f83.png +0 -0
- package/storybook-static/167.3fa3a909.iframe.bundle.js +1 -0
- package/storybook-static/294.ce38f65c.iframe.bundle.js +1 -0
- package/storybook-static/2dbc69731c3f9930a271.png +0 -0
- package/storybook-static/314.568bd9af.iframe.bundle.js +2 -0
- package/storybook-static/314.568bd9af.iframe.bundle.js.LICENSE.txt +15 -0
- package/storybook-static/364.0b18ef67.iframe.bundle.js +1 -0
- package/storybook-static/735.1625d9f4.iframe.bundle.js +2 -0
- package/storybook-static/735.1625d9f4.iframe.bundle.js.LICENSE.txt +9 -0
- package/storybook-static/742.597501f6.iframe.bundle.js +1 -0
- package/storybook-static/7a58d2cb9a6358f85e9b.png +0 -0
- package/storybook-static/844.aec20bdb.iframe.bundle.js +95 -0
- package/storybook-static/844.aec20bdb.iframe.bundle.js.LICENSE.txt +19 -0
- package/storybook-static/844.aec20bdb.iframe.bundle.js.map +1 -0
- package/storybook-static/9335a1a91b80ad4fec70.png +0 -0
- package/storybook-static/936.fd850a3f.iframe.bundle.js +1 -0
- package/storybook-static/961.0e5457c5.iframe.bundle.js +2 -0
- package/storybook-static/961.0e5457c5.iframe.bundle.js.LICENSE.txt +9 -0
- package/storybook-static/c720ced26387af8a9cb2.png +0 -0
- package/storybook-static/e93de094692245f1ec04.png +0 -0
- package/storybook-static/f7d8b9a8cec7528e0e36.png +0 -0
- package/storybook-static/favicon.ico +0 -0
- package/storybook-static/favicon.svg +1 -0
- package/storybook-static/iframe.html +511 -0
- package/storybook-static/index.html +185 -0
- package/storybook-static/index.json +1 -0
- package/storybook-static/logo192.png +0 -0
- package/storybook-static/logo512.png +0 -0
- package/storybook-static/main.069281cf.iframe.bundle.js +1 -0
- package/storybook-static/manifest.json +25 -0
- package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
- package/storybook-static/nunito-sans-bold.woff2 +0 -0
- package/storybook-static/nunito-sans-italic.woff2 +0 -0
- package/storybook-static/nunito-sans-regular.woff2 +0 -0
- package/storybook-static/project.json +1 -0
- package/storybook-static/robots.txt +3 -0
- package/storybook-static/runtime~main.295ddda4.iframe.bundle.js +1 -0
- package/storybook-static/sb-addons/chromatic-com-storybook-10/manager-bundle.js +331 -0
- package/storybook-static/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +51 -0
- package/storybook-static/sb-addons/essentials-actions-2/manager-bundle.js +3 -0
- package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js +12 -0
- package/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js +402 -0
- package/storybook-static/sb-addons/essentials-docs-3/manager-bundle.js +242 -0
- package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js +3 -0
- package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js +3 -0
- package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js +3 -0
- package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js +3 -0
- package/storybook-static/sb-addons/interactions-11/manager-bundle.js +222 -0
- package/storybook-static/sb-addons/links-12/manager-bundle.js +3 -0
- package/storybook-static/sb-addons/onboarding-9/manager-bundle.js +127 -0
- package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
- package/storybook-static/sb-common-assets/favicon.svg +1 -0
- package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
- package/storybook-static/sb-manager/globals-module-info.js +1051 -0
- package/storybook-static/sb-manager/globals-runtime.js +41591 -0
- package/storybook-static/sb-manager/globals.js +48 -0
- package/storybook-static/sb-manager/runtime.js +12048 -0
- package/storybook-static/sb-preview/globals.js +33 -0
- package/storybook-static/sb-preview/runtime.js +7745 -0
- package/storybook-static/static/css/main.08036cd2.css +2294 -0
- package/storybook-static/static/css/main.08036cd2.css.map +1 -0
- package/storybook-static/static/media/discord.d85804c7f88be863ff119366ab74d826.svg +1 -0
- package/storybook-static/static/media/github.e4e8df827592b1ed0288e4678e1965ce.svg +1 -0
- package/storybook-static/static/media/tutorials.fde6e46fc254fa77b6e39d1118470f7c.svg +1 -0
- package/storybook-static/static/media/youtube.fd046a09fac357359f94cc21068d6560.svg +1 -0
- package/storybook-static/stories-Badge-stories.484f7206.iframe.bundle.js +1 -0
- package/storybook-static/stories-Button-stories.5e29be85.iframe.bundle.js +1 -0
- package/storybook-static/stories-ButtonGroup-stories.cc89968c.iframe.bundle.js +1 -0
- package/storybook-static/stories-Colors-stories.f892dc75.iframe.bundle.js +2 -0
- package/storybook-static/stories-Colors-stories.f892dc75.iframe.bundle.js.LICENSE.txt +15 -0
- package/storybook-static/stories-Configure-mdx.81346d97.iframe.bundle.js +1 -0
- package/storybook-static/stories-Header-stories.cf691094.iframe.bundle.js +2 -0
- package/storybook-static/stories-Header-stories.cf691094.iframe.bundle.js.LICENSE.txt +15 -0
- package/storybook-static/stories-MobileNav-stories.f04cccdd.iframe.bundle.js +1 -0
- package/storybook-static/stories-Page-stories.0c9aa29d.iframe.bundle.js +2 -0
- package/storybook-static/stories-Page-stories.0c9aa29d.iframe.bundle.js.LICENSE.txt +15 -0
- package/storybook-static/stories-Paginate-stories.3b161781.iframe.bundle.js +1 -0
- package/storybook-static/stories-Select-stories.7556ae0d.iframe.bundle.js +1 -0
- package/storybook-static/stories-SideNav-stories.093fac6a.iframe.bundle.js +1 -0
- package/storybook-static/stories-TextInput-stories.6d3e15c6.iframe.bundle.js +1 -0
- package/storybook-static/stories-Typography-stories.6640f7ac.iframe.bundle.js +2 -0
- package/storybook-static/stories-Typography-stories.6640f7ac.iframe.bundle.js.LICENSE.txt +15 -0
- package/tailwind.config.js +113 -0
- package/tsconfig.json +29 -0
@@ -0,0 +1,165 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { SideNavProps, INavItem } from "../@interfaces";
|
3
|
+
import classNames from "classnames";
|
4
|
+
import { Typography } from "../Typography";
|
5
|
+
import { NavItem } from "./NavItem";
|
6
|
+
import { FiLogOut, FiSearch } from "react-icons/fi";
|
7
|
+
import { TextInput } from "../TextInput";
|
8
|
+
import { images } from "../data/images";
|
9
|
+
|
10
|
+
export const renderLogo = () => (
|
11
|
+
<img src={images.logo} className="w-8 h-8 select-none" alt="logo" />
|
12
|
+
);
|
13
|
+
|
14
|
+
export const SideNav = ({
|
15
|
+
className,
|
16
|
+
navItemsTop,
|
17
|
+
navItemsBottom,
|
18
|
+
username,
|
19
|
+
email,
|
20
|
+
open,
|
21
|
+
setOpen,
|
22
|
+
}: SideNavProps) => {
|
23
|
+
|
24
|
+
|
25
|
+
const Logout = FiLogOut as React.FC<any>;
|
26
|
+
const Search = FiSearch as React.FC<any>;
|
27
|
+
|
28
|
+
const [searchString, setSearchString] = React.useState<string>("");
|
29
|
+
const [activeNavItem, setActiveNavItem] = React.useState<string>("");
|
30
|
+
const [activeSubNavItem, setActiveSubNavItem] = React.useState<string>("");
|
31
|
+
const [openDropdowns, setOpenDropdowns] = React.useState<string[]>([]);
|
32
|
+
|
33
|
+
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
|
34
|
+
setSearchString(e.target.value);
|
35
|
+
};
|
36
|
+
|
37
|
+
const onClickNavItem = (item: INavItem, subNavPath?: string) => {
|
38
|
+
if (subNavPath) {
|
39
|
+
setActiveSubNavItem(subNavPath);
|
40
|
+
}
|
41
|
+
if (!item.toggleSidebar) {
|
42
|
+
setActiveNavItem(item.label);
|
43
|
+
} else if (item.toggleSidebar) {
|
44
|
+
setOpen(!open);
|
45
|
+
}
|
46
|
+
|
47
|
+
if (item.subItems && openDropdowns.includes(item.label) && !subNavPath) {
|
48
|
+
setOpenDropdowns(
|
49
|
+
openDropdowns.filter((dropdownItem) => dropdownItem !== item.label),
|
50
|
+
);
|
51
|
+
} else if (item.subItems && !openDropdowns.includes(item.label)) {
|
52
|
+
setOpenDropdowns([...openDropdowns, item.label]);
|
53
|
+
}
|
54
|
+
};
|
55
|
+
|
56
|
+
return (
|
57
|
+
<div
|
58
|
+
className={classNames(
|
59
|
+
"py-6 flex flex-col flex-grow bg-white dark:bg-gray-900 transform ease-out duration-100 overflow-y-auto xs:overflow-y-visible",
|
60
|
+
{
|
61
|
+
"w-80": open,
|
62
|
+
"w-24": !open,
|
63
|
+
"border-r border-gray-300 dark:border-opacity-20": true,
|
64
|
+
},
|
65
|
+
className,
|
66
|
+
)}
|
67
|
+
>
|
68
|
+
<div className="flex items-center w-full mb-8 ml-9">
|
69
|
+
{renderLogo()}
|
70
|
+
<Typography
|
71
|
+
variant="xl"
|
72
|
+
className={classNames("ml-2.5 whitespace-nowrap select-none", {
|
73
|
+
"opacity-0 hidden": !open,
|
74
|
+
})}
|
75
|
+
customWeight="medium"
|
76
|
+
>
|
77
|
+
Box UI
|
78
|
+
</Typography>
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<div className="mb-8 mx-9">
|
82
|
+
{open ? (
|
83
|
+
<TextInput
|
84
|
+
type="text"
|
85
|
+
value={searchString}
|
86
|
+
handleChange={handleSearch}
|
87
|
+
placeholder="Search"
|
88
|
+
LeadingIcon={<Search />}
|
89
|
+
/>
|
90
|
+
) : (
|
91
|
+
<div className="h-11" />
|
92
|
+
)}
|
93
|
+
</div>
|
94
|
+
|
95
|
+
<div
|
96
|
+
className={classNames(
|
97
|
+
"flex flex-col justify-between h-full ml-5 w-70",
|
98
|
+
{
|
99
|
+
"w-14": !open,
|
100
|
+
},
|
101
|
+
)}
|
102
|
+
>
|
103
|
+
<ul className="flex flex-col space-y-1">
|
104
|
+
{navItemsTop.map((item) => (
|
105
|
+
<NavItem
|
106
|
+
key={item.label}
|
107
|
+
item={item}
|
108
|
+
isActive={activeNavItem === item.label}
|
109
|
+
activeSubNavItem={activeSubNavItem}
|
110
|
+
open={open}
|
111
|
+
openDropdown={openDropdowns.includes(item.label)}
|
112
|
+
onClick={onClickNavItem}
|
113
|
+
/>
|
114
|
+
))}
|
115
|
+
</ul>
|
116
|
+
<ul className="flex flex-col mb-6 space-y-1">
|
117
|
+
{navItemsBottom.map((item) => (
|
118
|
+
<NavItem
|
119
|
+
key={item.label}
|
120
|
+
item={item}
|
121
|
+
isActive={activeNavItem === item.label}
|
122
|
+
activeSubNavItem={activeSubNavItem}
|
123
|
+
open={open}
|
124
|
+
openDropdown={openDropdowns.includes(item.label)}
|
125
|
+
onClick={onClickNavItem}
|
126
|
+
/>
|
127
|
+
))}
|
128
|
+
</ul>
|
129
|
+
</div>
|
130
|
+
|
131
|
+
<hr
|
132
|
+
className={classNames(
|
133
|
+
"ml-5 border-t border-gray-300 dark:border-opacity-20",
|
134
|
+
{
|
135
|
+
"w-70": open,
|
136
|
+
"w-14": !open,
|
137
|
+
},
|
138
|
+
)}
|
139
|
+
/>
|
140
|
+
|
141
|
+
<div className="flex mt-6 w-70 ml-7">
|
142
|
+
{open ? (
|
143
|
+
<div className="flex justify-between ml-3">
|
144
|
+
<div className="select-none">
|
145
|
+
<Typography
|
146
|
+
variant="sm"
|
147
|
+
customWeight="medium"
|
148
|
+
customColor="text-gray-700 dark:text-white"
|
149
|
+
>
|
150
|
+
{username}
|
151
|
+
</Typography>
|
152
|
+
|
153
|
+
<Typography variant="sm" customColor="text-gray-500">
|
154
|
+
{email}
|
155
|
+
</Typography>
|
156
|
+
</div>
|
157
|
+
|
158
|
+
<Logout size={24} className="ml-6 text-gray-400 cursor-pointer" />
|
159
|
+
</div>
|
160
|
+
) : null}
|
161
|
+
</div>
|
162
|
+
</div>
|
163
|
+
);
|
164
|
+
|
165
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import React, { FC } from "react";
|
2
|
+
import { Typography } from "../Typography";
|
3
|
+
import classNames from "classnames";
|
4
|
+
import { SubNavItemProps } from "../@interfaces";
|
5
|
+
|
6
|
+
export const SubNavItem: FC<SubNavItemProps> = ({
|
7
|
+
inDropdown,
|
8
|
+
isActive,
|
9
|
+
subItem,
|
10
|
+
onClick,
|
11
|
+
}) => {
|
12
|
+
return (
|
13
|
+
<li
|
14
|
+
key={subItem.label}
|
15
|
+
className={classNames("navItem group", {
|
16
|
+
"bg-primary-50 dark:bg-gray-100 dark:bg-opacity-10": isActive,
|
17
|
+
})}
|
18
|
+
onClick={onClick}
|
19
|
+
>
|
20
|
+
<Typography
|
21
|
+
variant="md"
|
22
|
+
customWeight="medium"
|
23
|
+
customColor={classNames(
|
24
|
+
"group-hover:text-primary-600 dark:group-hover:text-white",
|
25
|
+
{
|
26
|
+
"text-gray-800 dark:text-white": !isActive,
|
27
|
+
"text-primary-600 dark:text-white": isActive,
|
28
|
+
}
|
29
|
+
)}
|
30
|
+
className={classNames("flex-grow", {
|
31
|
+
"pl-13": !inDropdown,
|
32
|
+
"pl-4": inDropdown,
|
33
|
+
})}
|
34
|
+
>
|
35
|
+
{subItem.label}
|
36
|
+
</Typography>
|
37
|
+
</li>
|
38
|
+
);
|
39
|
+
};
|
package/src/Page.tsx
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
import { Header } from './Header';
|
4
|
+
|
5
|
+
type User = {
|
6
|
+
name: string;
|
7
|
+
};
|
8
|
+
|
9
|
+
export const Page: React.FC = () => {
|
10
|
+
const [user, setUser] = React.useState<User>();
|
11
|
+
|
12
|
+
return (
|
13
|
+
<article>
|
14
|
+
<Header
|
15
|
+
user={user}
|
16
|
+
onLogin={() => setUser({ name: 'Jane Doe' })}
|
17
|
+
onLogout={() => setUser(undefined)}
|
18
|
+
onCreateAccount={() => setUser({ name: 'Jane Doe' })}
|
19
|
+
/>
|
20
|
+
|
21
|
+
<section className="storybook-page">
|
22
|
+
<h2>Pages in Storybook</h2>
|
23
|
+
<p>
|
24
|
+
We recommend building UIs with a{' '}
|
25
|
+
<a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
|
26
|
+
<strong>component-driven</strong>
|
27
|
+
</a>{' '}
|
28
|
+
process starting with atomic components and ending with pages.
|
29
|
+
</p>
|
30
|
+
<p>
|
31
|
+
Render pages with mock data. This makes it easy to build and review page states without
|
32
|
+
needing to navigate to them in your app. Here are some handy patterns for managing page
|
33
|
+
data in Storybook:
|
34
|
+
</p>
|
35
|
+
<ul>
|
36
|
+
<li>
|
37
|
+
Use a higher-level connected component. Storybook helps you compose such data from the
|
38
|
+
"args" of child component stories
|
39
|
+
</li>
|
40
|
+
<li>
|
41
|
+
Assemble data in the page component from your services. You can mock these services out
|
42
|
+
using Storybook.
|
43
|
+
</li>
|
44
|
+
</ul>
|
45
|
+
<p>
|
46
|
+
Get a guided tutorial on component-driven development at{' '}
|
47
|
+
<a href="https://storybook.js.org/tutorials/" target="_blank" rel="noopener noreferrer">
|
48
|
+
Storybook tutorials
|
49
|
+
</a>
|
50
|
+
. Read more in the{' '}
|
51
|
+
<a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">
|
52
|
+
docs
|
53
|
+
</a>
|
54
|
+
.
|
55
|
+
</p>
|
56
|
+
<div className="tip-wrapper">
|
57
|
+
<span className="tip">Tip</span> Adjust the width of the canvas with the{' '}
|
58
|
+
<svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
|
59
|
+
<g fill="none" fillRule="evenodd">
|
60
|
+
<path
|
61
|
+
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
|
62
|
+
id="a"
|
63
|
+
fill="#999"
|
64
|
+
/>
|
65
|
+
</g>
|
66
|
+
</svg>
|
67
|
+
Viewports addon in the toolbar
|
68
|
+
</div>
|
69
|
+
</section>
|
70
|
+
</article>
|
71
|
+
);
|
72
|
+
};
|
package/src/Paginate.tsx
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { PaginationProps } from "./@interfaces";
|
3
|
+
import classNames from "classnames";
|
4
|
+
import { Pagination } from "react-headless-pagination";
|
5
|
+
import { FiArrowLeft, FiArrowRight } from "react-icons/fi";
|
6
|
+
|
7
|
+
export const Paginate = ({
|
8
|
+
totalPages,
|
9
|
+
page,
|
10
|
+
isMobile,
|
11
|
+
className,
|
12
|
+
setPage,
|
13
|
+
}: PaginationProps) => {
|
14
|
+
const handlePageChange = (page: number) => {
|
15
|
+
setPage(page);
|
16
|
+
};
|
17
|
+
|
18
|
+
const ArrowLeft = FiArrowLeft as React.FC<any>;
|
19
|
+
const ArrowRight = FiArrowRight as React.FC<any>;
|
20
|
+
|
21
|
+
if (isMobile) {
|
22
|
+
return (
|
23
|
+
<div className={classNames("flex w-full h-10 items-center", className)}>
|
24
|
+
<ArrowLeft
|
25
|
+
size={20}
|
26
|
+
className={classNames("mr-3 text-gray-500 dark:text-white", {
|
27
|
+
"cursor-pointer": page !== 0,
|
28
|
+
"opacity-50": page === 0,
|
29
|
+
})}
|
30
|
+
onClick={() => {
|
31
|
+
if (page > 0) {
|
32
|
+
handlePageChange(page - 1);
|
33
|
+
}
|
34
|
+
}}
|
35
|
+
/>
|
36
|
+
<div className="flex justify-center flex-grow text-sm text-gray-700 select-none dark:text-white">
|
37
|
+
{`Page ${page} of ${totalPages}`}
|
38
|
+
</div>
|
39
|
+
<ArrowRight
|
40
|
+
size={20}
|
41
|
+
className={classNames("ml-3 text-gray-500 dark:text-white", {
|
42
|
+
"cursor-pointer": page !== totalPages - 1,
|
43
|
+
"opacity-50": page === totalPages - 1,
|
44
|
+
})}
|
45
|
+
onClick={() => {
|
46
|
+
if (page < totalPages - 1) {
|
47
|
+
handlePageChange(page + 1);
|
48
|
+
}
|
49
|
+
}}
|
50
|
+
/>
|
51
|
+
</div>
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
55
|
+
return (
|
56
|
+
<Pagination
|
57
|
+
className={classNames(
|
58
|
+
"flex w-full items-center h-10 text-sm select-none",
|
59
|
+
className
|
60
|
+
)}
|
61
|
+
currentPage={page}
|
62
|
+
totalPages={totalPages}
|
63
|
+
edgePageCount={2}
|
64
|
+
setCurrentPage={handlePageChange}
|
65
|
+
truncableText="..."
|
66
|
+
middlePagesSiblingCount={2}
|
67
|
+
truncableClassName="w-10 px-0.5 text-center dark:text-gray-500"
|
68
|
+
>
|
69
|
+
<Pagination.PrevButton
|
70
|
+
className={classNames(
|
71
|
+
"h-10 font-medium flex items-center mr-2 text-gray-500 dark:text-white hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none",
|
72
|
+
{
|
73
|
+
"cursor-pointer": page !== 0,
|
74
|
+
"opacity-50": page === 0,
|
75
|
+
}
|
76
|
+
)}
|
77
|
+
>
|
78
|
+
<ArrowLeft size={20} className={classNames("mr-3")} />
|
79
|
+
Previous
|
80
|
+
</Pagination.PrevButton>
|
81
|
+
<div className="flex items-center justify-center flex-grow list-none">
|
82
|
+
<Pagination.PageButton
|
83
|
+
activeClassName="bg-primary-50 dark:bg-opacity-0 text-primary-600 dark:text-white"
|
84
|
+
inactiveClassName="text-gray-500"
|
85
|
+
className="flex items-center justify-center h-10 w-10 rounded-full cursor-pointer font-medium"
|
86
|
+
/>
|
87
|
+
</div>
|
88
|
+
<Pagination.NextButton
|
89
|
+
className={classNames(
|
90
|
+
"h-10 font-medium flex items-center mr-2 text-gray-500 dark:text-white hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none",
|
91
|
+
{
|
92
|
+
"cursor-pointer": page !== totalPages - 1,
|
93
|
+
"opacity-50": page === totalPages - 1,
|
94
|
+
}
|
95
|
+
)}
|
96
|
+
>
|
97
|
+
Next
|
98
|
+
<ArrowRight size={20} className={classNames("ml-3")} />
|
99
|
+
</Pagination.NextButton>
|
100
|
+
</Pagination>
|
101
|
+
);
|
102
|
+
};
|
package/src/Select.tsx
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
import React, {
|
2
|
+
FC,
|
3
|
+
ReactElement,
|
4
|
+
isValidElement,
|
5
|
+
cloneElement,
|
6
|
+
} from "react";
|
7
|
+
import { SelectProps } from "./@interfaces";
|
8
|
+
import {
|
9
|
+
Listbox,
|
10
|
+
ListboxButton,
|
11
|
+
ListboxOption,
|
12
|
+
ListboxOptions,
|
13
|
+
} from "@headlessui/react";
|
14
|
+
import classNames from "classnames";
|
15
|
+
import {FiCheck, FiChevronDown} from 'react-icons/fi'
|
16
|
+
|
17
|
+
export const Select: FC<SelectProps> = ({
|
18
|
+
options,
|
19
|
+
selectedOption,
|
20
|
+
setSelectedOption,
|
21
|
+
placeholder,
|
22
|
+
LeadingIcon,
|
23
|
+
width,
|
24
|
+
}) => {
|
25
|
+
|
26
|
+
const ArrowDown = FiChevronDown as React.FC<any>;
|
27
|
+
const Check = FiCheck as React.FC<any>;
|
28
|
+
|
29
|
+
const setProps = (
|
30
|
+
icon: ReactElement,
|
31
|
+
iconSize: number,
|
32
|
+
additionalClass: string
|
33
|
+
) => {
|
34
|
+
if (
|
35
|
+
isValidElement<{ size?: number; className?: string }>(icon) &&
|
36
|
+
"size" in icon.props
|
37
|
+
) {
|
38
|
+
return cloneElement(icon, {
|
39
|
+
size: iconSize,
|
40
|
+
className: classNames(icon.props.className, additionalClass),
|
41
|
+
});
|
42
|
+
}
|
43
|
+
return icon;
|
44
|
+
};
|
45
|
+
|
46
|
+
return (
|
47
|
+
<div className={classNames("relative inline-block", width)}>
|
48
|
+
<Listbox value={selectedOption && selectedOption.value} onChange={setSelectedOption}>
|
49
|
+
{({ open }) => (
|
50
|
+
<>
|
51
|
+
<ListboxButton className={classNames("shadow-sm flex items-center text-md border border-gray-300 dark:border-gray-500 h-11 px-3.5 rounded-lg bg-white dark:bg-gray-800",
|
52
|
+
"focus:ring-4 focus:border-primary-300 dark:focus:border-gray-100 focus:ring-primary-100 dark:focus:ring-gray-100 dark:focus:ring-opacity-20 whitespace-nowrap",
|
53
|
+
{
|
54
|
+
"text-gray-900 dark:text-white": selectedOption,
|
55
|
+
"text-gray-500 dark:text-gray-300": !selectedOption,
|
56
|
+
},
|
57
|
+
width,)}>
|
58
|
+
{LeadingIcon && (
|
59
|
+
<div className="w-5 h-5 mr-2 overflow-hidden">
|
60
|
+
{setProps(LeadingIcon, 20, classNames("text-gray-400"))}
|
61
|
+
</div>
|
62
|
+
)}
|
63
|
+
{selectedOption ? selectedOption.label : placeholder}
|
64
|
+
<ArrowDown
|
65
|
+
size={20}
|
66
|
+
className={classNames(
|
67
|
+
"text-gray-500 dark:text-gray-300 transform duration-100 ease-out",
|
68
|
+
{
|
69
|
+
"-rotate-180": open,
|
70
|
+
"ml-auto": width,
|
71
|
+
"ml-3.5": !width,
|
72
|
+
},
|
73
|
+
)}
|
74
|
+
/>
|
75
|
+
</ListboxButton>
|
76
|
+
<ListboxOptions className="absolute z-10 inline-flex flex-col w-full bg-white border border-gray-300 rounded-lg shadow-lg top-13 dark:border-gray-500 dark:bg-gray-800">
|
77
|
+
{options?.map((option, index) => (
|
78
|
+
<ListboxOption as={React.Fragment} key={option.value} value={option.value}>
|
79
|
+
{({focus, selected}) => (
|
80
|
+
<li className={classNames(classNames(
|
81
|
+
"flex items-center pl-3.5 pr-3 justify-between h-11 text-gray-900 dark:text-white text-md cursor-pointer hover:bg-primary-25 dark:hover:bg-gray-100 dark:hover:bg-opacity-10 whitespace-nowrap",
|
82
|
+
{
|
83
|
+
"bg-primary-25 dark:bg-gray-100 dark:bg-opacity-10":
|
84
|
+
focus,
|
85
|
+
"rounded-t-lg": index === 0,
|
86
|
+
"rounded-b-lg": index === options.length - 1,
|
87
|
+
},
|
88
|
+
))}>
|
89
|
+
<div className="flex items-center">{option.label}</div>
|
90
|
+
{selected && <Check className="ml-5 text-primary-600 dark:text-white" />}
|
91
|
+
</li>
|
92
|
+
)}
|
93
|
+
|
94
|
+
</ListboxOption>
|
95
|
+
))}
|
96
|
+
</ListboxOptions>
|
97
|
+
</>
|
98
|
+
)}
|
99
|
+
</Listbox>
|
100
|
+
</div>
|
101
|
+
);
|
102
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import classNames from "classnames";
|
3
|
+
|
4
|
+
export interface IStoryArgs {
|
5
|
+
darkMode: boolean;
|
6
|
+
className?: String;
|
7
|
+
children?: React.ReactNode;
|
8
|
+
noPadding?: String;
|
9
|
+
}
|
10
|
+
|
11
|
+
export const StoryLayout = (args: IStoryArgs) => (
|
12
|
+
<div className={classNames({ "dark bg-gray-900": args.darkMode }, "-m-4")}>
|
13
|
+
<div className={classNames(args.className, { "p-4": !args.noPadding })}>
|
14
|
+
{args.children}
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
);
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import React, { FC } from "react";
|
2
|
+
import { TextInputProps } from "./@interfaces";
|
3
|
+
import { Typography } from "./Typography";
|
4
|
+
import classNames from "classnames";
|
5
|
+
import { useIconClassName } from "./hooks/useIconClassName";
|
6
|
+
|
7
|
+
export const TextInput: FC<TextInputProps> = ({
|
8
|
+
type,
|
9
|
+
value,
|
10
|
+
label,
|
11
|
+
placeholder,
|
12
|
+
error,
|
13
|
+
helperText,
|
14
|
+
disabled,
|
15
|
+
LeadingIcon,
|
16
|
+
TrailingIcon,
|
17
|
+
leadingText,
|
18
|
+
handleChange,
|
19
|
+
}) => {
|
20
|
+
const { setClassName } = useIconClassName();
|
21
|
+
|
22
|
+
return (
|
23
|
+
<div>
|
24
|
+
{label && (
|
25
|
+
<Typography
|
26
|
+
variant="sm"
|
27
|
+
customWeight="medium"
|
28
|
+
customColor="text-gray-700 dark:text-white"
|
29
|
+
className="mb-1.5"
|
30
|
+
>
|
31
|
+
{label}
|
32
|
+
</Typography>
|
33
|
+
)}
|
34
|
+
<div
|
35
|
+
className={classNames("relative", { "flex items-center": leadingText })}
|
36
|
+
>
|
37
|
+
<div className="h-11 absolute shadow-sm rounded-lg w-full flex justify-between items-center px-3.5 pointer-events-none">
|
38
|
+
{LeadingIcon ? setClassName(LeadingIcon, "text-gray-500") : <div />}
|
39
|
+
{TrailingIcon &&
|
40
|
+
setClassName(
|
41
|
+
TrailingIcon,
|
42
|
+
classNames({ "text-error-500": error, "text-gray-400": !error })
|
43
|
+
)}
|
44
|
+
</div>
|
45
|
+
{leadingText && (
|
46
|
+
<Typography
|
47
|
+
variant="sm"
|
48
|
+
customWeight="regular"
|
49
|
+
className={classNames(
|
50
|
+
"flex items-center h-11 text-lg text-gray-500 pl-3.5 pr-3 border border-r-0 rounded-l-lg border-gray-300 dark:border-gray-500",
|
51
|
+
{
|
52
|
+
"bg-gray-50 dark:bg-gray-700": disabled,
|
53
|
+
"dark:bg-gray-800": !disabled,
|
54
|
+
},
|
55
|
+
)}
|
56
|
+
>
|
57
|
+
{leadingText}
|
58
|
+
</Typography>
|
59
|
+
)}
|
60
|
+
<input
|
61
|
+
type={type}
|
62
|
+
value={value}
|
63
|
+
placeholder={placeholder}
|
64
|
+
onChange={handleChange}
|
65
|
+
disabled={disabled}
|
66
|
+
className={classNames(
|
67
|
+
"w-full select-none text-gray-900 dark:text-white text-md border h-11 px-2",
|
68
|
+
{
|
69
|
+
"pl-9": LeadingIcon,
|
70
|
+
"pr-9": TrailingIcon,
|
71
|
+
"rounded-l-0 rounded-r-lg": leadingText,
|
72
|
+
"rounded-lg": !leadingText,
|
73
|
+
"border-gray-300 dark:border-gray-500 focus:ring-4 focus:border-primary-300 dark:focus:border-gray-100 focus:ring-primary-100 dark:focus:ring-gray-100 dark:focus:ring-opacity-20":
|
74
|
+
!error,
|
75
|
+
"border-error-300 focus:ring-4 focus:border-error-300 focus:ring-error-100":
|
76
|
+
error,
|
77
|
+
"bg-white dark:bg-gray-800": !disabled,
|
78
|
+
"bg-gray-50 dark:bg-gray-700": disabled,
|
79
|
+
},
|
80
|
+
)}
|
81
|
+
/>
|
82
|
+
</div>
|
83
|
+
{error && (
|
84
|
+
<Typography
|
85
|
+
variant="sm"
|
86
|
+
customWeight="regular"
|
87
|
+
className="mt-1.5 text-error-500"
|
88
|
+
>
|
89
|
+
{error}
|
90
|
+
</Typography>
|
91
|
+
)}
|
92
|
+
{helperText && (
|
93
|
+
<Typography
|
94
|
+
variant="sm"
|
95
|
+
customWeight="regular"
|
96
|
+
className="mt-1.5 text-gray-500"
|
97
|
+
>
|
98
|
+
{helperText}
|
99
|
+
</Typography>
|
100
|
+
)}
|
101
|
+
</div>
|
102
|
+
);
|
103
|
+
};
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import React, { FC, JSX } from "react";
|
2
|
+
import classNames from "classnames";
|
3
|
+
|
4
|
+
type TypographyVariant =
|
5
|
+
| "xs"
|
6
|
+
| "sm"
|
7
|
+
| "md"
|
8
|
+
| "lg"
|
9
|
+
| "xl"
|
10
|
+
| "h6"
|
11
|
+
| "h5"
|
12
|
+
| "h4"
|
13
|
+
| "h3"
|
14
|
+
| "h2"
|
15
|
+
| "h1";
|
16
|
+
|
17
|
+
type TypographyWeightOption = "regular" | "medium" | "semibold" | "bold";
|
18
|
+
|
19
|
+
type TypographyWeightValue = "font-normal" | "font-medium" | "font-semibold" | "font-bold";
|
20
|
+
|
21
|
+
export interface TypographyProps {
|
22
|
+
variant?: TypographyVariant;
|
23
|
+
customWeight?: TypographyWeightOption;
|
24
|
+
customColor?: string;
|
25
|
+
customClass?: string;
|
26
|
+
className?: string;
|
27
|
+
children: string | React.ReactNode;
|
28
|
+
}
|
29
|
+
|
30
|
+
const TypographyVariantClasses: Record<TypographyVariant, string> = {
|
31
|
+
xs: "text-xs",
|
32
|
+
sm: "text-sm",
|
33
|
+
md: "text-md",
|
34
|
+
lg: "text-lg",
|
35
|
+
xl: "text-xl",
|
36
|
+
h6: "text-h6",
|
37
|
+
h5: "text-h5",
|
38
|
+
h4: "text-h4",
|
39
|
+
h3: "text-h3",
|
40
|
+
h2: "text-h2",
|
41
|
+
h1: "text-h1",
|
42
|
+
};
|
43
|
+
|
44
|
+
const TypographyWeightClasses: Record<TypographyWeightOption, TypographyWeightValue> = {
|
45
|
+
regular: "font-normal",
|
46
|
+
medium: "font-medium",
|
47
|
+
semibold: "font-semibold",
|
48
|
+
bold: "font-bold",
|
49
|
+
};
|
50
|
+
|
51
|
+
export const Typography: FC<TypographyProps> = ({
|
52
|
+
variant = "md",
|
53
|
+
customWeight = "regular",
|
54
|
+
customColor,
|
55
|
+
className,
|
56
|
+
children,
|
57
|
+
}) => {
|
58
|
+
const TypographyVariantClassName = TypographyVariantClasses[variant];
|
59
|
+
const TypographyWeightClassName = TypographyWeightClasses[customWeight];
|
60
|
+
|
61
|
+
|
62
|
+
const Component: React.ElementType =
|
63
|
+
["h1", "h2", "h3", "h4", "h5", "h6"].includes(variant ?? "p") ? (variant as keyof JSX.IntrinsicElements) : "p";
|
64
|
+
|
65
|
+
return (
|
66
|
+
<Component
|
67
|
+
className={classNames(
|
68
|
+
TypographyVariantClassName,
|
69
|
+
TypographyWeightClassName,
|
70
|
+
className,
|
71
|
+
{
|
72
|
+
"tracking-tight": ["h1", "h2", "h3"].includes(variant),
|
73
|
+
"text-black dark:text-white": !customColor,
|
74
|
+
},
|
75
|
+
customColor
|
76
|
+
)}
|
77
|
+
>
|
78
|
+
{children}
|
79
|
+
</Component>
|
80
|
+
);
|
81
|
+
};
|