@idem.agency/popups-engine 0.0.9
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.
- package/README.md +176 -0
- package/dist/css.d.ts +2 -0
- package/dist/popups-engine.css +1 -0
- package/dist/popups-engine.d.ts +119 -0
- package/dist/popups-engine.js +152 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Popups-engine
|
|
2
|
+
|
|
3
|
+
Движок для управления попапами в React с поддержкой кастомных компонентов и анимаций через `motion`.
|
|
4
|
+
|
|
5
|
+
Версия `motion`: **^12.24.7**
|
|
6
|
+
|
|
7
|
+
## Установка
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @barabel324/popups-engine
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Основные компоненты
|
|
14
|
+
|
|
15
|
+
### PopupsEngineProvider
|
|
16
|
+
|
|
17
|
+
Провайдер для регистрации и управления попапами.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<PopupsEngineProvider popups={popups}>
|
|
21
|
+
{children}
|
|
22
|
+
|
|
23
|
+
<PopupsEngineRoot
|
|
24
|
+
id="popups-root"
|
|
25
|
+
lockBodyScroll={() => (document.body.style.overflow = 'hidden')}
|
|
26
|
+
enableBodyScroll={() => (document.body.style.overflow = '')}
|
|
27
|
+
/>
|
|
28
|
+
</PopupsEngineProvider>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### PopupsEngineRoot
|
|
32
|
+
|
|
33
|
+
Компонент, который рендерит все попапы и обёртки. Обычно используется один раз в корне приложения.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
<PopupsEngineRoot
|
|
37
|
+
id="popups-root"
|
|
38
|
+
lockBodyScroll={() => (document.body.style.overflow = 'hidden')}
|
|
39
|
+
enableBodyScroll={() => (document.body.style.overflow = '')}
|
|
40
|
+
/>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Пропсы
|
|
44
|
+
|
|
45
|
+
| Проп | Тип | Описание |
|
|
46
|
+
| ------------------ | ------------------- | ------------------------------------------------------------------ |
|
|
47
|
+
| `id` | `string` | `id` атрибут для корневого элемента попапов |
|
|
48
|
+
| `lockBodyScroll` | `() => void` | Функция блокировки скролла страницы |
|
|
49
|
+
| `enableBodyScroll` | `() => void` | Функция разблокировки скролла страницы |
|
|
50
|
+
| `components` | `TPEComponents` | Кастомные компоненты. `openPopup` имеет приоритет над этим пропсом |
|
|
51
|
+
| `classNames` | `TPEClassNames` | Кастомные классы. `openPopup` имеет приоритет над этим пропсом |
|
|
52
|
+
| `motionVariants` | `TPEMotionVariants` | Анимации для `motion`-обёртки попапа. `openPopup` имеет приоритет |
|
|
53
|
+
|
|
54
|
+
`PopupsEngineProvider` должен оборачивать приложение, а `PopupsEngineRoot` должен быть отрендерен внутри него.
|
|
55
|
+
|
|
56
|
+
## Хук usePopupsEngineProvider
|
|
57
|
+
|
|
58
|
+
Позволяет управлять попапами внутри компонентов.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const {
|
|
62
|
+
openPopup,
|
|
63
|
+
closePopup,
|
|
64
|
+
closeFirstPopup,
|
|
65
|
+
closeAllPopups,
|
|
66
|
+
} = usePopupsEngineProvider();
|
|
67
|
+
|
|
68
|
+
openPopup({ variant: 'MyPopup', popupProps: { title: 'Hello' } });
|
|
69
|
+
closePopup();
|
|
70
|
+
closeFirstPopup();
|
|
71
|
+
closeAllPopups();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Пропсы openPopup
|
|
75
|
+
|
|
76
|
+
| Проп | Тип | Описание |
|
|
77
|
+
| ---------------- | --------------------- | ---------------------------------------------------------------------- |
|
|
78
|
+
| `variant` | `string` | Ключ попапа, зарегистрированного в провайдере |
|
|
79
|
+
| `popupProps` | `Record<string, any>` | Пропсы, передаваемые в компонент попапа |
|
|
80
|
+
| `isCloseAll` | `boolean` | Закрывать ли все попапы при вызове `close` внутри попапа |
|
|
81
|
+
| `components` | `TPEComponents` | Кастомные компоненты. Приоритет над `PopupsEngineRoot` |
|
|
82
|
+
| `classNames` | `TPEClassNames` | Кастомные классы. Приоритет над `PopupsEngineRoot` |
|
|
83
|
+
| `motionVariants` | `TPEMotionVariants` | Анимации для `motion`-обёртки попапа. Приоритет над `PopupsEngineRoot` |
|
|
84
|
+
|
|
85
|
+
## Кастомизация
|
|
86
|
+
|
|
87
|
+
Кастомизация возможна глобально через `PopupsEngineRoot` или локально через `openPopup`.
|
|
88
|
+
|
|
89
|
+
Пропсы, переданные в `openPopup`, имеют приоритет над пропсами `PopupsEngineRoot`.
|
|
90
|
+
|
|
91
|
+
### Компоненты
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
const components = {
|
|
95
|
+
wrapper: CustomWrapper,
|
|
96
|
+
loader: CustomLoader,
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Классы
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
const classNames = {
|
|
104
|
+
wrapper: 'my-wrapper-class',
|
|
105
|
+
loader: 'my-loader-class',
|
|
106
|
+
};
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Анимации (motion / framer-motion)
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
const motionVariants = {
|
|
113
|
+
initial: { opacity: 0, y: -20 },
|
|
114
|
+
animate: { opacity: 1, y: 0 },
|
|
115
|
+
exit: { opacity: 0, y: 20 },
|
|
116
|
+
};
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Дженерики
|
|
120
|
+
|
|
121
|
+
`TPEComponentWrapper` — дженерик для типизации попапов. Библиотека автоматически передаёт в компонент служебные пропсы (например, `closePopup`).
|
|
122
|
+
|
|
123
|
+
## Минимальный пример
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
// '@/popup-templates/message'
|
|
127
|
+
export const PopupMessage: TPEComponentWrapper<TPopupMessage> = ({
|
|
128
|
+
title,
|
|
129
|
+
description,
|
|
130
|
+
closePopup,
|
|
131
|
+
}) => (
|
|
132
|
+
<div>
|
|
133
|
+
<div>{title}</div>
|
|
134
|
+
<div>{description}</div>
|
|
135
|
+
<button type="button" onClick={closePopup}>
|
|
136
|
+
close
|
|
137
|
+
</button>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
// '@/popup-templates'
|
|
142
|
+
const popups = {
|
|
143
|
+
message: lazy(() => import('@views/popup-templates/message')),
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// '@/show-popup'
|
|
147
|
+
export const ShowPopup = () => {
|
|
148
|
+
const { openPopup } = usePopupsEngineProvider();
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<button
|
|
152
|
+
type="button"
|
|
153
|
+
onClick={() =>
|
|
154
|
+
openPopup({
|
|
155
|
+
variant: 'message',
|
|
156
|
+
popupProps: {
|
|
157
|
+
title: 'I am popup',
|
|
158
|
+
description: 'Destroyer of the worlds',
|
|
159
|
+
},
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
>
|
|
163
|
+
Press
|
|
164
|
+
</button>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// 'app.tsx'
|
|
169
|
+
import { PopupsEngineProvider, PopupsEngineRoot } from '@barabel324/popups-engine';
|
|
170
|
+
import '@barabel324/popups-engine/css';
|
|
171
|
+
|
|
172
|
+
<PopupsEngineProvider popups={popups}>
|
|
173
|
+
<ShowPopup />
|
|
174
|
+
<PopupsEngineRoot />
|
|
175
|
+
</PopupsEngineProvider>
|
|
176
|
+
```
|
package/dist/css.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._parent_wmksm_1{z-index:100;position:fixed;inset:0;display:flex;align-items:center;justify-content:center;width:100%;height:100vh;background-color:#00000080}._parent_1ud1o_1{color:#fff}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Variant } from 'motion/react';
|
|
2
|
+
|
|
3
|
+
/** Утилитарный дженерик для обозначения функционального компонента с пропсами children и className */
|
|
4
|
+
declare type FCClass<P = object> = React.FC<P & React.PropsWithChildren & {
|
|
5
|
+
className?: string;
|
|
6
|
+
}>;
|
|
7
|
+
|
|
8
|
+
export declare const PopupsEngineProvider: FCClass<TPEProvider>;
|
|
9
|
+
|
|
10
|
+
export declare const PopupsEngineRoot: FCClass<TPERoot>;
|
|
11
|
+
|
|
12
|
+
declare type TPEClassNames = {
|
|
13
|
+
[K in keyof TPEMapComponents]?: TPEMapComponents[K]['className'];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
declare type TPEComponents = {
|
|
17
|
+
[K in keyof TPEMapComponents]?: TPEMapComponents[K]['component'];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Дженерик для частного попапа. Либа передает некоторые методы пропсом в попап, который прокидывают в провайдер */
|
|
21
|
+
export declare type TPEComponentWrapper<K = object> = FCClass<{
|
|
22
|
+
/** Закрыть последний попап */
|
|
23
|
+
closePopup: () => void;
|
|
24
|
+
} & K>;
|
|
25
|
+
|
|
26
|
+
/** Контекст методов */
|
|
27
|
+
declare type TPEContext = {
|
|
28
|
+
/** Открыть попап */
|
|
29
|
+
openPopup: (data: TPEExecute) => void;
|
|
30
|
+
/** Закрыть последний попап */
|
|
31
|
+
closePopup: () => void;
|
|
32
|
+
/** Закрыть первый попап */
|
|
33
|
+
closeFirstPopup: () => void;
|
|
34
|
+
/** Закрыть все попапы */
|
|
35
|
+
closeAllPopups: () => void;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* пропсы openPopup
|
|
40
|
+
*/
|
|
41
|
+
declare type TPEExecute = {
|
|
42
|
+
/** вариант попапа (берется из ключей объекта, переданного в провайдер) */
|
|
43
|
+
variant: string;
|
|
44
|
+
/** пропсы попапа, который хотят вызывать */
|
|
45
|
+
popupProps?: Record<string, any>;
|
|
46
|
+
/** закрыть ли все попапы, если вызвать пропс close, переданный в попап */
|
|
47
|
+
isCloseAll?: boolean;
|
|
48
|
+
/** кастомные компоненты либы */
|
|
49
|
+
components?: TPEComponents;
|
|
50
|
+
/** кастомные классы для компонентов либы */
|
|
51
|
+
classNames?: TPEClassNames;
|
|
52
|
+
/** Варианты анимации обертки для motion */
|
|
53
|
+
motionVariants?: TPEMotionVariants;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
declare type TPEMapComponents = {
|
|
57
|
+
/** обертка, в которую ставится попап */
|
|
58
|
+
wrapper: {
|
|
59
|
+
/** компонент обертки */
|
|
60
|
+
component: TPEWrapper;
|
|
61
|
+
/** класс обертки */
|
|
62
|
+
className: string;
|
|
63
|
+
};
|
|
64
|
+
/** лоудер, который отображается, когда лези попап грузится (Suspense fallback) */
|
|
65
|
+
loader: {
|
|
66
|
+
/** компонент лоудера */
|
|
67
|
+
component: FCClass;
|
|
68
|
+
/** класс лоудера */
|
|
69
|
+
className: string;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Варианты анимации обертки для motion
|
|
75
|
+
*/
|
|
76
|
+
declare type TPEMotionVariants = {
|
|
77
|
+
/** Начальное положение обертки */
|
|
78
|
+
initial: Variant;
|
|
79
|
+
/** Активное положение обертки */
|
|
80
|
+
animate: Variant;
|
|
81
|
+
/** Анимация ухода обертки */
|
|
82
|
+
exit: Variant;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/** провайдер для открытия попаов */
|
|
86
|
+
declare type TPEProvider = {
|
|
87
|
+
/** частные попапы */
|
|
88
|
+
popups: Record<string, FCClass<any>>;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** Рут для попапов */
|
|
92
|
+
declare type TPERoot = {
|
|
93
|
+
/** аттрибут id рута */
|
|
94
|
+
id?: string;
|
|
95
|
+
/** кастомные компоненты либы */
|
|
96
|
+
components?: TPEComponents;
|
|
97
|
+
/** кастомные классы для компонентов либы */
|
|
98
|
+
classNames?: TPEClassNames;
|
|
99
|
+
/** Варианты анимации обертки для motion */
|
|
100
|
+
motionVariants?: TPEMotionVariants;
|
|
101
|
+
/** Каллбак для вызова разрешающего метода скролл лока */
|
|
102
|
+
enableBodyScroll?: () => void;
|
|
103
|
+
/** Каллбак для вызова запрещающего метода скролл лока */
|
|
104
|
+
lockBodyScroll?: () => void;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Компонент обертки
|
|
109
|
+
*/
|
|
110
|
+
declare type TPEWrapper = FCClass<{
|
|
111
|
+
/**
|
|
112
|
+
* Варианты анимации обертки для motion
|
|
113
|
+
*/
|
|
114
|
+
motionVariants?: TPEMotionVariants;
|
|
115
|
+
}>;
|
|
116
|
+
|
|
117
|
+
export declare const usePopupsEngineProvider: () => TPEContext;
|
|
118
|
+
|
|
119
|
+
export { }
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { jsx as n } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as g, useContext as x, useRef as O, useEffect as y, Suspense as R, useState as $, useCallback as b, useMemo as f } from "react";
|
|
3
|
+
import { motion as j, AnimatePresence as F } from "motion/react";
|
|
4
|
+
const L = g({
|
|
5
|
+
openPopup: () => {
|
|
6
|
+
},
|
|
7
|
+
closePopup: () => {
|
|
8
|
+
},
|
|
9
|
+
closeFirstPopup: () => {
|
|
10
|
+
},
|
|
11
|
+
closeAllPopups: () => {
|
|
12
|
+
}
|
|
13
|
+
}), k = g({
|
|
14
|
+
popupList: []
|
|
15
|
+
}), A = g({
|
|
16
|
+
popups: {}
|
|
17
|
+
}), V = () => x(L), I = () => x(k), S = () => x(A), z = "_parent_wmksm_1", K = {
|
|
18
|
+
parent: z
|
|
19
|
+
}, M = {
|
|
20
|
+
initial: { opacity: 0 },
|
|
21
|
+
animate: { opacity: 1 },
|
|
22
|
+
exit: { opacity: 0 }
|
|
23
|
+
}, q = ({
|
|
24
|
+
className: o,
|
|
25
|
+
motionVariants: u = M,
|
|
26
|
+
children: p
|
|
27
|
+
}) => {
|
|
28
|
+
const t = O(null), { closePopup: r } = V(), i = (c) => {
|
|
29
|
+
c.target === t.current && r();
|
|
30
|
+
};
|
|
31
|
+
return /* @__PURE__ */ n(
|
|
32
|
+
j.div,
|
|
33
|
+
{
|
|
34
|
+
variants: u,
|
|
35
|
+
initial: "initial",
|
|
36
|
+
animate: "animate",
|
|
37
|
+
exit: "exit",
|
|
38
|
+
ref: t,
|
|
39
|
+
className: o ?? K.parent,
|
|
40
|
+
onClick: i,
|
|
41
|
+
children: p
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}, G = "_parent_1ud1o_1", H = {
|
|
45
|
+
parent: G
|
|
46
|
+
}, J = ({
|
|
47
|
+
className: o
|
|
48
|
+
}) => /* @__PURE__ */ n(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: o ?? H.parent,
|
|
52
|
+
children: "Loading..."
|
|
53
|
+
}
|
|
54
|
+
), W = ({
|
|
55
|
+
className: o,
|
|
56
|
+
id: u = "popups-engine-root",
|
|
57
|
+
components: p,
|
|
58
|
+
classNames: t,
|
|
59
|
+
motionVariants: r,
|
|
60
|
+
enableBodyScroll: i,
|
|
61
|
+
lockBodyScroll: c
|
|
62
|
+
}) => {
|
|
63
|
+
const { popupList: s } = I(), { popups: v } = S(), { closePopup: l, closeAllPopups: P } = V();
|
|
64
|
+
return y(() => (s.length > 0 && c?.(), () => {
|
|
65
|
+
s.length > 0 && i?.();
|
|
66
|
+
}), [
|
|
67
|
+
s,
|
|
68
|
+
i,
|
|
69
|
+
c
|
|
70
|
+
]), y(() => {
|
|
71
|
+
const e = (m) => {
|
|
72
|
+
m.key === "Escape" && (s.at(-1)?.isCloseAll ? P : l)();
|
|
73
|
+
};
|
|
74
|
+
return s.length > 0 && window.addEventListener("keydown", e), () => {
|
|
75
|
+
window.removeEventListener("keydown", e);
|
|
76
|
+
};
|
|
77
|
+
}, [
|
|
78
|
+
s,
|
|
79
|
+
l,
|
|
80
|
+
P
|
|
81
|
+
]), /* @__PURE__ */ n(
|
|
82
|
+
"div",
|
|
83
|
+
{
|
|
84
|
+
className: o,
|
|
85
|
+
id: u,
|
|
86
|
+
children: /* @__PURE__ */ n(F, { children: s.map((e) => {
|
|
87
|
+
const {
|
|
88
|
+
popupID: m,
|
|
89
|
+
variant: a,
|
|
90
|
+
popupProps: E,
|
|
91
|
+
isCloseAll: d,
|
|
92
|
+
components: w,
|
|
93
|
+
classNames: C,
|
|
94
|
+
motionVariants: _
|
|
95
|
+
} = e, N = w?.wrapper || p?.wrapper || q, D = w?.loader || p?.loader || J, h = v[a];
|
|
96
|
+
return h ? /* @__PURE__ */ n(
|
|
97
|
+
N,
|
|
98
|
+
{
|
|
99
|
+
className: C?.wrapper || t?.wrapper,
|
|
100
|
+
motionVariants: _ || r,
|
|
101
|
+
children: /* @__PURE__ */ n(
|
|
102
|
+
R,
|
|
103
|
+
{
|
|
104
|
+
fallback: /* @__PURE__ */ n(D, { className: C?.loader || t?.loader }),
|
|
105
|
+
children: /* @__PURE__ */ n(
|
|
106
|
+
h,
|
|
107
|
+
{
|
|
108
|
+
...E,
|
|
109
|
+
closePopup: d ? P : l
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
},
|
|
115
|
+
m
|
|
116
|
+
) : null;
|
|
117
|
+
}) })
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}, X = ({
|
|
121
|
+
popups: o,
|
|
122
|
+
children: u
|
|
123
|
+
}) => {
|
|
124
|
+
const [p, t] = $([]), r = b((e) => {
|
|
125
|
+
const m = Object.keys(o), { variant: a } = e;
|
|
126
|
+
a && (m.some((d) => d === a) ? t((d) => [...d, {
|
|
127
|
+
...e,
|
|
128
|
+
popupID: Date.now()
|
|
129
|
+
}]) : console.error(`there are no "${a}" popup`));
|
|
130
|
+
}, [o]), i = () => {
|
|
131
|
+
t((e) => e.slice(0, -1));
|
|
132
|
+
}, c = () => {
|
|
133
|
+
t((e) => e.slice(1));
|
|
134
|
+
}, s = () => {
|
|
135
|
+
t(() => []);
|
|
136
|
+
}, v = f(() => ({
|
|
137
|
+
openPopup: r,
|
|
138
|
+
closePopup: i,
|
|
139
|
+
closeFirstPopup: c,
|
|
140
|
+
closeAllPopups: s
|
|
141
|
+
}), [r]), l = f(() => ({
|
|
142
|
+
popupList: p
|
|
143
|
+
}), [p]), P = f(() => ({
|
|
144
|
+
popups: o
|
|
145
|
+
}), [o]);
|
|
146
|
+
return /* @__PURE__ */ n(L.Provider, { value: v, children: /* @__PURE__ */ n(k.Provider, { value: l, children: /* @__PURE__ */ n(A.Provider, { value: P, children: u }) }) });
|
|
147
|
+
};
|
|
148
|
+
export {
|
|
149
|
+
X as PopupsEngineProvider,
|
|
150
|
+
W as PopupsEngineRoot,
|
|
151
|
+
V as usePopupsEngineProvider
|
|
152
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@idem.agency/popups-engine",
|
|
3
|
+
"version": "0.0.9",
|
|
4
|
+
"author": "@barabel324",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/popups-engine.js",
|
|
7
|
+
"types": "./dist/popups-engine.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/popups-engine.js"
|
|
14
|
+
},
|
|
15
|
+
"./css": {
|
|
16
|
+
"import": "./dist/popups-engine.css",
|
|
17
|
+
"types": "./dist/css.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "vite",
|
|
25
|
+
"build": "tsc -b && vite build",
|
|
26
|
+
"lint": "eslint .",
|
|
27
|
+
"lintFix": "eslint . --fix",
|
|
28
|
+
"preview": "vite preview",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"motion": "12.24.7",
|
|
33
|
+
"react": "19.2.3",
|
|
34
|
+
"react-dom": "19.2.3"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@eslint/js": "9.39.2",
|
|
38
|
+
"@microsoft/api-extractor": "7.55.2",
|
|
39
|
+
"@stylistic/eslint-plugin": "5.7.0",
|
|
40
|
+
"@types/node": "25.0.9",
|
|
41
|
+
"@types/react": "19.2.9",
|
|
42
|
+
"@types/react-dom": "19.2.3",
|
|
43
|
+
"@vitejs/plugin-react": "5.1.2",
|
|
44
|
+
"eslint": "9.39.2",
|
|
45
|
+
"eslint-plugin-react-hooks": "7.0.1",
|
|
46
|
+
"eslint-plugin-react-refresh": "0.4.26",
|
|
47
|
+
"globals": "17.0.0",
|
|
48
|
+
"motion": "12.27.3",
|
|
49
|
+
"react": "19.2.3",
|
|
50
|
+
"react-dom": "19.2.3",
|
|
51
|
+
"sass-embedded": "1.97.2",
|
|
52
|
+
"typescript": "5.9.3",
|
|
53
|
+
"typescript-eslint": "8.53.1",
|
|
54
|
+
"unplugin-dts": "1.0.0-beta.6",
|
|
55
|
+
"vite": "7.3.1"
|
|
56
|
+
},
|
|
57
|
+
"gitHead": "0a18b8cd441ad4a319fc8a3b536246b8c42a84be"
|
|
58
|
+
}
|