@k8o/arte-odyssey 1.0.0 → 1.2.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.
@@ -1,14 +1,14 @@
1
1
  export declare const Accordion: {
2
- readonly Root: React.FC<{
3
- children?: React.ReactNode | undefined;
2
+ readonly Root: import("react").FC<{
3
+ children?: import("react").ReactNode | undefined;
4
4
  }>;
5
- readonly Button: React.FC<{
6
- children?: React.ReactNode | undefined;
5
+ readonly Button: import("react").FC<{
6
+ children?: import("react").ReactNode | undefined;
7
7
  }>;
8
- readonly Item: React.FC<React.PropsWithChildren<{
8
+ readonly Item: import("react").FC<import("react").PropsWithChildren<{
9
9
  defaultOpen?: boolean;
10
10
  }>>;
11
- readonly Panel: React.FC<{
12
- children?: React.ReactNode | undefined;
11
+ readonly Panel: import("react").FC<{
12
+ children?: import("react").ReactNode | undefined;
13
13
  }>;
14
14
  };
@@ -4,7 +4,7 @@ export declare const Breadcrumb: {
4
4
  size?: "sm" | "md" | "lg";
5
5
  }>>;
6
6
  readonly Item: FC<{
7
- children?: React.ReactNode | undefined;
7
+ children?: import("react").ReactNode | undefined;
8
8
  }>;
9
9
  readonly Separator: FC;
10
10
  readonly Link: <T extends string>({ href, current, children, component, }: PropsWithChildren<{
@@ -18,7 +18,7 @@ const Code = ({ children }) => {
18
18
  "span",
19
19
  {
20
20
  "aria-label": `Color: ${colorInfo.color}`,
21
- className: "inline-block h-3 w-3 flex-shrink-0 rounded-sm border border-gray-300",
21
+ className: "inline-block h-3 w-3 shrink-0 rounded-sm border border-border-base",
22
22
  role: "img",
23
23
  style: { backgroundColor: colorInfo.color }
24
24
  }
@@ -12,6 +12,6 @@ export declare const Dialog: {
12
12
  onClose: () => void;
13
13
  }>;
14
14
  readonly Content: FC<{
15
- children?: React.ReactNode | undefined;
15
+ children?: import("react").ReactNode | undefined;
16
16
  }>;
17
17
  };
@@ -6,8 +6,8 @@ type MenuContext = {
6
6
  getContentProps: (userProps?: HTMLProps<HTMLElement>) => Record<string, unknown>;
7
7
  getItemProps: (userProps?: Omit<HTMLProps<HTMLButtonElement>, 'selected' | 'active'>) => Record<string, unknown>;
8
8
  };
9
- declare const MenuContext: React.Context<MenuContext | null>;
10
- export declare const MenuContextProvider: React.Context<MenuContext | null>;
9
+ declare const MenuContext: import("react").Context<MenuContext | null>;
10
+ export declare const MenuContextProvider: import("react").Context<MenuContext | null>;
11
11
  export declare const useMenuContent: () => {
12
12
  contentProps: Record<string, unknown>;
13
13
  itemElementsRef: RefObject<(HTMLElement | null)[]>;
@@ -0,0 +1,42 @@
1
+ import type { ChangeEventHandler, FC, PropsWithChildren, ReactElement } from 'react';
2
+ type AcceptedFile = {
3
+ file: File;
4
+ id: string;
5
+ };
6
+ type FileFieldContext = {
7
+ isDisabled: boolean;
8
+ isInvalid: boolean;
9
+ acceptedFiles: AcceptedFile[];
10
+ onFileDelete: (id: string) => void;
11
+ openFilePicker: () => void;
12
+ };
13
+ declare const FileFieldContext: import("react").Context<FileFieldContext | null>;
14
+ export declare const FileFieldProvider: import("react").Context<FileFieldContext | null>;
15
+ export declare const FileField: {
16
+ readonly Root: ({ children, id, name, describedbyId, isDisabled, isInvalid, isRequired, accept, multiple, maxFiles, onChange, webkitDirectory, }: PropsWithChildren<{
17
+ id?: string;
18
+ name?: string;
19
+ describedbyId?: string | undefined;
20
+ isDisabled?: boolean;
21
+ isInvalid?: boolean;
22
+ isRequired?: boolean;
23
+ accept?: string;
24
+ multiple?: boolean;
25
+ maxFiles?: number;
26
+ defaultValue?: File[];
27
+ onChange?: ChangeEventHandler<HTMLInputElement>;
28
+ webkitDirectory?: boolean;
29
+ }>) => import("react/jsx-runtime").JSX.Element;
30
+ readonly Trigger: FC<{
31
+ renderItem: (props: {
32
+ onClick: () => void;
33
+ disabled: boolean;
34
+ invalid: boolean;
35
+ }) => ReactElement;
36
+ }>;
37
+ readonly ItemList: FC<{
38
+ showWebkitRelativePath?: boolean;
39
+ clearable?: boolean;
40
+ }>;
41
+ };
42
+ export {};
@@ -0,0 +1,153 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ createContext,
5
+ use,
6
+ useCallback,
7
+ useId,
8
+ useMemo,
9
+ useRef,
10
+ useState
11
+ } from "react";
12
+ import { uuidV4 } from "../../../helpers/uuid-v4";
13
+ import { IconButton } from "../../icon-button";
14
+ import { CloseIcon } from "../../icons";
15
+ const FileFieldContext = createContext(null);
16
+ const FileFieldProvider = FileFieldContext;
17
+ const useFileFieldContext = () => {
18
+ const fileField = use(FileFieldContext);
19
+ if (!fileField) {
20
+ throw new Error("useFileFieldContext must be used within a FileField.Root");
21
+ }
22
+ return fileField;
23
+ };
24
+ const Root = ({
25
+ children,
26
+ id,
27
+ name,
28
+ describedbyId,
29
+ isDisabled = false,
30
+ isInvalid = false,
31
+ isRequired = false,
32
+ accept,
33
+ multiple = false,
34
+ maxFiles,
35
+ onChange,
36
+ webkitDirectory = false
37
+ }) => {
38
+ const generatedId = useId();
39
+ const inputRef = useRef(null);
40
+ const [acceptedFiles, setAcceptedFiles] = useState([]);
41
+ const onFilesChange = useCallback(
42
+ (event) => {
43
+ onChange?.(event);
44
+ const files = Array.from(event.target.files ?? []);
45
+ const newFiles = files.map((file) => ({ file, id: uuidV4() }));
46
+ const updatedFiles = multiple || webkitDirectory ? [...acceptedFiles, ...newFiles].slice(
47
+ 0,
48
+ maxFiles ?? Number.POSITIVE_INFINITY
49
+ ) : newFiles.slice(0, 1);
50
+ setAcceptedFiles(updatedFiles);
51
+ },
52
+ [acceptedFiles, multiple, maxFiles, onChange, webkitDirectory]
53
+ );
54
+ const onFileDelete = useCallback(
55
+ (fileId) => {
56
+ const updatedFiles = acceptedFiles.filter((f) => f.id !== fileId);
57
+ setAcceptedFiles(updatedFiles);
58
+ if (inputRef.current && onChange) {
59
+ const dataTransfer = new DataTransfer();
60
+ for (const { file } of updatedFiles) {
61
+ dataTransfer.items.add(file);
62
+ }
63
+ inputRef.current.files = dataTransfer.files;
64
+ const event = new Event("change", { bubbles: true });
65
+ Object.defineProperty(event, "target", {
66
+ writable: false,
67
+ value: inputRef.current
68
+ });
69
+ onChange(event);
70
+ }
71
+ },
72
+ [acceptedFiles, onChange]
73
+ );
74
+ const openFilePicker = useCallback(() => {
75
+ inputRef.current?.click();
76
+ }, []);
77
+ const contextValue = useMemo(
78
+ () => ({
79
+ isDisabled,
80
+ isInvalid,
81
+ acceptedFiles,
82
+ onFileDelete,
83
+ openFilePicker
84
+ }),
85
+ [isDisabled, isInvalid, acceptedFiles, onFileDelete, openFilePicker]
86
+ );
87
+ return /* @__PURE__ */ jsxs(FileFieldProvider, { value: contextValue, children: [
88
+ /* @__PURE__ */ jsx(
89
+ "input",
90
+ {
91
+ accept,
92
+ "aria-describedby": describedbyId,
93
+ "aria-invalid": isInvalid,
94
+ className: "sr-only",
95
+ disabled: isDisabled,
96
+ id: id ?? generatedId,
97
+ multiple,
98
+ name,
99
+ onChange: onFilesChange,
100
+ ref: inputRef,
101
+ required: isRequired,
102
+ type: "file",
103
+ webkitdirectory: webkitDirectory ? "true" : void 0
104
+ }
105
+ ),
106
+ children
107
+ ] });
108
+ };
109
+ const Trigger = ({ renderItem }) => {
110
+ const context = useFileFieldContext();
111
+ return renderItem({
112
+ onClick: context.openFilePicker,
113
+ disabled: context.isDisabled,
114
+ invalid: context.isInvalid
115
+ });
116
+ };
117
+ const ItemList = ({ showWebkitRelativePath, clearable }) => {
118
+ const { acceptedFiles, onFileDelete } = useFileFieldContext();
119
+ if (acceptedFiles.length === 0) {
120
+ return null;
121
+ }
122
+ return /* @__PURE__ */ jsx("ul", { className: "mt-2 space-y-2", children: acceptedFiles.map((acceptedFile) => {
123
+ const { file, id } = acceptedFile;
124
+ const onDelete = () => onFileDelete(id);
125
+ const sizeInKB = (file.size / 1024).toFixed(2);
126
+ return /* @__PURE__ */ jsxs(
127
+ "li",
128
+ {
129
+ className: "flex items-center justify-between rounded-md border border-border-base bg-bg-base px-3 py-2",
130
+ children: [
131
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
132
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-fg-base text-sm", children: showWebkitRelativePath ? file.webkitRelativePath : file.name }),
133
+ /* @__PURE__ */ jsxs("span", { className: "text-fg-mute text-xs", children: [
134
+ sizeInKB,
135
+ " KB"
136
+ ] })
137
+ ] }),
138
+ clearable && /* @__PURE__ */ jsx(IconButton, { label: "\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664", onClick: onDelete, children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" }) })
139
+ ]
140
+ },
141
+ id
142
+ );
143
+ }) });
144
+ };
145
+ const FileField = {
146
+ Root,
147
+ Trigger,
148
+ ItemList
149
+ };
150
+ export {
151
+ FileField,
152
+ FileFieldProvider
153
+ };
@@ -0,0 +1,137 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Button } from "../../button";
3
+ import { FileField } from "./file-field";
4
+ const meta = {
5
+ title: "components/form/file-field",
6
+ component: FileField.Root,
7
+ args: {
8
+ id: "filefield"
9
+ },
10
+ render: (args) => {
11
+ return /* @__PURE__ */ jsxs(FileField.Root, { ...args, children: [
12
+ /* @__PURE__ */ jsx(
13
+ FileField.Trigger,
14
+ {
15
+ renderItem: ({ disabled, onClick }) => /* @__PURE__ */ jsx(Button, { disabled, onClick, children: "\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E" })
16
+ }
17
+ ),
18
+ /* @__PURE__ */ jsx(FileField.ItemList, {})
19
+ ] });
20
+ },
21
+ parameters: {
22
+ a11y: {
23
+ options: {
24
+ rules: {
25
+ // FileField単体ではラベルを付随しない
26
+ "label-title-only": { enabled: false },
27
+ label: { enabled: false }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ };
33
+ var file_field_stories_default = meta;
34
+ const Default = {
35
+ args: {
36
+ isDisabled: false,
37
+ isInvalid: false,
38
+ isRequired: false
39
+ }
40
+ };
41
+ const Multiple = {
42
+ args: {
43
+ isDisabled: false,
44
+ isInvalid: false,
45
+ isRequired: false,
46
+ multiple: true
47
+ }
48
+ };
49
+ const MaxFiles = {
50
+ args: {
51
+ isDisabled: false,
52
+ isInvalid: false,
53
+ isRequired: false,
54
+ multiple: true,
55
+ maxFiles: 3
56
+ }
57
+ };
58
+ const ImageOnly = {
59
+ args: {
60
+ isDisabled: false,
61
+ isInvalid: false,
62
+ isRequired: false,
63
+ accept: "image/*"
64
+ }
65
+ };
66
+ const WebkitDirectory = {
67
+ args: {
68
+ isDisabled: false,
69
+ isInvalid: false,
70
+ isRequired: false,
71
+ webkitDirectory: true
72
+ }
73
+ };
74
+ const HasClearButton = {
75
+ args: {
76
+ isDisabled: false,
77
+ isInvalid: false,
78
+ isRequired: false,
79
+ multiple: true
80
+ },
81
+ render: (args) => {
82
+ return /* @__PURE__ */ jsxs(FileField.Root, { ...args, children: [
83
+ /* @__PURE__ */ jsx(
84
+ FileField.Trigger,
85
+ {
86
+ renderItem: ({ disabled, onClick }) => /* @__PURE__ */ jsx(Button, { disabled, onClick, children: "\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0" })
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsx(FileField.ItemList, { clearable: true })
90
+ ] });
91
+ }
92
+ };
93
+ const ShowWebkitRelativePath = {
94
+ args: {
95
+ isDisabled: false,
96
+ isInvalid: false,
97
+ isRequired: false,
98
+ webkitDirectory: true
99
+ },
100
+ render: (args) => {
101
+ return /* @__PURE__ */ jsxs(FileField.Root, { ...args, children: [
102
+ /* @__PURE__ */ jsx(
103
+ FileField.Trigger,
104
+ {
105
+ renderItem: ({ disabled, onClick }) => /* @__PURE__ */ jsx(Button, { disabled, onClick, variant: "outlined", children: "\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E" })
106
+ }
107
+ ),
108
+ /* @__PURE__ */ jsx(FileField.ItemList, { showWebkitRelativePath: true })
109
+ ] });
110
+ }
111
+ };
112
+ const OnlyTrigger = {
113
+ args: {
114
+ isDisabled: false,
115
+ isInvalid: false,
116
+ isRequired: false
117
+ },
118
+ render: (args) => {
119
+ return /* @__PURE__ */ jsx(FileField.Root, { ...args, children: /* @__PURE__ */ jsx(
120
+ FileField.Trigger,
121
+ {
122
+ renderItem: ({ disabled, onClick }) => /* @__PURE__ */ jsx(Button, { disabled, onClick, variant: "outlined", children: "\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E" })
123
+ }
124
+ ) });
125
+ }
126
+ };
127
+ export {
128
+ Default,
129
+ HasClearButton,
130
+ ImageOnly,
131
+ MaxFiles,
132
+ Multiple,
133
+ OnlyTrigger,
134
+ ShowWebkitRelativePath,
135
+ WebkitDirectory,
136
+ file_field_stories_default as default
137
+ };
@@ -0,0 +1 @@
1
+ export * from './file-field';
@@ -0,0 +1 @@
1
+ export * from "./file-field";
@@ -12,6 +12,7 @@ export * from './dropdown-menu';
12
12
  export * from './error-boundary';
13
13
  export * from './form/autocomplete';
14
14
  export * from './form/checkbox';
15
+ export * from './form/file-field';
15
16
  export * from './form/form-control';
16
17
  export * from './form/number-field';
17
18
  export * from './form/radio';
@@ -12,6 +12,7 @@ export * from "./dropdown-menu";
12
12
  export * from "./error-boundary";
13
13
  export * from "./form/autocomplete";
14
14
  export * from "./form/checkbox";
15
+ export * from "./form/file-field";
15
16
  export * from "./form/form-control";
16
17
  export * from "./form/number-field";
17
18
  export * from "./form/radio";
@@ -13,8 +13,8 @@ type MenuContext = {
13
13
  getContentProps: (userProps?: HTMLProps<HTMLElement>) => Record<string, unknown>;
14
14
  getItemProps: (userProps?: Omit<HTMLProps<HTMLElement>, 'selected' | 'active'>) => Record<string, unknown>;
15
15
  };
16
- declare const MenuContext: React.Context<MenuContext | null>;
17
- export declare const MenuContextProvider: React.Context<MenuContext | null>;
16
+ declare const MenuContext: import("react").Context<MenuContext | null>;
17
+ export declare const MenuContextProvider: import("react").Context<MenuContext | null>;
18
18
  export declare const useMenuContent: () => {
19
19
  options: Option[];
20
20
  selectedIndex: number | null;
@@ -87,7 +87,8 @@ const Modal = ({ ref, type = "center", defaultOpen, isOpen, onClose, children })
87
87
  realDialogOpen,
88
88
  realRef.current?.close,
89
89
  realRef.current?.open,
90
- realRef.current?.showModal
90
+ realRef.current?.showModal,
91
+ realRef.current
91
92
  ]);
92
93
  return /* @__PURE__ */ jsx(
93
94
  motion.dialog,
@@ -14,8 +14,8 @@ type PopoverContext = {
14
14
  setContentRef: (node: HTMLElement | null) => void;
15
15
  contentStyles: CSSProperties;
16
16
  };
17
- declare const PopoverContext: React.Context<PopoverContext | null>;
18
- export declare const PopoverProvider: React.Context<PopoverContext | null>;
17
+ declare const PopoverContext: import("react").Context<PopoverContext | null>;
18
+ export declare const PopoverProvider: import("react").Context<PopoverContext | null>;
19
19
  export declare const useFloatingUIContext: () => FloatingContext;
20
20
  export declare const usePlacement: () => Placement;
21
21
  export declare const useOpenContext: () => {
@@ -8,6 +8,6 @@ export declare const Tooltip: {
8
8
  renderItem: (props: Record<string, unknown>) => ReactElement;
9
9
  }>;
10
10
  readonly Content: FC<{
11
- children?: React.ReactNode | undefined;
11
+ children?: import("react").ReactNode | undefined;
12
12
  }>;
13
13
  };
@@ -79,7 +79,8 @@ function findAllColors(text) {
79
79
  while (index !== -1) {
80
80
  const beforeChar = index > 0 ? lowerText[index - 1] ?? " " : " ";
81
81
  const afterChar = index + color.length < lowerText.length ? lowerText[index + color.length] ?? " " : " ";
82
- if (/\s|;|,|:/.test(beforeChar) && /\s|;|,|$|\)|]|}/.test(afterChar)) {
82
+ const isWordBoundary = !(/[a-zA-Z0-9]/.test(beforeChar) || /[a-zA-Z0-9]/.test(afterChar));
83
+ if (isWordBoundary) {
83
84
  results.push({
84
85
  color,
85
86
  start: index,
@@ -202,6 +203,18 @@ if (import.meta.vitest) {
202
203
  const result = findAllColors("red");
203
204
  expect(result).toEqual([{ color: "red", start: 0, end: 3 }]);
204
205
  });
206
+ it("\u4ED6\u306E\u5358\u8A9E\u306E\u4E00\u90E8\u3068\u3057\u3066\u542B\u307E\u308C\u308B\u8272\u540D\u3092\u691C\u51FA\u3057\u306A\u3044", () => {
207
+ const result = findAllColors("reduce");
208
+ expect(result).toEqual([]);
209
+ });
210
+ it("\u4ED6\u306E\u5358\u8A9E\u306E\u4E00\u90E8\u3068\u3057\u3066\u542B\u307E\u308C\u308B\u8272\u540D\u3092\u691C\u51FA\u3057\u306A\u3044\uFF08\u8907\u6570\u30D1\u30BF\u30FC\u30F3\uFF09", () => {
211
+ const result = findAllColors("blueberry, greenfield, redirection");
212
+ expect(result).toEqual([]);
213
+ });
214
+ it("\u5358\u8A9E\u306E\u4E00\u90E8\u3067\u306A\u3044\u8272\u540D\u306E\u307F\u3092\u691C\u51FA\u3059\u308B", () => {
215
+ const result = findAllColors("reduce color: red; blueberry");
216
+ expect(result).toEqual([{ color: "red", start: 14, end: 17 }]);
217
+ });
205
218
  });
206
219
  });
207
220
  }
@@ -1,5 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { fireEvent, render } from "@testing-library/react";
2
+ import { userEvent } from "vitest/browser";
3
+ import { render } from "vitest-browser-react";
3
4
  import { useClickAway } from ".";
4
5
  const OutsideClicker = ({ callback }) => {
5
6
  const ref = useClickAway(callback);
@@ -9,23 +10,17 @@ const OutsideClicker = ({ callback }) => {
9
10
  ] });
10
11
  };
11
12
  describe("useClickAway", () => {
12
- it("\u9818\u57DF\u5916\u3092\u89E6\u308B\u3068callback\u304C\u547C\u3073\u51FA\u3055\u308C\u308B", () => {
13
+ it("\u9818\u57DF\u5916\u3092\u89E6\u308B\u3068callback\u304C\u547C\u3073\u51FA\u3055\u308C\u308B", async () => {
13
14
  const fn = vi.fn();
14
- const { getByText } = render(/* @__PURE__ */ jsx(OutsideClicker, { callback: fn }));
15
+ const { getByText } = await render(/* @__PURE__ */ jsx(OutsideClicker, { callback: fn }));
15
16
  const element = getByText("Element");
16
17
  const outsideElement = getByText("Outside");
17
- const click = (el) => {
18
- fireEvent.mouseDown(el);
19
- fireEvent.mouseUp(el);
20
- };
21
18
  expect(fn).not.toHaveBeenCalled();
22
- click(element);
19
+ await userEvent.click(element);
23
20
  expect(fn).not.toHaveBeenCalled();
24
- click(outsideElement);
21
+ await userEvent.click(outsideElement);
25
22
  expect(fn).toHaveBeenCalledOnce();
26
- click(document.body);
23
+ await userEvent.click(document.body);
27
24
  expect(fn).toHaveBeenCalledTimes(2);
28
- click(document);
29
- expect(fn).toHaveBeenCalledTimes(3);
30
25
  });
31
26
  });
@@ -1,4 +1,4 @@
1
- import { act, renderHook } from "@testing-library/react";
1
+ import { renderHook } from "vitest-browser-react";
2
2
  import { useClipboard } from ".";
3
3
  describe("useClipboard", () => {
4
4
  afterEach(() => {
@@ -12,10 +12,8 @@ describe("useClipboard", () => {
12
12
  writeText: writeTextMockFn
13
13
  }
14
14
  });
15
- const { result } = renderHook(() => useClipboard());
16
- await act(async () => {
17
- await result.current.writeClipboard(writeText);
18
- });
15
+ const { result } = await renderHook(() => useClipboard());
16
+ await result.current.writeClipboard(writeText);
19
17
  expect(writeTextMockFn).toBeCalledWith(writeText);
20
18
  expect(navigator.clipboard.writeText).toHaveBeenCalledOnce();
21
19
  });
@@ -26,10 +24,8 @@ describe("useClipboard", () => {
26
24
  readText: readTextMockFn
27
25
  }
28
26
  });
29
- const { result } = renderHook(() => useClipboard());
30
- await act(async () => {
31
- await result.current.readClipboard();
32
- });
27
+ const { result } = await renderHook(() => useClipboard());
28
+ await result.current.readClipboard();
33
29
  expect(readTextMockFn).toHaveBeenCalledOnce();
34
30
  });
35
31
  });
@@ -1,5 +1,4 @@
1
- import { renderHook, waitFor } from "@testing-library/react";
2
- import { act } from "react";
1
+ import { renderHook } from "vitest-browser-react";
3
2
  import { useHash } from ".";
4
3
  vi.mock("../client", () => ({
5
4
  useClient: () => true
@@ -13,33 +12,33 @@ describe("useHash", () => {
13
12
  vi.unstubAllGlobals();
14
13
  window.location.hash = realHash;
15
14
  });
16
- it("\u73FE\u5728\u306Ehash\u5024\u3092\u53D6\u5F97\u3067\u304D\u308B", () => {
17
- const { result } = renderHook(() => useHash());
15
+ it("\u73FE\u5728\u306Ehash\u5024\u3092\u53D6\u5F97\u3067\u304D\u308B", async () => {
16
+ const { result } = await renderHook(() => useHash());
18
17
  expect(result.current).toBe("test");
19
18
  });
20
- it("hash\u5024\u304C\u5909\u66F4\u3055\u308C\u305F\u3068\u304D\u306B\u66F4\u65B0\u3055\u308C\u308B", () => {
21
- const { result } = renderHook(() => useHash());
22
- window.location.hash = "#changed";
19
+ it("hash\u5024\u304C\u5909\u66F4\u3055\u308C\u305F\u3068\u304D\u306B\u66F4\u65B0\u3055\u308C\u308B", async () => {
20
+ const { result, act } = await renderHook(() => useHash());
23
21
  act(() => {
22
+ window.location.hash = "#changed";
24
23
  window.dispatchEvent(new Event("hashchange"));
25
24
  });
26
25
  expect(result.current).toBe("changed");
27
26
  });
28
27
  it("pushState\u3067hash\u5024\u304C\u5909\u66F4\u3055\u308C\u305F\u3068\u304D\u306B\u66F4\u65B0\u3055\u308C\u308B", async () => {
29
- const { result } = renderHook(() => useHash());
28
+ const { result, act } = await renderHook(() => useHash());
30
29
  act(() => {
31
30
  window.history.pushState({}, "", "/#pushed");
32
31
  });
33
- await waitFor(() => {
32
+ await vi.waitFor(() => {
34
33
  expect(result.current).toBe("pushed");
35
34
  });
36
35
  });
37
36
  it("replaceState\u3067hash\u5024\u304C\u5909\u66F4\u3055\u308C\u305F\u3068\u304D\u306B\u66F4\u65B0\u3055\u308C\u308B", async () => {
38
- const { result } = renderHook(() => useHash());
37
+ const { result, act } = await renderHook(() => useHash());
39
38
  act(() => {
40
39
  window.history.replaceState({}, "", "/#replaced");
41
40
  });
42
- await waitFor(() => {
41
+ await vi.waitFor(() => {
43
42
  expect(result.current).toBe("replaced");
44
43
  });
45
44
  });
@@ -1,28 +1,28 @@
1
- import { renderHook } from "@testing-library/react";
1
+ import { renderHook } from "vitest-browser-react";
2
2
  import { useInterval } from ".";
3
3
  describe("useInterval", () => {
4
- it("\u6307\u5B9A\u6642\u9593\u3054\u3068\u306B\u5B9F\u884C\u3055\u308C\u308B", () => {
4
+ it("\u6307\u5B9A\u6642\u9593\u3054\u3068\u306B\u5B9F\u884C\u3055\u308C\u308B", async () => {
5
5
  const fn = vi.fn();
6
6
  vi.useFakeTimers();
7
- renderHook(() => {
7
+ await renderHook(() => {
8
8
  useInterval(fn, 1e3);
9
9
  });
10
10
  vi.advanceTimersByTime(2e3);
11
11
  expect(fn).toHaveBeenCalledTimes(2);
12
12
  });
13
- it("\u6307\u5B9A\u6642\u9593\u3092\u904E\u304E\u306A\u3044\u3068\u5B9F\u884C\u3055\u308C\u306A\u3044", () => {
13
+ it("\u6307\u5B9A\u6642\u9593\u3092\u904E\u304E\u306A\u3044\u3068\u5B9F\u884C\u3055\u308C\u306A\u3044", async () => {
14
14
  const fn = vi.fn();
15
15
  vi.useFakeTimers();
16
- renderHook(() => {
16
+ await renderHook(() => {
17
17
  useInterval(fn, 1e3);
18
18
  });
19
19
  vi.advanceTimersByTime(10);
20
20
  expect(fn).not.toHaveBeenCalled();
21
21
  });
22
- it("\u30A2\u30F3\u30DE\u30A6\u30F3\u30C8\u5F8C\u306F\u5B9F\u884C\u3055\u308C\u306A\u3044", () => {
22
+ it("\u30A2\u30F3\u30DE\u30A6\u30F3\u30C8\u5F8C\u306F\u5B9F\u884C\u3055\u308C\u306A\u3044", async () => {
23
23
  const fn = vi.fn();
24
24
  vi.useFakeTimers();
25
- const { unmount } = renderHook(() => {
25
+ const { unmount } = await renderHook(() => {
26
26
  useInterval(fn, 1e3);
27
27
  });
28
28
  unmount();
@@ -1,4 +1,4 @@
1
- import { act, renderHook } from "@testing-library/react";
1
+ import { renderHook } from "vitest-browser-react";
2
2
  import { useLocalStorage } from "./index";
3
3
  const consoleErrorMock = vi.spyOn(console, "error").mockImplementation(() => void 0);
4
4
  describe("useLocalStorage", () => {
@@ -9,34 +9,42 @@ describe("useLocalStorage", () => {
9
9
  afterAll(() => {
10
10
  consoleErrorMock.mockReset();
11
11
  });
12
- it("localStorage\u306B\u5024\u304C\u306A\u3051\u308C\u3070\u521D\u671F\u5024\u3092\u8FD4\u3059", () => {
13
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
12
+ it("localStorage\u306B\u5024\u304C\u306A\u3051\u308C\u3070\u521D\u671F\u5024\u3092\u8FD4\u3059", async () => {
13
+ const { result } = await renderHook(
14
+ () => useLocalStorage(key, "defaultValue")
15
+ );
14
16
  expect(result.current[0]).toBe("defaultValue");
15
17
  });
16
- it("localStorage\u306B\u5024\u304C\u5B58\u5728\u3042\u308C\u3070\u305D\u306E\u5024\u3092\u8FD4\u3059", () => {
18
+ it("localStorage\u306B\u5024\u304C\u5B58\u5728\u3042\u308C\u3070\u305D\u306E\u5024\u3092\u8FD4\u3059", async () => {
17
19
  localStorage.setItem(key, JSON.stringify("storedValue"));
18
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
20
+ const { result } = await renderHook(
21
+ () => useLocalStorage(key, "defaultValue")
22
+ );
19
23
  expect(result.current[0]).toBe("storedValue");
20
24
  });
21
- it("\u66F4\u65B0\u51E6\u7406\u3067\u306FlocalStorage\u3068state\u306E\u4E21\u65B9\u3092\u66F4\u65B0\u3059\u308B", () => {
22
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
25
+ it("\u66F4\u65B0\u51E6\u7406\u3067\u306FlocalStorage\u3068state\u306E\u4E21\u65B9\u3092\u66F4\u65B0\u3059\u308B", async () => {
26
+ const { result, act } = await renderHook(
27
+ () => useLocalStorage(key, "defaultValue")
28
+ );
23
29
  act(() => {
24
30
  result.current[1]("newValue");
25
31
  });
26
32
  expect(localStorage.getItem(key)).toBe(JSON.stringify("newValue"));
27
33
  expect(result.current[0]).toBe("newValue");
28
34
  });
29
- it("\u524A\u9664\u51E6\u7406\u3067\u306FlocalStorage\u306F\u5024\u3092\u524A\u9664\u3055\u308C\u3001state\u306F\u521D\u671F\u5024\u306B\u306A\u308B", () => {
35
+ it("\u524A\u9664\u51E6\u7406\u3067\u306FlocalStorage\u306F\u5024\u3092\u524A\u9664\u3055\u308C\u3001state\u306F\u521D\u671F\u5024\u306B\u306A\u308B", async () => {
30
36
  localStorage.setItem(key, JSON.stringify("storedValue"));
31
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
37
+ const { result, act } = await renderHook(
38
+ () => useLocalStorage(key, "defaultValue")
39
+ );
32
40
  act(() => {
33
41
  result.current[2]();
34
42
  });
35
43
  expect(localStorage.getItem(key)).toBeNull();
36
44
  expect(result.current[0]).toBe("defaultValue");
37
45
  });
38
- it("null\u3067\u66F4\u65B0\u3057\u305F\u5834\u5408\u306Fremove\u3068\u540C\u3058\u7D50\u679C\u306B\u306A\u308B", () => {
39
- const { result } = renderHook(
46
+ it("null\u3067\u66F4\u65B0\u3057\u305F\u5834\u5408\u306Fremove\u3068\u540C\u3058\u7D50\u679C\u306B\u306A\u308B", async () => {
47
+ const { result, act } = await renderHook(
40
48
  () => useLocalStorage(key, {
41
49
  lang: ["ja", "en"]
42
50
  })
@@ -47,8 +55,10 @@ describe("useLocalStorage", () => {
47
55
  expect(localStorage.getItem(key)).toBeNull();
48
56
  expect(result.current[0]).toEqual({ lang: ["ja", "en"] });
49
57
  });
50
- it("storage\u30A4\u30D9\u30F3\u30C8\u306E\u767A\u706B\u306B\u5FDC\u3058\u3066\u72B6state\u304C\u66F4\u65B0\u3055\u308C\u308B", () => {
51
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
58
+ it("storage\u30A4\u30D9\u30F3\u30C8\u306E\u767A\u706B\u306B\u5FDC\u3058\u3066\u72B6state\u304C\u66F4\u65B0\u3055\u308C\u308B", async () => {
59
+ const { result, act } = await renderHook(
60
+ () => useLocalStorage(key, "defaultValue")
61
+ );
52
62
  act(() => {
53
63
  localStorage.setItem(key, JSON.stringify("updatedValue"));
54
64
  window.dispatchEvent(
@@ -60,8 +70,10 @@ describe("useLocalStorage", () => {
60
70
  });
61
71
  expect(result.current[0]).toBe("updatedValue");
62
72
  });
63
- it("\u7570\u306A\u308B\u30AD\u30FC\u306Estorage\u30A4\u30D9\u30F3\u30C8\u306Fstate\u3092\u66F4\u65B0\u3057\u306A\u3044", () => {
64
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
73
+ it("\u7570\u306A\u308B\u30AD\u30FC\u306Estorage\u30A4\u30D9\u30F3\u30C8\u306Fstate\u3092\u66F4\u65B0\u3057\u306A\u3044", async () => {
74
+ const { result, act } = await renderHook(
75
+ () => useLocalStorage(key, "defaultValue")
76
+ );
65
77
  act(() => {
66
78
  localStorage.setItem("otherKey", JSON.stringify("otherValue"));
67
79
  window.dispatchEvent(
@@ -73,9 +85,11 @@ describe("useLocalStorage", () => {
73
85
  });
74
86
  expect(result.current[0]).toBe("defaultValue");
75
87
  });
76
- it("JSON\u3092\u30D1\u30FC\u30B9\u3067\u304D\u306A\u3044\u6642\u306F\u30A8\u30E9\u30FC\u3092\u5410\u3044\u3066\u521D\u671F\u5024\u3092\u8FD4\u3059", () => {
88
+ it("JSON\u3092\u30D1\u30FC\u30B9\u3067\u304D\u306A\u3044\u6642\u306F\u30A8\u30E9\u30FC\u3092\u5410\u3044\u3066\u521D\u671F\u5024\u3092\u8FD4\u3059", async () => {
77
89
  localStorage.setItem(key, "{invalidJSON");
78
- const { result } = renderHook(() => useLocalStorage(key, "defaultValue"));
90
+ const { result } = await renderHook(
91
+ () => useLocalStorage(key, "defaultValue")
92
+ );
79
93
  expect(result.current[0]).toBe("defaultValue");
80
94
  expect(consoleErrorMock).toHaveBeenCalledOnce();
81
95
  });
@@ -1,4 +1,4 @@
1
- import { act, renderHook } from "@testing-library/react";
1
+ import { renderHook } from "vitest-browser-react";
2
2
  import { useScrollDirection } from ".";
3
3
  describe("useScrollDirection", () => {
4
4
  beforeEach(() => {
@@ -11,29 +11,29 @@ describe("useScrollDirection", () => {
11
11
  value: 0
12
12
  });
13
13
  });
14
- it("\u521D\u671F\u72B6\u614B\u3067\u306Fx: right, y: up\u3092\u8FD4\u3059", () => {
15
- const { result } = renderHook(() => useScrollDirection());
14
+ it("\u521D\u671F\u72B6\u614B\u3067\u306Fx: right, y: up\u3092\u8FD4\u3059", async () => {
15
+ const { result } = await renderHook(() => useScrollDirection());
16
16
  expect(result.current).toEqual({ x: "right", y: "up" });
17
17
  });
18
18
  describe("Vertical scroll", () => {
19
- it("100px\u4EE5\u4E0A\u4E0B\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068y: down\u3092\u8FD4\u3059", () => {
20
- const { result } = renderHook(() => useScrollDirection());
19
+ it("100px\u4EE5\u4E0A\u4E0B\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068y: down\u3092\u8FD4\u3059", async () => {
20
+ const { result, act } = await renderHook(() => useScrollDirection());
21
21
  act(() => {
22
22
  Object.defineProperty(window, "scrollY", { value: 150 });
23
23
  window.dispatchEvent(new Event("scroll"));
24
24
  });
25
25
  expect(result.current.y).toBe("down");
26
26
  });
27
- it("100px\u672A\u6E80\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306Fy: up\u306E\u307E\u307E", () => {
28
- const { result } = renderHook(() => useScrollDirection());
27
+ it("100px\u672A\u6E80\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306Fy: up\u306E\u307E\u307E", async () => {
28
+ const { result, act } = await renderHook(() => useScrollDirection());
29
29
  act(() => {
30
30
  Object.defineProperty(window, "scrollY", { value: 50 });
31
31
  window.dispatchEvent(new Event("scroll"));
32
32
  });
33
33
  expect(result.current.y).toBe("up");
34
34
  });
35
- it("\u4E0A\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068y: up\u3092\u8FD4\u3059", () => {
36
- const { result } = renderHook(() => useScrollDirection());
35
+ it("\u4E0A\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068y: up\u3092\u8FD4\u3059", async () => {
36
+ const { result, act } = await renderHook(() => useScrollDirection());
37
37
  act(() => {
38
38
  Object.defineProperty(window, "scrollY", { value: 200 });
39
39
  window.dispatchEvent(new Event("scroll"));
@@ -47,24 +47,24 @@ describe("useScrollDirection", () => {
47
47
  });
48
48
  });
49
49
  describe("Horizontal scroll", () => {
50
- it("100px\u4EE5\u4E0A\u53F3\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068x: right\u3092\u8FD4\u3059", () => {
51
- const { result } = renderHook(() => useScrollDirection());
50
+ it("100px\u4EE5\u4E0A\u53F3\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068x: right\u3092\u8FD4\u3059", async () => {
51
+ const { result, act } = await renderHook(() => useScrollDirection());
52
52
  act(() => {
53
53
  Object.defineProperty(window, "scrollX", { value: 150 });
54
54
  window.dispatchEvent(new Event("scroll"));
55
55
  });
56
56
  expect(result.current.x).toBe("right");
57
57
  });
58
- it("100px\u672A\u6E80\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306Fx: right\u306E\u307E\u307E", () => {
59
- const { result } = renderHook(() => useScrollDirection());
58
+ it("100px\u672A\u6E80\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306Fx: right\u306E\u307E\u307E", async () => {
59
+ const { result, act } = await renderHook(() => useScrollDirection());
60
60
  act(() => {
61
61
  Object.defineProperty(window, "scrollX", { value: 50 });
62
62
  window.dispatchEvent(new Event("scroll"));
63
63
  });
64
64
  expect(result.current.x).toBe("right");
65
65
  });
66
- it("\u5DE6\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068x: left\u3092\u8FD4\u3059", () => {
67
- const { result } = renderHook(() => useScrollDirection());
66
+ it("\u5DE6\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3059\u308B\u3068x: left\u3092\u8FD4\u3059", async () => {
67
+ const { result, act } = await renderHook(() => useScrollDirection());
68
68
  act(() => {
69
69
  Object.defineProperty(window, "scrollX", { value: 200 });
70
70
  window.dispatchEvent(new Event("scroll"));
@@ -78,8 +78,8 @@ describe("useScrollDirection", () => {
78
78
  });
79
79
  });
80
80
  describe("Combined scroll", () => {
81
- it("\u7E26\u6A2A\u540C\u6642\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3057\u305F\u5834\u5408\u3001\u4E21\u65B9\u5411\u3092\u6B63\u3057\u304F\u691C\u77E5\u3059\u308B", () => {
82
- const { result } = renderHook(() => useScrollDirection());
81
+ it("\u7E26\u6A2A\u540C\u6642\u306B\u30B9\u30AF\u30ED\u30FC\u30EB\u3057\u305F\u5834\u5408\u3001\u4E21\u65B9\u5411\u3092\u6B63\u3057\u304F\u691C\u77E5\u3059\u308B", async () => {
82
+ const { result, act } = await renderHook(() => useScrollDirection());
83
83
  act(() => {
84
84
  Object.defineProperty(window, "scrollY", { value: 150 });
85
85
  Object.defineProperty(window, "scrollX", { value: 150 });
@@ -88,18 +88,18 @@ describe("useScrollDirection", () => {
88
88
  expect(result.current).toEqual({ x: "right", y: "down" });
89
89
  });
90
90
  });
91
- it("\u30A2\u30F3\u30DE\u30A6\u30F3\u30C8\u5F8C\u306F\u30A4\u30D9\u30F3\u30C8\u30EA\u30B9\u30CA\u30FC\u304C\u524A\u9664\u3055\u308C\u308B", () => {
91
+ it("\u30A2\u30F3\u30DE\u30A6\u30F3\u30C8\u5F8C\u306F\u30A4\u30D9\u30F3\u30C8\u30EA\u30B9\u30CA\u30FC\u304C\u524A\u9664\u3055\u308C\u308B", async () => {
92
92
  const removeEventListenerSpy = vi.spyOn(window, "removeEventListener");
93
- const { unmount } = renderHook(() => useScrollDirection());
93
+ const { unmount } = await renderHook(() => useScrollDirection());
94
94
  unmount();
95
95
  expect(removeEventListenerSpy).toHaveBeenCalledWith(
96
96
  "scroll",
97
97
  expect.any(Function)
98
98
  );
99
99
  });
100
- it("\u30B9\u30AF\u30ED\u30FC\u30EB\u30A4\u30D9\u30F3\u30C8\u304Cpassive: true\u3067\u767B\u9332\u3055\u308C\u308B", () => {
100
+ it("\u30B9\u30AF\u30ED\u30FC\u30EB\u30A4\u30D9\u30F3\u30C8\u304Cpassive: true\u3067\u767B\u9332\u3055\u308C\u308B", async () => {
101
101
  const addEventListenerSpy = vi.spyOn(window, "addEventListener");
102
- renderHook(() => useScrollDirection());
102
+ await renderHook(() => useScrollDirection());
103
103
  expect(addEventListenerSpy).toHaveBeenCalledWith(
104
104
  "scroll",
105
105
  expect.any(Function),
@@ -107,8 +107,8 @@ describe("useScrollDirection", () => {
107
107
  );
108
108
  });
109
109
  describe("Threshold parameter", () => {
110
- it("threshold\u304C100\u306E\u5834\u5408\u3001100px\u4EE5\u4E0B\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306F\u65B9\u5411\u304C\u5909\u308F\u3089\u306A\u3044", () => {
111
- const { result } = renderHook(() => useScrollDirection(100));
110
+ it("threshold\u304C100\u306E\u5834\u5408\u3001100px\u4EE5\u4E0B\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306F\u65B9\u5411\u304C\u5909\u308F\u3089\u306A\u3044", async () => {
111
+ const { result, act } = await renderHook(() => useScrollDirection(100));
112
112
  act(() => {
113
113
  Object.defineProperty(window, "scrollY", { value: 100 });
114
114
  window.dispatchEvent(new Event("scroll"));
@@ -120,8 +120,8 @@ describe("useScrollDirection", () => {
120
120
  });
121
121
  expect(result.current.x).toBe("right");
122
122
  });
123
- it("threshold\u304C100\u306E\u5834\u5408\u3001101px\u4EE5\u4E0A\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u65B9\u5411\u304C\u5909\u308F\u308B", () => {
124
- const { result } = renderHook(() => useScrollDirection(100));
123
+ it("threshold\u304C100\u306E\u5834\u5408\u3001101px\u4EE5\u4E0A\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u65B9\u5411\u304C\u5909\u308F\u308B", async () => {
124
+ const { result, act } = await renderHook(() => useScrollDirection(100));
125
125
  act(() => {
126
126
  Object.defineProperty(window, "scrollY", { value: 101 });
127
127
  window.dispatchEvent(new Event("scroll"));
@@ -133,32 +133,32 @@ describe("useScrollDirection", () => {
133
133
  });
134
134
  expect(result.current.x).toBe("right");
135
135
  });
136
- it("threshold\u304C10\u306E\u5834\u5408\u300110px\u4EE5\u4E0B\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306F\u65B9\u5411\u304C\u5909\u308F\u3089\u306A\u3044", () => {
137
- const { result } = renderHook(() => useScrollDirection(10));
136
+ it("threshold\u304C10\u306E\u5834\u5408\u300110px\u4EE5\u4E0B\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u306F\u65B9\u5411\u304C\u5909\u308F\u3089\u306A\u3044", async () => {
137
+ const { result, act } = await renderHook(() => useScrollDirection(10));
138
138
  act(() => {
139
139
  Object.defineProperty(window, "scrollY", { value: 10 });
140
140
  window.dispatchEvent(new Event("scroll"));
141
141
  });
142
142
  expect(result.current.y).toBe("up");
143
143
  });
144
- it("threshold\u304C10\u306E\u5834\u5408\u300111px\u4EE5\u4E0A\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u65B9\u5411\u304C\u5909\u308F\u308B", () => {
145
- const { result } = renderHook(() => useScrollDirection(10));
144
+ it("threshold\u304C10\u306E\u5834\u5408\u300111px\u4EE5\u4E0A\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u65B9\u5411\u304C\u5909\u308F\u308B", async () => {
145
+ const { result, act } = await renderHook(() => useScrollDirection(10));
146
146
  act(() => {
147
147
  Object.defineProperty(window, "scrollY", { value: 11 });
148
148
  window.dispatchEvent(new Event("scroll"));
149
149
  });
150
150
  expect(result.current.y).toBe("down");
151
151
  });
152
- it("threshold\u304C0\u306E\u5834\u5408\u30011px\u4EE5\u4E0A\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u65B9\u5411\u304C\u5909\u308F\u308B", () => {
153
- const { result } = renderHook(() => useScrollDirection(0));
152
+ it("threshold\u304C0\u306E\u5834\u5408\u30011px\u4EE5\u4E0A\u306E\u30B9\u30AF\u30ED\u30FC\u30EB\u3067\u65B9\u5411\u304C\u5909\u308F\u308B", async () => {
153
+ const { result, act } = await renderHook(() => useScrollDirection(0));
154
154
  act(() => {
155
155
  Object.defineProperty(window, "scrollY", { value: 1 });
156
156
  window.dispatchEvent(new Event("scroll"));
157
157
  });
158
158
  expect(result.current.y).toBe("down");
159
159
  });
160
- it("\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\uFF08threshold\u672A\u6307\u5B9A\uFF09\u3067\u306F50px\u306E\u95BE\u5024\u304C\u9069\u7528\u3055\u308C\u308B", () => {
161
- const { result } = renderHook(() => useScrollDirection());
160
+ it("\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\uFF08threshold\u672A\u6307\u5B9A\uFF09\u3067\u306F50px\u306E\u95BE\u5024\u304C\u9069\u7528\u3055\u308C\u308B", async () => {
161
+ const { result, act } = await renderHook(() => useScrollDirection());
162
162
  act(() => {
163
163
  Object.defineProperty(window, "scrollY", { value: 50 });
164
164
  window.dispatchEvent(new Event("scroll"));
@@ -1,19 +1,23 @@
1
- import { act, renderHook } from "@testing-library/react";
2
- import { userEvent } from "@vitest/browser/context";
1
+ import { userEvent } from "vitest/browser";
2
+ import { renderHook } from "vitest-browser-react";
3
3
  import { useStep } from ".";
4
4
  describe("useStep", () => {
5
- it("\u521D\u671F\u72B6\u614B", () => {
5
+ it("\u521D\u671F\u72B6\u614B", async () => {
6
6
  const initialCount = 1;
7
7
  const maxCount = 10;
8
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
8
+ const { result } = await renderHook(
9
+ () => useStep({ initialCount, maxCount })
10
+ );
9
11
  expect(result.current.count).toBe(initialCount);
10
12
  expect(result.current.isDisabledBack).toBeTruthy();
11
13
  expect(result.current.isDisabledNext).toBeFalsy();
12
14
  });
13
- it("next\u3067initialCount\u304B\u30891\u9032\u3080", () => {
15
+ it("next\u3067initialCount\u304B\u30891\u9032\u3080", async () => {
14
16
  const initialCount = 1;
15
17
  const maxCount = 10;
16
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
18
+ const { result, act } = await renderHook(
19
+ () => useStep({ initialCount, maxCount })
20
+ );
17
21
  act(() => {
18
22
  result.current.next();
19
23
  });
@@ -21,10 +25,12 @@ describe("useStep", () => {
21
25
  expect(result.current.isDisabledBack).toBeFalsy();
22
26
  expect(result.current.isDisabledNext).toBeFalsy();
23
27
  });
24
- it("initialCount\u304B\u3089\u306Fback\u3067\u304D\u306A\u3044", () => {
28
+ it("initialCount\u304B\u3089\u306Fback\u3067\u304D\u306A\u3044", async () => {
25
29
  const initialCount = 1;
26
30
  const maxCount = 10;
27
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
31
+ const { result, act } = await renderHook(
32
+ () => useStep({ initialCount, maxCount })
33
+ );
28
34
  act(() => {
29
35
  result.current.back();
30
36
  });
@@ -32,10 +38,12 @@ describe("useStep", () => {
32
38
  expect(result.current.isDisabledBack).toBeTruthy();
33
39
  expect(result.current.isDisabledNext).toBeFalsy();
34
40
  });
35
- it("maxCount\u307E\u3067\u9032\u3080", () => {
41
+ it("maxCount\u307E\u3067\u9032\u3080", async () => {
36
42
  const initialCount = 1;
37
43
  const maxCount = 3;
38
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
44
+ const { result, act } = await renderHook(
45
+ () => useStep({ initialCount, maxCount })
46
+ );
39
47
  act(() => {
40
48
  result.current.next();
41
49
  result.current.next();
@@ -44,10 +52,12 @@ describe("useStep", () => {
44
52
  expect(result.current.isDisabledBack).toBeFalsy();
45
53
  expect(result.current.isDisabledNext).toBeTruthy();
46
54
  });
47
- it("maxCount\u4EE5\u4E0A\u306F\u9032\u3081\u306A\u3044", () => {
55
+ it("maxCount\u4EE5\u4E0A\u306F\u9032\u3081\u306A\u3044", async () => {
48
56
  const initialCount = 1;
49
57
  const maxCount = 3;
50
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
58
+ const { result, act } = await renderHook(
59
+ () => useStep({ initialCount, maxCount })
60
+ );
51
61
  act(() => {
52
62
  result.current.next();
53
63
  result.current.next();
@@ -57,10 +67,12 @@ describe("useStep", () => {
57
67
  expect(result.current.isDisabledBack).toBeFalsy();
58
68
  expect(result.current.isDisabledNext).toBeTruthy();
59
69
  });
60
- it("next\u3068back\u3092\u7D44\u307F\u5408\u308F\u305B\u3066\u5229\u7528\u3067\u304D\u308B", () => {
70
+ it("next\u3068back\u3092\u7D44\u307F\u5408\u308F\u305B\u3066\u5229\u7528\u3067\u304D\u308B", async () => {
61
71
  const initialCount = 1;
62
72
  const maxCount = 3;
63
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
73
+ const { result, act } = await renderHook(
74
+ () => useStep({ initialCount, maxCount })
75
+ );
64
76
  act(() => {
65
77
  result.current.next();
66
78
  result.current.back();
@@ -72,14 +84,12 @@ describe("useStep", () => {
72
84
  it("\u5DE6\u53F3\u30AD\u30FC\u3067\u64CD\u4F5C\u3067\u304D\u308B", async () => {
73
85
  const initialCount = 1;
74
86
  const maxCount = 3;
75
- const { result } = renderHook(() => useStep({ initialCount, maxCount }));
76
- await act(async () => {
77
- await userEvent.keyboard("{arrowright}");
78
- });
87
+ const { result } = await renderHook(
88
+ () => useStep({ initialCount, maxCount })
89
+ );
90
+ await userEvent.keyboard("{arrowright}");
79
91
  expect(result.current.count).toBe(initialCount + 1);
80
- await act(async () => {
81
- await userEvent.keyboard("{arrowleft}");
82
- });
92
+ await userEvent.keyboard("{arrowleft}");
83
93
  expect(result.current.count).toBe(initialCount);
84
94
  });
85
95
  });
@@ -1,28 +1,28 @@
1
- import { renderHook } from "@testing-library/react";
1
+ import { renderHook } from "vitest-browser-react";
2
2
  import { useTimeout } from ".";
3
3
  describe("useTimeout", () => {
4
- it("\u6307\u5B9A\u6642\u9593\u5F8C\u306B\u5B9F\u884C\u3055\u308C\u308B", () => {
4
+ it("\u6307\u5B9A\u6642\u9593\u5F8C\u306B\u5B9F\u884C\u3055\u308C\u308B", async () => {
5
5
  const fn = vi.fn();
6
6
  vi.useFakeTimers();
7
- renderHook(() => {
7
+ await renderHook(() => {
8
8
  useTimeout(fn, 1e3);
9
9
  });
10
10
  vi.advanceTimersByTime(1e3);
11
11
  expect(fn).toHaveBeenCalledOnce();
12
12
  });
13
- it("\u6307\u5B9A\u6642\u9593\u524D\u306B\u5B9F\u884C\u3055\u308C\u306A\u3044", () => {
13
+ it("\u6307\u5B9A\u6642\u9593\u524D\u306B\u5B9F\u884C\u3055\u308C\u306A\u3044", async () => {
14
14
  const fn = vi.fn();
15
15
  vi.useFakeTimers();
16
- renderHook(() => {
16
+ await renderHook(() => {
17
17
  useTimeout(fn, 1e3);
18
18
  });
19
19
  vi.advanceTimersByTime(10);
20
20
  expect(fn).not.toHaveBeenCalled();
21
21
  });
22
- it("\u6307\u5B9A\u6642\u9593\u524D\u306B\u30A2\u30F3\u30DE\u30A6\u30F3\u30C8\u3055\u308C\u306A\u3044\u5834\u5408\u306F\u5B9F\u884C\u3055\u308C\u306A\u3044", () => {
22
+ it("\u6307\u5B9A\u6642\u9593\u524D\u306B\u30A2\u30F3\u30DE\u30A6\u30F3\u30C8\u3055\u308C\u306A\u3044\u5834\u5408\u306F\u5B9F\u884C\u3055\u308C\u306A\u3044", async () => {
23
23
  const fn = vi.fn();
24
24
  vi.useFakeTimers();
25
- const { unmount } = renderHook(() => {
25
+ const { unmount } = await renderHook(() => {
26
26
  useTimeout(fn, 1e3);
27
27
  });
28
28
  unmount();
@@ -1,12 +1,12 @@
1
- import { act, renderHook } from "@testing-library/react";
1
+ import { renderHook } from "vitest-browser-react";
2
2
  import { useWindowSize } from ".";
3
3
  describe("useWindowSize", () => {
4
- it("window\u30B5\u30A4\u30BA\u306E\u5909\u66F4\u306B\u5408\u308F\u305B\u3066\u73FE\u5728\u306Ewindow\u30B5\u30A4\u30BA\u3092\u53D6\u5F97\u3059\u308B", () => {
4
+ it("window\u30B5\u30A4\u30BA\u306E\u5909\u66F4\u306B\u5408\u308F\u305B\u3066\u73FE\u5728\u306Ewindow\u30B5\u30A4\u30BA\u3092\u53D6\u5F97\u3059\u308B", async () => {
5
5
  const initWindowSize = { width: 0, height: 0 };
6
6
  const resizedWindowSize = { width: 1e3, height: 1e3 };
7
7
  window.innerWidth = initWindowSize.width;
8
8
  window.innerHeight = initWindowSize.height;
9
- const { result } = renderHook(() => useWindowSize());
9
+ const { result, act } = await renderHook(() => useWindowSize());
10
10
  expect(result.current).toEqual(initWindowSize);
11
11
  window.innerWidth = resizedWindowSize.width;
12
12
  window.innerHeight = resizedWindowSize.height;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k8o/arte-odyssey",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "k8o's react ui library",
5
5
  "author": "k8o <kosakanoki@gmail.com>",
6
6
  "keywords": [
@@ -55,34 +55,33 @@
55
55
  "@floating-ui/react": "0.27.16",
56
56
  "baseline-status": "1.0.11",
57
57
  "clsx": "2.1.1",
58
- "esbuild": "0.25.9",
59
- "lucide-react": "0.542.0",
60
- "motion": "12.23.12",
58
+ "esbuild": "0.25.12",
59
+ "lucide-react": "0.552.0",
60
+ "motion": "12.23.24",
61
61
  "react-error-boundary": "6.0.0",
62
62
  "tailwind-merge": "3.3.1"
63
63
  },
64
64
  "devDependencies": {
65
- "@chromatic-com/storybook": "4.1.1",
66
- "@storybook/addon-a11y": "9.1.5",
67
- "@storybook/addon-docs": "9.1.5",
68
- "@storybook/addon-vitest": "9.1.5",
69
- "@storybook/react-vite": "9.1.5",
70
- "@tailwindcss/postcss": "4.1.12",
71
- "@testing-library/dom": "10.4.1",
72
- "@testing-library/react": "16.3.0",
73
- "@types/react": "19.1.12",
74
- "@types/react-dom": "19.1.9",
75
- "@vitejs/plugin-react-swc": "4.0.1",
76
- "@vitest/browser": "3.2.4",
77
- "@vitest/ui": "3.2.4",
65
+ "@chromatic-com/storybook": "4.1.2",
66
+ "@storybook/addon-a11y": "10.0.2",
67
+ "@storybook/addon-docs": "10.0.2",
68
+ "@storybook/addon-vitest": "10.0.2",
69
+ "@storybook/react-vite": "10.0.2",
70
+ "@tailwindcss/postcss": "4.1.16",
71
+ "@types/react": "19.2.2",
72
+ "@types/react-dom": "19.2.2",
73
+ "@vitejs/plugin-react-swc": "4.2.0",
74
+ "@vitest/browser-playwright": "4.0.6",
75
+ "@vitest/ui": "4.0.6",
78
76
  "postcss": "8.5.6",
79
- "react": "19.1.1",
80
- "react-dom": "19.1.1",
81
- "storybook": "9.1.5",
82
- "storybook-addon-mock-date": "1.0.1",
83
- "tailwindcss": "4.1.12",
84
- "vite": "7.1.4",
85
- "vitest": "3.2.4"
77
+ "react": "19.2.0",
78
+ "react-dom": "19.2.0",
79
+ "storybook": "10.0.2",
80
+ "storybook-addon-mock-date": "1.0.2",
81
+ "tailwindcss": "4.1.16",
82
+ "vite": "7.1.12",
83
+ "vitest": "4.0.6",
84
+ "vitest-browser-react": "2.0.2"
86
85
  },
87
86
  "peerDependencies": {
88
87
  "@types/react": ">=19.0.0",