@soul-refiner/design-system 0.0.10 → 0.0.11

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 (267) hide show
  1. package/dist/custom.d.ts +4 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/{design-system.umd.cjs → index.umd.cjs} +1 -1
  4. package/dist/src/actions/Button/Button.module.scss +205 -0
  5. package/dist/src/actions/Button/Button.spec.js +56 -0
  6. package/dist/src/actions/Button/Button.tsx +143 -0
  7. package/dist/src/actions/Button/index.ts +1 -0
  8. package/dist/src/actions/Dropdown/Dropdown.module.scss +77 -0
  9. package/dist/src/actions/Dropdown/Dropdown.spec.js +149 -0
  10. package/dist/src/actions/Dropdown/Dropdown.tsx +224 -0
  11. package/dist/src/actions/Dropdown/index.ts +6 -0
  12. package/dist/src/actions/Dropzone/Dropzone.module.scss +48 -0
  13. package/dist/src/actions/Dropzone/Dropzone.spec.js +60 -0
  14. package/dist/src/actions/Dropzone/Dropzone.tsx +191 -0
  15. package/dist/src/actions/Dropzone/index.ts +1 -0
  16. package/dist/src/actions/Rate/Rate.module.scss +17 -0
  17. package/dist/src/actions/Rate/Rate.tsx +53 -0
  18. package/dist/src/actions/Rate/index.ts +1 -0
  19. package/dist/src/actions/Switch/Switch.module.scss +35 -0
  20. package/dist/src/actions/Switch/Switch.spec.js +31 -0
  21. package/dist/src/actions/Switch/Switch.tsx +34 -0
  22. package/dist/src/actions/Switch/index.ts +1 -0
  23. package/dist/src/actions/index.ts +5 -0
  24. package/dist/src/cards/CourseCard/CourseCard.module.scss +219 -0
  25. package/dist/src/cards/CourseCard/CourseCard.spec.js +60 -0
  26. package/dist/src/cards/CourseCard/CourseCard.tsx +145 -0
  27. package/dist/src/cards/CourseCard/index.ts +1 -0
  28. package/dist/src/cards/EpisodeCard/EpisodeCard.module.scss +69 -0
  29. package/dist/src/cards/EpisodeCard/EpisodeCard.tsx +53 -0
  30. package/dist/src/cards/EpisodeCard/index.ts +1 -0
  31. package/dist/src/cards/FeatureCard/FeatureCard.module.scss +116 -0
  32. package/dist/src/cards/FeatureCard/FeatureCard.spec.js +70 -0
  33. package/dist/src/cards/FeatureCard/FeatureCard.tsx +123 -0
  34. package/dist/src/cards/FeatureCard/index.ts +1 -0
  35. package/dist/src/cards/index.ts +3 -0
  36. package/dist/src/data/Bar/Bar.module.scss +105 -0
  37. package/dist/src/data/Bar/Bar.tsx +161 -0
  38. package/dist/src/data/Bar/index.ts +1 -0
  39. package/dist/src/data/Line/Line.module.scss +102 -0
  40. package/dist/src/data/Line/Line.tsx +162 -0
  41. package/dist/src/data/Line/index.ts +1 -0
  42. package/dist/src/data/Pie/Pie.module.scss +56 -0
  43. package/dist/src/data/Pie/Pie.spec.js +72 -0
  44. package/dist/src/data/Pie/Pie.tsx +111 -0
  45. package/dist/src/data/Pie/index.ts +1 -0
  46. package/dist/src/data/index.ts +3 -0
  47. package/dist/src/editor/Editor.module.scss +125 -0
  48. package/dist/src/editor/Editor.tsx +327 -0
  49. package/dist/src/editor/common/elements.ts +50 -0
  50. package/dist/src/editor/common/index.ts +2 -0
  51. package/dist/src/editor/common/marks.ts +27 -0
  52. package/dist/src/editor/components/MediaDrawer/MediaDrawer.module.scss +316 -0
  53. package/dist/src/editor/components/MediaDrawer/MediaDrawer.tsx +457 -0
  54. package/dist/src/editor/components/MediaDrawer/index.ts +1 -0
  55. package/dist/src/editor/components/index.ts +1 -0
  56. package/dist/src/editor/config/default.ts +213 -0
  57. package/dist/src/editor/config/index.ts +2 -0
  58. package/dist/src/editor/config/props.ts +9 -0
  59. package/dist/src/editor/index.ts +2 -0
  60. package/dist/src/editor/plateUI.ts +82 -0
  61. package/dist/src/editor/plugins/blocks.tsx +71 -0
  62. package/dist/src/editor/plugins/custom/assets/DefaultThumbnail.tsx +57 -0
  63. package/dist/src/editor/plugins/custom/assets/index.ts +1 -0
  64. package/dist/src/editor/plugins/custom/buttons.tsx +289 -0
  65. package/dist/src/editor/plugins/custom/example.tsx +64 -0
  66. package/dist/src/editor/plugins/custom/exitBreak.ts +41 -0
  67. package/dist/src/editor/plugins/custom/footnote.tsx +185 -0
  68. package/dist/src/editor/plugins/custom/index.ts +14 -0
  69. package/dist/src/editor/plugins/custom/paywall.tsx +156 -0
  70. package/dist/src/editor/plugins/custom/qa.tsx +390 -0
  71. package/dist/src/editor/plugins/custom/resetBlockType.ts +29 -0
  72. package/dist/src/editor/plugins/custom/selectOnBackspace.ts +7 -0
  73. package/dist/src/editor/plugins/custom/softBreak.ts +20 -0
  74. package/dist/src/editor/plugins/custom/styles/Button.module.scss +51 -0
  75. package/dist/src/editor/plugins/custom/styles/Footnote.module.scss +58 -0
  76. package/dist/src/editor/plugins/custom/styles/Paywall.module.scss +67 -0
  77. package/dist/src/editor/plugins/custom/styles/QA.module.scss +140 -0
  78. package/dist/src/editor/plugins/custom/styles/Video.module.scss +79 -0
  79. package/dist/src/editor/plugins/custom/video.tsx +163 -0
  80. package/dist/src/editor/plugins/index.ts +18 -0
  81. package/dist/src/editor/plugins/inline.ts +46 -0
  82. package/dist/src/editor/plugins/marks.ts +25 -0
  83. package/dist/src/editor/plugins/utils.ts +22 -0
  84. package/dist/src/feedback/Chip/Chip.module.scss +23 -0
  85. package/dist/src/feedback/Chip/Chip.tsx +58 -0
  86. package/dist/src/feedback/Chip/index.ts +1 -0
  87. package/dist/src/feedback/Loader/Loader.module.scss +18 -0
  88. package/dist/src/feedback/Loader/Loader.spec.js +18 -0
  89. package/dist/src/feedback/Loader/Loader.tsx +53 -0
  90. package/dist/src/feedback/Loader/index.ts +1 -0
  91. package/dist/src/feedback/ProgressBar/ProgressBar.module.scss +13 -0
  92. package/dist/src/feedback/ProgressBar/ProgressBar.tsx +32 -0
  93. package/dist/src/feedback/ProgressBar/index.ts +1 -0
  94. package/dist/src/feedback/Toast/Toast.module.scss +44 -0
  95. package/dist/src/feedback/Toast/Toast.tsx +76 -0
  96. package/dist/src/feedback/Toast/index.ts +1 -0
  97. package/dist/src/feedback/Tooltip/Tooltip.module.scss +47 -0
  98. package/dist/src/feedback/Tooltip/Tooltip.tsx +10 -0
  99. package/dist/src/feedback/Tooltip/index.ts +1 -0
  100. package/dist/src/feedback/index.ts +5 -0
  101. package/dist/src/global.d.ts +6 -0
  102. package/dist/src/iconography/Avatar/Avatar.module.scss +90 -0
  103. package/dist/src/iconography/Avatar/Avatar.spec.js +75 -0
  104. package/dist/src/iconography/Avatar/Avatar.tsx +96 -0
  105. package/dist/src/iconography/Avatar/DefaultIcon.svg +4 -0
  106. package/dist/src/iconography/Avatar/DefaultIcon.tsx +12 -0
  107. package/dist/src/iconography/Avatar/iconHelpers.tsx +186 -0
  108. package/dist/src/iconography/Avatar/index.ts +1 -0
  109. package/dist/src/iconography/ColoredIcon/ColoredIcon.module.scss +40 -0
  110. package/dist/src/iconography/ColoredIcon/ColoredIcon.tsx +30 -0
  111. package/dist/src/iconography/ColoredIcon/index.ts +5 -0
  112. package/dist/src/iconography/DevicePreview/DevicePreview.module.scss +143 -0
  113. package/dist/src/iconography/DevicePreview/DevicePreview.tsx +592 -0
  114. package/dist/src/iconography/DevicePreview/index.ts +1 -0
  115. package/dist/src/iconography/IconHeader/IconHeader.module.scss +42 -0
  116. package/dist/src/iconography/IconHeader/IconHeader.tsx +42 -0
  117. package/dist/src/iconography/IconHeader/index.ts +1 -0
  118. package/dist/src/iconography/StarRating/StarRating.tsx +99 -0
  119. package/dist/src/iconography/StarRating/index.ts +1 -0
  120. package/dist/src/iconography/index.ts +5 -0
  121. package/dist/src/implementations/BodyContent/BodyContent.module.scss +38 -0
  122. package/dist/src/implementations/BodyContent/BodyContent.tsx +78 -0
  123. package/dist/src/implementations/BodyContent/index.ts +2 -0
  124. package/dist/src/implementations/JoinGroupModal/JoinGroupModal.module.scss +83 -0
  125. package/dist/src/implementations/JoinGroupModal/JoinGroupModal.tsx +176 -0
  126. package/dist/src/implementations/JoinGroupModal/index.ts +1 -0
  127. package/dist/src/implementations/index.ts +2 -0
  128. package/dist/src/index.ts +149 -0
  129. package/dist/src/inputs/CalendarInput/CalendarInput.module.scss +38 -0
  130. package/dist/src/inputs/CalendarInput/CalendarInput.spec.js +19 -0
  131. package/dist/src/inputs/CalendarInput/CalendarInput.tsx +29 -0
  132. package/dist/src/inputs/CalendarInput/index.ts +1 -0
  133. package/dist/src/inputs/CheckboxInput/CheckboxInput.module.scss +23 -0
  134. package/dist/src/inputs/CheckboxInput/CheckboxInput.tsx +39 -0
  135. package/dist/src/inputs/CheckboxInput/index.ts +1 -0
  136. package/dist/src/inputs/FeedInput/FeedInput.module.scss +48 -0
  137. package/dist/src/inputs/FeedInput/FeedInput.spec.js +16 -0
  138. package/dist/src/inputs/FeedInput/FeedInput.tsx +197 -0
  139. package/dist/src/inputs/FeedInput/index.ts +1 -0
  140. package/dist/src/inputs/InboxInput/InboxInput.module.scss +48 -0
  141. package/dist/src/inputs/InboxInput/InboxInput.spec.js +19 -0
  142. package/dist/src/inputs/InboxInput/InboxInput.tsx +97 -0
  143. package/dist/src/inputs/InboxInput/index.ts +1 -0
  144. package/dist/src/inputs/PostInput/PostInput.module.scss +49 -0
  145. package/dist/src/inputs/PostInput/PostInput.spec.js +19 -0
  146. package/dist/src/inputs/PostInput/PostInput.tsx +54 -0
  147. package/dist/src/inputs/PostInput/index.ts +1 -0
  148. package/dist/src/inputs/RadioInput/RadioInput.module.scss +68 -0
  149. package/dist/src/inputs/RadioInput/RadioInput.tsx +55 -0
  150. package/dist/src/inputs/RadioInput/index.ts +1 -0
  151. package/dist/src/inputs/SearchInput/SearchInput.module.scss +40 -0
  152. package/dist/src/inputs/SearchInput/SearchInput.tsx +61 -0
  153. package/dist/src/inputs/SearchInput/index.ts +1 -0
  154. package/dist/src/inputs/SelectInput/SelectInput.module.scss +66 -0
  155. package/dist/src/inputs/SelectInput/SelectInput.tsx +145 -0
  156. package/dist/src/inputs/SelectInput/index.ts +1 -0
  157. package/dist/src/inputs/TagInput/TagInput.module.scss +75 -0
  158. package/dist/src/inputs/TagInput/TagInput.tsx +115 -0
  159. package/dist/src/inputs/TagInput/index.ts +1 -0
  160. package/dist/src/inputs/TextInput/TextInput.module.scss +35 -0
  161. package/dist/src/inputs/TextInput/TextInput.tsx +46 -0
  162. package/dist/src/inputs/TextInput/index.ts +1 -0
  163. package/dist/src/inputs/index.ts +10 -0
  164. package/dist/src/lists/ContactDetails/ContactDetails.module.scss +70 -0
  165. package/dist/src/lists/ContactDetails/ContactDetails.spec.js +69 -0
  166. package/dist/src/lists/ContactDetails/ContactDetails.tsx +185 -0
  167. package/dist/src/lists/ContactDetails/index.ts +1 -0
  168. package/dist/src/lists/index.ts +1 -0
  169. package/dist/src/navigation/Breadcrumbs/Breadcrumbs.module.scss +18 -0
  170. package/dist/src/navigation/Breadcrumbs/Breadcrumbs.spec.js +38 -0
  171. package/dist/src/navigation/Breadcrumbs/Breadcrumbs.tsx +43 -0
  172. package/dist/src/navigation/Breadcrumbs/index.ts +1 -0
  173. package/dist/src/navigation/Drawer/Drawer.module.scss +104 -0
  174. package/dist/src/navigation/Drawer/Drawer.tsx +177 -0
  175. package/dist/src/navigation/Drawer/index.ts +1 -0
  176. package/dist/src/navigation/EditorBar/EditorBar.module.scss +118 -0
  177. package/dist/src/navigation/EditorBar/EditorBar.tsx +416 -0
  178. package/dist/src/navigation/EditorBar/components/AlignmentDropdown/AlignmentDropdown.tsx +106 -0
  179. package/dist/src/navigation/EditorBar/components/AlignmentDropdown/index.ts +1 -0
  180. package/dist/src/navigation/EditorBar/components/ButtonModal/ButtonModal.module.scss +85 -0
  181. package/dist/src/navigation/EditorBar/components/ButtonModal/ButtonModal.tsx +314 -0
  182. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/Comment.tsx +28 -0
  183. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/GiftSubscription.tsx +28 -0
  184. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/Link.tsx +28 -0
  185. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/Share.tsx +28 -0
  186. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/ShareCommunity.tsx +42 -0
  187. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/Signup.tsx +68 -0
  188. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/Special.tsx +24 -0
  189. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/Subscribe.tsx +28 -0
  190. package/dist/src/navigation/EditorBar/components/ButtonModal/assets/index.ts +8 -0
  191. package/dist/src/navigation/EditorBar/components/ButtonModal/index.ts +1 -0
  192. package/dist/src/navigation/EditorBar/components/FontDropdown/FontDropdown.module.scss +16 -0
  193. package/dist/src/navigation/EditorBar/components/FontDropdown/FontDropdown.tsx +137 -0
  194. package/dist/src/navigation/EditorBar/components/FontDropdown/index.ts +1 -0
  195. package/dist/src/navigation/EditorBar/components/MoreDropdown/MoreDropdown.module.scss +43 -0
  196. package/dist/src/navigation/EditorBar/components/MoreDropdown/MoreDropdown.tsx +124 -0
  197. package/dist/src/navigation/EditorBar/components/MoreDropdown/index.ts +1 -0
  198. package/dist/src/navigation/EditorBar/components/OutlineDropdown/OutlineDropdown.module.scss +21 -0
  199. package/dist/src/navigation/EditorBar/components/OutlineDropdown/OutlineDropdown.tsx +37 -0
  200. package/dist/src/navigation/EditorBar/components/OutlineDropdown/index.ts +1 -0
  201. package/dist/src/navigation/EditorBar/components/TextTypeDropdown/TextTypeDropdown.module.scss +51 -0
  202. package/dist/src/navigation/EditorBar/components/TextTypeDropdown/TextTypeDropdown.tsx +80 -0
  203. package/dist/src/navigation/EditorBar/components/TextTypeDropdown/index.ts +1 -0
  204. package/dist/src/navigation/EditorBar/components/VideoModal/VideoModal.module.scss +150 -0
  205. package/dist/src/navigation/EditorBar/components/VideoModal/VideoModal.tsx +163 -0
  206. package/dist/src/navigation/EditorBar/components/VideoModal/index.ts +1 -0
  207. package/dist/src/navigation/EditorBar/components/index.ts +7 -0
  208. package/dist/src/navigation/EditorBar/index.ts +1 -0
  209. package/dist/src/navigation/MenuTabs/MenuTabs.module.scss +34 -0
  210. package/dist/src/navigation/MenuTabs/MenuTabs.spec.js +36 -0
  211. package/dist/src/navigation/MenuTabs/MenuTabs.tsx +52 -0
  212. package/dist/src/navigation/MenuTabs/index.ts +1 -0
  213. package/dist/src/navigation/Navigation/Navigation.module.scss +92 -0
  214. package/dist/src/navigation/Navigation/Navigation.spec.js +144 -0
  215. package/dist/src/navigation/Navigation/Navigation.tsx +111 -0
  216. package/dist/src/navigation/Navigation/SubNavigation.module.scss +255 -0
  217. package/dist/src/navigation/Navigation/SubNavigation.spec.js +112 -0
  218. package/dist/src/navigation/Navigation/SubNavigation.tsx +443 -0
  219. package/dist/src/navigation/Navigation/index.ts +15 -0
  220. package/dist/src/navigation/Pagination/Pagination.module.scss +49 -0
  221. package/dist/src/navigation/Pagination/Pagination.tsx +115 -0
  222. package/dist/src/navigation/Pagination/index.ts +1 -0
  223. package/dist/src/navigation/index.ts +21 -0
  224. package/dist/src/surfaces/Comment/Comment.module.scss +106 -0
  225. package/dist/src/surfaces/Comment/Comment.spec.js +105 -0
  226. package/dist/src/surfaces/Comment/Comment.tsx +157 -0
  227. package/dist/src/surfaces/Comment/index.ts +1 -0
  228. package/dist/src/surfaces/Faq/Faq.module.scss +91 -0
  229. package/dist/src/surfaces/Faq/Faq.spec.js +38 -0
  230. package/dist/src/surfaces/Faq/Faq.tsx +156 -0
  231. package/dist/src/surfaces/Faq/index.ts +1 -0
  232. package/dist/src/surfaces/Message/Message.module.scss +37 -0
  233. package/dist/src/surfaces/Message/Message.spec.js +47 -0
  234. package/dist/src/surfaces/Message/Message.tsx +54 -0
  235. package/dist/src/surfaces/Message/index.ts +1 -0
  236. package/dist/src/surfaces/Modal/Modal.module.scss +52 -0
  237. package/dist/src/surfaces/Modal/Modal.spec.js +38 -0
  238. package/dist/src/surfaces/Modal/Modal.tsx +131 -0
  239. package/dist/src/surfaces/Modal/index.ts +5 -0
  240. package/dist/src/surfaces/Plan/Plan.module.scss +79 -0
  241. package/dist/src/surfaces/Plan/Plan.tsx +75 -0
  242. package/dist/src/surfaces/Plan/index.ts +1 -0
  243. package/dist/src/surfaces/Post/Post.module.scss +46 -0
  244. package/dist/src/surfaces/Post/Post.spec.js +103 -0
  245. package/dist/src/surfaces/Post/Post.tsx +185 -0
  246. package/dist/src/surfaces/Post/index.ts +1 -0
  247. package/dist/src/surfaces/Post/postHelpers.ts +20 -0
  248. package/dist/src/surfaces/ProfileHeader/ProfileHeader.module.scss +202 -0
  249. package/dist/src/surfaces/ProfileHeader/ProfileHeader.tsx +103 -0
  250. package/dist/src/surfaces/ProfileHeader/index.ts +1 -0
  251. package/dist/src/surfaces/RatingsOverview/RatingsOverview.module.scss +54 -0
  252. package/dist/src/surfaces/RatingsOverview/RatingsOverview.tsx +69 -0
  253. package/dist/src/surfaces/RatingsOverview/index.ts +1 -0
  254. package/dist/src/surfaces/Review/Review.module.scss +73 -0
  255. package/dist/src/surfaces/Review/Review.tsx +88 -0
  256. package/dist/src/surfaces/Review/index.ts +1 -0
  257. package/dist/src/surfaces/index.ts +9 -0
  258. package/dist/src/tables/Filter/Filter.module.scss +34 -0
  259. package/dist/src/tables/Filter/Filter.tsx +30 -0
  260. package/dist/src/tables/Filter/index.ts +1 -0
  261. package/dist/src/tables/Table/Table.module.scss +126 -0
  262. package/dist/src/tables/Table/Table.spec.js +113 -0
  263. package/dist/src/tables/Table/Table.tsx +251 -0
  264. package/dist/src/tables/Table/index.ts +7 -0
  265. package/dist/src/tables/index.ts +7 -0
  266. package/package.json +3 -2
  267. /package/dist/{design-system.js → index.js} +0 -0
@@ -0,0 +1,443 @@
1
+ import React, { UIEventHandler } from "react";
2
+ import { Component, sortChildrenByType } from "@soul-refiner/utils/src";
3
+ import { abbrRelativeTimeString } from "@soul-refiner/utils/src";
4
+ import {
5
+ ArrowLeft,
6
+ ChevronDown,
7
+ ChevronUp,
8
+ EllipsisHorizontal,
9
+ Plus,
10
+ } from "@soul-refiner/icons/src";
11
+ import styles from "./SubNavigation.module.scss";
12
+ import { MenuTabs } from "../MenuTabs";
13
+ import { SearchInput } from "../../inputs";
14
+ import { Button, ButtonProps } from "../../actions";
15
+ import { Dropdown, DropdownOptionProps } from "../../actions/Dropdown";
16
+ import { Avatar, AvatarProps } from "../../iconography";
17
+
18
+ /********************************************************
19
+ * Sub Navigation
20
+ */
21
+ export interface SubNavigationProps extends React.PropsWithChildren {
22
+ onSearch: (query: string) => void;
23
+ onScrollEnd?: () => void;
24
+ show: boolean;
25
+ title: string;
26
+ }
27
+
28
+ const SubNavigation = ({
29
+ children,
30
+ onSearch,
31
+ onScrollEnd,
32
+ show,
33
+ title,
34
+ }: SubNavigationProps) => {
35
+ const tabsRef = React.useRef<HTMLDivElement>(null);
36
+ const [prevLoc, setPrevLoc] = React.useState(0);
37
+ const [clickLoc, setClickLoc] = React.useState(0);
38
+ const [scrolling, setScrolling] = React.useState(false);
39
+ const [activeTab, setActiveTab] = React.useState(0);
40
+ const [activeSubMenu, setActiveSubMenu] = React.useState<
41
+ number | undefined
42
+ >();
43
+ const [query, setQuery] = React.useState("");
44
+
45
+ const _children = sortChildrenByType(children);
46
+ let tabs: string[] = [];
47
+
48
+ React.Children.forEach(_children["SubNavigation.Tab"], (child) => {
49
+ tabs.push((child as { props: { name: string } })?.props.name);
50
+ });
51
+
52
+ const handleChange = (event: React.FormEvent) => {
53
+ setQuery((event.target as HTMLInputElement).value);
54
+ };
55
+
56
+ const handleSubmit = (event: React.FormEvent) => {
57
+ event.preventDefault();
58
+ onSearch(query);
59
+ };
60
+
61
+ const handleTabChange = (index: number) => setActiveTab(index);
62
+
63
+ const handleTabMouseDown = (event: React.MouseEvent) => {
64
+ setScrolling(true);
65
+ setClickLoc(event.clientX);
66
+ };
67
+
68
+ const handleTabDrag = (event: React.MouseEvent) => {
69
+ if (tabsRef.current && scrolling) {
70
+ tabsRef.current.scrollLeft = prevLoc + clickLoc - event.clientX;
71
+ }
72
+ };
73
+
74
+ const handleTabMouseUp = () => {
75
+ setScrolling(false);
76
+ setPrevLoc(tabsRef.current?.scrollLeft ?? 0);
77
+ };
78
+
79
+ const handleScroll = (event: React.WheelEvent<HTMLDivElement>) => {
80
+ const target = event.target as HTMLDivElement;
81
+ const scrollDistance = target.scrollHeight - target.scrollTop;
82
+ // Margin of 10 for browser differences
83
+ if (scrollDistance - target.clientHeight < 11 && onScrollEnd) {
84
+ onScrollEnd();
85
+ }
86
+ };
87
+
88
+ submenu: if (activeSubMenu !== undefined) {
89
+ const activeTabElement = React.Children.toArray(
90
+ _children?.["SubNavigation.Tab"]?.[activeTab]
91
+ );
92
+ if (!activeTabElement || activeSubMenu === undefined) break submenu;
93
+ let parentProps = (activeTabElement[0] as any)?.props?.children?.props;
94
+ let activeSubMenuElement = parentProps?.submenu;
95
+
96
+ if (!activeSubMenuElement) {
97
+ // if there is more than one child
98
+ parentProps = (activeTabElement[0] as any)?.props?.children?.[
99
+ activeSubMenu
100
+ ]?.props;
101
+ activeSubMenuElement = parentProps?.submenu;
102
+ if (
103
+ !activeSubMenuElement ||
104
+ activeSubMenuElement.type.displayName !== "SubNavigation.SubMenu"
105
+ )
106
+ break submenu;
107
+ }
108
+
109
+ return (
110
+ <div
111
+ data-testid="submenu"
112
+ className={`${styles.secondary}${show ? " show" : " hidden"}`}
113
+ >
114
+ <div className="header">
115
+ <div
116
+ className="title-wrapper submenu"
117
+ onClick={() => setActiveSubMenu(undefined)}
118
+ >
119
+ <ArrowLeft fill="var(--color-grey-1)" iconSize={16} size={30} />
120
+ <h4>{activeSubMenuElement.props.title}</h4>
121
+ </div>
122
+ <Avatar size={40} title={parentProps.title} url={parentProps.url} />
123
+ </div>
124
+ <div className="contents">{activeSubMenuElement}</div>
125
+ </div>
126
+ );
127
+ }
128
+
129
+ return (
130
+ <div
131
+ data-testid="subnavigation"
132
+ className={`${styles.secondary}${show ? " show" : " hidden"}`}
133
+ >
134
+ <div className="header">
135
+ <div className="title-wrapper">
136
+ <h4>{title}</h4>
137
+ <SearchInput
138
+ expandable
139
+ onChange={handleChange}
140
+ onSubmit={handleSubmit as () => undefined}
141
+ value={query}
142
+ />
143
+ </div>
144
+ <div className="buttons-wrapper">
145
+ {_children["SubNavigation.Button"]}
146
+ </div>
147
+ </div>
148
+ <div
149
+ className="tab-wrapper"
150
+ onMouseDown={handleTabMouseDown}
151
+ onMouseMove={handleTabDrag}
152
+ onMouseUp={handleTabMouseUp}
153
+ ref={tabsRef}
154
+ >
155
+ <MenuTabs
156
+ activeItem={activeTab}
157
+ onTabClick={handleTabChange}
158
+ tabItems={tabs}
159
+ />
160
+ </div>
161
+ <div
162
+ className="contents"
163
+ onScroll={
164
+ onScrollEnd
165
+ ? (handleScroll as unknown as UIEventHandler<HTMLDivElement>)
166
+ : undefined
167
+ }
168
+ >
169
+ {React.Children.map(
170
+ (_children["SubNavigation.Tab"][activeTab] as React.ReactElement)
171
+ .props.children,
172
+ (child, index) => {
173
+ if (child.props.submenu) {
174
+ return React.cloneElement(child, {
175
+ key: "menu-item-" + index.toString(36),
176
+ onClick: (event: React.MouseEvent) => {
177
+ event.stopPropagation();
178
+ setActiveSubMenu(index);
179
+ },
180
+ });
181
+ }
182
+ return React.cloneElement(child, {
183
+ key: "menu-item-" + index.toString(36),
184
+ });
185
+ }
186
+ )}
187
+ </div>
188
+ <div className="create-wrapper">{_children["SubNavigation.Create"]}</div>
189
+ </div>
190
+ );
191
+ };
192
+
193
+ /********************************************************
194
+ * Item - Renders individual items of the sub navigation
195
+ */
196
+ export interface SubNavigationItemProps
197
+ extends Omit<AvatarProps, "as" | "size"> {
198
+ as?: React.ElementType;
199
+ active?: boolean;
200
+ /**
201
+ * The time stamp renders only if isMessage is true
202
+ */
203
+ dateCreated?: Date;
204
+ /**
205
+ * Dropdown options render only if isMessage is false
206
+ */
207
+ dropdownOptions?: DropdownOptionProps[];
208
+ dropdownElements?: React.ReactNode[];
209
+ isMessage?: boolean;
210
+ onClick?: () => void;
211
+ submenu?: React.ReactNode;
212
+ /**
213
+ * The unread props is for messages only
214
+ */
215
+ unread?: boolean;
216
+ }
217
+
218
+ const Item = ({
219
+ as,
220
+ active,
221
+ dateCreated,
222
+ dropdownOptions,
223
+ dropdownElements,
224
+ isMessage,
225
+ onClick,
226
+ subtitle,
227
+ title,
228
+ unread,
229
+ url,
230
+ }: SubNavigationItemProps) => {
231
+ return (
232
+ <Component
233
+ as={as ?? "a"}
234
+ className={`${styles.subitem}${active ? " active" : ""}${
235
+ unread ? " unread" : ""
236
+ }`}
237
+ onClick={onClick}
238
+ >
239
+ {isMessage && unread && <div className="notification" />}
240
+ <Avatar size={36} subtitle={subtitle} title={title} url={url} />
241
+ {!isMessage && dropdownOptions && (
242
+ <Dropdown
243
+ onChange={() => undefined}
244
+ open="left"
245
+ options={dropdownOptions}
246
+ style={{ marginLeft: "auto" }}
247
+ trigger={
248
+ <EllipsisHorizontal
249
+ iconSize={18}
250
+ size={18}
251
+ fill="var(--color-blue-6)"
252
+ />
253
+ }
254
+ >
255
+ {dropdownElements}
256
+ </Dropdown>
257
+ )}
258
+ {isMessage && dateCreated && (
259
+ <p className="time-stamp">
260
+ {abbrRelativeTimeString(dateCreated, { message: true })}
261
+ </p>
262
+ )}
263
+ </Component>
264
+ );
265
+ };
266
+
267
+ Item.displayName = "SubNavigation.Item";
268
+ SubNavigation.Item = Item;
269
+
270
+ /********************************************************
271
+ * Button - Renders one of the call to actions at the top of the inner drawer navigation
272
+ */
273
+ export interface SubNavigationButtonProps
274
+ extends Omit<ButtonProps, "size" | "buttonColor" | "bold" | "uppercase"> {
275
+ active?: boolean;
276
+ }
277
+
278
+ const SubNavButton = ({
279
+ active,
280
+ children,
281
+ ...rest
282
+ }: SubNavigationButtonProps) => {
283
+ return (
284
+ <Button
285
+ buttonColor="#F5F8FF"
286
+ color="var(--color-blue-3)"
287
+ className="sub-nav-button"
288
+ size="small"
289
+ style={active ? { border: "1px solid var(--color-blue-3)" } : {}}
290
+ uppercase={false}
291
+ {...rest}
292
+ >
293
+ {children}
294
+ </Button>
295
+ );
296
+ };
297
+
298
+ SubNavButton.displayName = "SubNavigation.Button";
299
+ SubNavigation.Button = SubNavButton;
300
+
301
+ /********************************************************
302
+ * Create - Renders the CTA to create something at the bottom of the inner drawer navigation
303
+ */
304
+ export interface SubNavigationCreateProps
305
+ extends Omit<
306
+ ButtonProps,
307
+ "size" | "buttonColor" | "bold" | "uppercase" | "icon"
308
+ > {
309
+ active?: boolean;
310
+ }
311
+
312
+ const SubNavCreate = ({
313
+ active,
314
+ children,
315
+ ...rest
316
+ }: SubNavigationCreateProps) => {
317
+ return (
318
+ <Button
319
+ bold={false}
320
+ buttonColor="var(--color-blue-3)"
321
+ className="create"
322
+ color="var(--color-blue-10)"
323
+ icon={
324
+ <Plus
325
+ iconSize={11}
326
+ fill="#FFFFFF"
327
+ size={29}
328
+ style={{
329
+ borderRadius: "50%",
330
+ border: "1px dashed var(--color-blue-10)",
331
+ }}
332
+ />
333
+ }
334
+ uppercase={false}
335
+ {...rest}
336
+ >
337
+ {children}
338
+ </Button>
339
+ );
340
+ };
341
+
342
+ SubNavCreate.displayName = "SubNavigation.Create";
343
+ SubNavigation.Create = SubNavCreate;
344
+
345
+ /********************************************************
346
+ * Tab - Renders both the tabs in the header and the content of each tab
347
+ */
348
+ export interface SubNavigationTabProps extends React.PropsWithChildren {
349
+ name: string;
350
+ }
351
+
352
+ const Tab = ({ children }: SubNavigationTabProps) => {
353
+ return <>{React.Children.toArray(children)}</>;
354
+ };
355
+
356
+ Tab.displayName = "SubNavigation.Tab";
357
+ SubNavigation.Tab = Tab;
358
+
359
+ /********************************************************
360
+ * Sub Menu - Renders a sub menu that navigates to a new page of the inner drawer navigation
361
+ */
362
+ export interface SubNavigationSubMenuProps extends React.PropsWithChildren {
363
+ title: string;
364
+ }
365
+
366
+ const SubMenu = ({ children }: SubNavigationSubMenuProps) => {
367
+ return <>{React.Children.toArray(children)}</>;
368
+ };
369
+
370
+ SubMenu.displayName = "SubNavigation.SubMenu";
371
+ SubNavigation.SubMenu = SubMenu;
372
+
373
+ /********************************************************
374
+ * Sub Menu Item - Renders a child element of the sub menu
375
+ */
376
+ export interface SubNavigationSubMenuItemProps extends React.PropsWithChildren {
377
+ as?: React.ElementType;
378
+ icon?: React.ReactElement;
379
+ href?: string;
380
+ onClick?: () => void;
381
+ title: string;
382
+ }
383
+
384
+ const SubMenuItem = ({
385
+ as,
386
+ children,
387
+ icon,
388
+ href,
389
+ onClick,
390
+ title,
391
+ }: SubNavigationSubMenuItemProps) => {
392
+ const [open, setOpen] = React.useState(false);
393
+
394
+ const handleClick = () => {
395
+ if (children) {
396
+ setOpen((prev) => !prev);
397
+ }
398
+ if (onClick) {
399
+ onClick();
400
+ }
401
+ };
402
+
403
+ return (
404
+ <>
405
+ <Component
406
+ as={as ?? "div"}
407
+ className={`${styles.submenuitem}`}
408
+ href={href}
409
+ onClick={children || onClick ? handleClick : undefined}
410
+ >
411
+ {icon &&
412
+ React.cloneElement(icon, {
413
+ fill: "var(--color-blue-2)",
414
+ iconSize: 21,
415
+ size: 24,
416
+ })}
417
+ <p>{title}</p>
418
+ {!!children &&
419
+ (open ? (
420
+ <ChevronUp
421
+ fill="var(--color-blue-2)"
422
+ iconSize={12}
423
+ size={24}
424
+ style={{ marginLeft: "auto" }}
425
+ />
426
+ ) : (
427
+ <ChevronDown
428
+ fill="var(--color-blue-2)"
429
+ iconSize={12}
430
+ size={24}
431
+ style={{ marginLeft: "auto" }}
432
+ />
433
+ ))}
434
+ </Component>
435
+ {children && open && <div className="children-wrapper">{children}</div>}
436
+ </>
437
+ );
438
+ };
439
+
440
+ SubMenuItem.displayName = "SubNavigation.SubMenuItem";
441
+ SubNavigation.SubMenuItem = SubMenuItem;
442
+
443
+ export { SubNavigation };
@@ -0,0 +1,15 @@
1
+ export {
2
+ Navigation,
3
+ type NavigationProps,
4
+ type NavigationItemProps,
5
+ } from "./Navigation";
6
+ export {
7
+ SubNavigation,
8
+ type SubNavigationProps,
9
+ type SubNavigationItemProps,
10
+ type SubNavigationButtonProps,
11
+ type SubNavigationCreateProps,
12
+ type SubNavigationTabProps,
13
+ type SubNavigationSubMenuProps,
14
+ type SubNavigationSubMenuItemProps,
15
+ } from "./SubNavigation";
@@ -0,0 +1,49 @@
1
+ @use "@soul-refiner/styles/mixins";
2
+
3
+ .pagination {
4
+ @include mixins.flex($gap: 10px, $align: center, $justify: center);
5
+ padding: 10px 20px;
6
+
7
+ & > * {
8
+ width: 35px;
9
+ height: 35px;
10
+ border-radius: 50%;
11
+ color: var(--color-grey-4);
12
+ &:first-child > svg {
13
+ padding-right: 3px;
14
+ }
15
+ &:last-child > svg {
16
+ padding-left: 3px;
17
+ }
18
+ }
19
+
20
+ & > *:not([class~="break"]) {
21
+ &:not([class~="active"]):hover {
22
+ background-color: var(--color-grey-9);
23
+ color: var(--color-blue-3);
24
+ & > svg {
25
+ fill: var(--color-blue-3);
26
+ }
27
+ }
28
+ }
29
+
30
+ & > [class~="active"] {
31
+ background-color: var(--color-blue-3);
32
+ color: #ffffff;
33
+ }
34
+
35
+ & > [class~="break"] {
36
+ flex-shrink: 0;
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ background-color: white;
41
+ }
42
+
43
+ & > [class~="disabled"] {
44
+ pointer-events: none;
45
+ & > svg {
46
+ fill: var(--color-grey-8);
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,115 @@
1
+ import React from "react";
2
+ import { ChevronLeft, ChevronRight } from "@soul-refiner/icons/src";
3
+
4
+ import styles from "./Pagination.module.scss";
5
+
6
+ export interface PaginationProps {
7
+ currentPage: number;
8
+ /**
9
+ * The max number of pages visible from which one may select
10
+ * @default 3
11
+ */
12
+ visibilityInterval: number;
13
+ numPages: number;
14
+ onNavigate: (page: number) => void;
15
+ }
16
+
17
+ export const Pagination = ({
18
+ currentPage,
19
+ visibilityInterval = 3,
20
+ numPages,
21
+ onNavigate,
22
+ }: PaginationProps) => {
23
+ const generatePages = () => {
24
+ if (numPages <= 2 * visibilityInterval)
25
+ return [...Array(numPages + 1).keys()].slice(1).map((num) => num + "");
26
+ else {
27
+ const firstSet = [...Array(visibilityInterval + 1).keys()].slice(1);
28
+ const secondSet = Array.from(
29
+ firstSet,
30
+ (num) => num + numPages - visibilityInterval
31
+ );
32
+ if (currentPage === visibilityInterval + 1) {
33
+ firstSet.push(visibilityInterval + 1);
34
+ }
35
+ if (
36
+ currentPage === numPages - visibilityInterval &&
37
+ numPages - visibilityInterval !== firstSet[firstSet.length - 1]
38
+ ) {
39
+ secondSet.splice(0, 0, numPages - visibilityInterval);
40
+ }
41
+ if (
42
+ currentPage > visibilityInterval + 1 &&
43
+ currentPage < numPages - visibilityInterval
44
+ ) {
45
+ const middleSet: (string | number)[] = [currentPage];
46
+ if (!firstSet.includes(currentPage - 1)) {
47
+ if (firstSet[firstSet.length - 1] === currentPage - 2) {
48
+ firstSet.pop();
49
+ }
50
+ middleSet.splice(0, 0, "break", currentPage - 1);
51
+ }
52
+ if (!secondSet.includes(currentPage + 1)) {
53
+ if (secondSet[0] === currentPage + 2) {
54
+ secondSet.shift();
55
+ }
56
+ middleSet.push(currentPage + 1, "break");
57
+ }
58
+ return [...firstSet, ...middleSet, ...secondSet];
59
+ }
60
+ return [...firstSet, "break", ...secondSet];
61
+ }
62
+ };
63
+
64
+ const handleDecrement = () => {
65
+ if (currentPage > 1) {
66
+ onNavigate(currentPage - 1);
67
+ }
68
+ };
69
+
70
+ const handleIncrement = () => {
71
+ if (currentPage < numPages - 1) {
72
+ onNavigate(currentPage + 1);
73
+ }
74
+ };
75
+
76
+ return (
77
+ <nav className={styles.pagination}>
78
+ <ChevronLeft
79
+ as="button"
80
+ className={currentPage === 1 ? "disabled" : ""}
81
+ fill="var(--color-grey-5)"
82
+ iconSize={18}
83
+ onClick={handleDecrement}
84
+ size={35}
85
+ />
86
+ {generatePages().map((page, index) => {
87
+ if (page === "break") {
88
+ return (
89
+ <div key={"break-" + index.toString(36)} className="break">
90
+ ...
91
+ </div>
92
+ );
93
+ } else {
94
+ return (
95
+ <button
96
+ key={"page-" + index.toString(36)}
97
+ className={page === currentPage ? "active" : ""}
98
+ onClick={() => onNavigate(page as number)}
99
+ >
100
+ {page}
101
+ </button>
102
+ );
103
+ }
104
+ })}
105
+ <ChevronRight
106
+ as="button"
107
+ className={currentPage === numPages ? "disabled" : ""}
108
+ fill="var(--color-grey-5)"
109
+ iconSize={18}
110
+ onClick={handleIncrement}
111
+ size={35}
112
+ />
113
+ </nav>
114
+ );
115
+ };
@@ -0,0 +1 @@
1
+ export { Pagination, type PaginationProps } from "./Pagination";
@@ -0,0 +1,21 @@
1
+ export { Breadcrumbs, type BreadcrumbsProps } from "./Breadcrumbs";
2
+ export { Drawer, type DrawerProps } from "./Drawer";
3
+ export { EditorBar, type EditorBarProps } from "./EditorBar";
4
+ export { MenuTabs, type MenuTabsProps } from "./MenuTabs";
5
+ export {
6
+ Navigation,
7
+ SubNavigation,
8
+ type NavigationProps,
9
+ type NavigationItemProps,
10
+ type SubNavigationProps,
11
+ type SubNavigationItemProps,
12
+ type SubNavigationButtonProps,
13
+ type SubNavigationCreateProps,
14
+ type SubNavigationTabProps,
15
+ type SubNavigationSubMenuProps,
16
+ type SubNavigationSubMenuItemProps,
17
+ } from "./Navigation";
18
+ export {
19
+ Pagination,
20
+ type PaginationProps
21
+ } from "./Pagination";