@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
|
+
};
|