chop-logic-components 4.3.0 → 4.4.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.
@@ -3,5 +3,6 @@ export interface FormContextProps {
3
3
  onChangeFormInput?: (params: FormInputParams) => void;
4
4
  initialValues?: FormValues;
5
5
  resetSignal?: number;
6
+ isPending?: boolean;
6
7
  }
7
8
  export declare const FormContext: import('react').Context<FormContextProps>;
@@ -1,5 +1,5 @@
1
1
  import { createContext as e } from "react";
2
2
  //#region src/components/contexts/form/FormContext.tsx
3
- var t = e({});
3
+ var t = e({ isPending: !1 });
4
4
  //#endregion
5
5
  export { t as FormContext };
@@ -33,7 +33,8 @@ function c({ name: c, defaultValue: l, onChange: u, onDecrement: d, onIncrement:
33
33
  });
34
34
  }, [c])), {
35
35
  handleChange: (e) => {
36
- k(Number(e.target.value)), u?.(e);
36
+ let t = Number(e.target.value);
37
+ k(t), u?.(e);
37
38
  },
38
39
  value: C,
39
40
  valid: T,
@@ -1,14 +1,22 @@
1
1
  import { FormInputParams, FormValues } from '../../../types';
2
- import { FormEvent, FormEventHandler } from 'react';
3
- export declare function useFormController({ initialValues, onReset, onSubmit, onClickSubmit, }: {
2
+ import { SubmitEvent, SubmitEventHandler } from 'react';
3
+ interface UseFormControllerParams<TActionState = void> {
4
4
  initialValues?: FormValues;
5
- onReset?: FormEventHandler<HTMLFormElement>;
6
- onSubmit?: FormEventHandler<HTMLFormElement>;
7
- onClickSubmit?: (data: FormValues) => void;
8
- }): {
5
+ resetOnSuccess?: boolean;
6
+ onReset?: SubmitEventHandler<HTMLFormElement>;
7
+ action?: (prevState: TActionState, formData: FormData) => TActionState | Promise<TActionState>;
8
+ actionInitialState?: TActionState;
9
+ onActionComplete?: (state: TActionState) => void;
10
+ onSubmit?: (data: FormValues) => void | Promise<void>;
11
+ }
12
+ interface UseFormControllerReturn {
9
13
  handleInputChange: (params: FormInputParams) => void;
10
- handleSubmit: (event: FormEvent<HTMLFormElement>) => void;
11
- handleReset: (event: FormEvent<HTMLFormElement>) => void;
14
+ handleReset: (event: SubmitEvent<HTMLFormElement>) => void;
12
15
  resetSignal: number;
13
16
  valid: boolean;
14
- };
17
+ isPending: boolean;
18
+ formAction?: (formData: FormData) => void;
19
+ handleSubmit?: (event: SubmitEvent<HTMLFormElement>) => void;
20
+ }
21
+ export declare function useFormController<TActionState = void>({ initialValues, resetOnSuccess, onReset, action, actionInitialState, onActionComplete, onSubmit, }: UseFormControllerParams<TActionState>): UseFormControllerReturn;
22
+ export {};
@@ -1,29 +1,49 @@
1
1
  import { getInitialValidationState as e, isFormDataValid as t, updateValidationState as n } from "./Form.helpers.js";
2
- import { useState as r } from "react";
2
+ import { useActionState as r, useCallback as i, useState as a } from "react";
3
3
  //#region src/components/organisms/form/Form.controller.ts
4
- function i({ initialValues: i, onReset: a, onSubmit: o, onClickSubmit: s }) {
5
- let [c, l] = r(i), [u, d] = r(e(i)), [f, p] = r(0);
6
- return {
7
- handleInputChange: (e) => {
8
- l({
9
- ...c,
10
- [e.name]: e.value
11
- }), d(n(u, e));
12
- },
13
- handleSubmit: (e) => {
14
- e.preventDefault();
4
+ function o({ initialValues: o, resetOnSuccess: s = !1, onReset: c, action: l, actionInitialState: u, onActionComplete: d, onSubmit: f }) {
5
+ let [p, m] = a(o), [h, g] = a(e(o)), [_, v] = a(0), [y, b] = a(!1), x = (e) => {
6
+ let t = {
7
+ ...p,
8
+ [e.name]: e.value
9
+ };
10
+ m(t), g(n(h, e));
11
+ }, S = i(() => {
12
+ m(o), v((e) => e + 1), g(e(o));
13
+ }, [o]), C = (e) => {
14
+ c?.(e), S();
15
+ }, w = t(h), [, T, E] = r(async (e, t) => {
16
+ if (!l) return e;
17
+ let n = await l(e, t);
18
+ return d?.(n), s && S(), n;
19
+ }, u);
20
+ return l ? {
21
+ handleInputChange: x,
22
+ handleReset: C,
23
+ resetSignal: _,
24
+ valid: w,
25
+ isPending: E,
26
+ formAction: T
27
+ } : {
28
+ handleInputChange: x,
29
+ handleReset: C,
30
+ resetSignal: _,
31
+ valid: w,
32
+ isPending: y,
33
+ handleSubmit: async (e) => {
34
+ if (e.preventDefault(), !w || !f) return;
15
35
  let t = {
16
36
  ...Object.fromEntries(new FormData(e.target)),
17
- ...c
37
+ ...p
18
38
  };
19
- o?.(e), s?.(t);
20
- },
21
- handleReset: (e) => {
22
- a?.(e), l(i), p(f + 1);
23
- },
24
- resetSignal: f,
25
- valid: t(u)
39
+ b(!0);
40
+ try {
41
+ await f(t), s && S();
42
+ } finally {
43
+ b(!1);
44
+ }
45
+ }
26
46
  };
27
47
  }
28
48
  //#endregion
29
- export { i as useFormController };
49
+ export { o as useFormController };
@@ -1 +1 @@
1
- .cl-form{align-items:end;gap:var(--cl-l-gap);grid-template-rows:auto;grid-template-columns:auto;display:grid}@media screen and (width>=640px){.cl-form{grid-template-columns:repeat(2,1fr)}}@media screen and (width>=1024px){.cl-form{grid-template-columns:repeat(3,1fr)}}@media screen and (width>=1280px){.cl-form{grid-template-columns:repeat(4,1fr)}}.cl-form__buttons{padding-top:var(--cl-l-gap);grid-column:1/-1;justify-content:space-between;align-items:center;display:flex}
1
+ .cl-form{align-items:end;gap:var(--cl-l-gap);grid-template-rows:auto;grid-template-columns:auto;display:grid}@media screen and (width>=640px){.cl-form{grid-template-columns:repeat(2,1fr)}}@media screen and (width>=1024px){.cl-form{grid-template-columns:repeat(3,1fr)}}@media screen and (width>=1280px){.cl-form{grid-template-columns:repeat(4,1fr)}}.cl-form__buttons{padding-top:var(--cl-l-gap);grid-column:1/-1;justify-content:space-between;align-items:center;display:flex}.cl-form_pending{opacity:.7;pointer-events:none}
@@ -8,41 +8,50 @@ import './Form.css';/* empty css */
8
8
  import { useMemo as o } from "react";
9
9
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
10
10
  //#region src/components/organisms/form/Form.tsx
11
- var l = ({ children: l, initialValues: u, onReset: d, onSubmit: f, onClickSubmit: p, hasReset: m = !0, className: h, ...g }) => {
12
- let { handleInputChange: _, handleSubmit: v, handleReset: y, resetSignal: b, valid: x } = a({
11
+ var l = ({ children: l, initialValues: u, onReset: d, onSubmit: f, action: p, actionInitialState: m, onActionComplete: h, resetOnSuccess: g = !1, hasReset: _ = !0, className: v }) => {
12
+ let { handleInputChange: y, handleSubmit: b, handleReset: x, formAction: S, resetSignal: C, valid: w, isPending: T } = a({
13
13
  initialValues: u,
14
+ resetOnSuccess: g,
14
15
  onReset: d,
15
16
  onSubmit: f,
16
- onClickSubmit: p
17
- }), S = n(["cl-form", h]), C = o(() => ({
18
- onChangeFormInput: _,
17
+ action: p,
18
+ actionInitialState: m,
19
+ onActionComplete: h
20
+ }), E = n([
21
+ "cl-form",
22
+ v,
23
+ { "cl-form_pending": T }
24
+ ]), D = o(() => ({
25
+ onChangeFormInput: y,
19
26
  initialValues: u,
20
- resetSignal: b
27
+ resetSignal: C,
28
+ isPending: T
21
29
  }), [
22
- _,
30
+ y,
23
31
  u,
24
- b
32
+ C,
33
+ T
25
34
  ]);
26
35
  return /* @__PURE__ */ s("form", {
27
- onSubmit: v,
28
- onReset: y,
29
- ...g,
30
- className: S,
36
+ ...p ? { action: S } : { onSubmit: b },
37
+ onReset: x,
38
+ className: E,
31
39
  children: /* @__PURE__ */ c(i.Provider, {
32
- value: C,
40
+ value: D,
33
41
  children: [l, /* @__PURE__ */ c("div", {
34
42
  className: "cl-form__buttons",
35
- children: [m && /* @__PURE__ */ s(r, {
43
+ children: [_ && /* @__PURE__ */ s(r, {
36
44
  type: "reset",
37
- text: "Reset",
38
- icon: t.Delete,
39
- view: e.Secondary
45
+ text: "Clear",
46
+ icon: t.Trash,
47
+ view: e.Secondary,
48
+ disabled: T
40
49
  }), /* @__PURE__ */ s(r, {
41
50
  type: "submit",
42
51
  text: "Submit",
43
52
  icon: t.ArrowRight,
44
- extended: !m,
45
- disabled: !x
53
+ extended: !_,
54
+ disabled: !w || T
46
55
  })]
47
56
  })]
48
57
  })
@@ -17,10 +17,12 @@ var n = ({ data: n, id: r, onSelect: i }) => {
17
17
  d([]);
18
18
  },
19
19
  handleSelectRowById: (e) => {
20
- d([...o, e]);
20
+ let t = [...o, e];
21
+ d(t);
21
22
  },
22
23
  handleDeselectRowById: (e) => {
23
- d(o.filter((t) => t !== e));
24
+ let t = o.filter((t) => t !== e);
25
+ d(t);
24
26
  }
25
27
  };
26
28
  };
@@ -3,6 +3,7 @@ export { useClickOutside } from './use-click-outside/use-click-outside';
3
3
  export { useContainerDimensions } from './use-container-dimensions/use-container-dimensions';
4
4
  export { useDebounce } from './use-debounce/use-debounce';
5
5
  export { useElementIds } from './use-element-ids/use-element-ids';
6
+ export { useFormPending } from './use-form-pending/use-form-pending';
6
7
  export { useIsHovered } from './use-is-hovered/use-is-hovered';
7
8
  export { useIsMounted } from './use-is-mounted/use-is-mounted';
8
9
  export { useIsOverflow } from './use-is-overflow/use-is-overflow';
@@ -3,6 +3,7 @@ export * from './use-click-outside/index.js';
3
3
  export * from './use-container-dimensions/index.js';
4
4
  export * from './use-debounce/index.js';
5
5
  export * from './use-element-ids/index.js';
6
+ export * from './use-form-pending/index.js';
6
7
  export * from './use-is-hovered/index.js';
7
8
  export * from './use-is-mounted/index.js';
8
9
  export * from './use-is-overflow/index.js';
@@ -3,7 +3,7 @@ import { useEffect as e } from "react";
3
3
  var t = ({ ref: t, onClickOutsideHandler: n, dependentRef: r }) => {
4
4
  e(() => {
5
5
  let e = (e) => {
6
- let i = t?.current && !t.current.contains(e.target), a = r?.current ? !r?.current?.contains(e.target) : !0;
6
+ let i = t?.current && !t.current.contains(e.target), a = !r?.current || !r?.current?.contains(e.target);
7
7
  i && a && n();
8
8
  };
9
9
  return document.addEventListener("mousedown", e), () => {
@@ -0,0 +1,2 @@
1
+ export * from './use-form-pending.js';
2
+ export { default } from './use-form-pending.js';
@@ -0,0 +1 @@
1
+ export declare const useFormPending: () => boolean;
@@ -0,0 +1,9 @@
1
+ import { FormContext as e } from "../../components/contexts/form/FormContext.js";
2
+ import { useContext as t } from "react";
3
+ //#region src/hooks/use-form-pending/use-form-pending.ts
4
+ var n = () => {
5
+ let { isPending: n } = t(e);
6
+ return n ?? !1;
7
+ };
8
+ //#endregion
9
+ export { n as useFormPending };
@@ -15,7 +15,9 @@ function r({ isOpened: r, isHovered: i, onClose: a, autoClose: o = !0, autoClose
15
15
  u.current = Date.now() - d.current;
16
16
  let e = () => {
17
17
  let t = Date.now() - u.current;
18
- if (d.current = t, l(Math.max(0, 100 - t / s * 100)), t >= s) {
18
+ d.current = t;
19
+ let n = Math.max(0, 100 - t / s * 100);
20
+ if (l(n), t >= s) {
19
21
  a();
20
22
  return;
21
23
  }
package/dist/index.es.js CHANGED
@@ -27,35 +27,36 @@ import { useClickOutside as T } from "./hooks/use-click-outside/use-click-outsid
27
27
  import { useContainerDimensions as E } from "./hooks/use-container-dimensions/use-container-dimensions.js";
28
28
  import { useDebounce as D } from "./hooks/use-debounce/use-debounce.js";
29
29
  import { useElementIds as O } from "./hooks/use-element-ids/use-element-ids.js";
30
- import { useIsHovered as k } from "./hooks/use-is-hovered/use-is-hovered.js";
31
- import { useIsMounted as A } from "./hooks/use-is-mounted/use-is-mounted.js";
32
- import { useIsOverflow as j } from "./hooks/use-is-overflow/use-is-overflow.js";
33
- import { useKeyPress as M } from "./hooks/use-key-press/use-key-press.js";
34
- import { useModalFocusTrap as N } from "./hooks/use-modal-focus-trap/use-modal-focus-trap.js";
35
- import { useRemainingTimer as P } from "./hooks/use-remaining-timer/use-remaining-timer.js";
36
- import { FormContext as F } from "./components/contexts/form/FormContext.js";
37
- import { CL_DARK_THEME_CLASS as I, CL_LIGHT_THEME_CLASS as L, ThemeContext as R } from "./components/contexts/theme/ThemeContext.js";
38
- import { ThemeProvider as z } from "./components/contexts/theme/ThemeProvider.js";
39
- import { useResetFormInput as B } from "./hooks/use-reset-form-input/use-reset-form-input.js";
40
- import { useTheme as V } from "./hooks/use-theme/use-theme.js";
41
- import { useTooltipPosition as H } from "./hooks/use-tooltip-position/use-tooltip-position.js";
42
- import { useWindowDimensions as U } from "./hooks/use-window-dimensions/use-window-dimensions.js";
43
- import W from "./components/atoms/tooltip/Tooltip2.js";
44
- import G from "./components/molecules/accordion/Accordion2.js";
45
- import K from "./components/molecules/alert/Alert2.js";
46
- import q from "./components/molecules/breadcrumbs/Breadcrumbs2.js";
47
- import J from "./components/molecules/checkbox/Checkbox2.js";
48
- import Y from "./components/molecules/multi-select/MultiSelect.js";
49
- import X from "./components/molecules/numeric-input/NumericInput2.js";
50
- import Z from "./components/molecules/search/Search2.js";
51
- import Q from "./components/molecules/select/Select2.js";
52
- import $ from "./components/molecules/switch/Switch2.js";
53
- import ee from "./components/molecules/text-input/TextInput2.js";
54
- import te from "./components/organisms/dialog/Dialog2.js";
55
- import ne from "./components/organisms/form/Form2.js";
56
- import re from "./components/organisms/gallery/Gallery2.js";
57
- import ie from "./components/organisms/grid/Grid2.js";
58
- import ae from "./components/organisms/menu/Menu2.js";
59
- import oe from "./components/organisms/preview-card/PreviewCard2.js";
60
- import se from "./components/organisms/tabs/Tabs2.js";
61
- export { G as Accordion, K as Alert, r as AlertMode, f as Avatar, q as Breadcrumbs, p as Button, i as ButtonView, I as CL_DARK_THEME_CLASS, L as CL_LIGHT_THEME_CLASS, J as Checkbox, te as Dialog, m as EditableText, a as ElementSize, h as ErrorMessage, ne as Form, F as FormContext, re as Gallery, ie as Grid, g as Header, _ as Icon, o as IconName, v as Image, y as Input, b as Label, x as Link, s as LinkTarget, c as LoaderView, ae as Menu, Y as MultiSelect, X as NumericInput, l as OrientationMode, S as Portal, oe as PreviewCard, Z as Search, Q as Select, u as SemanticColor, $ as Switch, se as Tabs, C as Tag, ee as TextInput, R as ThemeContext, z as ThemeProvider, W as Tooltip, d as TooltipContainer, w as useAutoClose, T as useClickOutside, E as useContainerDimensions, D as useDebounce, O as useElementIds, k as useIsHovered, A as useIsMounted, j as useIsOverflow, M as useKeyPress, N as useModalFocusTrap, P as useRemainingTimer, B as useResetFormInput, V as useTheme, H as useTooltipPosition, U as useWindowDimensions, e as withErrorBoundary, t as withFigureCaption, n as withTooltip };
30
+ import { FormContext as k } from "./components/contexts/form/FormContext.js";
31
+ import { CL_DARK_THEME_CLASS as A, CL_LIGHT_THEME_CLASS as j, ThemeContext as M } from "./components/contexts/theme/ThemeContext.js";
32
+ import { ThemeProvider as N } from "./components/contexts/theme/ThemeProvider.js";
33
+ import { useFormPending as P } from "./hooks/use-form-pending/use-form-pending.js";
34
+ import { useIsHovered as F } from "./hooks/use-is-hovered/use-is-hovered.js";
35
+ import { useIsMounted as I } from "./hooks/use-is-mounted/use-is-mounted.js";
36
+ import { useIsOverflow as L } from "./hooks/use-is-overflow/use-is-overflow.js";
37
+ import { useKeyPress as R } from "./hooks/use-key-press/use-key-press.js";
38
+ import { useModalFocusTrap as z } from "./hooks/use-modal-focus-trap/use-modal-focus-trap.js";
39
+ import { useRemainingTimer as B } from "./hooks/use-remaining-timer/use-remaining-timer.js";
40
+ import { useResetFormInput as V } from "./hooks/use-reset-form-input/use-reset-form-input.js";
41
+ import { useTheme as H } from "./hooks/use-theme/use-theme.js";
42
+ import { useTooltipPosition as U } from "./hooks/use-tooltip-position/use-tooltip-position.js";
43
+ import { useWindowDimensions as W } from "./hooks/use-window-dimensions/use-window-dimensions.js";
44
+ import G from "./components/atoms/tooltip/Tooltip2.js";
45
+ import K from "./components/molecules/accordion/Accordion2.js";
46
+ import q from "./components/molecules/alert/Alert2.js";
47
+ import J from "./components/molecules/breadcrumbs/Breadcrumbs2.js";
48
+ import Y from "./components/molecules/checkbox/Checkbox2.js";
49
+ import X from "./components/molecules/multi-select/MultiSelect.js";
50
+ import Z from "./components/molecules/numeric-input/NumericInput2.js";
51
+ import Q from "./components/molecules/search/Search2.js";
52
+ import $ from "./components/molecules/select/Select2.js";
53
+ import ee from "./components/molecules/switch/Switch2.js";
54
+ import te from "./components/molecules/text-input/TextInput2.js";
55
+ import ne from "./components/organisms/dialog/Dialog2.js";
56
+ import re from "./components/organisms/form/Form2.js";
57
+ import ie from "./components/organisms/gallery/Gallery2.js";
58
+ import ae from "./components/organisms/grid/Grid2.js";
59
+ import oe from "./components/organisms/menu/Menu2.js";
60
+ import se from "./components/organisms/preview-card/PreviewCard2.js";
61
+ import ce from "./components/organisms/tabs/Tabs2.js";
62
+ export { K as Accordion, q as Alert, r as AlertMode, f as Avatar, J as Breadcrumbs, p as Button, i as ButtonView, A as CL_DARK_THEME_CLASS, j as CL_LIGHT_THEME_CLASS, Y as Checkbox, ne as Dialog, m as EditableText, a as ElementSize, h as ErrorMessage, re as Form, k as FormContext, ie as Gallery, ae as Grid, g as Header, _ as Icon, o as IconName, v as Image, y as Input, b as Label, x as Link, s as LinkTarget, c as LoaderView, oe as Menu, X as MultiSelect, Z as NumericInput, l as OrientationMode, S as Portal, se as PreviewCard, Q as Search, $ as Select, u as SemanticColor, ee as Switch, ce as Tabs, C as Tag, te as TextInput, M as ThemeContext, N as ThemeProvider, G as Tooltip, d as TooltipContainer, w as useAutoClose, T as useClickOutside, E as useContainerDimensions, D as useDebounce, O as useElementIds, P as useFormPending, F as useIsHovered, I as useIsMounted, L as useIsOverflow, R as useKeyPress, z as useModalFocusTrap, B as useRemainingTimer, V as useResetFormInput, H as useTheme, U as useTooltipPosition, W as useWindowDimensions, e as withErrorBoundary, t as withFigureCaption, n as withTooltip };
@@ -9,10 +9,13 @@ export interface FormInputParams {
9
9
  value: unknown;
10
10
  valid?: boolean;
11
11
  }
12
- export interface FormProps extends PropsWithChildren, ChopLogicComponentProps {
12
+ export interface FormProps<TActionState = void> extends PropsWithChildren, ChopLogicComponentProps {
13
13
  initialValues?: FormValues;
14
14
  hasReset?: boolean;
15
- onClickSubmit?: (data: FormValues) => void;
15
+ resetOnSuccess?: boolean;
16
+ action?: (prevState: TActionState, formData: FormData) => TActionState | Promise<TActionState>;
17
+ actionInitialState?: TActionState;
18
+ onActionComplete?: (state: TActionState) => void;
19
+ onSubmit?: (data: FormValues) => void | Promise<void>;
16
20
  onReset?: FormEventHandler<HTMLFormElement>;
17
- onSubmit?: FormEventHandler<HTMLFormElement>;
18
21
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/ChopLogic/chop-logic-components.git"
6
6
  },
7
- "version": "4.3.0",
7
+ "version": "4.4.0",
8
8
  "description": "Reusable React components and hooks for the Chop Logic project",
9
9
  "type": "module",
10
10
  "module": "dist/index.es.js",
@@ -72,6 +72,7 @@
72
72
  "prepublishOnly": "npm run build",
73
73
  "build": "vite build && node scripts/generate-exports.js",
74
74
  "build:storybook": "storybook build",
75
+ "upgrade:storybook": "npx storybook@latest upgrade",
75
76
  "prepare": "npm run build && husky",
76
77
  "format": "npm run format:biome && npm run format:prettier",
77
78
  "format:biome": "biome format --write",
@@ -107,8 +108,7 @@
107
108
  "chop-logic",
108
109
  "react",
109
110
  "typescript",
110
- "storybook",
111
- "styled-components"
111
+ "storybook"
112
112
  ],
113
113
  "author": "Dmitrii Suroviagin",
114
114
  "license": "MIT",
@@ -117,34 +117,34 @@
117
117
  },
118
118
  "homepage": "https://choplogic.github.io/chop-logic-components",
119
119
  "devDependencies": {
120
- "@biomejs/biome": "^2.5.1",
121
- "@commitlint/cli": "^21.1.0",
122
- "@commitlint/config-conventional": "^21.1.0",
123
- "@storybook/addon-a11y": "^10.4.6",
124
- "@storybook/addon-docs": "^10.4.6",
125
- "@storybook/react-vite": "^10.4.6",
120
+ "@biomejs/biome": "^2.5.4",
121
+ "@commitlint/cli": "^21.2.1",
122
+ "@commitlint/config-conventional": "^21.2.0",
123
+ "@storybook/addon-a11y": "^10.5.2",
124
+ "@storybook/addon-docs": "^10.5.2",
125
+ "@storybook/react-vite": "^10.5.2",
126
126
  "@storybook/test-runner": "^0.24.4",
127
127
  "@stryker-mutator/core": "^9.6.1",
128
128
  "@stryker-mutator/vitest-runner": "^9.6.1",
129
129
  "@testing-library/jest-dom": "^6.9.1",
130
130
  "@testing-library/react": "^16.3.2",
131
- "@types/node": "^26.0.1",
131
+ "@types/node": "^26.1.1",
132
132
  "@types/react": "^19.2.17",
133
133
  "@types/react-dom": "^19.2.3",
134
- "@vitest/coverage-v8": "^4.1.9",
134
+ "@vitest/coverage-v8": "^4.1.10",
135
135
  "http-server": "^14.1.1",
136
136
  "husky": "^9.1.7",
137
- "husky-init": "^8.0.0",
138
137
  "jsdom": "^29.1.1",
139
- "prettier": "^3.8.5",
138
+ "prettier": "^3.9.5",
140
139
  "remark-gfm": "^4.0.1",
141
140
  "start-server-and-test": "^3.0.11",
142
- "storybook": "^10.4.6",
141
+ "storybook": "^10.5.2",
143
142
  "typescript": "^6.0.3",
144
- "vite": "^8.1.0",
143
+ "vite": "^8.1.5",
145
144
  "vite-plugin-dts": "^5.0.3",
146
145
  "vite-plugin-lib-inject-css": "^2.2.2",
147
- "vitest": "^4.1.9"
146
+ "vitest": "^4.1.10",
147
+ "@storybook/addon-mcp": "^0.7.0"
148
148
  },
149
149
  "overrides": {
150
150
  "storybook": "$storybook"