@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,31 @@
1
+ import React from "react"
2
+ import { BrowserProvider } from "../../providers/BrowserProvider"
3
+ import { ColorModeProvider } from "../../providers/ColorMode"
4
+ import {
5
+ LayoutProvider,
6
+ type LayoutProviderProps,
7
+ } from "../../providers/Layout"
8
+ import { MobileProvider } from "../../providers/Mobile"
9
+ import { ModalProvider } from "../../providers/Modal"
10
+
11
+ type RootProvidersProps = {
12
+ children: React.ReactNode
13
+ layoutProviderProps?: Omit<LayoutProviderProps, "children">
14
+ }
15
+
16
+ export const RootProviders = ({
17
+ children,
18
+ layoutProviderProps = {},
19
+ }: RootProvidersProps) => {
20
+ return (
21
+ <BrowserProvider>
22
+ <MobileProvider>
23
+ <LayoutProvider {...layoutProviderProps}>
24
+ <ColorModeProvider>
25
+ <ModalProvider>{children}</ModalProvider>
26
+ </ColorModeProvider>
27
+ </LayoutProvider>
28
+ </MobileProvider>
29
+ </BrowserProvider>
30
+ )
31
+ }
@@ -0,0 +1,122 @@
1
+
2
+ import React, { useCallback, useRef, useState } from "react"
3
+ import { useSelect } from "../../../hooks"
4
+ import clsx from "clsx"
5
+ import { SelectDropdown, SelectProps } from ".."
6
+ import { TriangleDownMini } from "@acmekit/icons"
7
+
8
+ export const SelectBadge = ({
9
+ value,
10
+ options,
11
+ setSelected,
12
+ addSelected,
13
+ removeSelected,
14
+ multiple,
15
+ className,
16
+ addAll = multiple,
17
+ handleAddAll,
18
+ ...props
19
+ }: SelectProps) => {
20
+ const [open, setOpen] = useState(false)
21
+ const ref = useRef<HTMLDivElement>(null)
22
+ const dropdownRef = useRef<HTMLDivElement>(null)
23
+ const {
24
+ isValueSelected,
25
+ isAllSelected,
26
+ handleChange,
27
+ handleSelectAll,
28
+ setSelectedValues,
29
+ } = useSelect({
30
+ value,
31
+ options,
32
+ multiple,
33
+ setSelected,
34
+ removeSelected,
35
+ addSelected,
36
+ handleAddAll,
37
+ })
38
+
39
+ const getSelectedText = useCallback(() => {
40
+ let str = ""
41
+ const selectedOptions = options.filter((option) =>
42
+ value.includes(option.value)
43
+ )
44
+
45
+ if (isAllSelected) {
46
+ str = "All areas"
47
+ } else {
48
+ if (
49
+ (!Array.isArray(value) && !value) ||
50
+ (Array.isArray(value) && !value.length)
51
+ ) {
52
+ str = "No Filters Selected"
53
+ } else {
54
+ str = selectedOptions[0].label
55
+ }
56
+ }
57
+
58
+ return (
59
+ <>
60
+ <span
61
+ className={clsx(
62
+ "text-compact-x-small-plus text-acmekit-tag-neutral-text"
63
+ )}
64
+ >
65
+ {str}
66
+ {!isAllSelected && selectedOptions.length > 1 && (
67
+ <> + {selectedOptions.length - 1}</>
68
+ )}
69
+ </span>
70
+ </>
71
+ )
72
+ }, [isAllSelected, options, value])
73
+
74
+ return (
75
+ <div
76
+ className={clsx("relative w-fit", className)}
77
+ data-testid="select-badge"
78
+ >
79
+ <div
80
+ className={clsx(
81
+ "border-acmekit-tag-neutral-border rounded-docs_sm border border-solid",
82
+ "h-fit cursor-pointer pl-docs_0.25 pr-[3px] text-acmekit-tag-neutral-text",
83
+ "bg-acmekit-tag-neutral-bg",
84
+ "flex items-center gap-[3px] whitespace-nowrap",
85
+ "text-acmekit-fg-subtle",
86
+ open && "bg-acmekit-tag-neutral-bg-hover"
87
+ )}
88
+ ref={ref}
89
+ onClick={(e) => {
90
+ if (!dropdownRef.current?.contains(e.target as Element)) {
91
+ setOpen((prev) => !prev)
92
+ }
93
+ }}
94
+ data-testid="select-badge-dropdown"
95
+ >
96
+ {getSelectedText()}
97
+ <TriangleDownMini className="text-acmekit-tag-neutral-icon" />
98
+ </div>
99
+ <input
100
+ type="hidden"
101
+ name={props.name}
102
+ value={Array.isArray(value) ? value.join(",") : value}
103
+ />
104
+ <SelectDropdown
105
+ options={options}
106
+ open={open}
107
+ setOpen={setOpen}
108
+ addAll={addAll}
109
+ multiple={multiple}
110
+ isAllSelected={isAllSelected}
111
+ isValueSelected={isValueSelected}
112
+ handleSelectAll={handleSelectAll}
113
+ handleChange={handleChange}
114
+ parentRef={ref as React.RefObject<HTMLDivElement>}
115
+ passedRef={dropdownRef}
116
+ setSelectedValues={setSelectedValues}
117
+ />
118
+ </div>
119
+ )
120
+ }
121
+
122
+ export default SelectBadge
@@ -0,0 +1,188 @@
1
+
2
+ import React, { useCallback, useEffect, useRef } from "react"
3
+ import clsx from "clsx"
4
+ import { OptionType } from "../../../hooks/use-select"
5
+ import { Ref } from "../../../types"
6
+ import { CheckMini, EllipseMiniSolid } from "@acmekit/icons"
7
+
8
+ export type SelectDropdownProps = {
9
+ options: OptionType[]
10
+ open: boolean
11
+ setOpen: React.Dispatch<React.SetStateAction<boolean>>
12
+ addAll?: boolean
13
+ multiple?: boolean
14
+ isAllSelected: boolean
15
+ isValueSelected: (val: string) => boolean
16
+ handleSelectAll: () => void
17
+ handleChange?: (selectedValue: string, wasSelected: boolean) => void
18
+ parentRef?: React.RefObject<HTMLDivElement>
19
+ className?: string
20
+ passedRef?: Ref<HTMLDivElement>
21
+ setSelectedValues?: (values: string[]) => void
22
+ }
23
+
24
+ export const SelectDropdown = ({
25
+ open,
26
+ setOpen,
27
+ options,
28
+ addAll,
29
+ multiple = false,
30
+ isAllSelected,
31
+ isValueSelected,
32
+ handleSelectAll,
33
+ handleChange: handleSelectChange,
34
+ parentRef,
35
+ className,
36
+ passedRef,
37
+ setSelectedValues,
38
+ }: SelectDropdownProps) => {
39
+ const ref = useRef<HTMLDivElement | null>(null)
40
+ const setRefs = useCallback(
41
+ (node: HTMLDivElement) => {
42
+ // Ref's from useRef needs to have the node assigned to `current`
43
+ ;(ref as any).current = node
44
+ if (typeof passedRef === "function") {
45
+ passedRef(node)
46
+ } else if (passedRef && "current" in passedRef) {
47
+ ;(passedRef as any).current = node
48
+ }
49
+ },
50
+ [passedRef]
51
+ )
52
+
53
+ const handleChange = (clickedValue: string, wasSelected: boolean) => {
54
+ if (isAllSelected && setSelectedValues) {
55
+ setSelectedValues([clickedValue])
56
+ } else {
57
+ handleSelectChange?.(clickedValue, wasSelected)
58
+ }
59
+ if (!multiple) {
60
+ setOpen(false)
61
+ }
62
+ }
63
+
64
+ const handleOutsideClick = useCallback(
65
+ (e: MouseEvent) => {
66
+ if (
67
+ open &&
68
+ !ref.current?.contains(e.target as Element) &&
69
+ !parentRef?.current?.contains(e.target as Element)
70
+ ) {
71
+ setOpen(false)
72
+ }
73
+ },
74
+ [open, parentRef, setOpen]
75
+ )
76
+
77
+ useEffect(() => {
78
+ document.body.addEventListener("click", handleOutsideClick)
79
+
80
+ return () => {
81
+ document.body.removeEventListener("click", handleOutsideClick)
82
+ }
83
+ }, [handleOutsideClick])
84
+
85
+ const getSelectOption = (option: OptionType, index: number) => {
86
+ const originalIsSelected = isValueSelected(option.value)
87
+ const isSelected = isAllSelected
88
+ ? option.isAllOption || false
89
+ : originalIsSelected
90
+
91
+ return (
92
+ <li
93
+ key={index}
94
+ className={clsx(
95
+ "px-docs_0.25",
96
+ index <= 0 && "rounded-t-docs_DEFAULT",
97
+ index === options.length - 1 && "rounded-b-docs_DEFAULT"
98
+ )}
99
+ onClick={() => {
100
+ if (option.isAllOption) {
101
+ handleSelectAll()
102
+ } else {
103
+ handleChange(option.value, originalIsSelected)
104
+ }
105
+ }}
106
+ >
107
+ <div
108
+ className={clsx(
109
+ "px-docs_0.5 py-docs_0.25 flex-1 min-w-max rounded-docs_xs",
110
+ "hover:bg-acmekit-bg-component-hover cursor-pointer",
111
+ "flex gap-docs_0.5 text-acmekit-fg-base items-center",
112
+ !isSelected && "text-compact-small",
113
+ isSelected && "text-compact-small-plus"
114
+ )}
115
+ data-testid="select-dropdown-option"
116
+ >
117
+ <span>
118
+ {isSelected && (
119
+ <>
120
+ {option.isAllOption && <EllipseMiniSolid />}
121
+ {!option.isAllOption && (
122
+ <>
123
+ {multiple && <CheckMini />}
124
+ {!multiple && <EllipseMiniSolid />}
125
+ </>
126
+ )}
127
+ </>
128
+ )}
129
+ {!isSelected && <EllipseMiniSolid className="invisible" />}
130
+ </span>
131
+ <span className="flex-1">{option.label}</span>
132
+ </div>
133
+ </li>
134
+ )
135
+ }
136
+
137
+ const getDivider = () => (
138
+ <svg
139
+ width="176"
140
+ height="8"
141
+ viewBox="0 0 176 8"
142
+ fill="none"
143
+ xmlns="http://www.w3.org/2000/svg"
144
+ >
145
+ <rect width="168" height="8" transform="translate(4)" fill="#FAFAFA" />
146
+ <rect y="4" width="176" height="1" fill="white" />
147
+ <rect y="3" width="176" height="1" fill="#E4E4E7" />
148
+ </svg>
149
+ )
150
+
151
+ return (
152
+ <div
153
+ className={clsx(
154
+ "absolute left-0 md:left-docs_1",
155
+ "z-10",
156
+ "h-0 translate-y-0 overflow-hidden transition-transform",
157
+ open && "h-auto translate-y-docs_0.5 !overflow-visible",
158
+ className
159
+ )}
160
+ ref={setRefs}
161
+ data-testid="select-dropdown-wrapper"
162
+ >
163
+ <ul
164
+ className={clsx(
165
+ "mb-0 py-docs_0.25 overflow-auto rounded-docs_DEFAULT",
166
+ "bg-acmekit-bg-component text-acmekit-fg-base",
167
+ "shadow-elevation-flyout dark:shadow-elevation-flyout-dark list-none",
168
+ "flex flex-col"
169
+ )}
170
+ >
171
+ {addAll && (
172
+ <>
173
+ {getSelectOption(
174
+ {
175
+ value: "all",
176
+ label: "All Areas",
177
+ isAllOption: true,
178
+ },
179
+ -1
180
+ )}
181
+ {getDivider()}
182
+ </>
183
+ )}
184
+ {options.map(getSelectOption)}
185
+ </ul>
186
+ </div>
187
+ )
188
+ }
@@ -0,0 +1,123 @@
1
+
2
+ import React, { useRef, useState } from "react"
3
+ import clsx from "clsx"
4
+ import { useSelect } from "../../../hooks"
5
+ import { SelectDropdown, SelectProps } from ".."
6
+ import { Badge } from "../../../components/Badge"
7
+ import { ChevronUpDown, XMarkMini } from "@acmekit/icons"
8
+
9
+ export const SelectInput = ({
10
+ value,
11
+ options,
12
+ setSelected,
13
+ addSelected,
14
+ removeSelected,
15
+ multiple,
16
+ className,
17
+ addAll = multiple,
18
+ handleAddAll,
19
+ showClearButton = true,
20
+ ...props
21
+ }: SelectProps) => {
22
+ const [open, setOpen] = useState(false)
23
+ const ref = useRef<HTMLDivElement>(null)
24
+ const dropdownRef = useRef<HTMLDivElement>(null)
25
+ const {
26
+ isValueSelected,
27
+ hasSelectedValue,
28
+ hasSelectedValues,
29
+ selectedValues,
30
+ isAllSelected,
31
+ handleChange,
32
+ handleSelectAll,
33
+ } = useSelect({
34
+ value,
35
+ options,
36
+ multiple,
37
+ setSelected,
38
+ removeSelected,
39
+ addSelected,
40
+ handleAddAll,
41
+ })
42
+
43
+ return (
44
+ <div
45
+ className={clsx(
46
+ "px-docs_0.75 relative py-[9px]",
47
+ "border-acmekit-border-base rounded-docs_sm border border-solid",
48
+ "bg-acmekit-bg-field shadow-button-neutral dark:shadow-button-neutral-dark",
49
+ "hover:bg-acmekit-bg-field-hover",
50
+ "active:shadow-active dark:active:shadow-active-dark",
51
+ "focus:shadow-active dark:focus:shadow-active-dark",
52
+ "text-acmekit-fg-base text-compact-medium",
53
+ "disabled:bg-acmekit-bg-disabled",
54
+ "disabled:text-acmekit-fg-disabled",
55
+ "flex items-center gap-docs_0.5",
56
+ !hasSelectedValues && "placeholder:text-acmekit-fg-muted",
57
+ hasSelectedValues && "placeholder:text-acmekit-fg-base",
58
+ className
59
+ )}
60
+ ref={ref}
61
+ onClick={(e) => {
62
+ if (!dropdownRef.current?.contains(e.target as Element)) {
63
+ setOpen((prev) => !prev)
64
+ }
65
+ }}
66
+ data-testid="select-input"
67
+ >
68
+ {hasSelectedValues && (
69
+ <Badge
70
+ variant="neutral"
71
+ className={clsx("flex", showClearButton && "flex-1")}
72
+ >
73
+ <span
74
+ className={clsx(
75
+ "text-compact-medium-plus inline-block",
76
+ showClearButton && "mr-docs_0.125"
77
+ )}
78
+ >
79
+ {(value as string[]).length}
80
+ </span>
81
+ {showClearButton && (
82
+ <XMarkMini
83
+ className="text-acmekit-tag-neutral-icon"
84
+ onClick={(e) => {
85
+ e.stopPropagation()
86
+ setSelected?.([])
87
+ }}
88
+ />
89
+ )}
90
+ </Badge>
91
+ )}
92
+ <span
93
+ className={clsx(
94
+ "inline-block flex-1 select-none overflow-ellipsis whitespace-nowrap break-words",
95
+ hasSelectedValues && "max-w-1/3"
96
+ )}
97
+ >
98
+ {!multiple && hasSelectedValue && selectedValues.length
99
+ ? selectedValues[0].label
100
+ : props.placeholder}
101
+ </span>
102
+ <ChevronUpDown className="text-acmekit-fg-muted" />
103
+ <input
104
+ type="hidden"
105
+ name={props.name}
106
+ value={Array.isArray(value) ? value.join(",") : value}
107
+ />
108
+ <SelectDropdown
109
+ options={options}
110
+ open={open}
111
+ setOpen={setOpen}
112
+ addAll={addAll}
113
+ multiple={multiple}
114
+ isAllSelected={isAllSelected}
115
+ isValueSelected={isValueSelected}
116
+ handleSelectAll={handleSelectAll}
117
+ handleChange={handleChange}
118
+ parentRef={ref as React.RefObject<HTMLDivElement>}
119
+ passedRef={dropdownRef}
120
+ />
121
+ </div>
122
+ )
123
+ }
@@ -0,0 +1,13 @@
1
+ import type { OptionType, SelectOptions } from "../../hooks"
2
+
3
+ export type SelectProps = {
4
+ options: OptionType[]
5
+ multiple?: boolean
6
+ addAll?: boolean
7
+ showClearButton?: boolean
8
+ } & SelectOptions &
9
+ React.ComponentProps<"input">
10
+
11
+ export * from "./Badge"
12
+ export * from "./Dropdown"
13
+ export * from "./Input"
@@ -0,0 +1,43 @@
1
+
2
+ import React, { useMemo } from "react"
3
+ import clsx from "clsx"
4
+ import { ArrowUturnLeft } from "@acmekit/icons"
5
+ import { useSidebar } from "../../../providers/Sidebar"
6
+
7
+ export const SidebarChild = () => {
8
+ const { goBack, shownSidebar } = useSidebar()
9
+
10
+ const title = useMemo(() => {
11
+ if (!shownSidebar) {
12
+ return ""
13
+ }
14
+
15
+ return "childSidebarTitle" in shownSidebar
16
+ ? shownSidebar.childSidebarTitle || shownSidebar.title
17
+ : shownSidebar.title
18
+ }, [shownSidebar])
19
+
20
+ if (!shownSidebar) {
21
+ return <></>
22
+ }
23
+
24
+ return (
25
+ <div className="px-docs_0.75" data-testid="sidebar-child">
26
+ <div
27
+ onClick={goBack}
28
+ className={clsx(
29
+ "flex items-center justify-start my-docs_0.75 gap-[10px]",
30
+ "border border-transparent cursor-pointer mx-docs_0.5",
31
+ "!text-acmekit-fg-base !text-compact-small-plus"
32
+ )}
33
+ tabIndex={-1}
34
+ data-testid="sidebar-child-back-button"
35
+ >
36
+ <ArrowUturnLeft />
37
+ <span className="truncate flex-1" data-testid="sidebar-child-title">
38
+ {title}
39
+ </span>
40
+ </div>
41
+ </div>
42
+ )
43
+ }
@@ -0,0 +1,151 @@
1
+
2
+ // @refresh reset
3
+
4
+ import React, { useEffect, useMemo, useState } from "react"
5
+ import { Sidebar } from "../../../../types"
6
+ import { Badge } from "../../../../components/Badge"
7
+ import { Loading } from "../../../../components/Loading"
8
+ import { SidebarItem } from "../../../../components/Sidebar/Item"
9
+ import { useSidebar } from "../../../../providers/Sidebar"
10
+ import clsx from "clsx"
11
+ import { TriangleDownMini, TriangleUpMini } from "@acmekit/icons"
12
+
13
+ export type SidebarItemCategoryProps = {
14
+ item: Sidebar.SidebarItemCategory
15
+ } & React.AllHTMLAttributes<HTMLDivElement>
16
+
17
+ export const SidebarItemCategory = ({
18
+ item,
19
+ className,
20
+ }: SidebarItemCategoryProps) => {
21
+ const [showLoading, setShowLoading] = useState(false)
22
+ const [open, setOpen] = useState(
23
+ item.initialOpen !== undefined ? item.initialOpen : false
24
+ )
25
+ const {
26
+ isItemActive,
27
+ updatePersistedCategoryState,
28
+ getPersistedCategoryState,
29
+ persistCategoryState,
30
+ } = useSidebar()
31
+ const itemShowLoading = useMemo(() => {
32
+ return !item.loaded || (item.showLoadingIfEmpty && !item.children?.length)
33
+ }, [item])
34
+ const isActive = useMemo(() => {
35
+ return isItemActive({
36
+ item,
37
+ })
38
+ }, [isItemActive, item])
39
+
40
+ useEffect(() => {
41
+ if (open && itemShowLoading) {
42
+ setShowLoading(true)
43
+ }
44
+ }, [open, itemShowLoading])
45
+
46
+ useEffect(() => {
47
+ if (!itemShowLoading && showLoading) {
48
+ setShowLoading(false)
49
+ }
50
+ }, [itemShowLoading, showLoading])
51
+
52
+ useEffect(() => {
53
+ if (isActive && !open) {
54
+ setOpen(true)
55
+ }
56
+ }, [isActive, item.children])
57
+
58
+ useEffect(() => {
59
+ if (!persistCategoryState) {
60
+ return
61
+ }
62
+ const persistedOpen = getPersistedCategoryState(item.title)
63
+ if (persistedOpen !== undefined && !isActive) {
64
+ setOpen(persistedOpen)
65
+ }
66
+ }, [persistCategoryState])
67
+
68
+ const handleOpen = () => {
69
+ if (!open) {
70
+ item.onOpen?.()
71
+ }
72
+ if (persistCategoryState) {
73
+ updatePersistedCategoryState(item.title, !open)
74
+ }
75
+ setOpen((prev) => !prev)
76
+ }
77
+
78
+ const isTitleOneWord = useMemo(
79
+ () => item.title.split(" ").length === 1,
80
+ [item.title]
81
+ )
82
+
83
+ return (
84
+ <div
85
+ className={clsx("my-docs_0.75 first:!mt-0 w-full relative", className)}
86
+ data-testid="sidebar-item-category-container"
87
+ >
88
+ <div className="px-docs_0.75">
89
+ <div
90
+ className={clsx(
91
+ "py-docs_0.25 px-docs_0.5",
92
+ "flex justify-between items-center gap-docs_0.5",
93
+ "text-acmekit-fg-muted",
94
+ "cursor-pointer relative",
95
+ "z-[2]",
96
+ !isTitleOneWord && "break-words"
97
+ )}
98
+ tabIndex={-1}
99
+ onClick={handleOpen}
100
+ data-testid="sidebar-item-category"
101
+ >
102
+ <span
103
+ className={clsx(
104
+ "text-compact-x-small-plus",
105
+ isTitleOneWord && "truncate"
106
+ )}
107
+ data-testid="sidebar-item-title"
108
+ >
109
+ {item.title}
110
+ </span>
111
+ {item.additionalElms}
112
+ {item.badge && (
113
+ <Badge variant={item.badge.variant}>{item.badge.text}</Badge>
114
+ )}
115
+ {!item.additionalElms && (
116
+ <>
117
+ {open && <TriangleDownMini />}
118
+ {!open && <TriangleUpMini />}
119
+ </>
120
+ )}
121
+ </div>
122
+ </div>
123
+ {!item.hideChildren && (
124
+ <ul
125
+ className={clsx(
126
+ "ease-ease",
127
+ "flex flex-col gap-docs_0.125",
128
+ "z-[1] relative",
129
+ !open && "overflow-hidden m-0 h-0"
130
+ )}
131
+ data-testid="sidebar-item-category-children"
132
+ >
133
+ {item.children?.map((childItem, index) => (
134
+ <SidebarItem
135
+ item={childItem}
136
+ key={index}
137
+ isParentCategoryOpen={open}
138
+ />
139
+ ))}
140
+ {showLoading && (
141
+ <Loading
142
+ count={3}
143
+ className="!mb-0 !px-docs_0.5"
144
+ barClassName="h-[20px]"
145
+ />
146
+ )}
147
+ </ul>
148
+ )}
149
+ </div>
150
+ )
151
+ }