This commit is contained in:
pincman 2024-05-15 06:36:45 +08:00
parent 112b737cc4
commit a9638cfa38
15 changed files with 634 additions and 184 deletions

View File

@ -23,6 +23,7 @@
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-use": "^17.5.0",
"zustand": "^4.5.2"
},
"devDependencies": {

View File

@ -0,0 +1,51 @@
import { StyleProvider } from '@ant-design/cssinjs';
import { ConfigProvider, App as AntdApp } from 'antd';
import { FC, useMemo } from 'react';
import $styles from './app.module.css';
import { localeData } from './components/demo/constants';
import ContextDemo from './components/demo/context';
import CustomDemo from './components/demo/custom';
import { useLocale } from './components/demo/hooks';
import { useAntdAlgorithm } from './components/theme/hooks';
export const Wrapper: FC = () => {
const locale = useLocale();
const antdLocaleData = useMemo(() => {
if (!Object.keys(localeData).find((v) => v === locale.name)) {
return localeData[0];
}
return localeData[locale.name];
}, [locale.name]);
// const themeState = useTheme();
// const algorithm = useMemo(() => {
// const result = [themeState.compact ? theme.compactAlgorithm : theme.defaultAlgorithm];
// if (themeState.mode === 'dark') result.push(theme.darkAlgorithm);
// return result;
// }, [themeState]);
const algorithm = useAntdAlgorithm();
return (
<ConfigProvider
locale={antdLocaleData}
theme={{
algorithm,
token: {},
}}
>
<StyleProvider hashPriority="high">
<AntdApp>
<div className={$styles.app}>
{/* <StateDemo />
<EffectDemo />
<RefDemo />
<MemoDemo />
<CallbackDemo /> */}
<ContextDemo />
{/* <ReducerDemo /> */}
<CustomDemo />
</div>
</AntdApp>
</StyleProvider>
</ConfigProvider>
);
};

View File

@ -1,15 +1,16 @@
import { StyleProvider } from '@ant-design/cssinjs';
import { ConfigProvider, theme, App as AntdApp } from 'antd';
import { ConfigProvider, App as AntdApp } from 'antd';
// import 'dayjs/locale/zh-cn';
import { FC, useMemo } from 'react';
import $styles from './app.module.css';
import { localeData } from './components/demo/constants';
import ContextDemo, { Locale } from './components/demo/context';
import CustomDemo from './components/demo/custom';
import { useLocale, useTheme } from './components/demo/hooks';
import ReducerDemo, { Theme } from './components/demo/reducer';
import { Locale } from './components/demo/context';
import { useLocale } from './components/demo/hooks';
import Theme from './components/theme';
import ThemeDemo from './components/theme/demo';
import { useAntdAlgorithm } from './components/theme/hooks';
const Wrapper: FC = () => {
const locale = useLocale();
@ -19,12 +20,13 @@ const Wrapper: FC = () => {
}
return localeData[locale.name];
}, [locale.name]);
const themeState = useTheme();
const algorithm = useMemo(() => {
const result = [themeState.compact ? theme.compactAlgorithm : theme.defaultAlgorithm];
if (themeState.mode === 'dark') result.push(theme.darkAlgorithm);
return result;
}, [themeState]);
// const themeState = useTheme();
// const algorithm = useMemo(() => {
// const result = [themeState.compact ? theme.compactAlgorithm : theme.defaultAlgorithm];
// if (themeState.mode === 'dark') result.push(theme.darkAlgorithm);
// return result;
// }, [themeState]);
const algorithm = useAntdAlgorithm();
return (
<ConfigProvider
locale={antdLocaleData}
@ -40,10 +42,11 @@ const Wrapper: FC = () => {
<EffectDemo />
<RefDemo />
<MemoDemo />
<CallbackDemo /> */}
<CallbackDemo />
<ContextDemo />
<ReducerDemo />
<CustomDemo />
<CustomDemo /> */}
<ThemeDemo />
</div>
</AntdApp>
</StyleProvider>

View File

@ -21,12 +21,16 @@ export type ThemeState = {
export enum ThemeActionType {
CHANGE_MODE = 'change_mode',
TOOGLE_MODE = 'toggle_mode',
CHANGE_COMPACT = 'change_compact',
TOOGLE_COMPACT = 'toggle_compact',
}
export type ThemeAction =
| { type: `${ThemeActionType.CHANGE_MODE}`; value: `${ThemeMode}` }
| { type: `${ThemeActionType.CHANGE_COMPACT}`; value: boolean };
| { type: `${ThemeActionType.TOOGLE_MODE}` }
| { type: `${ThemeActionType.CHANGE_COMPACT}`; value: boolean }
| { type: `${ThemeActionType.TOOGLE_COMPACT}` };
export type ThemeContextType = {
state: ThemeState;

View File

@ -1,2 +1,167 @@
export * from './utils';
export * from './types';
import { capitalize } from 'lodash';
import { create, StateCreator, Mutate, StoreApi, UseBoundStore } from 'zustand';
import {
subscribeWithSelector,
devtools,
persist,
PersistOptions,
DevtoolsOptions,
redux,
} from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
export type ZustandHookSelectors<StateType> = {
[Key in keyof StateType as `use${Capitalize<string & Key>}`]: () => StateType[Key];
};
export interface ZustandGetterSelectors<StateType> {
getters: {
[key in keyof StateType]: () => StateType[key];
};
}
/**
* immer以及devtoools功能的普通状态商店
* @param creator
* @param devtoolsOptions
*/
export const createStore = <T extends object>(
creator: StateCreator<
T,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
]
>,
devtoolsOptions?: DevtoolsOptions,
) => {
return create<T>()(subscribeWithSelector(immer(devtools(creator, devtoolsOptions))));
};
/**
* immer以及devtoools功能的普通状态商店
* localstorage
* @param creator
* @param persistOptions
* @param devtoolsOptions
*/
export const createPersistStore = <T extends object, P = T>(
creator: StateCreator<
T,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
['zustand/persist', P],
]
>,
persistOptions: PersistOptions<T, P>,
devtoolsOptions?: DevtoolsOptions,
) => {
return create<T>()(
subscribeWithSelector(
immer(devtools(persist(creator as unknown as any, persistOptions), devtoolsOptions)),
),
);
};
/**
* immer以及devtoools功能的reducer状态商店
* localstorage
* @param reducer
* @param initialState
* @param devtoolsOptions
*/
export const createReduxStore = <
T extends object,
A extends {
type: string;
},
>(
reducer: (state: T, action: A) => T,
initialState: T,
devtoolsOptions?: DevtoolsOptions,
) => create(subscribeWithSelector(immer(devtools(redux(reducer, initialState), devtoolsOptions))));
/**
* immer以及devtoools功能的reducer状态商店
* @param reducer
* @param initialState
* @param persistOptions
* @param devtoolsOptions
*/
export const createPersistReduxStore = <
T extends object,
A extends {
type: string;
},
P = T,
>(
reducer: (state: T, action: A) => T,
initialState: T,
persistOptions: PersistOptions<T, P>,
devtoolsOptions?: DevtoolsOptions,
) =>
create(
subscribeWithSelector(
immer(
devtools(
persist(redux(reducer, initialState), persistOptions as any),
devtoolsOptions,
),
),
),
);
/**
* getters获取状态值store.getters.xxx()
* @param store
*/
export function createStoreGetters<T extends object>(
store: UseBoundStore<
Mutate<
StoreApi<T>,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
]
>
>,
) {
const storeIn = store as any;
storeIn.getters = {};
Object.keys(storeIn.getState()).forEach((key) => {
const selector = (state: T) => state[key as keyof T];
storeIn.getters[key] = () => storeIn(selector);
});
return storeIn as typeof store & ZustandGetterSelectors<T>;
}
/**
* hooks的方法获取状态值store.useXxx()
* @param store
*/
export function createStoreHooks<T extends Record<string, any>>(
store: UseBoundStore<
Mutate<
StoreApi<T>,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
]
>
>,
) {
const storeIn = store as any;
Object.keys(storeIn.getState()).forEach((key) => {
const selector = (state: T) => state[key as keyof T];
storeIn[`use${capitalize(key)}`] = () => storeIn(selector);
});
return storeIn as typeof store & ZustandHookSelectors<T>;
}

View File

@ -1,8 +0,0 @@
export type ZustandHookSelectors<StateType> = {
[Key in keyof StateType as `use${Capitalize<string & Key>}`]: () => StateType[Key];
};
export interface ZustandGetterSelectors<StateType> {
getters: {
[key in keyof StateType]: () => StateType[key];
};
}

View File

@ -1,160 +0,0 @@
import { capitalize } from 'lodash';
import { create, Mutate, StateCreator, StoreApi, UseBoundStore } from 'zustand';
import {
subscribeWithSelector,
devtools,
persist,
PersistOptions,
DevtoolsOptions,
redux,
} from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import { ZustandGetterSelectors, ZustandHookSelectors } from './types';
/**
* immer以及devtoools功能的普通状态商店
* @param creator
* @param devtoolsOptions
*/
export const createStore = <T extends object>(
creator: StateCreator<
T,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
]
>,
devtoolsOptions?: DevtoolsOptions,
) => {
return create<T>()(subscribeWithSelector(immer(devtools(creator, devtoolsOptions))));
};
/**
* immer以及devtoools功能的普通状态商店
* localstorage
* @param creator
* @param persistOptions
* @param devtoolsOptions
*/
export const createPersistStore = <T extends object, P = T>(
creator: StateCreator<
T,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
['zustand/persist', P],
]
>,
persistOptions: PersistOptions<T, P>,
devtoolsOptions?: DevtoolsOptions,
) => {
return create<T>()(
subscribeWithSelector(
immer(devtools(persist(creator as unknown as any, persistOptions), devtoolsOptions)),
),
);
};
/**
* immer以及devtoools功能的reducer状态商店
* localstorage
* @param reducer
* @param initialState
* @param devtoolsOptions
*/
export const createReduxStore = <
T extends object,
A extends {
type: string;
},
>(
reducer: (state: T, action: A) => T,
initialState: T,
devtoolsOptions?: DevtoolsOptions,
) => create(subscribeWithSelector(immer(devtools(redux(reducer, initialState), devtoolsOptions))));
/**
* immer以及devtoools功能的reducer状态商店
* @param reducer
* @param initialState
* @param persistOptions
* @param devtoolsOptions
*/
export const createPersistReduxStore = <
T extends object,
A extends {
type: string;
},
P = T,
>(
reducer: (state: T, action: A) => T,
initialState: T,
persistOptions: PersistOptions<T, P>,
devtoolsOptions?: DevtoolsOptions,
) =>
create(
subscribeWithSelector(
immer(
devtools(
persist(redux(reducer, initialState), persistOptions as any),
devtoolsOptions,
),
),
),
);
/**
* getters获取状态值store.getters.xxx()
* @param store
*/
export function createStoreGetters<T extends object>(
store: UseBoundStore<
Mutate<
StoreApi<T>,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
]
>
>,
) {
const storeIn = store as any;
storeIn.getters = {};
Object.keys(storeIn.getState()).forEach((key) => {
const selector = (state: T) => state[key as keyof T];
storeIn.getters[key] = () => storeIn(selector);
});
return storeIn as typeof store & ZustandGetterSelectors<T>;
}
/**
* hooks的方法获取状态值store.useXxx()
* @param store
*/
export function createStoreHooks<T extends Record<string, any>>(
store: UseBoundStore<
Mutate<
StoreApi<T>,
[
['zustand/subscribeWithSelector', never],
['zustand/immer', never],
['zustand/devtools', never],
]
>
>,
) {
const storeIn = store as any;
Object.keys(storeIn.getState()).forEach((key) => {
const selector = (state: T) => state[key as keyof T];
storeIn[`use${capitalize(key)}`] = () => storeIn(selector);
});
return storeIn as typeof store & ZustandHookSelectors<T>;
}

View File

@ -0,0 +1,6 @@
import { ThemeState } from './types';
export const defaultThemeConfig: ThemeState = {
mode: 'light',
compact: false,
};

View File

@ -0,0 +1,48 @@
import { Calendar, Switch } from 'antd';
import { FC } from 'react';
import { useTheme, useThemeActions } from './hooks';
import $styles from './style.module.css';
const Setting: FC = () => {
const { mode, compact } = useTheme();
const { toggleMode, toggleCompact } = useThemeActions();
return (
<>
<Switch
checkedChildren="🌛"
unCheckedChildren="☀️"
onChange={toggleMode}
checked={mode === 'dark'}
defaultChecked={mode === 'dark'}
/>
<Switch
checkedChildren="紧凑"
unCheckedChildren="正常"
onChange={toggleCompact}
checked={compact}
defaultChecked={compact}
/>
</>
);
};
const ThemeDemo: FC = () => {
const { mode, compact } = useTheme();
return (
<div className={$styles.container}>
<h2 className="tw-text-center">Theme Setting Demo</h2>
<div className="tw-flex tw-items-center tw-flex-col">
<p>: {mode === 'dark' ? '暗黑' : '明亮'}</p>
<p>: {compact ? '是' : '否'}</p>
<div className="tw-flex-auto tw-mb-5">
<Setting />
</div>
<div className="tw-max-w-md">
<Calendar fullscreen={false} />
</div>
</div>
</div>
);
};
export default ThemeDemo;

View File

@ -0,0 +1,46 @@
import { theme } from 'antd';
import { omit } from 'lodash';
import { useCallback, useMemo } from 'react';
import { useShallow } from 'zustand/react/shallow';
import { useThemeStore } from './store';
import { ThemeMode } from './types';
/**
*
*/
export const useTheme = () => useThemeStore(useShallow((state) => omit(state, ['dispatch'])));
/**
* Antd主题算法
*/
export const useAntdAlgorithm = () => {
const { mode, compact } = useTheme();
return useMemo(() => {
const result = [compact ? theme.compactAlgorithm : theme.defaultAlgorithm];
if (mode === 'dark') result.push(theme.darkAlgorithm);
return result;
}, [mode, compact]);
};
/**
*
*/
export const useThemeActions = () => {
const dispatch = useThemeStore((state) => state.dispatch);
return {
changeMode: useCallback(
(v: `${ThemeMode}`) => dispatch({ type: 'change_mode', value: v }),
[],
),
toggleMode: useCallback(() => dispatch({ type: 'toggle_mode' }), []),
changeCompact: useCallback(
(v: boolean) => dispatch({ type: 'change_compact', value: v }),
[],
),
toggleCompact: useCallback(
useCallback(() => dispatch({ type: 'toggle_compact' }), []),
[],
),
};
};

View File

@ -0,0 +1,50 @@
import { debounce, isNil } from 'lodash';
import { FC, ReactNode } from 'react';
import { useLifecycles } from 'react-use';
import { useThemeStore } from './store';
const Theme: FC<{ children?: ReactNode }> = ({ children }) => {
let unSub: () => void;
useLifecycles(
() => {
useThemeStore.subscribe(
(state) => state.mode,
(mode) => {
debounce(() => {
console.log(mode);
});
const body = document.getElementsByTagName('body');
if (body.length) {
body[0].classList.remove('light');
body[0].classList.remove('dark');
body[0].classList.add(mode === 'dark' ? 'dark' : 'light');
}
},
// debounce(
// () => {
// const body = document.getElementsByTagName('body');
// if (body.length) {
// body[0].classList.remove('light');
// body[0].classList.remove('dark');
// body[0].classList.add(mode === 'dark' ? 'dark' : 'light');
// }
// },
// 10,
// {},
// ),
{
fireImmediately: true,
},
);
},
() => {
if (!isNil(unSub)) unSub();
},
);
return <>{children}</>;
};
export default Theme;

View File

@ -0,0 +1,32 @@
import { produce } from 'immer';
import { Reducer } from 'react';
import { ThemeAction } from '../demo/types';
import { createPersistReduxStore } from '../store';
import { defaultThemeConfig } from './constants';
import { ThemeState } from './types';
const ThemeReducer: Reducer<ThemeState, ThemeAction> = produce((draft, action) => {
switch (action.type) {
case 'change_mode':
draft.mode = action.value;
break;
case 'toggle_mode':
draft.mode = draft.mode === 'dark' ? 'light' : 'dark';
break;
case 'change_compact':
draft.compact = action.value;
break;
case 'toggle_compact':
draft.compact = !draft.compact;
break;
default:
break;
}
});
export const useThemeStore = createPersistReduxStore(ThemeReducer, defaultThemeConfig, {
name: 'theme',
partialize: (state) => ({ mode: state.mode, compact: state.compact }),
});

View File

@ -0,0 +1,9 @@
.container {
@apply tw-bg-neutral-100/40 tw-shadow-black/20 tw-backdrop-blur-sm tw-shadow-md tw-rounded-md tw-p-5 tw-m-5 tw-min-w-[20rem];
}
body(:global(.dark)) {
.container {
@apply tw-bg-neutral-800/40 tw-shadow-slate-100/30;
}
}

View File

@ -0,0 +1,9 @@
export enum ThemeMode {
LIGHT = 'light',
DARK = 'dark',
}
export type ThemeState = {
mode: `${ThemeMode}`;
compact: boolean;
};

View File

@ -56,6 +56,9 @@ importers:
react-dom:
specifier: ^18.2.0
version: 18.3.1(react@18.3.1)
react-use:
specifier: ^17.5.0
version: 17.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
zustand:
specifier: ^4.5.2
version: 4.5.2(@types/react@18.3.1)(immer@10.1.1)(react@18.3.1)
@ -1632,6 +1635,9 @@ packages:
'@types/jest@29.5.12':
resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==}
'@types/js-cookie@2.2.7':
resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==}
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@ -1798,6 +1804,9 @@ packages:
'@webassemblyjs/wast-printer@1.12.1':
resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==}
'@xobotyi/scrollbar-width@1.9.5':
resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==}
'@xtuc/ieee754@1.2.0':
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
@ -2361,6 +2370,13 @@ packages:
resolution: {integrity: sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==}
engines: {node: '>=12 || >=16'}
css-in-js-utils@3.1.0:
resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==}
css-tree@1.1.3:
resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
engines: {node: '>=8.0.0'}
css-tree@2.3.1:
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
@ -2524,6 +2540,9 @@ packages:
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
error-stack-parser@2.1.4:
resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==}
es-abstract@1.23.3:
resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
engines: {node: '>= 0.4'}
@ -2839,6 +2858,9 @@ packages:
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
fast-loops@1.1.3:
resolution: {integrity: sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==}
fast-querystring@1.1.2:
resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==}
@ -2849,6 +2871,9 @@ packages:
fast-safe-stringify@2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
fast-shallow-equal@1.0.0:
resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==}
fast-uri@2.3.0:
resolution: {integrity: sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==}
@ -2856,6 +2881,9 @@ packages:
resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
engines: {node: '>= 4.9.1'}
fastest-stable-stringify@2.0.2:
resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==}
fastify-plugin@4.5.1:
resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
@ -3171,6 +3199,9 @@ packages:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
hyphenate-style-name@1.0.4:
resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@ -3211,6 +3242,9 @@ packages:
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
inline-style-prefixer@7.0.0:
resolution: {integrity: sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ==}
inquirer@8.2.6:
resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==}
engines: {node: '>=12.0.0'}
@ -3569,6 +3603,9 @@ packages:
jju@1.4.0:
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
js-cookie@2.2.1:
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -3778,6 +3815,9 @@ packages:
mathml-tag-names@2.1.3:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
mdn-data@2.0.14:
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
mdn-data@2.0.30:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
@ -3883,6 +3923,12 @@ packages:
mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
nano-css@5.6.1:
resolution: {integrity: sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==}
peerDependencies:
react: '*'
react-dom: '*'
nanoid@3.3.7:
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -4636,6 +4682,18 @@ packages:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
react-universal-interface@0.6.2:
resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==}
peerDependencies:
react: '*'
tslib: '*'
react-use@17.5.0:
resolution: {integrity: sha512-PbfwSPMwp/hoL847rLnm/qkjg3sTRCvn6YhUZiHaUa3FA6/aNoFX79ul5Xt70O1rK+9GxSVqkY0eTwMdsR/bWg==}
peerDependencies:
react: '*'
react-dom: '*'
react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
@ -4786,6 +4844,9 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
rtl-css-js@1.16.1:
resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==}
run-async@2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'}
@ -4828,6 +4889,10 @@ packages:
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
engines: {node: '>= 10.13.0'}
screenfull@5.2.0:
resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==}
engines: {node: '>=0.10.0'}
scroll-into-view-if-needed@3.1.0:
resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==}
@ -4870,6 +4935,10 @@ packages:
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
engines: {node: '>= 0.4'}
set-harmonic-interval@1.0.1:
resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==}
engines: {node: '>=6.9'}
shebang-command@1.2.0:
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
engines: {node: '>=0.10.0'}
@ -4934,6 +5003,10 @@ packages:
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
source-map@0.5.6:
resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==}
engines: {node: '>=0.10.0'}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
@ -4953,10 +5026,22 @@ packages:
resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
engines: {node: '>= 0.6'}
stack-generator@2.0.10:
resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==}
stack-utils@2.0.6:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
stackframe@1.3.4:
resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==}
stacktrace-gps@3.1.2:
resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==}
stacktrace-js@2.0.2:
resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==}
streamsearch@1.1.0:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
@ -5208,6 +5293,10 @@ packages:
thread-stream@2.7.0:
resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==}
throttle-debounce@3.0.1:
resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==}
engines: {node: '>=10'}
throttle-debounce@5.0.0:
resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==}
engines: {node: '>=12.22'}
@ -5262,6 +5351,9 @@ packages:
peerDependencies:
typescript: '>=4.2.0'
ts-easing@0.2.0:
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
@ -6960,6 +7052,8 @@ snapshots:
expect: 29.7.0
pretty-format: 29.7.0
'@types/js-cookie@2.2.7': {}
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
@ -7191,6 +7285,8 @@ snapshots:
'@webassemblyjs/ast': 1.12.1
'@xtuc/long': 4.2.2
'@xobotyi/scrollbar-width@1.9.5': {}
'@xtuc/ieee754@1.2.0': {}
'@xtuc/long@4.2.2': {}
@ -7860,6 +7956,15 @@ snapshots:
css-functions-list@3.2.2: {}
css-in-js-utils@3.1.0:
dependencies:
hyphenate-style-name: 1.0.4
css-tree@1.1.3:
dependencies:
mdn-data: 2.0.14
source-map: 0.6.1
css-tree@2.3.1:
dependencies:
mdn-data: 2.0.30
@ -7989,6 +8094,10 @@ snapshots:
dependencies:
is-arrayish: 0.2.1
error-stack-parser@2.1.4:
dependencies:
stackframe: 1.3.4
es-abstract@1.23.3:
dependencies:
array-buffer-byte-length: 1.0.1
@ -8453,6 +8562,8 @@ snapshots:
fast-levenshtein@2.0.6: {}
fast-loops@1.1.3: {}
fast-querystring@1.1.2:
dependencies:
fast-decode-uri-component: 1.0.1
@ -8461,10 +8572,14 @@ snapshots:
fast-safe-stringify@2.1.1: {}
fast-shallow-equal@1.0.0: {}
fast-uri@2.3.0: {}
fastest-levenshtein@1.0.16: {}
fastest-stable-stringify@2.0.2: {}
fastify-plugin@4.5.1: {}
fastify@4.26.2:
@ -8844,6 +8959,8 @@ snapshots:
human-signals@2.1.0: {}
hyphenate-style-name@1.0.4: {}
iconv-lite@0.4.24:
dependencies:
safer-buffer: 2.1.2
@ -8877,6 +8994,11 @@ snapshots:
ini@1.3.8: {}
inline-style-prefixer@7.0.0:
dependencies:
css-in-js-utils: 3.1.0
fast-loops: 1.1.3
inquirer@8.2.6:
dependencies:
ansi-escapes: 4.3.2
@ -9431,6 +9553,8 @@ snapshots:
jju@1.4.0: {}
js-cookie@2.2.1: {}
js-tokens@4.0.0: {}
js-yaml@3.14.1:
@ -9613,6 +9737,8 @@ snapshots:
mathml-tag-names@2.1.3: {}
mdn-data@2.0.14: {}
mdn-data@2.0.30: {}
memfs@3.5.3:
@ -9690,6 +9816,19 @@ snapshots:
object-assign: 4.1.1
thenify-all: 1.6.0
nano-css@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
css-tree: 1.1.3
csstype: 3.1.3
fastest-stable-stringify: 2.0.2
inline-style-prefixer: 7.0.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
rtl-css-js: 1.16.1
stacktrace-js: 2.0.2
stylis: 4.3.2
nanoid@3.3.7: {}
natural-compare@1.4.0: {}
@ -10499,6 +10638,30 @@ snapshots:
react-refresh@0.14.2: {}
react-universal-interface@0.6.2(react@18.3.1)(tslib@2.6.2):
dependencies:
react: 18.3.1
tslib: 2.6.2
react-use@17.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@types/js-cookie': 2.2.7
'@xobotyi/scrollbar-width': 1.9.5
copy-to-clipboard: 3.3.3
fast-deep-equal: 3.1.3
fast-shallow-equal: 1.0.0
js-cookie: 2.2.1
nano-css: 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-universal-interface: 0.6.2(react@18.3.1)(tslib@2.6.2)
resize-observer-polyfill: 1.5.1
screenfull: 5.2.0
set-harmonic-interval: 1.0.1
throttle-debounce: 3.0.1
ts-easing: 0.2.0
tslib: 2.6.2
react@18.3.1:
dependencies:
loose-envify: 1.4.0
@ -10665,6 +10828,10 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.17.2
fsevents: 2.3.3
rtl-css-js@1.16.1:
dependencies:
'@babel/runtime': 7.24.5
run-async@2.4.1: {}
run-async@3.0.0: {}
@ -10710,6 +10877,8 @@ snapshots:
ajv: 6.12.6
ajv-keywords: 3.5.2(ajv@6.12.6)
screenfull@5.2.0: {}
scroll-into-view-if-needed@3.1.0:
dependencies:
compute-scroll-into-view: 3.1.0
@ -10752,6 +10921,8 @@ snapshots:
functions-have-names: 1.2.3
has-property-descriptors: 1.0.2
set-harmonic-interval@1.0.1: {}
shebang-command@1.2.0:
dependencies:
shebang-regex: 1.0.0
@ -10815,6 +10986,8 @@ snapshots:
buffer-from: 1.1.2
source-map: 0.6.1
source-map@0.5.6: {}
source-map@0.6.1: {}
source-map@0.7.4: {}
@ -10825,10 +10998,27 @@ snapshots:
sqlstring@2.3.3: {}
stack-generator@2.0.10:
dependencies:
stackframe: 1.3.4
stack-utils@2.0.6:
dependencies:
escape-string-regexp: 2.0.0
stackframe@1.3.4: {}
stacktrace-gps@3.1.2:
dependencies:
source-map: 0.5.6
stackframe: 1.3.4
stacktrace-js@2.0.2:
dependencies:
error-stack-parser: 2.1.4
stack-generator: 2.0.10
stacktrace-gps: 3.1.2
streamsearch@1.1.0: {}
string-argv@0.3.2: {}
@ -11157,6 +11347,8 @@ snapshots:
dependencies:
real-require: 0.2.0
throttle-debounce@3.0.1: {}
throttle-debounce@5.0.0: {}
through@2.3.8: {}
@ -11196,6 +11388,8 @@ snapshots:
dependencies:
typescript: 5.4.5
ts-easing@0.2.0: {}
ts-interface-checker@0.1.13: {}
ts-jest@29.1.2(@babel/core@7.24.5)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.5))(jest@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@swc/core@1.5.5(@swc/helpers@0.5.11))(@types/node@20.12.11)(typescript@5.4.5)))(typescript@5.4.5):