@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.
Files changed (295) hide show
  1. package/.babelrc +15 -0
  2. package/.storybook/main.ts +20 -0
  3. package/.storybook/preview.ts +15 -0
  4. package/README.md +46 -0
  5. package/dist/@interfaces/Badge.d.d.ts +12 -0
  6. package/dist/@interfaces/Badge.d.d.ts.map +1 -0
  7. package/dist/@interfaces/Button.d.d.ts +15 -0
  8. package/dist/@interfaces/Button.d.d.ts.map +1 -0
  9. package/dist/@interfaces/Color.d.d.ts +6 -0
  10. package/dist/@interfaces/Color.d.d.ts.map +1 -0
  11. package/dist/@interfaces/IButtonItem.d.d.ts +6 -0
  12. package/dist/@interfaces/IButtonItem.d.d.ts.map +1 -0
  13. package/dist/@interfaces/ISubNavItem.d.d.ts +9 -0
  14. package/dist/@interfaces/ISubNavItem.d.d.ts.map +1 -0
  15. package/dist/@interfaces/MobileNavProps.d.d.ts +5 -0
  16. package/dist/@interfaces/MobileNavProps.d.d.ts.map +1 -0
  17. package/dist/@interfaces/NavItem.d.d.ts +22 -0
  18. package/dist/@interfaces/NavItem.d.d.ts.map +1 -0
  19. package/dist/@interfaces/Pagination.d.d.ts +8 -0
  20. package/dist/@interfaces/Pagination.d.d.ts.map +1 -0
  21. package/dist/@interfaces/Select.d.d.ts +14 -0
  22. package/dist/@interfaces/Select.d.d.ts.map +1 -0
  23. package/dist/@interfaces/SideNavProps.d.d.ts +11 -0
  24. package/dist/@interfaces/SideNavProps.d.d.ts.map +1 -0
  25. package/dist/@interfaces/TextInput.d.d.ts +15 -0
  26. package/dist/@interfaces/TextInput.d.d.ts.map +1 -0
  27. package/dist/@interfaces/index.d.ts +12 -0
  28. package/dist/@interfaces/index.d.ts.map +1 -0
  29. package/dist/Badge.d.ts +4 -0
  30. package/dist/Badge.d.ts.map +1 -0
  31. package/dist/Button.d.ts +4 -0
  32. package/dist/Button.d.ts.map +1 -0
  33. package/dist/ButtonGroup.d.ts +9 -0
  34. package/dist/ButtonGroup.d.ts.map +1 -0
  35. package/dist/ColorBox.d.ts +4 -0
  36. package/dist/ColorBox.d.ts.map +1 -0
  37. package/dist/Header.d.ts +13 -0
  38. package/dist/Header.d.ts.map +1 -0
  39. package/dist/Nav/MobileNav.d.ts +4 -0
  40. package/dist/Nav/MobileNav.d.ts.map +1 -0
  41. package/dist/Nav/NavItem.d.ts +4 -0
  42. package/dist/Nav/NavItem.d.ts.map +1 -0
  43. package/dist/Nav/SideNav.d.ts +5 -0
  44. package/dist/Nav/SideNav.d.ts.map +1 -0
  45. package/dist/Nav/SubNavItem.d.ts +4 -0
  46. package/dist/Nav/SubNavItem.d.ts.map +1 -0
  47. package/dist/Page.d.ts +3 -0
  48. package/dist/Page.d.ts.map +1 -0
  49. package/dist/Paginate.d.ts +4 -0
  50. package/dist/Paginate.d.ts.map +1 -0
  51. package/dist/Select.d.ts +4 -0
  52. package/dist/Select.d.ts.map +1 -0
  53. package/dist/StoryLayout.d.ts +9 -0
  54. package/dist/StoryLayout.d.ts.map +1 -0
  55. package/dist/TextInput.d.ts +4 -0
  56. package/dist/TextInput.d.ts.map +1 -0
  57. package/dist/Typography.d.ts +14 -0
  58. package/dist/Typography.d.ts.map +1 -0
  59. package/dist/box-ui.cjs.development.js +1122 -0
  60. package/dist/box-ui.cjs.development.js.map +1 -0
  61. package/dist/box-ui.cjs.production.min.js +2 -0
  62. package/dist/box-ui.cjs.production.min.js.map +1 -0
  63. package/dist/box-ui.esm.js +1096 -0
  64. package/dist/box-ui.esm.js.map +1 -0
  65. package/dist/data/colors.d.ts +3 -0
  66. package/dist/data/colors.d.ts.map +1 -0
  67. package/dist/data/countries.d.ts +3 -0
  68. package/dist/data/countries.d.ts.map +1 -0
  69. package/dist/data/images/index.d.ts +5 -0
  70. package/dist/data/images/index.d.ts.map +1 -0
  71. package/dist/data/index.d.ts +6 -0
  72. package/dist/data/index.d.ts.map +1 -0
  73. package/dist/data/navItems.d.ts +4 -0
  74. package/dist/data/navItems.d.ts.map +1 -0
  75. package/dist/data/options.d.ts +5 -0
  76. package/dist/data/options.d.ts.map +1 -0
  77. package/dist/data/prices.d.ts +3 -0
  78. package/dist/data/prices.d.ts.map +1 -0
  79. package/dist/hooks/useIconClassName.d.ts +5 -0
  80. package/dist/hooks/useIconClassName.d.ts.map +1 -0
  81. package/dist/hooks/useIconProps.d.ts +5 -0
  82. package/dist/hooks/useIconProps.d.ts.map +1 -0
  83. package/dist/index.d.ts +14 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +8 -0
  86. package/dist/reportWebVitals.d.ts +4 -0
  87. package/dist/reportWebVitals.d.ts.map +1 -0
  88. package/dist/setupTests.d.ts +2 -0
  89. package/dist/setupTests.d.ts.map +1 -0
  90. package/dist/stories/Badge.stories.d.ts +13 -0
  91. package/dist/stories/Badge.stories.d.ts.map +1 -0
  92. package/dist/stories/Button.stories.d.ts +16 -0
  93. package/dist/stories/Button.stories.d.ts.map +1 -0
  94. package/dist/stories/ButtonGroup.stories.d.ts +11 -0
  95. package/dist/stories/ButtonGroup.stories.d.ts.map +1 -0
  96. package/dist/stories/Colors.stories.d.ts +8 -0
  97. package/dist/stories/Colors.stories.d.ts.map +1 -0
  98. package/dist/stories/Header.stories.d.ts +20 -0
  99. package/dist/stories/Header.stories.d.ts.map +1 -0
  100. package/dist/stories/MobileNav.stories.d.ts +10 -0
  101. package/dist/stories/MobileNav.stories.d.ts.map +1 -0
  102. package/dist/stories/Page.stories.d.ts +14 -0
  103. package/dist/stories/Page.stories.d.ts.map +1 -0
  104. package/dist/stories/Paginate.stories.d.ts +11 -0
  105. package/dist/stories/Paginate.stories.d.ts.map +1 -0
  106. package/dist/stories/Select.stories.d.ts +11 -0
  107. package/dist/stories/Select.stories.d.ts.map +1 -0
  108. package/dist/stories/SideNav.stories.d.ts +10 -0
  109. package/dist/stories/SideNav.stories.d.ts.map +1 -0
  110. package/dist/stories/TextInput.stories.d.ts +11 -0
  111. package/dist/stories/TextInput.stories.d.ts.map +1 -0
  112. package/dist/stories/Typography.stories.d.ts +11 -0
  113. package/dist/stories/Typography.stories.d.ts.map +1 -0
  114. package/output.css +639 -0
  115. package/package.json +91 -0
  116. package/postcss.config.js +6 -0
  117. package/public/favicon.ico +0 -0
  118. package/public/index.html +43 -0
  119. package/public/logo192.png +0 -0
  120. package/public/logo512.png +0 -0
  121. package/public/manifest.json +25 -0
  122. package/public/robots.txt +3 -0
  123. package/src/@interfaces/Badge.d.tsx +13 -0
  124. package/src/@interfaces/Button.d.tsx +17 -0
  125. package/src/@interfaces/Color.d.tsx +5 -0
  126. package/src/@interfaces/IButtonItem.d.tsx +6 -0
  127. package/src/@interfaces/ISubNavItem.d.tsx +10 -0
  128. package/src/@interfaces/MobileNavProps.d.tsx +4 -0
  129. package/src/@interfaces/NavItem.d.tsx +22 -0
  130. package/src/@interfaces/Pagination.d.tsx +7 -0
  131. package/src/@interfaces/Select.d.tsx +12 -0
  132. package/src/@interfaces/SideNavProps.d.tsx +11 -0
  133. package/src/@interfaces/TextInput.d.tsx +13 -0
  134. package/src/@interfaces/index.tsx +11 -0
  135. package/src/Badge.tsx +44 -0
  136. package/src/Button.tsx +132 -0
  137. package/src/ButtonGroup.tsx +37 -0
  138. package/src/ColorBox.tsx +15 -0
  139. package/src/Header.tsx +55 -0
  140. package/src/Nav/MobileNav.tsx +35 -0
  141. package/src/Nav/NavItem.tsx +101 -0
  142. package/src/Nav/SideNav.tsx +165 -0
  143. package/src/Nav/SubNavItem.tsx +39 -0
  144. package/src/Page.tsx +72 -0
  145. package/src/Paginate.tsx +102 -0
  146. package/src/Select.tsx +102 -0
  147. package/src/StoryLayout.tsx +17 -0
  148. package/src/TextInput.tsx +103 -0
  149. package/src/Typography.tsx +81 -0
  150. package/src/data/colors.tsx +279 -0
  151. package/src/data/countries.tsx +57 -0
  152. package/src/data/images/be.svg +1 -0
  153. package/src/data/images/de.svg +1 -0
  154. package/src/data/images/fr.svg +1 -0
  155. package/src/data/images/in.svg +1 -0
  156. package/src/data/images/index.tsx +33 -0
  157. package/src/data/images/it.svg +1 -0
  158. package/src/data/images/logo.svg +23 -0
  159. package/src/data/images/nl.svg +1 -0
  160. package/src/data/images/ru.svg +1 -0
  161. package/src/data/images/us.svg +1 -0
  162. package/src/data/index.tsx +5 -0
  163. package/src/data/navItems.tsx +109 -0
  164. package/src/data/options.tsx +51 -0
  165. package/src/data/prices.tsx +36 -0
  166. package/src/hooks/useIconClassName.tsx +14 -0
  167. package/src/hooks/useIconProps.tsx +19 -0
  168. package/src/index.js +15 -0
  169. package/src/react-app-env.d.ts +1 -0
  170. package/src/reportWebVitals.ts +15 -0
  171. package/src/setupTests.ts +5 -0
  172. package/src/stories/Badge.stories.tsx +86 -0
  173. package/src/stories/Button.stories.tsx +104 -0
  174. package/src/stories/ButtonGroup.stories.tsx +83 -0
  175. package/src/stories/Colors.stories.tsx +31 -0
  176. package/src/stories/Configure.mdx +364 -0
  177. package/src/stories/Header.stories.ts +33 -0
  178. package/src/stories/MobileNav.stories.tsx +60 -0
  179. package/src/stories/Page.stories.ts +32 -0
  180. package/src/stories/Paginate.stories.tsx +64 -0
  181. package/src/stories/Select.stories.tsx +77 -0
  182. package/src/stories/SideNav.stories.tsx +38 -0
  183. package/src/stories/TextInput.stories.tsx +100 -0
  184. package/src/stories/Typography.stories.tsx +115 -0
  185. package/src/stories/assets/accessibility.png +0 -0
  186. package/src/stories/assets/accessibility.svg +1 -0
  187. package/src/stories/assets/addon-library.png +0 -0
  188. package/src/stories/assets/assets.png +0 -0
  189. package/src/stories/assets/avif-test-image.avif +0 -0
  190. package/src/stories/assets/context.png +0 -0
  191. package/src/stories/assets/discord.svg +1 -0
  192. package/src/stories/assets/docs.png +0 -0
  193. package/src/stories/assets/figma-plugin.png +0 -0
  194. package/src/stories/assets/github.svg +1 -0
  195. package/src/stories/assets/share.png +0 -0
  196. package/src/stories/assets/styling.png +0 -0
  197. package/src/stories/assets/testing.png +0 -0
  198. package/src/stories/assets/theming.png +0 -0
  199. package/src/stories/assets/tutorials.svg +1 -0
  200. package/src/stories/assets/youtube.svg +1 -0
  201. package/src/styles/global.css +367 -0
  202. package/storybook-static/125.65b26339.iframe.bundle.js +405 -0
  203. package/storybook-static/125.65b26339.iframe.bundle.js.LICENSE.txt +9 -0
  204. package/storybook-static/125.65b26339.iframe.bundle.js.map +1 -0
  205. package/storybook-static/13.0638081a.iframe.bundle.js +2 -0
  206. package/storybook-static/13.0638081a.iframe.bundle.js.LICENSE.txt +9 -0
  207. package/storybook-static/161.a19908ac.iframe.bundle.js +2 -0
  208. package/storybook-static/161.a19908ac.iframe.bundle.js.LICENSE.txt +9 -0
  209. package/storybook-static/161528bb6c25115b3f83.png +0 -0
  210. package/storybook-static/167.3fa3a909.iframe.bundle.js +1 -0
  211. package/storybook-static/294.ce38f65c.iframe.bundle.js +1 -0
  212. package/storybook-static/2dbc69731c3f9930a271.png +0 -0
  213. package/storybook-static/314.568bd9af.iframe.bundle.js +2 -0
  214. package/storybook-static/314.568bd9af.iframe.bundle.js.LICENSE.txt +15 -0
  215. package/storybook-static/364.0b18ef67.iframe.bundle.js +1 -0
  216. package/storybook-static/735.1625d9f4.iframe.bundle.js +2 -0
  217. package/storybook-static/735.1625d9f4.iframe.bundle.js.LICENSE.txt +9 -0
  218. package/storybook-static/742.597501f6.iframe.bundle.js +1 -0
  219. package/storybook-static/7a58d2cb9a6358f85e9b.png +0 -0
  220. package/storybook-static/844.aec20bdb.iframe.bundle.js +95 -0
  221. package/storybook-static/844.aec20bdb.iframe.bundle.js.LICENSE.txt +19 -0
  222. package/storybook-static/844.aec20bdb.iframe.bundle.js.map +1 -0
  223. package/storybook-static/9335a1a91b80ad4fec70.png +0 -0
  224. package/storybook-static/936.fd850a3f.iframe.bundle.js +1 -0
  225. package/storybook-static/961.0e5457c5.iframe.bundle.js +2 -0
  226. package/storybook-static/961.0e5457c5.iframe.bundle.js.LICENSE.txt +9 -0
  227. package/storybook-static/c720ced26387af8a9cb2.png +0 -0
  228. package/storybook-static/e93de094692245f1ec04.png +0 -0
  229. package/storybook-static/f7d8b9a8cec7528e0e36.png +0 -0
  230. package/storybook-static/favicon.ico +0 -0
  231. package/storybook-static/favicon.svg +1 -0
  232. package/storybook-static/iframe.html +511 -0
  233. package/storybook-static/index.html +185 -0
  234. package/storybook-static/index.json +1 -0
  235. package/storybook-static/logo192.png +0 -0
  236. package/storybook-static/logo512.png +0 -0
  237. package/storybook-static/main.069281cf.iframe.bundle.js +1 -0
  238. package/storybook-static/manifest.json +25 -0
  239. package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  240. package/storybook-static/nunito-sans-bold.woff2 +0 -0
  241. package/storybook-static/nunito-sans-italic.woff2 +0 -0
  242. package/storybook-static/nunito-sans-regular.woff2 +0 -0
  243. package/storybook-static/project.json +1 -0
  244. package/storybook-static/robots.txt +3 -0
  245. package/storybook-static/runtime~main.295ddda4.iframe.bundle.js +1 -0
  246. package/storybook-static/sb-addons/chromatic-com-storybook-10/manager-bundle.js +331 -0
  247. package/storybook-static/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +51 -0
  248. package/storybook-static/sb-addons/essentials-actions-2/manager-bundle.js +3 -0
  249. package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js +12 -0
  250. package/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js +402 -0
  251. package/storybook-static/sb-addons/essentials-docs-3/manager-bundle.js +242 -0
  252. package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js +3 -0
  253. package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js +3 -0
  254. package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js +3 -0
  255. package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js +3 -0
  256. package/storybook-static/sb-addons/interactions-11/manager-bundle.js +222 -0
  257. package/storybook-static/sb-addons/links-12/manager-bundle.js +3 -0
  258. package/storybook-static/sb-addons/onboarding-9/manager-bundle.js +127 -0
  259. package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
  260. package/storybook-static/sb-common-assets/favicon.svg +1 -0
  261. package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  262. package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  263. package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  264. package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  265. package/storybook-static/sb-manager/globals-module-info.js +1051 -0
  266. package/storybook-static/sb-manager/globals-runtime.js +41591 -0
  267. package/storybook-static/sb-manager/globals.js +48 -0
  268. package/storybook-static/sb-manager/runtime.js +12048 -0
  269. package/storybook-static/sb-preview/globals.js +33 -0
  270. package/storybook-static/sb-preview/runtime.js +7745 -0
  271. package/storybook-static/static/css/main.08036cd2.css +2294 -0
  272. package/storybook-static/static/css/main.08036cd2.css.map +1 -0
  273. package/storybook-static/static/media/discord.d85804c7f88be863ff119366ab74d826.svg +1 -0
  274. package/storybook-static/static/media/github.e4e8df827592b1ed0288e4678e1965ce.svg +1 -0
  275. package/storybook-static/static/media/tutorials.fde6e46fc254fa77b6e39d1118470f7c.svg +1 -0
  276. package/storybook-static/static/media/youtube.fd046a09fac357359f94cc21068d6560.svg +1 -0
  277. package/storybook-static/stories-Badge-stories.484f7206.iframe.bundle.js +1 -0
  278. package/storybook-static/stories-Button-stories.5e29be85.iframe.bundle.js +1 -0
  279. package/storybook-static/stories-ButtonGroup-stories.cc89968c.iframe.bundle.js +1 -0
  280. package/storybook-static/stories-Colors-stories.f892dc75.iframe.bundle.js +2 -0
  281. package/storybook-static/stories-Colors-stories.f892dc75.iframe.bundle.js.LICENSE.txt +15 -0
  282. package/storybook-static/stories-Configure-mdx.81346d97.iframe.bundle.js +1 -0
  283. package/storybook-static/stories-Header-stories.cf691094.iframe.bundle.js +2 -0
  284. package/storybook-static/stories-Header-stories.cf691094.iframe.bundle.js.LICENSE.txt +15 -0
  285. package/storybook-static/stories-MobileNav-stories.f04cccdd.iframe.bundle.js +1 -0
  286. package/storybook-static/stories-Page-stories.0c9aa29d.iframe.bundle.js +2 -0
  287. package/storybook-static/stories-Page-stories.0c9aa29d.iframe.bundle.js.LICENSE.txt +15 -0
  288. package/storybook-static/stories-Paginate-stories.3b161781.iframe.bundle.js +1 -0
  289. package/storybook-static/stories-Select-stories.7556ae0d.iframe.bundle.js +1 -0
  290. package/storybook-static/stories-SideNav-stories.093fac6a.iframe.bundle.js +1 -0
  291. package/storybook-static/stories-TextInput-stories.6d3e15c6.iframe.bundle.js +1 -0
  292. package/storybook-static/stories-Typography-stories.6640f7ac.iframe.bundle.js +2 -0
  293. package/storybook-static/stories-Typography-stories.6640f7ac.iframe.bundle.js.LICENSE.txt +15 -0
  294. package/tailwind.config.js +113 -0
  295. 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
+ };
@@ -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
+ };