@dotss/ui 1.3.1 → 1.5.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.
- package/Button/Button.cjs +8 -7
- package/Button/Button.d.ts +3 -0
- package/Button/Button.es.js +77 -66
- package/Button/Button.stories.d.ts +1 -0
- package/Tab/Tab.cjs +7 -7
- package/Tab/Tab.es.js +145 -96
- package/Tab/TabBlock/TabBlock.cjs +6 -6
- package/Tab/TabBlock/TabBlock.es.js +72 -55
- package/TextField/TextField.stories.d.ts +1 -0
- package/Tooltip/Tooltip.cjs +11 -6
- package/Tooltip/Tooltip.d.ts +2 -1
- package/Tooltip/Tooltip.es.js +177 -160
- package/Tooltip/Tooltip.stories.d.ts +6 -0
- package/hooks/index.cjs +1 -1
- package/hooks/index.d.ts +2 -0
- package/hooks/index.es.js +6 -4
- package/hooks/useForm/useForm.cjs +1 -0
- package/hooks/useForm/useForm.d.ts +48 -0
- package/hooks/useForm/useForm.es.js +98 -0
- package/hooks/useForm/useForm.utils.cjs +1 -0
- package/hooks/useForm/useForm.utils.d.ts +4 -0
- package/hooks/useForm/useForm.utils.es.js +12 -0
- package/package.json +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DEFAULT_SCROLL_OPTIONS } from './useForm.utils';
|
|
2
|
+
|
|
3
|
+
export type FieldErrors<K extends string> = Partial<Record<K, string>>;
|
|
4
|
+
export type FormFieldHelper = {
|
|
5
|
+
severity: 'error';
|
|
6
|
+
message?: string;
|
|
7
|
+
};
|
|
8
|
+
export type FormContext<V, N extends string, M> = {
|
|
9
|
+
values: V;
|
|
10
|
+
meta?: M;
|
|
11
|
+
fieldRefs: Map<N, HTMLElement | null>;
|
|
12
|
+
error: FieldErrors<N>;
|
|
13
|
+
};
|
|
14
|
+
export type ValidateFn<V, N extends string, M> = (ctx: FormContext<V, N, M>) => FieldErrors<N>;
|
|
15
|
+
export type OnSubmitFn<V, N extends string, M> = (ctx: FormContext<V, N, M>) => void | Promise<void>;
|
|
16
|
+
export type SubmitFn<V, N extends string, M> = (options?: Partial<Record<'onError' | 'onSuccess' | 'onSettled', OnSubmitFn<V, N, M>>>) => () => Promise<void>;
|
|
17
|
+
export interface UseFormProps<V, N extends string, M> {
|
|
18
|
+
fieldNames: readonly N[];
|
|
19
|
+
values: V;
|
|
20
|
+
validate: ValidateFn<V, N, M>;
|
|
21
|
+
meta?: M;
|
|
22
|
+
scrollOptions?: typeof DEFAULT_SCROLL_OPTIONS;
|
|
23
|
+
scrollOnError?: boolean;
|
|
24
|
+
focusOnError?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface UseFormReturn<V, N extends string, M> {
|
|
27
|
+
/** 제출 여부 */
|
|
28
|
+
isSubmitted: boolean;
|
|
29
|
+
/** 에러 상태 */
|
|
30
|
+
errors: FieldErrors<N>;
|
|
31
|
+
/** 필드 등록 */
|
|
32
|
+
registerField: (name: N) => (element: HTMLElement | null) => void;
|
|
33
|
+
/** 에러 초기화 */
|
|
34
|
+
clearErrors: () => void;
|
|
35
|
+
/** 필드 에러 도움말 반환 */
|
|
36
|
+
getFieldHelper: (name: N) => FormFieldHelper | undefined;
|
|
37
|
+
/** 제출 함수 */
|
|
38
|
+
submit: SubmitFn<V, N, M>;
|
|
39
|
+
/** [imperative] 검증 후 errors 갱신 직접 호출 */
|
|
40
|
+
triggerValidate: (options?: {
|
|
41
|
+
callEffectOnError?: boolean;
|
|
42
|
+
}) => void;
|
|
43
|
+
/** [imperative] 필드 에러 설정 직접 호출 */
|
|
44
|
+
triggerSetFieldError: (name: N, message: string) => void;
|
|
45
|
+
/** [imperative] 에러 발생 시 스크롤·포커스 처리 직접 호출 */
|
|
46
|
+
triggerEffectOnError: (errors: FieldErrors<N>) => void;
|
|
47
|
+
}
|
|
48
|
+
export default function useForm<V, N extends string, M = unknown>({ fieldNames, values, validate, meta, scrollOptions, scrollOnError, focusOnError }: UseFormProps<V, N, M>): UseFormReturn<V, N, M>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { useRef as C, useState as R, useCallback as n } from "react";
|
|
2
|
+
import { DEFAULT_SCROLL_OPTIONS as T, hasError as _ } from "./useForm.utils.es.js";
|
|
3
|
+
function H({
|
|
4
|
+
fieldNames: b,
|
|
5
|
+
values: f,
|
|
6
|
+
validate: E,
|
|
7
|
+
meta: i,
|
|
8
|
+
scrollOptions: m,
|
|
9
|
+
scrollOnError: d = !0,
|
|
10
|
+
focusOnError: o = !1
|
|
11
|
+
}) {
|
|
12
|
+
const s = C(/* @__PURE__ */ new Map()), w = C(/* @__PURE__ */ new Map()), [a, g] = R({}), [k, F] = R(!1), V = d || o, h = n((e) => {
|
|
13
|
+
const r = w.current.get(e);
|
|
14
|
+
if (r)
|
|
15
|
+
return r;
|
|
16
|
+
const c = (t) => {
|
|
17
|
+
t ? s.current.set(e, t) : s.current.delete(e);
|
|
18
|
+
};
|
|
19
|
+
return w.current.set(e, c), c;
|
|
20
|
+
}, []), u = n(
|
|
21
|
+
(e) => {
|
|
22
|
+
requestAnimationFrame(() => {
|
|
23
|
+
for (const r of b) {
|
|
24
|
+
if (!(e == null ? void 0 : e[r])) continue;
|
|
25
|
+
const t = s.current.get(r);
|
|
26
|
+
if (d && t && t.scrollIntoView(m ?? T), o && t) {
|
|
27
|
+
const S = t.querySelector(
|
|
28
|
+
'input:not([type="hidden"]):not([disabled]), textarea:not([disabled])'
|
|
29
|
+
);
|
|
30
|
+
S == null || S.focus({
|
|
31
|
+
preventScroll: !0
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
[b, m, d, o]
|
|
39
|
+
), y = n(() => {
|
|
40
|
+
const e = {};
|
|
41
|
+
return E({ values: f, meta: i, fieldRefs: s.current, error: e });
|
|
42
|
+
}, [E, f, i]), l = n(
|
|
43
|
+
({ callEffectOnError: e = !0 } = {}) => {
|
|
44
|
+
const r = y();
|
|
45
|
+
g(r);
|
|
46
|
+
const c = _(r);
|
|
47
|
+
return c && e && V && u(r), { isValid: !c, errors: r };
|
|
48
|
+
},
|
|
49
|
+
[y, V, u]
|
|
50
|
+
), I = n(
|
|
51
|
+
({ callEffectOnError: e = !0 } = {}) => {
|
|
52
|
+
l({ callEffectOnError: e });
|
|
53
|
+
},
|
|
54
|
+
[l]
|
|
55
|
+
), L = n(() => {
|
|
56
|
+
g({});
|
|
57
|
+
}, []), q = n((e, r) => {
|
|
58
|
+
g((c) => ({ ...c, [e]: r }));
|
|
59
|
+
}, []), A = n(
|
|
60
|
+
(e) => {
|
|
61
|
+
u(e);
|
|
62
|
+
},
|
|
63
|
+
[u]
|
|
64
|
+
), M = n(
|
|
65
|
+
(e) => {
|
|
66
|
+
const r = a == null ? void 0 : a[e];
|
|
67
|
+
if (r)
|
|
68
|
+
return { severity: "error", message: r };
|
|
69
|
+
},
|
|
70
|
+
[a]
|
|
71
|
+
), O = n(
|
|
72
|
+
(e = {}) => async () => {
|
|
73
|
+
F(!0);
|
|
74
|
+
const { isValid: r, errors: c } = l({ callEffectOnError: !0 }), t = {
|
|
75
|
+
values: f,
|
|
76
|
+
meta: i,
|
|
77
|
+
fieldRefs: s.current,
|
|
78
|
+
error: c
|
|
79
|
+
};
|
|
80
|
+
r ? e != null && e.onSuccess && await e.onSuccess(t) : e != null && e.onError && await e.onError(t), e != null && e.onSettled && await e.onSettled(t);
|
|
81
|
+
},
|
|
82
|
+
[l, f, i, F]
|
|
83
|
+
);
|
|
84
|
+
return {
|
|
85
|
+
isSubmitted: k,
|
|
86
|
+
errors: a,
|
|
87
|
+
registerField: h,
|
|
88
|
+
clearErrors: L,
|
|
89
|
+
triggerValidate: I,
|
|
90
|
+
triggerSetFieldError: q,
|
|
91
|
+
triggerEffectOnError: A,
|
|
92
|
+
getFieldHelper: M,
|
|
93
|
+
submit: O
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
H as default
|
|
98
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function t(e){return e?Object.values(e).some(r=>r!=null&&r!==""):!1}const n=Object.freeze({block:"center",inline:"center",behavior:"smooth"});exports.DEFAULT_SCROLL_OPTIONS=n;exports.hasError=t;
|