@simplysm/solid 13.0.55 → 13.0.56
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 +3 -1
- package/dist/components/data/crud-detail/CrudDetail.d.ts +14 -0
- package/dist/components/data/crud-detail/CrudDetail.d.ts.map +1 -0
- package/dist/components/data/crud-detail/CrudDetail.js +348 -0
- package/dist/components/data/crud-detail/CrudDetail.js.map +6 -0
- package/dist/components/data/crud-detail/CrudDetailAfter.d.ts +7 -0
- package/dist/components/data/crud-detail/CrudDetailAfter.d.ts.map +1 -0
- package/dist/components/data/crud-detail/CrudDetailAfter.js +14 -0
- package/dist/components/data/crud-detail/CrudDetailAfter.js.map +6 -0
- package/dist/components/data/crud-detail/CrudDetailBefore.d.ts +7 -0
- package/dist/components/data/crud-detail/CrudDetailBefore.d.ts.map +1 -0
- package/dist/components/data/crud-detail/CrudDetailBefore.js +14 -0
- package/dist/components/data/crud-detail/CrudDetailBefore.js.map +6 -0
- package/dist/components/data/crud-detail/CrudDetailTools.d.ts +7 -0
- package/dist/components/data/crud-detail/CrudDetailTools.d.ts.map +1 -0
- package/dist/components/data/crud-detail/CrudDetailTools.js +14 -0
- package/dist/components/data/crud-detail/CrudDetailTools.js.map +6 -0
- package/dist/components/data/crud-detail/types.d.ts +45 -0
- package/dist/components/data/crud-detail/types.d.ts.map +1 -0
- package/dist/components/data/crud-detail/types.js +1 -0
- package/dist/components/data/crud-detail/types.js.map +6 -0
- package/dist/components/data/crud-sheet/CrudSheet.d.ts +17 -0
- package/dist/components/data/crud-sheet/CrudSheet.d.ts.map +1 -0
- package/dist/components/data/crud-sheet/CrudSheet.js +679 -0
- package/dist/components/data/crud-sheet/CrudSheet.js.map +6 -0
- package/dist/components/data/crud-sheet/CrudSheetColumn.d.ts +5 -0
- package/dist/components/data/crud-sheet/CrudSheetColumn.d.ts.map +1 -0
- package/dist/components/data/crud-sheet/CrudSheetColumn.js +29 -0
- package/dist/components/data/crud-sheet/CrudSheetColumn.js.map +6 -0
- package/dist/components/data/crud-sheet/CrudSheetFilter.d.ts +7 -0
- package/dist/components/data/crud-sheet/CrudSheetFilter.d.ts.map +1 -0
- package/dist/components/data/crud-sheet/CrudSheetFilter.js +14 -0
- package/dist/components/data/crud-sheet/CrudSheetFilter.js.map +6 -0
- package/dist/components/data/crud-sheet/CrudSheetHeader.d.ts +7 -0
- package/dist/components/data/crud-sheet/CrudSheetHeader.d.ts.map +1 -0
- package/dist/components/data/crud-sheet/CrudSheetHeader.js +14 -0
- package/dist/components/data/crud-sheet/CrudSheetHeader.js.map +6 -0
- package/dist/components/data/crud-sheet/CrudSheetTools.d.ts +7 -0
- package/dist/components/data/crud-sheet/CrudSheetTools.d.ts.map +1 -0
- package/dist/components/data/crud-sheet/CrudSheetTools.js +14 -0
- package/dist/components/data/crud-sheet/CrudSheetTools.js.map +6 -0
- package/dist/components/data/crud-sheet/types.d.ts +109 -0
- package/dist/components/data/crud-sheet/types.d.ts.map +1 -0
- package/dist/components/data/crud-sheet/types.js +1 -0
- package/dist/components/data/crud-sheet/types.js.map +6 -0
- package/dist/components/data/kanban/Kanban.d.ts.map +1 -1
- package/dist/components/data/kanban/Kanban.js +137 -138
- package/dist/components/data/kanban/Kanban.js.map +2 -2
- package/dist/components/data/kanban/KanbanContext.d.ts +5 -1
- package/dist/components/data/kanban/KanbanContext.d.ts.map +1 -1
- package/dist/components/data/kanban/KanbanContext.js.map +1 -1
- package/dist/components/data/list/ListItem.d.ts.map +1 -1
- package/dist/components/data/list/ListItem.js +109 -99
- package/dist/components/data/list/ListItem.js.map +2 -2
- package/dist/components/data/sheet/DataSheet.js +1 -1
- package/dist/components/data/sheet/DataSheet.js.map +2 -2
- package/dist/components/data/sheet/DataSheet.styles.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheet.styles.js +1 -1
- package/dist/components/data/sheet/DataSheet.styles.js.map +1 -1
- package/dist/components/disclosure/Dialog.d.ts +16 -10
- package/dist/components/disclosure/Dialog.d.ts.map +1 -1
- package/dist/components/disclosure/Dialog.js +126 -91
- package/dist/components/disclosure/Dialog.js.map +2 -2
- package/dist/components/disclosure/DialogContext.d.ts +2 -4
- package/dist/components/disclosure/DialogContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogContext.js.map +1 -1
- package/dist/components/disclosure/DialogProvider.d.ts.map +1 -1
- package/dist/components/disclosure/DialogProvider.js +14 -9
- package/dist/components/disclosure/DialogProvider.js.map +2 -2
- package/dist/components/disclosure/Dropdown.d.ts +46 -22
- package/dist/components/disclosure/Dropdown.d.ts.map +1 -1
- package/dist/components/disclosure/Dropdown.js +100 -65
- package/dist/components/disclosure/Dropdown.js.map +2 -2
- package/dist/components/feedback/notification/NotificationBanner.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationBanner.js +3 -3
- package/dist/components/feedback/notification/NotificationBanner.js.map +1 -1
- package/dist/components/feedback/notification/NotificationBell.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationBell.js +84 -84
- package/dist/components/feedback/notification/NotificationBell.js.map +2 -2
- package/dist/components/form-control/combobox/Combobox.d.ts +6 -3
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/Combobox.js +150 -168
- package/dist/components/form-control/combobox/Combobox.js.map +2 -2
- package/dist/components/form-control/combobox/ComboboxContext.d.ts +3 -0
- package/dist/components/form-control/combobox/ComboboxContext.d.ts.map +1 -1
- package/dist/components/form-control/combobox/ComboboxContext.js.map +1 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts +0 -2
- package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts.map +1 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.js +9 -17
- package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
- package/dist/components/form-control/field/Field.styles.d.ts.map +1 -1
- package/dist/components/form-control/field/Field.styles.js +2 -1
- package/dist/components/form-control/field/Field.styles.js.map +1 -1
- package/dist/components/form-control/field/NumberInput.d.ts +15 -5
- package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.js +181 -141
- package/dist/components/form-control/field/NumberInput.js.map +2 -2
- package/dist/components/form-control/field/TextInput.d.ts +9 -5
- package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
- package/dist/components/form-control/field/TextInput.js +199 -154
- package/dist/components/form-control/field/TextInput.js.map +2 -2
- package/dist/components/form-control/select/Select.d.ts +3 -3
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +116 -100
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/select/SelectContext.d.ts +9 -1
- package/dist/components/form-control/select/SelectContext.d.ts.map +1 -1
- package/dist/components/form-control/select/SelectContext.js.map +1 -1
- package/dist/components/form-control/select/SelectItem.d.ts.map +1 -1
- package/dist/components/form-control/select/SelectItem.js +77 -67
- package/dist/components/form-control/select/SelectItem.js.map +2 -2
- package/dist/components/layout/topbar/TopbarMenu.d.ts.map +1 -1
- package/dist/components/layout/topbar/TopbarMenu.js +63 -57
- package/dist/components/layout/topbar/TopbarMenu.js.map +2 -2
- package/dist/components/layout/topbar/TopbarUser.d.ts.map +1 -1
- package/dist/components/layout/topbar/TopbarUser.js +53 -54
- package/dist/components/layout/topbar/TopbarUser.js.map +2 -2
- package/dist/hooks/createControllableStore.d.ts +29 -0
- package/dist/hooks/createControllableStore.d.ts.map +1 -0
- package/dist/hooks/createControllableStore.js +19 -0
- package/dist/hooks/createControllableStore.js.map +6 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/styles/patterns.styles.d.ts.map +1 -1
- package/dist/styles/patterns.styles.js +7 -1
- package/dist/styles/patterns.styles.js.map +1 -1
- package/docs/data-components.md +428 -0
- package/docs/disclosure.md +65 -35
- package/docs/form-controls.md +18 -3
- package/docs/helpers.md +0 -39
- package/docs/hooks.md +39 -0
- package/package.json +4 -3
- package/src/components/data/crud-detail/CrudDetail.tsx +346 -0
- package/src/components/data/crud-detail/CrudDetailAfter.tsx +19 -0
- package/src/components/data/crud-detail/CrudDetailBefore.tsx +19 -0
- package/src/components/data/crud-detail/CrudDetailTools.tsx +19 -0
- package/src/components/data/crud-detail/types.ts +58 -0
- package/src/components/data/crud-sheet/CrudSheet.tsx +628 -0
- package/src/components/data/crud-sheet/CrudSheetColumn.tsx +34 -0
- package/src/components/data/crud-sheet/CrudSheetFilter.tsx +21 -0
- package/src/components/data/crud-sheet/CrudSheetHeader.tsx +19 -0
- package/src/components/data/crud-sheet/CrudSheetTools.tsx +21 -0
- package/src/components/data/crud-sheet/types.ts +133 -0
- package/src/components/data/kanban/Kanban.tsx +72 -65
- package/src/components/data/kanban/KanbanContext.ts +7 -1
- package/src/components/data/list/ListItem.tsx +31 -18
- package/src/components/data/sheet/DataSheet.styles.ts +1 -1
- package/src/components/data/sheet/DataSheet.tsx +1 -1
- package/src/components/disclosure/Dialog.tsx +143 -105
- package/src/components/disclosure/DialogContext.ts +2 -4
- package/src/components/disclosure/DialogProvider.tsx +4 -2
- package/src/components/disclosure/Dropdown.tsx +174 -86
- package/src/components/feedback/notification/NotificationBanner.tsx +3 -9
- package/src/components/feedback/notification/NotificationBell.tsx +51 -57
- package/src/components/form-control/combobox/Combobox.tsx +109 -134
- package/src/components/form-control/combobox/ComboboxContext.ts +4 -1
- package/src/components/form-control/date-range-picker/DateRangePicker.tsx +6 -16
- package/src/components/form-control/field/Field.styles.ts +1 -0
- package/src/components/form-control/field/NumberInput.tsx +131 -88
- package/src/components/form-control/field/TextInput.tsx +139 -88
- package/src/components/form-control/select/Select.tsx +85 -67
- package/src/components/form-control/select/SelectContext.ts +12 -1
- package/src/components/form-control/select/SelectItem.tsx +39 -18
- package/src/components/layout/topbar/TopbarMenu.tsx +52 -55
- package/src/components/layout/topbar/TopbarUser.tsx +28 -31
- package/src/hooks/createControllableStore.ts +47 -0
- package/src/index.ts +5 -1
- package/src/styles/patterns.styles.ts +7 -1
- package/tailwind.css +4 -0
- package/dist/helpers/splitSlots.d.ts +0 -25
- package/dist/helpers/splitSlots.d.ts.map +0 -1
- package/dist/helpers/splitSlots.js +0 -25
- package/dist/helpers/splitSlots.js.map +0 -6
- package/dist/hooks/createItemTemplate.d.ts +0 -17
- package/dist/hooks/createItemTemplate.d.ts.map +0 -1
- package/dist/hooks/createItemTemplate.js +0 -40
- package/dist/hooks/createItemTemplate.js.map +0 -6
- package/src/helpers/splitSlots.ts +0 -51
- package/src/hooks/createItemTemplate.tsx +0 -42
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type JSX,
|
|
3
3
|
type ParentComponent,
|
|
4
|
+
createContext,
|
|
4
5
|
createEffect,
|
|
6
|
+
createUniqueId,
|
|
5
7
|
onCleanup,
|
|
6
8
|
Show,
|
|
7
9
|
splitProps,
|
|
8
10
|
For,
|
|
9
11
|
useContext,
|
|
12
|
+
createSignal,
|
|
10
13
|
} from "solid-js";
|
|
11
14
|
import { Portal } from "solid-js/web";
|
|
12
15
|
import clsx from "clsx";
|
|
@@ -21,15 +24,42 @@ import { borderSubtle } from "../../styles/tokens.styles";
|
|
|
21
24
|
import { DialogDefaultsContext } from "./DialogContext";
|
|
22
25
|
import { registerDialog, unregisterDialog, bringToFront } from "./dialogZIndex";
|
|
23
26
|
|
|
27
|
+
type SlotAccessor = (() => JSX.Element) | undefined;
|
|
28
|
+
|
|
29
|
+
interface DialogSlotsContextValue {
|
|
30
|
+
setHeader: (content: SlotAccessor) => void;
|
|
31
|
+
setAction: (content: SlotAccessor) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const DialogSlotsContext = createContext<DialogSlotsContextValue>();
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 다이얼로그 헤더 서브 컴포넌트
|
|
38
|
+
*/
|
|
39
|
+
const DialogHeader: ParentComponent = (props) => {
|
|
40
|
+
const ctx = useContext(DialogSlotsContext)!;
|
|
41
|
+
// eslint-disable-next-line solid/reactivity -- slot accessor: children은 렌더 시점에 lazy 평가됨
|
|
42
|
+
ctx.setHeader(() => props.children);
|
|
43
|
+
onCleanup(() => ctx.setHeader(undefined));
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 다이얼로그 액션 서브 컴포넌트
|
|
49
|
+
*/
|
|
50
|
+
const DialogAction: ParentComponent = (props) => {
|
|
51
|
+
const ctx = useContext(DialogSlotsContext)!;
|
|
52
|
+
// eslint-disable-next-line solid/reactivity -- slot accessor: children은 렌더 시점에 lazy 평가됨
|
|
53
|
+
ctx.setAction(() => props.children);
|
|
54
|
+
onCleanup(() => ctx.setAction(undefined));
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
|
|
24
58
|
export interface DialogProps {
|
|
25
59
|
/** 모달 열림 상태 */
|
|
26
60
|
open?: boolean;
|
|
27
61
|
/** 열림 상태 변경 시 콜백 */
|
|
28
62
|
onOpenChange?: (open: boolean) => void;
|
|
29
|
-
/** 모달 제목 */
|
|
30
|
-
title: string;
|
|
31
|
-
/** 헤더 숨김 */
|
|
32
|
-
hideHeader?: boolean;
|
|
33
63
|
/** 닫기 버튼 표시 (기본: true) */
|
|
34
64
|
closable?: boolean;
|
|
35
65
|
/** 백드롭 클릭으로 닫기 */
|
|
@@ -56,16 +86,12 @@ export interface DialogProps {
|
|
|
56
86
|
position?: "bottom-right" | "top-right";
|
|
57
87
|
/** 헤더 스타일 */
|
|
58
88
|
headerStyle?: JSX.CSSProperties | string;
|
|
59
|
-
/** 헤더 액션 영역 */
|
|
60
|
-
headerAction?: JSX.Element;
|
|
61
89
|
/** 닫기 전 확인 함수 */
|
|
62
90
|
canDeactivate?: () => boolean;
|
|
63
91
|
/** 닫기 애니메이션 완료 후 콜백 */
|
|
64
92
|
onCloseComplete?: () => void;
|
|
65
93
|
/** 추가 CSS 클래스 */
|
|
66
94
|
class?: string;
|
|
67
|
-
/** 자식 요소 */
|
|
68
|
-
children: JSX.Element;
|
|
69
95
|
}
|
|
70
96
|
|
|
71
97
|
type ResizeDirection =
|
|
@@ -124,19 +150,23 @@ const resizePositionMap: Record<ResizeDirection, string> = {
|
|
|
124
150
|
* const [open, setOpen] = createSignal(false);
|
|
125
151
|
*
|
|
126
152
|
* <Button onClick={() => setOpen(true)}>다이얼로그 열기</Button>
|
|
127
|
-
* <Dialog open={open()} onOpenChange={setOpen}
|
|
153
|
+
* <Dialog open={open()} onOpenChange={setOpen}>
|
|
154
|
+
* <Dialog.Header>내 다이얼로그</Dialog.Header>
|
|
128
155
|
* <div class="p-4">다이얼로그 내용</div>
|
|
129
156
|
* </Dialog>
|
|
130
157
|
* ```
|
|
131
158
|
*/
|
|
132
|
-
|
|
159
|
+
interface DialogComponent extends ParentComponent<DialogProps> {
|
|
160
|
+
Header: typeof DialogHeader;
|
|
161
|
+
Action: typeof DialogAction;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const Dialog: DialogComponent = (props) => {
|
|
133
165
|
const dialogDefaults = useContext(DialogDefaultsContext);
|
|
134
166
|
|
|
135
167
|
const [local] = splitProps(props, [
|
|
136
168
|
"open",
|
|
137
169
|
"onOpenChange",
|
|
138
|
-
"title",
|
|
139
|
-
"hideHeader",
|
|
140
170
|
"closable",
|
|
141
171
|
"closeOnBackdrop",
|
|
142
172
|
"closeOnEscape",
|
|
@@ -150,13 +180,20 @@ export const Dialog: ParentComponent<DialogProps> = (props) => {
|
|
|
150
180
|
"minHeight",
|
|
151
181
|
"position",
|
|
152
182
|
"headerStyle",
|
|
153
|
-
"headerAction",
|
|
154
183
|
"canDeactivate",
|
|
155
184
|
"onCloseComplete",
|
|
156
185
|
"class",
|
|
157
186
|
"children",
|
|
158
187
|
]);
|
|
159
188
|
|
|
189
|
+
const headerId = "dialog-header-" + createUniqueId();
|
|
190
|
+
|
|
191
|
+
const [header, _setHeader] = createSignal<SlotAccessor>();
|
|
192
|
+
const setHeader = (content: SlotAccessor) => _setHeader(() => content);
|
|
193
|
+
const [action, _setAction] = createSignal<SlotAccessor>();
|
|
194
|
+
const setAction = (content: SlotAccessor) => _setAction(() => content);
|
|
195
|
+
const hasHeader = () => header() !== undefined;
|
|
196
|
+
|
|
160
197
|
const [open, setOpen] = createControllableSignal({
|
|
161
198
|
value: () => local.open ?? false,
|
|
162
199
|
onChange: () => local.onOpenChange,
|
|
@@ -185,8 +222,8 @@ export const Dialog: ParentComponent<DialogProps> = (props) => {
|
|
|
185
222
|
// dialog ref
|
|
186
223
|
let dialogRef: HTMLDivElement | undefined;
|
|
187
224
|
|
|
188
|
-
// wrapper ref
|
|
189
|
-
|
|
225
|
+
// wrapper ref (signal로 관리하여 Portal ref 타이밍 보장)
|
|
226
|
+
const [wrapperRef, setWrapperRef] = createSignal<HTMLDivElement>();
|
|
190
227
|
|
|
191
228
|
const closeOnEscape = () => local.closeOnEscape ?? dialogDefaults?.().closeOnEscape ?? true;
|
|
192
229
|
const closeOnBackdrop = () =>
|
|
@@ -210,11 +247,10 @@ export const Dialog: ParentComponent<DialogProps> = (props) => {
|
|
|
210
247
|
// 열릴 때 등록, 닫힐 때 해제
|
|
211
248
|
createEffect(() => {
|
|
212
249
|
if (!open()) return;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
});
|
|
250
|
+
const el = wrapperRef();
|
|
251
|
+
if (!el) return;
|
|
252
|
+
registerDialog(el);
|
|
253
|
+
onCleanup(() => unregisterDialog(el));
|
|
218
254
|
});
|
|
219
255
|
|
|
220
256
|
// 닫기 시도 (canDeactivate 체크)
|
|
@@ -244,21 +280,22 @@ export const Dialog: ParentComponent<DialogProps> = (props) => {
|
|
|
244
280
|
|
|
245
281
|
// z-index 자동 관리
|
|
246
282
|
const handleDialogFocus = () => {
|
|
247
|
-
|
|
248
|
-
|
|
283
|
+
const el = wrapperRef();
|
|
284
|
+
if (!el) return;
|
|
285
|
+
bringToFront(el);
|
|
249
286
|
};
|
|
250
287
|
|
|
251
288
|
// 드래그 이동
|
|
252
289
|
const handleHeaderPointerDown = (event: PointerEvent) => {
|
|
253
290
|
// movable 기본값은 true
|
|
254
291
|
if (local.movable === false) return;
|
|
255
|
-
|
|
292
|
+
const wrapperEl = wrapperRef();
|
|
293
|
+
if (!dialogRef || !wrapperEl) return;
|
|
256
294
|
// 닫기 버튼 등 인터랙티브 요소에서 시작된 이벤트는 드래그로 처리하지 않음
|
|
257
295
|
if ((event.target as HTMLElement).closest("button")) return;
|
|
258
296
|
|
|
259
297
|
const target = event.currentTarget as HTMLElement;
|
|
260
298
|
const dialogEl = dialogRef;
|
|
261
|
-
const wrapperEl = wrapperRef;
|
|
262
299
|
|
|
263
300
|
const startX = event.clientX;
|
|
264
301
|
const startY = event.clientY;
|
|
@@ -445,92 +482,93 @@ export const Dialog: ParentComponent<DialogProps> = (props) => {
|
|
|
445
482
|
return (
|
|
446
483
|
<Show when={mounted()}>
|
|
447
484
|
<Portal>
|
|
448
|
-
<
|
|
449
|
-
ref={
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
class={wrapperClass()}
|
|
454
|
-
>
|
|
455
|
-
{/* 백드롭 */}
|
|
456
|
-
<Show when={!local.float}>
|
|
457
|
-
<div data-modal-backdrop class={backdropClass()} onClick={handleBackdropClick} />
|
|
458
|
-
</Show>
|
|
459
|
-
|
|
460
|
-
{/* 다이얼로그 */}
|
|
461
|
-
<div
|
|
462
|
-
ref={(el) => {
|
|
463
|
-
dialogRef = el;
|
|
464
|
-
}}
|
|
465
|
-
data-modal-dialog
|
|
466
|
-
role="dialog"
|
|
467
|
-
aria-modal={local.float ? undefined : true}
|
|
468
|
-
aria-label={local.title}
|
|
469
|
-
tabIndex={0}
|
|
470
|
-
class={twMerge(dialogBaseClass(), local.class)}
|
|
471
|
-
style={dialogStyle()}
|
|
472
|
-
onFocus={handleDialogFocus}
|
|
473
|
-
onTransitionEnd={handleTransitionEnd}
|
|
474
|
-
>
|
|
475
|
-
{/* 헤더 */}
|
|
476
|
-
<Show when={!local.hideHeader}>
|
|
477
|
-
<div
|
|
478
|
-
data-modal-header
|
|
479
|
-
class={clsx(headerClass(), "touch-none")}
|
|
480
|
-
style={
|
|
481
|
-
typeof local.headerStyle === "string"
|
|
482
|
-
? mergeStyles(local.headerStyle)
|
|
483
|
-
: local.headerStyle
|
|
484
|
-
}
|
|
485
|
-
onPointerDown={handleHeaderPointerDown}
|
|
486
|
-
>
|
|
487
|
-
<h5 class={clsx("flex-1", "px-4 py-2", "text-sm font-bold")}>{local.title}</h5>
|
|
488
|
-
{local.headerAction}
|
|
489
|
-
<Show when={local.closable ?? true}>
|
|
490
|
-
<button
|
|
491
|
-
data-modal-close
|
|
492
|
-
type="button"
|
|
493
|
-
class={clsx(
|
|
494
|
-
"inline-flex items-center justify-center",
|
|
495
|
-
"px-3 py-2",
|
|
496
|
-
"text-base-400 dark:text-base-500",
|
|
497
|
-
"hover:text-base-600 dark:hover:text-base-300",
|
|
498
|
-
"cursor-pointer",
|
|
499
|
-
"transition-colors",
|
|
500
|
-
)}
|
|
501
|
-
onClick={handleCloseClick}
|
|
502
|
-
>
|
|
503
|
-
<Icon icon={IconX} size="1.25em" />
|
|
504
|
-
</button>
|
|
505
|
-
</Show>
|
|
506
|
-
</div>
|
|
485
|
+
<DialogSlotsContext.Provider value={{ setHeader, setAction }}>
|
|
486
|
+
<div ref={setWrapperRef} data-modal class={wrapperClass()}>
|
|
487
|
+
{/* 백드롭 */}
|
|
488
|
+
<Show when={!local.float}>
|
|
489
|
+
<div data-modal-backdrop class={backdropClass()} onClick={handleBackdropClick} />
|
|
507
490
|
</Show>
|
|
508
491
|
|
|
509
|
-
{/*
|
|
510
|
-
<div
|
|
511
|
-
{
|
|
512
|
-
|
|
492
|
+
{/* 다이얼로그 */}
|
|
493
|
+
<div
|
|
494
|
+
ref={(el) => {
|
|
495
|
+
dialogRef = el;
|
|
496
|
+
}}
|
|
497
|
+
data-modal-dialog
|
|
498
|
+
role="dialog"
|
|
499
|
+
aria-modal={local.float ? undefined : true}
|
|
500
|
+
aria-labelledby={hasHeader() ? headerId : undefined}
|
|
501
|
+
tabIndex={0}
|
|
502
|
+
class={twMerge(dialogBaseClass(), local.class)}
|
|
503
|
+
style={dialogStyle()}
|
|
504
|
+
onFocus={handleDialogFocus}
|
|
505
|
+
onTransitionEnd={handleTransitionEnd}
|
|
506
|
+
>
|
|
507
|
+
{/* 헤더 */}
|
|
508
|
+
<Show when={hasHeader()}>
|
|
509
|
+
<div
|
|
510
|
+
data-modal-header
|
|
511
|
+
class={clsx(headerClass(), "touch-none")}
|
|
512
|
+
style={
|
|
513
|
+
typeof local.headerStyle === "string"
|
|
514
|
+
? mergeStyles(local.headerStyle)
|
|
515
|
+
: local.headerStyle
|
|
516
|
+
}
|
|
517
|
+
onPointerDown={handleHeaderPointerDown}
|
|
518
|
+
>
|
|
519
|
+
<h5 id={headerId} class={clsx("flex-1", "px-4 py-2", "text-sm font-bold")}>
|
|
520
|
+
{header()!()}
|
|
521
|
+
</h5>
|
|
522
|
+
<Show when={action()}>{action()!()}</Show>
|
|
523
|
+
<Show when={local.closable ?? true}>
|
|
524
|
+
<button
|
|
525
|
+
data-modal-close
|
|
526
|
+
type="button"
|
|
527
|
+
class={clsx(
|
|
528
|
+
"inline-flex items-center justify-center",
|
|
529
|
+
"px-3 py-2",
|
|
530
|
+
"text-base-400 dark:text-base-500",
|
|
531
|
+
"hover:text-base-600 dark:hover:text-base-300",
|
|
532
|
+
"cursor-pointer",
|
|
533
|
+
"transition-colors",
|
|
534
|
+
)}
|
|
535
|
+
onClick={handleCloseClick}
|
|
536
|
+
>
|
|
537
|
+
<Icon icon={IconX} size="1.25em" />
|
|
538
|
+
</button>
|
|
539
|
+
</Show>
|
|
540
|
+
</div>
|
|
541
|
+
</Show>
|
|
542
|
+
|
|
543
|
+
{/* 콘텐츠 */}
|
|
544
|
+
<div data-modal-content class={dialogContentClass}>
|
|
545
|
+
{local.children}
|
|
546
|
+
</div>
|
|
513
547
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
548
|
+
{/* 리사이즈 바 */}
|
|
549
|
+
<Show when={local.resizable}>
|
|
550
|
+
<For each={RESIZE_DIRECTIONS}>
|
|
551
|
+
{(direction) => (
|
|
552
|
+
<div
|
|
553
|
+
data-resize-bar={direction}
|
|
554
|
+
class={clsx(
|
|
555
|
+
"absolute",
|
|
556
|
+
"touch-none",
|
|
557
|
+
resizePositionMap[direction],
|
|
558
|
+
resizeCursorMap[direction],
|
|
559
|
+
)}
|
|
560
|
+
onPointerDown={(e) => handleResizeBarPointerDown(e, direction)}
|
|
561
|
+
/>
|
|
562
|
+
)}
|
|
563
|
+
</For>
|
|
564
|
+
</Show>
|
|
565
|
+
</div>
|
|
531
566
|
</div>
|
|
532
|
-
</
|
|
567
|
+
</DialogSlotsContext.Provider>
|
|
533
568
|
</Portal>
|
|
534
569
|
</Show>
|
|
535
570
|
);
|
|
536
571
|
};
|
|
572
|
+
|
|
573
|
+
Dialog.Header = DialogHeader;
|
|
574
|
+
Dialog.Action = DialogAction;
|
|
@@ -13,10 +13,8 @@ export const DialogDefaultsContext = createContext<Accessor<DialogDefaults>>();
|
|
|
13
13
|
|
|
14
14
|
/** 프로그래매틱 다이얼로그 옵션 */
|
|
15
15
|
export interface DialogShowOptions {
|
|
16
|
-
/** 다이얼로그
|
|
17
|
-
|
|
18
|
-
/** 헤더 숨김 */
|
|
19
|
-
hideHeader?: boolean;
|
|
16
|
+
/** 다이얼로그 헤더 */
|
|
17
|
+
header?: JSX.Element;
|
|
20
18
|
/** 닫기 버튼 표시 */
|
|
21
19
|
closable?: boolean;
|
|
22
20
|
/** 백드롭 클릭으로 닫기 */
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type ParentComponent,
|
|
4
4
|
createSignal,
|
|
5
5
|
For,
|
|
6
|
+
Show,
|
|
6
7
|
splitProps,
|
|
7
8
|
type JSX,
|
|
8
9
|
} from "solid-js";
|
|
@@ -115,8 +116,6 @@ export const DialogProvider: ParentComponent<DialogProviderProps> = (props) => {
|
|
|
115
116
|
}
|
|
116
117
|
}}
|
|
117
118
|
onCloseComplete={() => removeEntry(entry.id)}
|
|
118
|
-
title={entry.options.title}
|
|
119
|
-
hideHeader={entry.options.hideHeader}
|
|
120
119
|
closable={entry.options.closable}
|
|
121
120
|
closeOnBackdrop={entry.options.closeOnBackdrop}
|
|
122
121
|
closeOnEscape={entry.options.closeOnEscape}
|
|
@@ -132,6 +131,9 @@ export const DialogProvider: ParentComponent<DialogProviderProps> = (props) => {
|
|
|
132
131
|
headerStyle={entry.options.headerStyle}
|
|
133
132
|
canDeactivate={entry.options.canDeactivate}
|
|
134
133
|
>
|
|
134
|
+
<Show when={entry.options.header !== undefined}>
|
|
135
|
+
<Dialog.Header>{entry.options.header}</Dialog.Header>
|
|
136
|
+
</Show>
|
|
135
137
|
<DialogInstanceContext.Provider value={instance}>
|
|
136
138
|
{entry.factory()}
|
|
137
139
|
</DialogInstanceContext.Provider>
|