@acmekit/docs-ui 2.13.41

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 (236) hide show
  1. package/dist/Items-YPPZD6C6.mjs +312 -0
  2. package/dist/chunk-JD7BP7O5.mjs +13144 -0
  3. package/dist/index.d.mts +1550 -0
  4. package/dist/index.d.ts +1550 -0
  5. package/dist/index.js +15218 -0
  6. package/dist/index.mjs +366 -0
  7. package/package.json +58 -0
  8. package/src/components/Badge/index.tsx +74 -0
  9. package/src/components/BadgesList/index.tsx +18 -0
  10. package/src/components/BetaBadge/index.tsx +24 -0
  11. package/src/components/Bordered/index.tsx +21 -0
  12. package/src/components/BorderedIcon/index.tsx +60 -0
  13. package/src/components/Breadcrumbs/index.tsx +83 -0
  14. package/src/components/Button/index.tsx +100 -0
  15. package/src/components/Card/Layout/Default/index.tsx +124 -0
  16. package/src/components/Card/Layout/Filler/index.tsx +30 -0
  17. package/src/components/Card/Layout/Large/index.tsx +88 -0
  18. package/src/components/Card/Layout/Mini/index.tsx +142 -0
  19. package/src/components/Card/index.tsx +50 -0
  20. package/src/components/CardList/index.tsx +40 -0
  21. package/src/components/ChildDocs/index.tsx +9 -0
  22. package/src/components/CodeBlock/Actions/AskAi/index.tsx +10 -0
  23. package/src/components/CodeBlock/Actions/Copy/index.tsx +59 -0
  24. package/src/components/CodeBlock/Actions/index.tsx +137 -0
  25. package/src/components/CodeBlock/Collapsible/Button/index.tsx +58 -0
  26. package/src/components/CodeBlock/Collapsible/Fade/index.tsx +55 -0
  27. package/src/components/CodeBlock/Collapsible/Lines/index.tsx +22 -0
  28. package/src/components/CodeBlock/Header/Wrapper/index.tsx +46 -0
  29. package/src/components/CodeBlock/Header/index.tsx +67 -0
  30. package/src/components/CodeBlock/Inline/index.tsx +20 -0
  31. package/src/components/CodeBlock/Line/index.tsx +331 -0
  32. package/src/components/CodeBlock/index.tsx +510 -0
  33. package/src/components/CodeMdx/index.tsx +45 -0
  34. package/src/components/CodeTabs/Item/index.tsx +67 -0
  35. package/src/components/CodeTabs/index.tsx +319 -0
  36. package/src/components/ContentMenu/Actions/index.tsx +7 -0
  37. package/src/components/ContentMenu/Products/index.tsx +64 -0
  38. package/src/components/ContentMenu/Toc/index.tsx +148 -0
  39. package/src/components/ContentMenu/Version/index.tsx +77 -0
  40. package/src/components/ContentMenu/index.tsx +31 -0
  41. package/src/components/CopyButton/index.tsx +76 -0
  42. package/src/components/Details/Summary/index.tsx +75 -0
  43. package/src/components/Details/index.tsx +98 -0
  44. package/src/components/DetailsList/index.tsx +32 -0
  45. package/src/components/DottedSeparator/index.tsx +30 -0
  46. package/src/components/EditButton/index.tsx +32 -0
  47. package/src/components/EditDate/index.tsx +33 -0
  48. package/src/components/ErrorPage/Icon/index.tsx +428 -0
  49. package/src/components/ErrorPage/index.tsx +32 -0
  50. package/src/components/Feedback/Solutions/index.tsx +105 -0
  51. package/src/components/Feedback/index.tsx +304 -0
  52. package/src/components/Footer/index.tsx +23 -0
  53. package/src/components/Heading/H1/index.tsx +21 -0
  54. package/src/components/Heading/H2/index.tsx +47 -0
  55. package/src/components/Heading/H3/index.tsx +42 -0
  56. package/src/components/Heading/H4/index.tsx +14 -0
  57. package/src/components/Heading/index.tsx +4 -0
  58. package/src/components/IconHeadline/index.tsx +15 -0
  59. package/src/components/Icons/AiAssistant/index.tsx +462 -0
  60. package/src/components/Icons/ArrowRightDown/index.tsx +30 -0
  61. package/src/components/Icons/BundledProduct/index.tsx +72 -0
  62. package/src/components/Icons/CalendarRefresh/index.tsx +70 -0
  63. package/src/components/Icons/ChefHat/index.tsx +65 -0
  64. package/src/components/Icons/CircleDottedLine/index.tsx +60 -0
  65. package/src/components/Icons/CloudSolid/index.tsx +47 -0
  66. package/src/components/Icons/ColoredAcmeKit/index.tsx +13 -0
  67. package/src/components/Icons/DecisionProcess/index.tsx +58 -0
  68. package/src/components/Icons/Erp/index.tsx +92 -0
  69. package/src/components/Icons/Github/index.tsx +22 -0
  70. package/src/components/Icons/House/index.tsx +23 -0
  71. package/src/components/Icons/ImageBinary/index.tsx +69 -0
  72. package/src/components/Icons/Kapa/index.tsx +22 -0
  73. package/src/components/Icons/Markdown/index.tsx +25 -0
  74. package/src/components/Icons/NavigationDropdown/Admin/index.tsx +33 -0
  75. package/src/components/Icons/NavigationDropdown/Doc/index.tsx +41 -0
  76. package/src/components/Icons/NavigationDropdown/DocV1/index.tsx +37 -0
  77. package/src/components/Icons/NavigationDropdown/Modules/index.tsx +33 -0
  78. package/src/components/Icons/NavigationDropdown/Resources/index.tsx +37 -0
  79. package/src/components/Icons/NavigationDropdown/Store/index.tsx +37 -0
  80. package/src/components/Icons/NavigationDropdown/Ui/index.tsx +37 -0
  81. package/src/components/Icons/NavigationDropdown/User/index.tsx +37 -0
  82. package/src/components/Icons/PuzzleColored/index.tsx +35 -0
  83. package/src/components/Icons/QuestionMark/index.tsx +23 -0
  84. package/src/components/Icons/Restock/index.tsx +55 -0
  85. package/src/components/Icons/ScrollText/index.tsx +68 -0
  86. package/src/components/Icons/ShadedBg/index.tsx +334 -0
  87. package/src/components/Icons/Shop/index.tsx +68 -0
  88. package/src/components/Icons/SidebarLeft/index.tsx +42 -0
  89. package/src/components/Icons/StripeColored/index.tsx +60 -0
  90. package/src/components/Icons/ThumbDown/index.tsx +23 -0
  91. package/src/components/Icons/ThumbUp/index.tsx +23 -0
  92. package/src/components/Icons/WindowPaintbrush/index.tsx +57 -0
  93. package/src/components/Icons/index.tsx +20 -0
  94. package/src/components/InlineCode/index.tsx +42 -0
  95. package/src/components/InlineIcon/index.tsx +21 -0
  96. package/src/components/InlineThemeImage/index.tsx +14 -0
  97. package/src/components/Input/Search/index.tsx +64 -0
  98. package/src/components/Input/Text/index.tsx +39 -0
  99. package/src/components/Kbd/index.tsx +33 -0
  100. package/src/components/Label/index.tsx +19 -0
  101. package/src/components/Link/index.tsx +67 -0
  102. package/src/components/LinkButton/index.tsx +43 -0
  103. package/src/components/Loading/Dots/index.tsx +16 -0
  104. package/src/components/Loading/Spinner/index.tsx +19 -0
  105. package/src/components/Loading/index.tsx +43 -0
  106. package/src/components/MDXComponents/index.tsx +209 -0
  107. package/src/components/MainNav/DesktopMenu/ThemeMenu/index.tsx +76 -0
  108. package/src/components/MainNav/DesktopMenu/index.tsx +100 -0
  109. package/src/components/MainNav/Items/Dropdown/index.tsx +88 -0
  110. package/src/components/MainNav/Items/Link/index.tsx +34 -0
  111. package/src/components/MainNav/Items/index.tsx +61 -0
  112. package/src/components/MainNav/MobileMenu/Main/index.tsx +67 -0
  113. package/src/components/MainNav/MobileMenu/SubMenu/index.tsx +77 -0
  114. package/src/components/MainNav/MobileMenu/index.tsx +103 -0
  115. package/src/components/MainNav/Version/index.tsx +33 -0
  116. package/src/components/MainNav/index.tsx +153 -0
  117. package/src/components/MarkdownContent/index.tsx +41 -0
  118. package/src/components/Menu/Action/index.tsx +43 -0
  119. package/src/components/Menu/Divider/index.tsx +35 -0
  120. package/src/components/Menu/Dropdown/index.tsx +78 -0
  121. package/src/components/Menu/Item/index.tsx +36 -0
  122. package/src/components/Menu/SubMenu/index.tsx +47 -0
  123. package/src/components/Menu/index.tsx +44 -0
  124. package/src/components/Modal/Footer/index.tsx +29 -0
  125. package/src/components/Modal/Header/index.tsx +33 -0
  126. package/src/components/Modal/index.tsx +124 -0
  127. package/src/components/Note/Layout/index.tsx +139 -0
  128. package/src/components/Note/Types/checks.tsx +7 -0
  129. package/src/components/Note/Types/default.tsx +7 -0
  130. package/src/components/Note/Types/error.tsx +7 -0
  131. package/src/components/Note/Types/soon.tsx +7 -0
  132. package/src/components/Note/Types/sucess.tsx +7 -0
  133. package/src/components/Note/Types/warning.tsx +7 -0
  134. package/src/components/Note/index.tsx +32 -0
  135. package/src/components/Notices/DeprecatedNotice/index.tsx +33 -0
  136. package/src/components/Notices/ExpandableNotice/index.tsx +36 -0
  137. package/src/components/Notices/FeatureFlagNotice/index.tsx +36 -0
  138. package/src/components/Notices/VersionNotice/index.tsx +37 -0
  139. package/src/components/Notification/Item/Layout/Default/index.tsx +89 -0
  140. package/src/components/Notification/Item/index.tsx +88 -0
  141. package/src/components/Notification/index.tsx +65 -0
  142. package/src/components/Pagination/Card/index.tsx +80 -0
  143. package/src/components/Pagination/index.tsx +35 -0
  144. package/src/components/Prerequisites/Item/index.tsx +43 -0
  145. package/src/components/Prerequisites/index.tsx +94 -0
  146. package/src/components/RadioItem/index.tsx +38 -0
  147. package/src/components/Rating/index.tsx +133 -0
  148. package/src/components/RootProviders/index.tsx +31 -0
  149. package/src/components/Select/Badge/index.tsx +122 -0
  150. package/src/components/Select/Dropdown/index.tsx +188 -0
  151. package/src/components/Select/Input/index.tsx +123 -0
  152. package/src/components/Select/index.ts +13 -0
  153. package/src/components/Sidebar/Child/index.tsx +43 -0
  154. package/src/components/Sidebar/Item/Category/index.tsx +151 -0
  155. package/src/components/Sidebar/Item/Link/index.tsx +174 -0
  156. package/src/components/Sidebar/Item/Sidebar/index.tsx +67 -0
  157. package/src/components/Sidebar/Item/SubCategory/index.tsx +83 -0
  158. package/src/components/Sidebar/Item/index.tsx +41 -0
  159. package/src/components/Sidebar/Top/MobileClose/index.tsx +21 -0
  160. package/src/components/Sidebar/Top/index.tsx +33 -0
  161. package/src/components/Sidebar/index.tsx +153 -0
  162. package/src/components/SourceCodeLink/index.tsx +37 -0
  163. package/src/components/SplitLists/index.tsx +58 -0
  164. package/src/components/Table/index.tsx +87 -0
  165. package/src/components/Tabs/index.tsx +106 -0
  166. package/src/components/TextArea/index.tsx +30 -0
  167. package/src/components/ThemeImage/index.tsx +26 -0
  168. package/src/components/Toggle/index.tsx +28 -0
  169. package/src/components/Tooltip/index.tsx +65 -0
  170. package/src/components/TypeList/Items/index.tsx +337 -0
  171. package/src/components/TypeList/index.tsx +63 -0
  172. package/src/components/WideSection/index.tsx +25 -0
  173. package/src/components/ZoomImg/index.tsx +17 -0
  174. package/src/components/index.ts +75 -0
  175. package/src/constants.tsx +261 -0
  176. package/src/global-config.ts +11 -0
  177. package/src/hooks/index.ts +14 -0
  178. package/src/hooks/use-active-on-scroll/index.tsx +223 -0
  179. package/src/hooks/use-click-outside/index.tsx +37 -0
  180. package/src/hooks/use-collapsible/index.tsx +128 -0
  181. package/src/hooks/use-collapsible-code-lines/index.tsx +149 -0
  182. package/src/hooks/use-copy/index.tsx +28 -0
  183. package/src/hooks/use-heading-url/index.tsx +32 -0
  184. package/src/hooks/use-is-external-link/index.tsx +19 -0
  185. package/src/hooks/use-keyboard-shortcut/index.tsx +71 -0
  186. package/src/hooks/use-mutation-observer/index.ts +32 -0
  187. package/src/hooks/use-page-scroll-manager/index.tsx +82 -0
  188. package/src/hooks/use-resize-observer/index.ts +20 -0
  189. package/src/hooks/use-scroll-utils/index.tsx +372 -0
  190. package/src/hooks/use-select/index.tsx +99 -0
  191. package/src/hooks/use-tabs/index.tsx +94 -0
  192. package/src/index.ts +8 -0
  193. package/src/layouts/barebone.tsx +18 -0
  194. package/src/layouts/index.ts +4 -0
  195. package/src/layouts/main-content.tsx +86 -0
  196. package/src/layouts/root.tsx +43 -0
  197. package/src/layouts/tight.tsx +29 -0
  198. package/src/layouts/wide.tsx +25 -0
  199. package/src/providers/AiAssistant/index.tsx +65 -0
  200. package/src/providers/BrowserProvider/index.tsx +40 -0
  201. package/src/providers/ColorMode/index.tsx +73 -0
  202. package/src/providers/Layout/index.tsx +52 -0
  203. package/src/providers/MainNav/index.tsx +134 -0
  204. package/src/providers/Mobile/index.tsx +62 -0
  205. package/src/providers/Modal/index.tsx +52 -0
  206. package/src/providers/Notification/index.tsx +149 -0
  207. package/src/providers/Pagination/index.tsx +230 -0
  208. package/src/providers/Search/index.tsx +91 -0
  209. package/src/providers/Sidebar/index.tsx +745 -0
  210. package/src/providers/SiteConfig/index.tsx +70 -0
  211. package/src/providers/index.ts +13 -0
  212. package/src/types/config.ts +34 -0
  213. package/src/types/frontmatter.ts +23 -0
  214. package/src/types/general.ts +1 -0
  215. package/src/types/index.ts +9 -0
  216. package/src/types/menu.ts +40 -0
  217. package/src/types/navigation-dropdown.ts +16 -0
  218. package/src/types/navigation.ts +21 -0
  219. package/src/types/sidebar.ts +109 -0
  220. package/src/types/toc.ts +19 -0
  221. package/src/types/ui.ts +9 -0
  222. package/src/utils/array-same-elms.ts +10 -0
  223. package/src/utils/capitalize.ts +3 -0
  224. package/src/utils/check-sidebar-item-visibility.ts +47 -0
  225. package/src/utils/decode-str.ts +8 -0
  226. package/src/utils/dom-utils.ts +29 -0
  227. package/src/utils/event-parser.ts +54 -0
  228. package/src/utils/get-link-with-base-path.ts +3 -0
  229. package/src/utils/get-navbar-items.ts +55 -0
  230. package/src/utils/get-scrolled-top.ts +8 -0
  231. package/src/utils/index.ts +13 -0
  232. package/src/utils/is-elm-window.ts +3 -0
  233. package/src/utils/is-in-view.ts +10 -0
  234. package/src/utils/os-browser-utils.ts +39 -0
  235. package/src/utils/set-obj-value.ts +38 -0
  236. package/src/utils/sidebar-utils.ts +129 -0
@@ -0,0 +1,89 @@
1
+ import React from "react"
2
+ import { NotificationItemProps } from "../../../../../components/Notification/Item"
3
+ import clsx from "clsx"
4
+ import {
5
+ CheckCircleSolid,
6
+ ExclamationCircleSolid,
7
+ InformationCircleSolid,
8
+ XCircleSolid,
9
+ } from "@acmekit/icons"
10
+ import { Button } from "../../../../../components/Button"
11
+
12
+ export type NotificationItemLayoutDefaultProps = NotificationItemProps & {
13
+ handleClose: () => void
14
+ closeButtonText?: string
15
+ }
16
+
17
+ export const NotificationItemLayoutDefault: React.FC<
18
+ NotificationItemLayoutDefaultProps
19
+ > = ({
20
+ type = "info",
21
+ title = "",
22
+ text = "",
23
+ children,
24
+ isClosable = true,
25
+ handleClose,
26
+ CustomIcon,
27
+ closeButtonText = "Close",
28
+ }) => {
29
+ return (
30
+ <div
31
+ className="bg-acmekit-bg-base w-full h-full shadow-elevation-flyout dark:shadow-elevation-flyout-dark rounded-docs_DEFAULT"
32
+ data-testid="default-layout"
33
+ >
34
+ <div className={clsx("flex gap-docs_1 p-docs_1")}>
35
+ {type !== "none" && (
36
+ <div
37
+ className={clsx(
38
+ type !== "custom" && "w-docs_2 flex justify-center items-center"
39
+ )}
40
+ >
41
+ {type === "info" && (
42
+ <InformationCircleSolid className="text-acmekit-tag-blue-icon" />
43
+ )}
44
+ {type === "error" && (
45
+ <XCircleSolid className="text-acmekit-tag-red-icon" />
46
+ )}
47
+ {type === "warning" && (
48
+ <ExclamationCircleSolid className="text-acmekit-tag-orange-icon" />
49
+ )}
50
+ {type === "success" && (
51
+ <CheckCircleSolid className="text-acmekit-tag-green-icon" />
52
+ )}
53
+ {type === "custom" && CustomIcon}
54
+ </div>
55
+ )}
56
+ <span
57
+ className={clsx("text-compact-medium-plus", "text-acmekit-fg-base")}
58
+ data-testid="layout-title"
59
+ >
60
+ {title}
61
+ </span>
62
+ </div>
63
+ {(text || children) && (
64
+ <div
65
+ className={clsx(
66
+ "flex pt-0 pr-docs_1 pb-docs_1.5 pl-docs_1 gap-docs_1",
67
+ "border-0 border-b border-solid border-acmekit-border-base"
68
+ )}
69
+ data-testid="layout-content"
70
+ >
71
+ <div className="w-docs_2 flex-none"></div>
72
+ <div className={clsx("flex flex-col", children && "gap-docs_1")}>
73
+ {text && (
74
+ <span className={clsx("text-medium text-acmekit-fg-subtle")}>
75
+ {text}
76
+ </span>
77
+ )}
78
+ {children}
79
+ </div>
80
+ </div>
81
+ )}
82
+ {isClosable && (
83
+ <div className={clsx("p-docs_1 flex justify-end items-center")}>
84
+ <Button onClick={handleClose}>{closeButtonText}</Button>
85
+ </div>
86
+ )}
87
+ </div>
88
+ )
89
+ }
@@ -0,0 +1,88 @@
1
+
2
+ import clsx from "clsx"
3
+ import React, { Children, ReactElement, useRef } from "react"
4
+ import { NotificationItemLayoutDefault } from "./Layout/Default"
5
+ // @ts-expect-error can't install the types package because it doesn't support React v19
6
+ import { CSSTransition } from "react-transition-group"
7
+
8
+ export type NotificationItemProps = {
9
+ layout?: "default" | "empty"
10
+ type?: "info" | "error" | "warning" | "success" | "custom" | "none"
11
+ CustomIcon?: React.ReactNode
12
+ title?: string
13
+ text?: string
14
+ className?: string
15
+ children?: ReactElement
16
+ isClosable?: boolean
17
+ placement?: "top" | "bottom"
18
+ show?: boolean
19
+ setShow?: (value: boolean) => void
20
+ onClose?: () => void
21
+ closeButtonText?: string
22
+ } & React.HTMLAttributes<HTMLDivElement>
23
+
24
+ type EmptyLayoutProps = {
25
+ onClose?: () => void
26
+ }
27
+
28
+ export const NotificationItem = ({
29
+ className = "",
30
+ placement = "bottom",
31
+ show = true,
32
+ layout = "default",
33
+ setShow,
34
+ onClose,
35
+ children,
36
+ ...rest
37
+ }: NotificationItemProps) => {
38
+ const ref = useRef<HTMLDivElement>(null)
39
+ const handleClose = () => {
40
+ setShow?.(false)
41
+ onClose?.()
42
+ }
43
+
44
+ return (
45
+ <CSSTransition
46
+ timeout={200}
47
+ classNames={{
48
+ enter: "animate-slideInRight animate-fast",
49
+ exit: "animate-slideOutRight animate-fast",
50
+ }}
51
+ nodeRef={ref}
52
+ >
53
+ <div
54
+ className={clsx(
55
+ "md:max-w-[320px] md:w-[320px] w-full",
56
+ "fixed md:right-docs_1 left-0 md:m-docs_1",
57
+ placement === "bottom" && "md:bottom-docs_1 bottom-0",
58
+ placement === "top" && "md:top-docs_1 top-0",
59
+ "opacity-100 transition-opacity duration-200 ease-ease",
60
+ !show && "!opacity-0",
61
+ className
62
+ )}
63
+ ref={ref}
64
+ data-testid="notification-item"
65
+ >
66
+ {layout === "default" && (
67
+ <NotificationItemLayoutDefault {...rest} handleClose={handleClose}>
68
+ {children}
69
+ </NotificationItemLayoutDefault>
70
+ )}
71
+ {layout === "empty" &&
72
+ Children.map(children, (child) => {
73
+ if (child) {
74
+ return React.cloneElement<EmptyLayoutProps>(
75
+ child as React.ReactElement<
76
+ EmptyLayoutProps,
77
+ React.FunctionComponent<EmptyLayoutProps>
78
+ >,
79
+ {
80
+ onClose: handleClose,
81
+ }
82
+ )
83
+ }
84
+ })}
85
+ </div>
86
+ </CSSTransition>
87
+ )
88
+ }
@@ -0,0 +1,65 @@
1
+
2
+ import {
3
+ NotificationContextType,
4
+ NotificationItemType,
5
+ useNotifications,
6
+ } from "../../providers/Notification"
7
+ import React from "react"
8
+ import { NotificationItem } from "./Item"
9
+ // @ts-expect-error can't install the types package because it doesn't support React v19
10
+ import { TransitionGroup } from "react-transition-group"
11
+ import clsx from "clsx"
12
+
13
+ export const NotificationContainer = () => {
14
+ const { notifications, removeNotification } =
15
+ useNotifications() as NotificationContextType
16
+
17
+ const handleClose = (notification: NotificationItemType) => {
18
+ notification.onClose?.()
19
+ if (notification.id) {
20
+ removeNotification(notification.id)
21
+ }
22
+ }
23
+
24
+ const renderFilteredNotifications = (
25
+ condition: (notificaiton: NotificationItemType) => boolean,
26
+ className?: string
27
+ ) => {
28
+ return (
29
+ <TransitionGroup
30
+ className={clsx(
31
+ "flex fixed z-40 flex-col gap-docs_0.5 right-0",
32
+ "md:w-auto w-full overflow-y-auto",
33
+ "max-h-[50%] md:max-h-[calc(100vh-57px)]",
34
+ "max-[768px]:max-h-[50%]",
35
+ className
36
+ )}
37
+ >
38
+ {notifications.filter(condition).map((notification) => (
39
+ <NotificationItem
40
+ {...notification}
41
+ onClose={() => handleClose(notification)}
42
+ className={clsx(
43
+ notification.className,
44
+ "!relative !top-0 !bottom-0 !right-0"
45
+ )}
46
+ key={notification.id}
47
+ />
48
+ ))}
49
+ </TransitionGroup>
50
+ )
51
+ }
52
+
53
+ return (
54
+ <>
55
+ {renderFilteredNotifications(
56
+ (notification) => notification.placement === "top",
57
+ "top-0"
58
+ )}
59
+ {renderFilteredNotifications(
60
+ (notification) => notification.placement !== "top",
61
+ "bottom-0"
62
+ )}
63
+ </>
64
+ )
65
+ }
@@ -0,0 +1,80 @@
1
+ import { TriangleLeftMini, TriangleRightMini } from "@acmekit/icons"
2
+ import clsx from "clsx"
3
+ import { Link } from "react-router-dom"
4
+ import React from "react"
5
+
6
+ type PaginationCardProps = {
7
+ type: "previous" | "next"
8
+ title: string
9
+ parentTitle?: string
10
+ link: string
11
+ className?: string
12
+ }
13
+
14
+ export const PaginationCard = ({
15
+ type,
16
+ title,
17
+ parentTitle,
18
+ link,
19
+ className,
20
+ }: PaginationCardProps) => {
21
+ return (
22
+ <div
23
+ className={clsx(
24
+ "relative flex-1",
25
+ "py-docs_0.5 px-docs_0.75 rounded",
26
+ "bg-acmekit-bg-component hover:bg-acmekit-bg-component-hover",
27
+ "shadow-elevation-card-rest dark:shadow-elevation-card-rest-dark",
28
+ "hover:shadow-elevation-card-hover dark:shadow-elevation-card-hover-dark",
29
+ className
30
+ )}
31
+ data-testid="pagination-card"
32
+ >
33
+ <Link
34
+ to={link}
35
+ className="absolute top-0 left-0 w-full h-full"
36
+ data-testid="pagination-card-link"
37
+ />
38
+ <div
39
+ className={clsx("h-[40px] flex gap-docs_0.75 items-center")}
40
+ data-testid="pagination-card-content"
41
+ >
42
+ {type === "previous" && (
43
+ <TriangleLeftMini
44
+ className="text-acmekit-fg-muted"
45
+ data-testid="pagination-card-previous-icon"
46
+ />
47
+ )}
48
+ <div
49
+ className={clsx(
50
+ "flex-1",
51
+ type === "previous" && "text-left",
52
+ type === "next" && "text-right"
53
+ )}
54
+ data-testid="pagination-card-title-wrapper"
55
+ >
56
+ {parentTitle && (
57
+ <span
58
+ className="block text-compact-small text-acmekit-fg-subtle"
59
+ data-testid="pagination-card-parent-title"
60
+ >
61
+ {parentTitle}
62
+ </span>
63
+ )}
64
+ <span
65
+ className="block text-compact-small-plus text-acmekit-fg-base"
66
+ data-testid="pagination-card-title"
67
+ >
68
+ {title}
69
+ </span>
70
+ </div>
71
+ {type === "next" && (
72
+ <TriangleRightMini
73
+ className="text-acmekit-fg-muted"
74
+ data-testid="pagination-card-next-icon"
75
+ />
76
+ )}
77
+ </div>
78
+ </div>
79
+ )
80
+ }
@@ -0,0 +1,35 @@
1
+
2
+ import React from "react"
3
+ import { usePagination } from "../../providers/Pagination"
4
+ import clsx from "clsx"
5
+ import { PaginationCard } from "./Card"
6
+
7
+ export const Pagination = () => {
8
+ const { previousPage, nextPage } = usePagination()
9
+
10
+ return (
11
+ <div
12
+ className={clsx(
13
+ "flex justify-between",
14
+ "flex-col sm:flex-row gap-docs_0.75"
15
+ )}
16
+ >
17
+ {previousPage && (
18
+ <PaginationCard
19
+ type="previous"
20
+ title={previousPage.title}
21
+ parentTitle={previousPage.parentTitle}
22
+ link={previousPage.link}
23
+ />
24
+ )}
25
+ {nextPage && (
26
+ <PaginationCard
27
+ type="next"
28
+ title={nextPage.title}
29
+ parentTitle={nextPage.parentTitle}
30
+ link={nextPage.link}
31
+ />
32
+ )}
33
+ </div>
34
+ )
35
+ }
@@ -0,0 +1,43 @@
1
+ import clsx from "clsx"
2
+ import { Link } from "../../Link"
3
+ import React from "react"
4
+
5
+ export type PrerequisiteItemPosition = "top" | "middle" | "bottom" | "alone"
6
+
7
+ export type PrerequisiteItemType = {
8
+ text: string
9
+ link?: string
10
+ position?: PrerequisiteItemPosition
11
+ }
12
+
13
+ type PrerequisiteItemProps = {
14
+ item: PrerequisiteItemType
15
+ }
16
+
17
+ export const PrerequisiteItem = ({
18
+ item: { text, link, position = "alone" },
19
+ }: PrerequisiteItemProps) => {
20
+ return (
21
+ <Link
22
+ href={link || "#"}
23
+ className={clsx(
24
+ "bg-acmekit-tag-neutral-bg text-acmekit-fg-subtle",
25
+ "px-docs_0.75 py-docs_0.5 w-fit",
26
+ "flex justify-center items-center",
27
+ link && "hover:bg-acmekit-tag-neutral-bg-hover",
28
+ "rounded-tr-docs_xl rounded-br-docs_xl",
29
+ position === "alone" && "rounded-docs_xl",
30
+ position === "top" && "rounded-tl-docs_xl rounded-bl-docs_DEFAULT",
31
+ position === "middle" &&
32
+ "rounded-tl-docs_DEFAULT rounded-bl-docs_DEFAULT",
33
+ position === "bottom" && "rounded-tl-docs_DEFAULT rounded-bl-docs_xl",
34
+ !link && "cursor-text"
35
+ )}
36
+ target={link ? "_blank" : undefined}
37
+ rel={link ? "noopener noreferrer" : undefined}
38
+ >
39
+ {text}
40
+ {link && "↗"}
41
+ </Link>
42
+ )
43
+ }
@@ -0,0 +1,94 @@
1
+
2
+ import React, { useRef } from "react"
3
+ import { Button } from "../../components/Button"
4
+ import { useCollapsible } from "../../hooks/use-collapsible"
5
+ import clsx from "clsx"
6
+ import { TriangleRightMini } from "@acmekit/icons"
7
+ import {
8
+ PrerequisiteItem,
9
+ PrerequisiteItemPosition,
10
+ PrerequisiteItemType,
11
+ } from "./Item"
12
+
13
+ type PrerequisitesProps = {
14
+ items: PrerequisiteItemType[]
15
+ }
16
+
17
+ export const Prerequisites = ({ items }: PrerequisitesProps) => {
18
+ const itemsRef = useRef<HTMLDivElement>(null)
19
+ const { collapsed, getCollapsibleElms, setCollapsed } = useCollapsible({
20
+ initialValue: false,
21
+ translateEnabled: false,
22
+ childrenRef: itemsRef,
23
+ useChild: false,
24
+ })
25
+
26
+ const getPosition = (index: number): PrerequisiteItemPosition => {
27
+ if (items.length === 1) {
28
+ return "alone"
29
+ }
30
+
31
+ if (index === items.length - 1) {
32
+ return "bottom"
33
+ }
34
+
35
+ return index === 0 ? "top" : "middle"
36
+ }
37
+
38
+ return (
39
+ <details
40
+ open={!collapsed}
41
+ onClick={(event) => {
42
+ if (event.target instanceof HTMLAnchorElement) {
43
+ return
44
+ }
45
+ event.preventDefault()
46
+ }}
47
+ onToggle={(event) => {
48
+ // this is to avoid event propagation
49
+ // when details are nested, which is a bug
50
+ // in react. Learn more here:
51
+ // https://github.com/facebook/react/issues/22718
52
+ event.stopPropagation()
53
+ }}
54
+ className="my-docs_1"
55
+ >
56
+ <summary
57
+ className="flex no-marker items-center mb-[6px] w-fit"
58
+ onClick={() => setCollapsed((prev) => !prev)}
59
+ >
60
+ <Button
61
+ className={clsx(
62
+ "flex items-center",
63
+ "px-docs_0.5 py-docs_0.25",
64
+ "text-acmekit-fg-subtle",
65
+ "active:!outline-none active:!shadow-none",
66
+ "focus:!outline-none focus:!shadow-none"
67
+ )}
68
+ variant="transparent-clear"
69
+ >
70
+ <TriangleRightMini
71
+ className={clsx("transition-transform", !collapsed && "rotate-90")}
72
+ />
73
+ <span className="text-compact-small-plus block ml-[6px]">
74
+ Prerequisites
75
+ </span>
76
+ <span className="fg-muted text-compact-small">{items.length}</span>
77
+ </Button>
78
+ </summary>
79
+ {getCollapsibleElms(
80
+ <div className="flex gap-[6px] flex-col" ref={itemsRef}>
81
+ {items.map((item, index) => (
82
+ <PrerequisiteItem
83
+ item={{
84
+ ...item,
85
+ position: getPosition(index),
86
+ }}
87
+ key={index}
88
+ />
89
+ ))}
90
+ </div>
91
+ )}
92
+ </details>
93
+ )
94
+ }
@@ -0,0 +1,38 @@
1
+ import clsx from "clsx"
2
+ import React from "react"
3
+
4
+ export type RadioItemProps = React.DetailedHTMLProps<
5
+ React.InputHTMLAttributes<HTMLInputElement>,
6
+ HTMLInputElement
7
+ > & {
8
+ checked?: boolean
9
+ }
10
+
11
+ export const RadioItem = ({ className, checked, ...props }: RadioItemProps) => {
12
+ return (
13
+ <div className="p-[3px] flex justify-center items-center relative">
14
+ <input
15
+ type="radio"
16
+ className={clsx(
17
+ "appearance-none bg-acmekit-bg-component shadow-borders-base dark:shadow-border-base-dark",
18
+ "w-[14px] h-[14px] rounded-full",
19
+ "focus:shadow-borders-interactive-with-focus disabled:opacity-50",
20
+ "checked:!bg-acmekit-bg-interactive checked:!shadow-borders-interactive-with-shadow",
21
+ !checked && "hover:bg-acmekit-bg-component-hover",
22
+ className
23
+ )}
24
+ checked={checked}
25
+ {...props}
26
+ />
27
+ {checked && (
28
+ <span
29
+ className={clsx(
30
+ "w-[6px] h-[6px] bg-acmekit-bg-base dark:bg-acmekit-fg-on-color absolute top-1/2 left-1/2 rounded-full",
31
+ "-translate-x-1/2 -translate-y-1/2 shadow-details-contrast-on-bg-interactive"
32
+ )}
33
+ data-testid="radio-item-checked-indicator"
34
+ />
35
+ )}
36
+ </div>
37
+ )
38
+ }
@@ -0,0 +1,133 @@
1
+
2
+ import React, { useCallback, useEffect, useRef, useState } from "react"
3
+ import clsx from "clsx"
4
+ import { Star, StarSolid } from "@acmekit/icons"
5
+ import { Button } from "../../components/Button"
6
+ import { Label } from "../../components/Label"
7
+ import { TextArea } from "../../components/TextArea"
8
+ import { useNotifications } from "../../providers/Notification"
9
+
10
+ export type RatingProps = {
11
+ event?: string
12
+ className?: string
13
+ onRating?: (rating?: number) => void
14
+ additionalQuestion?: string
15
+ parentNotificationId?: string
16
+ } & React.HTMLAttributes<HTMLDivElement>
17
+
18
+ export const Rating: React.FC<RatingProps> = ({
19
+ event = "rating",
20
+ className = "",
21
+ onRating,
22
+ additionalQuestion = "What should we improve?",
23
+ parentNotificationId,
24
+ }) => {
25
+ const [rating, setRating] = useState(0)
26
+ const [additionalFeedback, setAdditionalFeedback] = useState("")
27
+ const [hoverRating, setHoverRating] = useState(0)
28
+ const starElms = useRef<HTMLElement[]>([])
29
+ const starArr = Array.from(Array(5).keys())
30
+ const track = (..._args: any[]) => {}
31
+ const { updateNotification } = useNotifications(true) || {}
32
+
33
+ const submitTracking = useCallback(
34
+ (selectedRating?: number, feedback?: string) => {
35
+ track({
36
+ event: {
37
+ event,
38
+ options: {
39
+ rating: selectedRating || rating,
40
+ additionalFeedback: feedback || additionalFeedback,
41
+ },
42
+ callback: () => onRating?.(selectedRating || rating),
43
+ },
44
+ })
45
+ },
46
+ [rating, additionalFeedback]
47
+ )
48
+
49
+ const handleRating = (selectedRating: number) => {
50
+ if (rating) {
51
+ return
52
+ }
53
+ setHoverRating(0)
54
+ setRating(selectedRating)
55
+ if (selectedRating >= 4) {
56
+ for (let i = 0; i < selectedRating; i++) {
57
+ starElms.current[i].classList.add("animate-tada")
58
+ }
59
+ submitTracking(selectedRating)
60
+ }
61
+ }
62
+
63
+ useEffect(() => {
64
+ if (
65
+ rating > 0 &&
66
+ rating < 4 &&
67
+ parentNotificationId &&
68
+ updateNotification
69
+ ) {
70
+ // update parent notification ID
71
+ updateNotification(parentNotificationId, {
72
+ closeButtonText: "Submit",
73
+ onClose: () => submitTracking(rating, additionalFeedback),
74
+ })
75
+ }
76
+ }, [additionalFeedback, rating])
77
+
78
+ return (
79
+ <div className={clsx("flex flex-col gap-docs_1")}>
80
+ <div className={clsx("flex gap-docs_0.5", className)}>
81
+ {starArr.map((i) => {
82
+ const isSelected =
83
+ (rating !== 0 && rating - 1 >= i) ||
84
+ (hoverRating !== 0 && hoverRating - 1 >= i)
85
+ return (
86
+ <Button
87
+ variant="transparent"
88
+ buttonRef={(element) => {
89
+ if (starElms.current.length - 1 < i) {
90
+ starElms.current.push(element as HTMLElement)
91
+ }
92
+ }}
93
+ key={i}
94
+ onMouseOver={() => {
95
+ if (!rating) {
96
+ setHoverRating(i + 1)
97
+ }
98
+ }}
99
+ onMouseLeave={() => {
100
+ if (!rating) {
101
+ setHoverRating(0)
102
+ }
103
+ }}
104
+ onClick={() => handleRating(i + 1)}
105
+ >
106
+ {!isSelected && <Star />}
107
+ {isSelected && (
108
+ <StarSolid className="text-acmekit-tag-orange-icon" />
109
+ )}
110
+ </Button>
111
+ )
112
+ })}
113
+ </div>
114
+ {rating !== 0 && rating < 4 && (
115
+ <div
116
+ className={clsx(
117
+ "text-acmekit-fg-subtle",
118
+ "flex flex-col gap-docs_0.5"
119
+ )}
120
+ >
121
+ <Label>{additionalQuestion}</Label>
122
+ <TextArea
123
+ placeholder="I didn't like..."
124
+ rows={4}
125
+ onChange={(e) => setAdditionalFeedback(e.target.value)}
126
+ value={additionalFeedback}
127
+ className="w-full"
128
+ />
129
+ </div>
130
+ )}
131
+ </div>
132
+ )
133
+ }