@k8o/arte-odyssey 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/accordion/accordion-button.d.ts +2 -0
  3. package/dist/components/accordion/accordion-button.js +40 -0
  4. package/dist/components/accordion/accordion-item.d.ts +4 -0
  5. package/dist/components/accordion/accordion-item.js +11 -0
  6. package/dist/components/accordion/accordion-panel.d.ts +2 -0
  7. package/dist/components/accordion/accordion-panel.js +21 -0
  8. package/dist/components/accordion/accordion.d.ts +2 -0
  9. package/dist/components/accordion/accordion.js +17 -0
  10. package/dist/components/accordion/accordion.stories.js +89 -0
  11. package/dist/components/accordion/context.d.ts +10 -0
  12. package/dist/components/accordion/context.js +38 -0
  13. package/dist/components/accordion/index.d.ts +4 -0
  14. package/dist/components/accordion/index.js +4 -0
  15. package/dist/components/alert/alert.d.ts +8 -0
  16. package/dist/components/alert/alert.js +46 -0
  17. package/dist/components/alert/alert.stories.js +51 -0
  18. package/dist/components/alert/index.d.ts +1 -0
  19. package/dist/components/alert/index.js +1 -0
  20. package/dist/components/anchor/anchor.d.ts +14 -0
  21. package/dist/components/anchor/anchor.js +31 -0
  22. package/dist/components/anchor/anchor.stories.js +23 -0
  23. package/dist/components/anchor/index.d.ts +1 -0
  24. package/dist/components/anchor/index.js +1 -0
  25. package/dist/components/baseline-status/baseline-status.d.ts +16 -0
  26. package/dist/components/baseline-status/baseline-status.js +39 -0
  27. package/dist/components/baseline-status/baseline-status.stories.js +15 -0
  28. package/dist/components/baseline-status/index.d.ts +1 -0
  29. package/dist/components/baseline-status/index.js +1 -0
  30. package/dist/components/breadcrumb/breadcrumb.d.ts +18 -0
  31. package/dist/components/breadcrumb/breadcrumb.js +36 -0
  32. package/dist/components/breadcrumb/breadcrumb.stories.js +40 -0
  33. package/dist/components/breadcrumb/index.d.ts +1 -0
  34. package/dist/components/breadcrumb/index.js +1 -0
  35. package/dist/components/button/button.d.ts +10 -0
  36. package/dist/components/button/button.js +55 -0
  37. package/dist/components/button/button.stories.js +96 -0
  38. package/dist/components/button/index.d.ts +1 -0
  39. package/dist/components/button/index.js +1 -0
  40. package/dist/components/card/card.d.ts +3 -0
  41. package/dist/components/card/card.js +26 -0
  42. package/dist/components/card/card.stories.js +38 -0
  43. package/dist/components/card/index.d.ts +2 -0
  44. package/dist/components/card/index.js +2 -0
  45. package/dist/components/card/interactive-card.d.ts +3 -0
  46. package/dist/components/card/interactive-card.js +34 -0
  47. package/dist/components/card/type.d.ts +6 -0
  48. package/dist/components/card/type.js +0 -0
  49. package/dist/components/code/code.d.ts +4 -0
  50. package/dist/components/code/code.js +38 -0
  51. package/dist/components/code/code.stories.js +60 -0
  52. package/dist/components/code/index.d.ts +1 -0
  53. package/dist/components/code/index.js +4 -0
  54. package/dist/components/dialog/dialog.d.ts +17 -0
  55. package/dist/components/dialog/dialog.js +85 -0
  56. package/dist/components/dialog/dialog.stories.js +98 -0
  57. package/dist/components/dialog/index.d.ts +1 -0
  58. package/dist/components/dialog/index.js +1 -0
  59. package/dist/components/drawer/drawer.d.ts +6 -0
  60. package/dist/components/drawer/drawer.js +56 -0
  61. package/dist/components/drawer/drawer.stories.js +25 -0
  62. package/dist/components/drawer/index.d.ts +1 -0
  63. package/dist/components/drawer/index.js +1 -0
  64. package/dist/components/dropdown-menu/dropdown-menu.d.ts +24 -0
  65. package/dist/components/dropdown-menu/dropdown-menu.js +130 -0
  66. package/dist/components/dropdown-menu/dropdown-menu.stories.js +111 -0
  67. package/dist/components/dropdown-menu/hooks.d.ts +23 -0
  68. package/dist/components/dropdown-menu/hooks.js +56 -0
  69. package/dist/components/dropdown-menu/index.d.ts +1 -0
  70. package/dist/components/dropdown-menu/index.js +1 -0
  71. package/dist/components/error-boundary/index.d.ts +1 -0
  72. package/dist/components/error-boundary/index.js +4 -0
  73. package/dist/components/form/autocomplete/autocomplete.d.ts +14 -0
  74. package/dist/components/form/autocomplete/autocomplete.js +225 -0
  75. package/dist/components/form/autocomplete/autocomplete.stories.js +59 -0
  76. package/dist/components/form/autocomplete/index.d.ts +1 -0
  77. package/dist/components/form/autocomplete/index.js +1 -0
  78. package/dist/components/form/checkbox/checkbox.d.ts +8 -0
  79. package/dist/components/form/checkbox/checkbox.js +40 -0
  80. package/dist/components/form/checkbox/checkbox.stories.js +27 -0
  81. package/dist/components/form/checkbox/index.d.ts +1 -0
  82. package/dist/components/form/checkbox/index.js +1 -0
  83. package/dist/components/form/form-control/form-control.d.ts +20 -0
  84. package/dist/components/form/form-control/form-control.js +53 -0
  85. package/dist/components/form/form-control/form-control.stories.js +94 -0
  86. package/dist/components/form/form-control/index.d.ts +1 -0
  87. package/dist/components/form/form-control/index.js +1 -0
  88. package/dist/components/form/number-field/index.d.ts +1 -0
  89. package/dist/components/form/number-field/index.js +1 -0
  90. package/dist/components/form/number-field/number-field.d.ts +17 -0
  91. package/dist/components/form/number-field/number-field.js +150 -0
  92. package/dist/components/form/number-field/number-field.stories.js +106 -0
  93. package/dist/components/form/radio/index.d.ts +1 -0
  94. package/dist/components/form/radio/index.js +1 -0
  95. package/dist/components/form/radio/radio.d.ts +11 -0
  96. package/dist/components/form/radio/radio.js +51 -0
  97. package/dist/components/form/radio/radio.stories.js +55 -0
  98. package/dist/components/form/range-field/index.d.ts +1 -0
  99. package/dist/components/form/range-field/index.js +4 -0
  100. package/dist/components/form/range-field/range-field.d.ts +17 -0
  101. package/dist/components/form/range-field/range-field.js +54 -0
  102. package/dist/components/form/range-field/range-field.stories.js +162 -0
  103. package/dist/components/form/select/index.d.ts +1 -0
  104. package/dist/components/form/select/index.js +1 -0
  105. package/dist/components/form/select/select.d.ts +14 -0
  106. package/dist/components/form/select/select.js +39 -0
  107. package/dist/components/form/select/select.stories.js +58 -0
  108. package/dist/components/form/text-field/index.d.ts +1 -0
  109. package/dist/components/form/text-field/index.js +1 -0
  110. package/dist/components/form/text-field/text-field.d.ts +15 -0
  111. package/dist/components/form/text-field/text-field.js +40 -0
  112. package/dist/components/form/text-field/text-field.stories.js +61 -0
  113. package/dist/components/form/textarea/index.d.ts +1 -0
  114. package/dist/components/form/textarea/index.js +1 -0
  115. package/dist/components/form/textarea/textarea.d.ts +18 -0
  116. package/dist/components/form/textarea/textarea.js +56 -0
  117. package/dist/components/form/textarea/textarea.stories.js +92 -0
  118. package/dist/components/heading/heading.d.ts +8 -0
  119. package/dist/components/heading/heading.js +77 -0
  120. package/dist/components/heading/heading.stories.js +52 -0
  121. package/dist/components/heading/index.d.ts +1 -0
  122. package/dist/components/heading/index.js +1 -0
  123. package/dist/components/icon-button/icon-button.d.ts +8 -0
  124. package/dist/components/icon-button/icon-button.js +38 -0
  125. package/dist/components/icon-button/icon-button.stories.js +54 -0
  126. package/dist/components/icon-button/index.d.ts +1 -0
  127. package/dist/components/icon-button/index.js +1 -0
  128. package/dist/components/icon-link/icon-link.d.ts +17 -0
  129. package/dist/components/icon-link/icon-link.js +37 -0
  130. package/dist/components/icon-link/icon-link.stories.js +40 -0
  131. package/dist/components/icon-link/index.d.ts +1 -0
  132. package/dist/components/icon-link/index.js +1 -0
  133. package/dist/components/icons/arte-odyssey.d.ts +3 -0
  134. package/dist/components/icons/arte-odyssey.js +463 -0
  135. package/dist/components/icons/base.d.ts +9 -0
  136. package/dist/components/icons/base.js +13 -0
  137. package/dist/components/icons/github-mark.d.ts +3 -0
  138. package/dist/components/icons/github-mark.js +33 -0
  139. package/dist/components/icons/icons.stories.js +276 -0
  140. package/dist/components/icons/index.d.ts +7 -0
  141. package/dist/components/icons/index.js +7 -0
  142. package/dist/components/icons/logo.d.ts +6 -0
  143. package/dist/components/icons/logo.js +50 -0
  144. package/dist/components/icons/lucide.d.ts +50 -0
  145. package/dist/components/icons/lucide.js +569 -0
  146. package/dist/components/icons/qiita.d.ts +3 -0
  147. package/dist/components/icons/qiita.js +48 -0
  148. package/dist/components/icons/twitter.d.ts +3 -0
  149. package/dist/components/icons/twitter.js +34 -0
  150. package/dist/components/icons/zenn.d.ts +6 -0
  151. package/dist/components/icons/zenn.js +41 -0
  152. package/dist/components/index.d.ts +37 -0
  153. package/dist/components/index.js +37 -0
  154. package/dist/components/link-button/index.d.ts +1 -0
  155. package/dist/components/link-button/index.js +1 -0
  156. package/dist/components/link-button/link-button.d.ts +19 -0
  157. package/dist/components/link-button/link-button.js +46 -0
  158. package/dist/components/link-button/link-button.stories.js +51 -0
  159. package/dist/components/list-box/hooks.d.ts +37 -0
  160. package/dist/components/list-box/hooks.js +70 -0
  161. package/dist/components/list-box/index.d.ts +1 -0
  162. package/dist/components/list-box/index.js +1 -0
  163. package/dist/components/list-box/list-box.d.ts +22 -0
  164. package/dist/components/list-box/list-box.js +145 -0
  165. package/dist/components/list-box/list-box.stories.js +69 -0
  166. package/dist/components/modal/index.d.ts +1 -0
  167. package/dist/components/modal/index.js +1 -0
  168. package/dist/components/modal/modal.d.ts +8 -0
  169. package/dist/components/modal/modal.js +118 -0
  170. package/dist/components/modal/modal.stories.js +22 -0
  171. package/dist/components/popover/hooks.d.ts +65 -0
  172. package/dist/components/popover/hooks.js +187 -0
  173. package/dist/components/popover/index.d.ts +1 -0
  174. package/dist/components/popover/index.js +1 -0
  175. package/dist/components/popover/popover.d.ts +18 -0
  176. package/dist/components/popover/popover.js +141 -0
  177. package/dist/components/popover/popover.stories.js +45 -0
  178. package/dist/components/progress/index.d.ts +1 -0
  179. package/dist/components/progress/index.js +1 -0
  180. package/dist/components/progress/progress.d.ts +7 -0
  181. package/dist/components/progress/progress.js +21 -0
  182. package/dist/components/progress/progress.stories.js +16 -0
  183. package/dist/components/providers/component-provider.d.ts +2 -0
  184. package/dist/components/providers/component-provider.js +9 -0
  185. package/dist/components/providers/index.d.ts +2 -0
  186. package/dist/components/providers/index.js +2 -0
  187. package/dist/components/providers/portal-root.d.ts +5 -0
  188. package/dist/components/providers/portal-root.js +17 -0
  189. package/dist/components/scroll-linked/index.d.ts +1 -0
  190. package/dist/components/scroll-linked/index.js +1 -0
  191. package/dist/components/scroll-linked/scroll-linked.d.ts +2 -0
  192. package/dist/components/scroll-linked/scroll-linked.js +21 -0
  193. package/dist/components/scroll-linked/scroll-linked.stories.js +18 -0
  194. package/dist/components/separator/index.d.ts +1 -0
  195. package/dist/components/separator/index.js +1 -0
  196. package/dist/components/separator/separator.d.ts +4 -0
  197. package/dist/components/separator/separator.js +20 -0
  198. package/dist/components/separator/separator.stories.js +27 -0
  199. package/dist/components/tabs/index.d.ts +1 -0
  200. package/dist/components/tabs/index.js +1 -0
  201. package/dist/components/tabs/tabs.d.ts +16 -0
  202. package/dist/components/tabs/tabs.js +145 -0
  203. package/dist/components/tabs/tabs.stories.js +49 -0
  204. package/dist/components/text-tag/index.d.ts +1 -0
  205. package/dist/components/text-tag/index.js +1 -0
  206. package/dist/components/text-tag/text-tag.d.ts +5 -0
  207. package/dist/components/text-tag/text-tag.js +23 -0
  208. package/dist/components/text-tag/text-tag.stories.js +30 -0
  209. package/dist/components/toast/index.d.ts +1 -0
  210. package/dist/components/toast/index.js +5 -0
  211. package/dist/components/toast/provider.d.ts +11 -0
  212. package/dist/components/toast/provider.js +125 -0
  213. package/dist/components/toast/toast.d.ts +9 -0
  214. package/dist/components/toast/toast.js +19 -0
  215. package/dist/components/toast/toast.stories.js +45 -0
  216. package/dist/components/tooltip/index.d.ts +1 -0
  217. package/dist/components/tooltip/index.js +1 -0
  218. package/dist/components/tooltip/tooltip.d.ts +13 -0
  219. package/dist/components/tooltip/tooltip.js +60 -0
  220. package/dist/components/tooltip/tooltip.stories.js +40 -0
  221. package/dist/helpers/cn.d.ts +2 -0
  222. package/dist/helpers/cn.js +8 -0
  223. package/dist/helpers/color/find-all-colors.d.ts +12 -0
  224. package/dist/helpers/color/find-all-colors.js +210 -0
  225. package/dist/helpers/is-internal-route.d.ts +1 -0
  226. package/dist/helpers/is-internal-route.js +12 -0
  227. package/dist/helpers/number/between.d.ts +1 -0
  228. package/dist/helpers/number/between.js +19 -0
  229. package/dist/helpers/number/cast.d.ts +1 -0
  230. package/dist/helpers/number/cast.js +41 -0
  231. package/dist/helpers/number/commalize.d.ts +1 -0
  232. package/dist/helpers/number/commalize.js +22 -0
  233. package/dist/helpers/number/index.d.ts +4 -0
  234. package/dist/helpers/number/index.js +10 -0
  235. package/dist/helpers/number/to-precision.d.ts +1 -0
  236. package/dist/helpers/number/to-precision.js +17 -0
  237. package/dist/helpers/uuid-v4.d.ts +1 -0
  238. package/dist/helpers/uuid-v4.js +32 -0
  239. package/dist/hooks/click-away/index.d.ts +2 -0
  240. package/dist/hooks/click-away/index.js +24 -0
  241. package/dist/hooks/click-away/index.test.js +31 -0
  242. package/dist/hooks/client/index.d.ts +1 -0
  243. package/dist/hooks/client/index.js +12 -0
  244. package/dist/hooks/clipboard/index.d.ts +4 -0
  245. package/dist/hooks/clipboard/index.js +17 -0
  246. package/dist/hooks/clipboard/index.test.js +35 -0
  247. package/dist/hooks/hash/index.d.ts +1 -0
  248. package/dist/hooks/hash/index.js +28 -0
  249. package/dist/hooks/hash/index.test.js +46 -0
  250. package/dist/hooks/index.d.ts +10 -0
  251. package/dist/hooks/index.js +10 -0
  252. package/dist/hooks/interval/index.d.ts +1 -0
  253. package/dist/hooks/interval/index.js +17 -0
  254. package/dist/hooks/interval/index.test.js +32 -0
  255. package/dist/hooks/local-storage/index.d.ts +1 -0
  256. package/dist/hooks/local-storage/index.js +48 -0
  257. package/dist/hooks/local-storage/index.test.js +82 -0
  258. package/dist/hooks/scroll-direction/index.d.ts +6 -0
  259. package/dist/hooks/scroll-direction/index.js +40 -0
  260. package/dist/hooks/scroll-direction/index.test.js +174 -0
  261. package/dist/hooks/step/index.d.ts +13 -0
  262. package/dist/hooks/step/index.js +39 -0
  263. package/dist/hooks/step/index.test.js +85 -0
  264. package/dist/hooks/timeout/index.d.ts +1 -0
  265. package/dist/hooks/timeout/index.js +17 -0
  266. package/dist/hooks/timeout/index.test.js +31 -0
  267. package/dist/hooks/window-size/index.d.ts +6 -0
  268. package/dist/hooks/window-size/index.js +22 -0
  269. package/dist/hooks/window-size/index.test.js +18 -0
  270. package/dist/index.d.ts +2 -0
  271. package/dist/index.js +2 -0
  272. package/dist/package.json +6 -0
  273. package/dist/styles/index.css +394 -0
  274. package/dist/types/variables.d.ts +6 -0
  275. package/dist/types/variables.js +0 -0
  276. package/package.json +110 -0
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useId } from "react";
4
+ import { Heading } from "../heading";
5
+ import { IconButton } from "../icon-button";
6
+ import { CloseIcon } from "../icons";
7
+ import { Modal } from "../modal";
8
+ const Drawer = ({ title, isOpen, onClose, children }) => {
9
+ const rootId = useId();
10
+ return /* @__PURE__ */ jsx(Modal, { isOpen, onClose, type: "right", children: /* @__PURE__ */ jsxs(
11
+ "section",
12
+ {
13
+ "aria-describedby": `${rootId}-content`,
14
+ "aria-labelledby": `${rootId}-header`,
15
+ className: "min-h-svh",
16
+ id: rootId,
17
+ children: [
18
+ /* @__PURE__ */ jsxs(
19
+ "div",
20
+ {
21
+ className: "flex items-center justify-center p-4 pb-2",
22
+ id: `${rootId}-header`,
23
+ children: [
24
+ /* @__PURE__ */ jsx(Heading, { type: "h3", children: title }),
25
+ /* @__PURE__ */ jsx("div", { className: "absolute top-2 right-2", children: /* @__PURE__ */ jsx(
26
+ IconButton,
27
+ {
28
+ label: "\u9589\u3058\u308B",
29
+ onClick: (e) => {
30
+ e.stopPropagation();
31
+ onClose();
32
+ },
33
+ children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" })
34
+ }
35
+ ) })
36
+ ]
37
+ }
38
+ ),
39
+ /* @__PURE__ */ jsx(
40
+ "div",
41
+ {
42
+ className: "p-4",
43
+ id: `${rootId}-content`,
44
+ onClick: (e) => {
45
+ e.stopPropagation();
46
+ },
47
+ children
48
+ }
49
+ )
50
+ ]
51
+ }
52
+ ) });
53
+ };
54
+ export {
55
+ Drawer
56
+ };
@@ -0,0 +1,25 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { fn } from "storybook/test";
3
+ import { Drawer } from "./drawer";
4
+ const meta = {
5
+ title: "components/drawer",
6
+ component: Drawer
7
+ };
8
+ var drawer_stories_default = meta;
9
+ const Default = {
10
+ args: {
11
+ isOpen: true,
12
+ onClose: fn(),
13
+ title: "Drawer Title",
14
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
15
+ /* @__PURE__ */ jsx("p", { className: "text-fg-mute", children: "This is a drawer component. You can put any content here." }),
16
+ /* @__PURE__ */ jsx("p", { className: "text-fg-mute", children: "You can use it to display additional information or actions related to the current context." }),
17
+ /* @__PURE__ */ jsx("p", { className: "text-fg-mute", children: "You can also use it to display forms, lists, or any other type of content that you want to show in a drawer." }),
18
+ /* @__PURE__ */ jsx("p", { className: "text-fg-mute", children: "This is a great way to keep your UI clean and organized while still providing access to important information or actions." })
19
+ ] })
20
+ }
21
+ };
22
+ export {
23
+ Default,
24
+ drawer_stories_default as default
25
+ };
@@ -0,0 +1 @@
1
+ export * from './drawer';
@@ -0,0 +1 @@
1
+ export * from "./drawer";
@@ -0,0 +1,24 @@
1
+ import { type Placement } from '@floating-ui/react';
2
+ import { type ComponentProps, type FC, type MouseEventHandler, type PropsWithChildren, type ReactNode } from 'react';
3
+ import { Button } from '../button';
4
+ export declare const DropdownMenu: {
5
+ Root: FC<PropsWithChildren<{
6
+ placement?: Placement;
7
+ }>>;
8
+ Content: FC<{
9
+ children?: ReactNode | undefined;
10
+ }>;
11
+ Item: FC<{
12
+ onClick: MouseEventHandler;
13
+ label: string;
14
+ }>;
15
+ Trigger: FC<{
16
+ text: string;
17
+ size?: ComponentProps<typeof Button>["size"];
18
+ variant?: ComponentProps<typeof Button>["variant"];
19
+ }>;
20
+ IconTrigger: FC<{
21
+ icon: ReactNode;
22
+ label: string;
23
+ }>;
24
+ };
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import {
4
+ FloatingList,
5
+ useInteractions,
6
+ useListNavigation
7
+ } from "@floating-ui/react";
8
+ import {
9
+ useRef,
10
+ useState
11
+ } from "react";
12
+ import { cn } from "./../../helpers/cn";
13
+ import { Button } from "../button";
14
+ import { IconButton } from "../icon-button";
15
+ import { ChevronIcon } from "../icons";
16
+ import { Popover } from "../popover";
17
+ import { useFloatingUIContext } from "../popover/hooks";
18
+ import {
19
+ MenuContextProvider,
20
+ useMenuContent,
21
+ useMenuItem,
22
+ useMenuTrigger
23
+ } from "./hooks";
24
+ const Root = ({
25
+ children,
26
+ placement = "bottom-start"
27
+ }) => {
28
+ return /* @__PURE__ */ jsx(Popover.Root, { placement, type: "menu", children: /* @__PURE__ */ jsx(MenuProvider, { children }) });
29
+ };
30
+ const MenuProvider = ({ children }) => {
31
+ const [activeIndex, setActiveIndex] = useState(null);
32
+ const itemElementsRef = useRef([]);
33
+ const context = useFloatingUIContext();
34
+ const listNavigation = useListNavigation(context, {
35
+ listRef: itemElementsRef,
36
+ activeIndex,
37
+ onNavigate: setActiveIndex,
38
+ loop: true
39
+ });
40
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(
41
+ [listNavigation]
42
+ );
43
+ return /* @__PURE__ */ jsx(
44
+ MenuContextProvider,
45
+ {
46
+ value: {
47
+ activeIndex,
48
+ itemElementsRef,
49
+ getTriggerProps: getReferenceProps,
50
+ getContentProps: getFloatingProps,
51
+ getItemProps
52
+ },
53
+ children
54
+ }
55
+ );
56
+ };
57
+ const Content = ({ children }) => {
58
+ const { contentProps, itemElementsRef } = useMenuContent();
59
+ return /* @__PURE__ */ jsx(FloatingList, { elementsRef: itemElementsRef, children: /* @__PURE__ */ jsx(
60
+ Popover.Content,
61
+ {
62
+ renderItem: (props) => /* @__PURE__ */ jsx(
63
+ "div",
64
+ {
65
+ ...props,
66
+ ...contentProps,
67
+ className: "flex min-w-40 flex-col rounded-lg border border-border-mute bg-bg-base py-2 shadow-xl",
68
+ children
69
+ }
70
+ )
71
+ }
72
+ ) });
73
+ };
74
+ const Item = ({
75
+ label,
76
+ onClick
77
+ }) => {
78
+ const props = useMenuItem({ onClick });
79
+ return /* @__PURE__ */ jsx(
80
+ "button",
81
+ {
82
+ className: cn(
83
+ "w-full px-2 py-1 text-left",
84
+ "hover:bg-primary-bg",
85
+ "focus-visible:border-transparent focus-visible:bg-primary-bg focus-visible:outline-hidden"
86
+ ),
87
+ ...props,
88
+ children: label
89
+ }
90
+ );
91
+ };
92
+ const Trigger = ({ text, size = "md", variant = "contained" }) => {
93
+ const getTriggerProps = useMenuTrigger();
94
+ return /* @__PURE__ */ jsx(
95
+ Popover.Trigger,
96
+ {
97
+ renderItem: (props) => /* @__PURE__ */ jsx(
98
+ Button,
99
+ {
100
+ color: "gray",
101
+ endIcon: /* @__PURE__ */ jsx(ChevronIcon, { direction: "down" }),
102
+ size,
103
+ type: "button",
104
+ variant,
105
+ ...getTriggerProps(props),
106
+ children: text
107
+ }
108
+ )
109
+ }
110
+ );
111
+ };
112
+ const IconTrigger = ({ icon, label }) => {
113
+ const getTriggerProps = useMenuTrigger();
114
+ return /* @__PURE__ */ jsx(
115
+ Popover.Trigger,
116
+ {
117
+ renderItem: (props) => /* @__PURE__ */ jsx(IconButton, { bg: "base", label, ...getTriggerProps(props), children: icon })
118
+ }
119
+ );
120
+ };
121
+ const DropdownMenu = {
122
+ Root,
123
+ Content,
124
+ Item,
125
+ Trigger,
126
+ IconTrigger
127
+ };
128
+ export {
129
+ DropdownMenu
130
+ };
@@ -0,0 +1,111 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { DarkModeIcon } from "../icons";
3
+ import { DropdownMenu } from "./dropdown-menu";
4
+ const meta = {
5
+ title: "components/dropdown-menu",
6
+ component: DropdownMenu.Root,
7
+ parameters: {
8
+ a11y: {
9
+ options: {
10
+ rules: {
11
+ // https://github.com/floating-ui/floating-ui/pull/2298#issuecomment-1518101512
12
+ "aria-hidden-focus": { enabled: false }
13
+ }
14
+ }
15
+ }
16
+ }
17
+ };
18
+ var dropdown_menu_stories_default = meta;
19
+ const Default = {
20
+ render: () => /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
21
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { text: "Options" }),
22
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
23
+ /* @__PURE__ */ jsx(
24
+ DropdownMenu.Item,
25
+ {
26
+ label: "Item 1",
27
+ onClick: () => {
28
+ console.log(1);
29
+ }
30
+ }
31
+ ),
32
+ /* @__PURE__ */ jsx(
33
+ DropdownMenu.Item,
34
+ {
35
+ label: "Item 2",
36
+ onClick: () => {
37
+ console.log(2);
38
+ }
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsx(
42
+ DropdownMenu.Item,
43
+ {
44
+ label: "Item 3",
45
+ onClick: () => {
46
+ console.log(3);
47
+ }
48
+ }
49
+ )
50
+ ] })
51
+ ] }),
52
+ play: async ({ canvas, userEvent }) => {
53
+ const trigger = canvas.getByRole("button", {
54
+ name: "Options"
55
+ });
56
+ trigger.focus();
57
+ await userEvent.keyboard("{Enter}");
58
+ }
59
+ };
60
+ const TriggerByIcon = {
61
+ render: () => /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
62
+ /* @__PURE__ */ jsx(
63
+ DropdownMenu.IconTrigger,
64
+ {
65
+ icon: /* @__PURE__ */ jsx(DarkModeIcon, { size: "lg" }),
66
+ label: "Options"
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
70
+ /* @__PURE__ */ jsx(
71
+ DropdownMenu.Item,
72
+ {
73
+ label: "Item 1",
74
+ onClick: () => {
75
+ console.log(1);
76
+ }
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsx(
80
+ DropdownMenu.Item,
81
+ {
82
+ label: "Item 2",
83
+ onClick: () => {
84
+ console.log(2);
85
+ }
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsx(
89
+ DropdownMenu.Item,
90
+ {
91
+ label: "Item 3",
92
+ onClick: () => {
93
+ console.log(3);
94
+ }
95
+ }
96
+ )
97
+ ] })
98
+ ] }),
99
+ play: async ({ canvas, userEvent }) => {
100
+ const trigger = canvas.getByRole("button", {
101
+ name: "Options"
102
+ });
103
+ trigger.focus();
104
+ await userEvent.keyboard("{Enter}");
105
+ }
106
+ };
107
+ export {
108
+ Default,
109
+ TriggerByIcon,
110
+ dropdown_menu_stories_default as default
111
+ };
@@ -0,0 +1,23 @@
1
+ import { type HTMLProps, type MouseEventHandler, type RefObject } from 'react';
2
+ type MenuContext = {
3
+ activeIndex: number | null;
4
+ itemElementsRef: RefObject<(HTMLElement | null)[]>;
5
+ getTriggerProps: (userProps?: HTMLProps<HTMLElement>) => Record<string, unknown>;
6
+ getContentProps: (userProps?: HTMLProps<HTMLElement>) => Record<string, unknown>;
7
+ getItemProps: (userProps?: Omit<HTMLProps<HTMLButtonElement>, 'selected' | 'active'>) => Record<string, unknown>;
8
+ };
9
+ declare const MenuContext: React.Context<MenuContext | null>;
10
+ export declare const MenuContextProvider: React.Context<MenuContext | null>;
11
+ export declare const useMenuContent: () => {
12
+ contentProps: Record<string, unknown>;
13
+ itemElementsRef: RefObject<(HTMLElement | null)[]>;
14
+ };
15
+ export declare const useMenuItem: ({ onClick }: {
16
+ onClick: MouseEventHandler;
17
+ }) => {
18
+ ref: (node: HTMLElement | null) => void;
19
+ role: string;
20
+ tabIndex: number;
21
+ };
22
+ export declare const useMenuTrigger: () => (userProps?: HTMLProps<HTMLElement>) => Record<string, unknown>;
23
+ export {};
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { useListItem } from "@floating-ui/react";
3
+ import {
4
+ createContext,
5
+ use,
6
+ useMemo
7
+ } from "react";
8
+ import { useOpenContext } from "../popover/hooks";
9
+ const MenuContext = createContext(null);
10
+ const MenuContextProvider = MenuContext;
11
+ const useMenuContext = () => {
12
+ const menu = use(MenuContext);
13
+ if (!menu) {
14
+ throw new Error("useMenuContext must be used within a DropdownMenu.Root");
15
+ }
16
+ return menu;
17
+ };
18
+ const useMenuContent = () => {
19
+ const menu = useMenuContext();
20
+ return useMemo(
21
+ () => ({
22
+ contentProps: menu.getContentProps(),
23
+ itemElementsRef: menu.itemElementsRef
24
+ }),
25
+ [menu]
26
+ );
27
+ };
28
+ const useMenuItem = ({ onClick }) => {
29
+ const menu = useMenuContext();
30
+ const { onClose } = useOpenContext();
31
+ const item = useListItem();
32
+ return useMemo(
33
+ () => ({
34
+ ref: item.ref,
35
+ role: "menuitem",
36
+ tabIndex: menu.activeIndex === item.index ? 0 : -1,
37
+ ...menu.getItemProps({
38
+ onClick: (e) => {
39
+ onClick(e);
40
+ onClose();
41
+ }
42
+ })
43
+ }),
44
+ [item.index, item.ref, menu, onClick, onClose]
45
+ );
46
+ };
47
+ const useMenuTrigger = () => {
48
+ const menu = useMenuContext();
49
+ return useMemo(() => menu.getTriggerProps, [menu]);
50
+ };
51
+ export {
52
+ MenuContextProvider,
53
+ useMenuContent,
54
+ useMenuItem,
55
+ useMenuTrigger
56
+ };
@@ -0,0 +1 @@
1
+ export * from './dropdown-menu';
@@ -0,0 +1 @@
1
+ export * from "./dropdown-menu";
@@ -0,0 +1 @@
1
+ export { ErrorBoundary } from 'react-error-boundary';
@@ -0,0 +1,4 @@
1
+ import { ErrorBoundary } from "react-error-boundary";
2
+ export {
3
+ ErrorBoundary
4
+ };
@@ -0,0 +1,14 @@
1
+ import { type FC } from 'react';
2
+ import type { Option } from '../../../types/variables';
3
+ type Props = {
4
+ id: string;
5
+ describedbyId: string | undefined;
6
+ isInvalid: boolean;
7
+ isDisabled: boolean;
8
+ isRequired: boolean;
9
+ options: readonly Option[];
10
+ value: string[];
11
+ onChange: (value: string[]) => void;
12
+ };
13
+ export declare const Autocomplete: FC<Props>;
14
+ export {};
@@ -0,0 +1,225 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { cn } from "./../../../helpers/cn";
4
+ import { IconButton } from "../../icon-button";
5
+ import { CloseIcon } from "../../icons";
6
+ const Autocomplete = ({
7
+ id,
8
+ describedbyId,
9
+ isInvalid,
10
+ isDisabled,
11
+ isRequired,
12
+ options,
13
+ value,
14
+ onChange
15
+ }) => {
16
+ const ref = useRef(null);
17
+ const [open, setOpen] = useState(false);
18
+ const [text, setText] = useState("");
19
+ const [selectIndex, setSelectIndex] = useState();
20
+ const filteredOptions = options.filter(
21
+ (option) => option.label.includes(text)
22
+ );
23
+ const reset = useCallback(() => {
24
+ setText("");
25
+ setOpen(false);
26
+ setSelectIndex(void 0);
27
+ }, []);
28
+ useEffect(() => {
29
+ const handleClick = (e) => {
30
+ if (ref.current?.contains(e.target)) return;
31
+ reset();
32
+ };
33
+ document.addEventListener("click", handleClick);
34
+ return () => {
35
+ document.removeEventListener("click", handleClick);
36
+ };
37
+ }, [reset]);
38
+ return /* @__PURE__ */ jsxs(
39
+ "div",
40
+ {
41
+ className: cn(
42
+ "relative w-full rounded-md border border-border-base bg-bg-base shadow-xs",
43
+ "focus-within:bordertransparent focus-within:outline-hidden focus-within:ring-2 focus-within:ring-border-info",
44
+ "has-aria-invalid:border-border-error",
45
+ "has-disabled:cursor-not-allowed has-disabled:border-border-mute has-disabled:bg-bg-mute has-disabled:has-hover:hover:bg-bg-mute"
46
+ ),
47
+ ref,
48
+ children: [
49
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-12 items-center justify-between gap-2 px-3 py-2", children: [
50
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-wrap gap-1", children: [
51
+ value.map((text2) => {
52
+ const label = options.find(
53
+ (option) => option.value === text2
54
+ )?.label;
55
+ return /* @__PURE__ */ jsxs(
56
+ "div",
57
+ {
58
+ className: "inline-flex items-center gap-2 rounded-full bg-bg-mute px-3 py-1 font-medium text-sm",
59
+ tabIndex: -1,
60
+ children: [
61
+ label,
62
+ /* @__PURE__ */ jsx(
63
+ IconButton,
64
+ {
65
+ label: "\u9589\u3058\u308B",
66
+ onClick: (e) => {
67
+ e.stopPropagation();
68
+ reset();
69
+ onChange(value.filter((v) => v !== text2));
70
+ },
71
+ size: "sm",
72
+ children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" })
73
+ }
74
+ )
75
+ ]
76
+ },
77
+ text2
78
+ );
79
+ }),
80
+ /* @__PURE__ */ jsx(
81
+ "input",
82
+ {
83
+ "aria-autocomplete": "list",
84
+ "aria-controls": open ? `${id}_listbox` : void 0,
85
+ "aria-describedby": describedbyId,
86
+ "aria-expanded": open,
87
+ "aria-invalid": isInvalid,
88
+ "aria-required": isRequired,
89
+ autoComplete: "off",
90
+ className: cn(
91
+ "grow bg-transparent focus-visible:outline-hidden",
92
+ "disabled:cursor-not-allowed"
93
+ ),
94
+ disabled: isDisabled,
95
+ id,
96
+ onBlur: (e) => {
97
+ if (e.relatedTarget?.id.startsWith(`${id}_option_`)) {
98
+ return;
99
+ }
100
+ setOpen(false);
101
+ },
102
+ onChange: (e) => {
103
+ setOpen(true);
104
+ setText(e.target.value);
105
+ setSelectIndex(void 0);
106
+ },
107
+ onClick: () => {
108
+ if (open && text.length === 0) {
109
+ setOpen(false);
110
+ return;
111
+ }
112
+ setOpen(true);
113
+ setSelectIndex(void 0);
114
+ },
115
+ onKeyDown: (e) => {
116
+ if (e.key === "Backspace" && text.length === 0) {
117
+ reset();
118
+ onChange(value.slice(0, -1));
119
+ return;
120
+ }
121
+ if (e.key === "ArrowDown") {
122
+ setOpen(true);
123
+ setSelectIndex((prev) => {
124
+ if (prev === void 0) {
125
+ return 0;
126
+ }
127
+ return Math.min(prev + 1, options.length - 1);
128
+ });
129
+ return;
130
+ }
131
+ if (e.key === "ArrowUp") {
132
+ setOpen(true);
133
+ setSelectIndex((prev) => {
134
+ if (prev === void 0) {
135
+ return 0;
136
+ }
137
+ return Math.max(prev - 1, 0);
138
+ });
139
+ return;
140
+ }
141
+ if (e.key === "Enter" && selectIndex !== void 0 && selectIndex >= 0) {
142
+ const selected = filteredOptions[selectIndex];
143
+ if (!selected) {
144
+ return;
145
+ }
146
+ if (value.includes(selected.value)) {
147
+ onChange(value.filter((v) => v !== selected.value));
148
+ reset();
149
+ return;
150
+ }
151
+ onChange([...value, selected.value]);
152
+ reset();
153
+ return;
154
+ }
155
+ },
156
+ placeholder: "\u5165\u529B\u3057\u3066\u7D5E\u308A\u8FBC\u3081\u307E\u3059",
157
+ role: "combobox",
158
+ type: "text",
159
+ value: text
160
+ }
161
+ )
162
+ ] }),
163
+ value.length > 0 && /* @__PURE__ */ jsx(
164
+ IconButton,
165
+ {
166
+ label: "\u3059\u3079\u3066\u9589\u3058\u308B",
167
+ onClick: (e) => {
168
+ e.stopPropagation();
169
+ onChange([]);
170
+ },
171
+ size: "sm",
172
+ children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" })
173
+ }
174
+ )
175
+ ] }),
176
+ /* @__PURE__ */ jsx("div", { className: "relative w-full", children: open && /* @__PURE__ */ jsx(
177
+ "div",
178
+ {
179
+ className: "absolute top-1 z-10 w-full rounded-md border border-border-mute bg-bg-base shadow-md",
180
+ role: "presentation",
181
+ children: /* @__PURE__ */ jsxs("ul", { className: "max-h-96 py-2", id: `${id}_listbox`, children: [
182
+ filteredOptions.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-fg-mute", children: "\u8A72\u5F53\u306A\u3057" }),
183
+ filteredOptions.map((option, idx) => {
184
+ const selected = value.includes(option.value);
185
+ return /* @__PURE__ */ jsx(
186
+ "li",
187
+ {
188
+ className: cn(
189
+ "cursor-pointer px-3 py-2",
190
+ selected && "bg-primary-bg text-fg-inverse",
191
+ selectIndex === idx && !selected && "bg-bg-emphasize",
192
+ selectIndex === idx && selected && "hover:bg-primary-bg/90"
193
+ ),
194
+ id: `${id}_option_${option.value}`,
195
+ onClick: (e) => {
196
+ e.stopPropagation();
197
+ reset();
198
+ if (selected) {
199
+ onChange(value.filter((v) => v !== option.value));
200
+ return;
201
+ }
202
+ onChange([...value, option.value]);
203
+ },
204
+ onKeyDown: (e) => {
205
+ e.preventDefault();
206
+ },
207
+ onMouseEnter: () => {
208
+ setSelectIndex(idx);
209
+ },
210
+ tabIndex: -1,
211
+ children: option.label
212
+ },
213
+ option.value
214
+ );
215
+ })
216
+ ] })
217
+ }
218
+ ) })
219
+ ]
220
+ }
221
+ );
222
+ };
223
+ export {
224
+ Autocomplete
225
+ };