@simplysm/solid 13.0.95 → 13.0.96
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 +22 -9
- package/dist/components/layout/sidebar/Sidebar.d.ts +5 -0
- package/dist/components/layout/sidebar/Sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar/Sidebar.js +7 -4
- package/dist/components/layout/sidebar/Sidebar.js.map +2 -2
- package/docs/display-feedback.md +142 -17
- package/docs/features.md +40 -0
- package/docs/form-controls.md +226 -17
- package/docs/layout-data.md +6 -0
- package/docs/providers-hooks.md +145 -40
- package/package.json +5 -5
- package/src/components/layout/sidebar/Sidebar.tsx +9 -3
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install @simplysm/solid
|
|
|
15
15
|
|
|
16
16
|
| 카테고리 | 설명 |
|
|
17
17
|
|---------|------|
|
|
18
|
-
| [폼 컨트롤](docs/form-controls.md) | TextInput, NumberInput, Select, Combobox, DatePicker, DateRangePicker, Checkbox, RadioGroup, CheckboxGroup, ColorPicker, RichTextEditor, Numpad, StatePreset 등 |
|
|
18
|
+
| [폼 컨트롤](docs/form-controls.md) | Button, TextInput, NumberInput, Select, Combobox, DatePicker, DateRangePicker, Checkbox, RadioGroup, CheckboxGroup, ColorPicker, RichTextEditor, Numpad, StatePreset 등 |
|
|
19
19
|
| [레이아웃 & 데이터](docs/layout-data.md) | FormGroup, FormTable, Sidebar, Topbar, Table, DataSheet, List, Calendar, Kanban, Pagination 등 |
|
|
20
20
|
| [디스플레이 & 피드백](docs/display-feedback.md) | Card, Alert, Icon, Link, Tag, Barcode, Echarts, Dialog, Dropdown, Collapse, Tabs, Notification, Busy, Progress, Print 등 |
|
|
21
21
|
| [프로바이더 & 훅](docs/providers-hooks.md) | SystemProvider, ThemeProvider, I18nProvider, SharedDataProvider, useDialog, useBusy, useNotification, createAppStructure 등 |
|
|
@@ -119,25 +119,38 @@ Tailwind 클래스 프리셋. 테마 일관성을 위해 사용한다.
|
|
|
119
119
|
import { bg, border, text, pad, gap, themeTokens } from "@simplysm/solid";
|
|
120
120
|
|
|
121
121
|
// 배경색
|
|
122
|
-
bg.surface //
|
|
123
|
-
bg.muted // base-100
|
|
124
|
-
bg.subtle // base-200
|
|
122
|
+
bg.surface // bg-white dark:bg-base-900
|
|
123
|
+
bg.muted // bg-base-100 dark:bg-base-800
|
|
124
|
+
bg.subtle // bg-base-200 dark:bg-base-700
|
|
125
125
|
|
|
126
126
|
// 테두리색
|
|
127
|
-
border.default // base-200
|
|
127
|
+
border.default // border-base-200 dark:border-base-700
|
|
128
128
|
|
|
129
129
|
// 텍스트색
|
|
130
|
-
text.default // base-900
|
|
131
|
-
text.muted // base-400
|
|
130
|
+
text.default // text-base-900 dark:text-base-100
|
|
131
|
+
text.muted // text-base-400 dark:text-base-500
|
|
132
132
|
text.placeholder // placeholder 전용
|
|
133
133
|
|
|
134
134
|
// 패딩/갭 프리셋
|
|
135
|
+
pad.xs // px-1 py-0
|
|
136
|
+
pad.sm // px-1.5 py-0.5
|
|
135
137
|
pad.md // px-2 py-1
|
|
138
|
+
pad.lg // px-3 py-2
|
|
139
|
+
pad.xl // px-4 py-3
|
|
140
|
+
|
|
141
|
+
gap.xs // gap-0
|
|
142
|
+
gap.sm // gap-0.5
|
|
136
143
|
gap.md // gap-1
|
|
144
|
+
gap.lg // gap-1.5
|
|
145
|
+
gap.xl // gap-2
|
|
137
146
|
|
|
138
147
|
// 테마 토큰 (semantic theme별 solid/light/text/hoverBg/border)
|
|
139
|
-
themeTokens.primary.solid
|
|
140
|
-
themeTokens.
|
|
148
|
+
themeTokens.primary.solid // bg-primary-500 text-white
|
|
149
|
+
themeTokens.primary.solidHover // hover:bg-primary-600 dark:hover:bg-primary-400
|
|
150
|
+
themeTokens.primary.light // bg-primary-100 text-primary-900
|
|
151
|
+
themeTokens.primary.text // text-primary-600 dark:text-primary-400
|
|
152
|
+
themeTokens.primary.hoverBg // hover:bg-primary-100 dark:hover:bg-primary-800/30
|
|
153
|
+
themeTokens.primary.border // border-primary-300 dark:border-primary-600
|
|
141
154
|
```
|
|
142
155
|
|
|
143
156
|
### 라이트/다크 테마
|
|
@@ -31,6 +31,11 @@ export interface SidebarMenuProps extends Omit<JSX.HTMLAttributes<HTMLDivElement
|
|
|
31
31
|
* Menu items array
|
|
32
32
|
*/
|
|
33
33
|
menus: AppMenu[];
|
|
34
|
+
/**
|
|
35
|
+
* When true, all nested menu lists are expanded on initial render.
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
defaultOpen?: boolean;
|
|
34
39
|
}
|
|
35
40
|
export interface SidebarUserMenu {
|
|
36
41
|
title: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\components\\layout\\sidebar\\Sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,GAAG,EACR,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,MAAM,EASZ,MAAM,UAAU,CAAC;AAKlB,OAAO,KAAK,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAanE;;;GAGG;AACH,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CAC5B;AAID,iBAAS,WAAW,IAAI,mBAAmB,CAM1C;AAED,iBAAS,mBAAmB,IAAI,mBAAmB,GAAG,SAAS,CAE9D;AAED,eAAO,MAAM,UAAU;;CAErB,CAAC;AAMH,MAAM,WAAW,qBAAsB,SAAQ,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC;IAC/E,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAiGD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5F;;OAEG;IACH,KAAK,EAAE,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["..\\..\\..\\..\\src\\components\\layout\\sidebar\\Sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,GAAG,EACR,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,MAAM,EASZ,MAAM,UAAU,CAAC;AAKlB,OAAO,KAAK,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAanE;;;GAGG;AACH,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CAC5B;AAID,iBAAS,WAAW,IAAI,mBAAmB,CAM1C;AAED,iBAAS,mBAAmB,IAAI,mBAAmB,GAAG,SAAS,CAE9D;AAED,eAAO,MAAM,UAAU;;CAErB,CAAC;AAMH,MAAM,WAAW,qBAAsB,SAAQ,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC;IAC/E,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAiGD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5F;;OAEG;IACH,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAoJD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3F;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAElC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;CAC3B;AA2FD,MAAM,WAAW,YAAa,SAAQ,GAAG,CAAC,cAAc,CAAC,WAAW,CAAC;IACnE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AA8DD,eAAO,MAAM,OAAO;;;;CAIlB,CAAC"}
|
|
@@ -104,7 +104,7 @@ const SidebarContainer = (props) => {
|
|
|
104
104
|
};
|
|
105
105
|
const MenuContext = createContext();
|
|
106
106
|
const SidebarMenu = (props) => {
|
|
107
|
-
const [local, rest] = splitProps(props, ["menus", "class"]);
|
|
107
|
+
const [local, rest] = splitProps(props, ["menus", "class", "defaultOpen"]);
|
|
108
108
|
const location = useLocation();
|
|
109
109
|
const findSelectedPath = (menus, pathname, path = []) => {
|
|
110
110
|
for (const menu of menus) {
|
|
@@ -125,8 +125,11 @@ const SidebarMenu = (props) => {
|
|
|
125
125
|
});
|
|
126
126
|
const getClassName = () => twMerge("flex-1 overflow-y-auto", local.class);
|
|
127
127
|
return _$createComponent(MenuContext.Provider, {
|
|
128
|
-
value
|
|
129
|
-
|
|
128
|
+
get value() {
|
|
129
|
+
return {
|
|
130
|
+
initialOpenItems,
|
|
131
|
+
defaultOpen: local.defaultOpen ?? false
|
|
132
|
+
};
|
|
130
133
|
},
|
|
131
134
|
get children() {
|
|
132
135
|
var _el$3 = _tmpl$3(), _el$4 = _el$3.firstChild;
|
|
@@ -165,7 +168,7 @@ const MenuItem = (props) => {
|
|
|
165
168
|
};
|
|
166
169
|
const isSelected = () => props.menu.href === location.pathname;
|
|
167
170
|
const shouldBeOpen = () => menuContext.initialOpenItems().has(props.menu);
|
|
168
|
-
const [open, setOpen] = createSignal(
|
|
171
|
+
const [open, setOpen] = createSignal(menuContext.defaultOpen);
|
|
169
172
|
createEffect(() => {
|
|
170
173
|
if (shouldBeOpen()) {
|
|
171
174
|
setOpen(true);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/layout/sidebar/Sidebar.tsx"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;AAAA,SAMEA,eACAC,YACAC,YACAC,YACAC,cACAC,cACAC,MACAC,WACK;AACP,SAASC,gBAAgBC,aAAaC,mBAAmB;AACzD,SAASC,wBAAwB;AACjC,OAAOC,UAAU;AACjB,SAASC,eAAe;AAExB,SAASC,gBAAgB;AACzB,SAASC,IAAIC,QAAQC,YAAY;AAEjC,SAASC,mBAAmB;AAE5B,SAASC,mBAAmB;AAC5B,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,YAAY;AACrB,SAASC,YAAY;AACrB,SAASC,gBAAgB;AACzB,SAASC,eAAe;AAExB,KAAKL;AAQE,MAAMM,iBAAiB;AAe9B,MAAMC,iBAAiB3B,cAAmC;AAE1D,SAAS4B,cAAmC;AAC1C,QAAMC,UAAU5B,WAAW0B,cAAc;AACzC,MAAI,CAACE,SAAS;AACZ,UAAM,IAAIC,MAAM,iDAAiD;EACnE;AACA,SAAOD;AACT;AAEA,SAASE,sBAAuD;AAC9D,SAAO9B,WAAW0B,cAAc;AAClC;AAEO,MAAMK,aAAaC,OAAOC,OAAON,aAAa;EACnDO,UAAUJ;AACZ,CAAC;AAsCD,MAAMK,mBAA4DC,WAAU;AAC1E,QAAM,CAACC,OAAOC,IAAI,IAAIrC,WAAWmC,OAAO,CAAC,YAAY,SAAS,OAAO,CAAC;AAEtE,QAAMG,OAAOf,QAAQ;AACrB,QAAM,CAACgB,QAAQC,SAAS,IAAItC,aAAa,KAAK;AAG9C,QAAMuC,YAAYhC,iBAAiBe,cAAc;AAGjD,QAAMkB,SAASzC,WAAW,MAAM;AAC9B,QAAIwC,UAAU,GAAG;AACf,aAAO,CAACF,OAAO;IACjB;AACA,WAAOA,OAAO;EAChB,CAAC;AAGD,QAAMI,sBAAsBA,MAAM;AAChCH,cAAU,KAAK;EACjB;AAGAlC,iBAAe,MAAM;AACnB,QAAI,CAACmC,UAAU,KAAKF,OAAO,GAAG;AAC5BC,gBAAU,KAAK;IACjB;EACF,CAAC;AAGD,QAAMI,iBAAiBA,MAAM;AAC3B,QAAIH,UAAU,KAAKC,OAAO,GAAG;AAC3B,aAAO;IACT;AACA,WAAOG;EACT;AAEA,QAAMC,eAAeA,MAAMnC,QAAQ,0DAA0DyB,MAAMW,KAAK;AAExG,SAAAC,kBACGvB,eAAewB,UAAQ;IAACC,OAAO;MAAEX;MAAQC;IAAU;IAAC,IAAAW,WAAA;AAAA,UAAAC,OAAAC,QAAA;AAAAC,eAAAF,MAAAG,aAE7ClB,MAAI;QAAA,0BAAA;QAAA,KAAA,OAAA,IAAA;AAAA,iBAEDS,aAAa;QAAC;QAAA,IACrBU,QAAK;AAAA,iBAAEvC,YAAYmB,MAAMoB,OAAO;YAAE,gBAAgBZ,eAAe;UAAE,CAAC;QAAC;MAAA,CAAA,GAAA,OAAA,IAAA;AAAAa,eAAAL,MAAA,MAEpEhB,MAAMe,UAAQ,IAAA;AAAAM,eAAAL,MAAAJ,kBACd5C,MAAI;QAAA,IAACsD,OAAI;AAAA,iBAAEC,OAAA,MAAA,CAAA,CAAA,CAAClB,UAAU,CAAC,EAAA,KAAIC,OAAO;QAAC;QAAA,IAAAS,WAAA;AAAA,cAAAS,QAAAC,OAAA;AAAAD,gBAAAE,YAIpBC,OAAMA,EAAEC,QAAQ,YAAYrB,oBAAoB;AAACiB,gBAAAK,UADpDtB;AAAmBuB,mBAAA,MAAAC,eAAAP,OAAA,cAGhBtB,KAAK8B,EAAE,sBAAsB,CAAC,CAAA;AAAA,iBAAAR;QAAA;MAAA,CAAA,GAAA,IAAA;AAAA,aAAAR;IAAA;EAAA,CAAA;AAOtD;
|
|
5
|
-
"names": ["createContext", "useContext", "splitProps", "createMemo", "createSignal", "createEffect", "Show", "For", "useBeforeLeave", "useLocation", "useNavigate", "createMediaQuery", "clsx", "twMerge", "IconUser", "bg", "border", "text", "themeTokens", "mergeStyles", "ripple", "Collapse", "Icon", "List", "ListItem", "useI18n", "SM_MEDIA_QUERY", "SidebarContext", "_useSidebar", "context", "Error", "_useSidebarOptional", "useSidebar", "Object", "assign", "optional", "SidebarContainer", "props", "local", "rest", "i18n", "toggle", "setToggle", "isDesktop", "isOpen", "handleBackdropClick", "getPaddingLeft", "undefined", "getClassName", "class", "_$createComponent", "Provider", "value", "children", "_el$", "_tmpl$2", "_$spread", "_$mergeProps", "style", "_$insert", "when", "_$memo", "_el$2", "_tmpl$", "$$keydown", "e", "key", "$$click", "_$effect", "_$setAttribute", "t", "MenuContext", "SidebarMenu", "location", "findSelectedPath", "menus", "pathname", "path", "menu", "currentPath", "href", "found", "initialOpenItems", "selectedPath", "Set", "slice", "_el$3", "_tmpl$3", "_el$4", "firstChild", "inset", "each", "MenuItem", "_$className", "muted", "navigate", "menuContext", "hasChildren", "length", "isExternalLink", "includes", "isSelected", "shouldBeOpen", "has", "open", "setOpen", "handleClick", "v", "window", "selected", "onOpenChange", "onClick", "size", "icon", "_el$5", "_tmpl$4", "title", "Children", "child", "SidebarUser", "hasMenus", "handleMenuClick", "getHeaderClassName", "base", "hoverBg", "getContainerClassName", "_el$6", "_tmpl$7", "_el$7", "_el$8", "_el$9", "_$use", "description", "fallback", "_el$12", "_tmpl$8", "name", "_el$0", "_tmpl$5", "_el$1", "_el$10", "nextSibling", "_el$11", "_tmpl$6", "default", "_p$", "_v$", "_v$2", "SidebarInner", "getTransform", "_el$13", "_tmpl$9", "transform", "inert", "Sidebar", "Container", "Menu", "User", "_$delegateEvents"]
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["createContext", "useContext", "splitProps", "createMemo", "createSignal", "createEffect", "Show", "For", "useBeforeLeave", "useLocation", "useNavigate", "createMediaQuery", "clsx", "twMerge", "IconUser", "bg", "border", "text", "themeTokens", "mergeStyles", "ripple", "Collapse", "Icon", "List", "ListItem", "useI18n", "SM_MEDIA_QUERY", "SidebarContext", "_useSidebar", "context", "Error", "_useSidebarOptional", "useSidebar", "Object", "assign", "optional", "SidebarContainer", "props", "local", "rest", "i18n", "toggle", "setToggle", "isDesktop", "isOpen", "handleBackdropClick", "getPaddingLeft", "undefined", "getClassName", "class", "_$createComponent", "Provider", "value", "children", "_el$", "_tmpl$2", "_$spread", "_$mergeProps", "style", "_$insert", "when", "_$memo", "_el$2", "_tmpl$", "$$keydown", "e", "key", "$$click", "_$effect", "_$setAttribute", "t", "MenuContext", "SidebarMenu", "location", "findSelectedPath", "menus", "pathname", "path", "menu", "currentPath", "href", "found", "initialOpenItems", "selectedPath", "Set", "slice", "defaultOpen", "_el$3", "_tmpl$3", "_el$4", "firstChild", "inset", "each", "MenuItem", "_$className", "muted", "navigate", "menuContext", "hasChildren", "length", "isExternalLink", "includes", "isSelected", "shouldBeOpen", "has", "open", "setOpen", "handleClick", "v", "window", "selected", "onOpenChange", "onClick", "size", "icon", "_el$5", "_tmpl$4", "title", "Children", "child", "SidebarUser", "hasMenus", "handleMenuClick", "getHeaderClassName", "base", "hoverBg", "getContainerClassName", "_el$6", "_tmpl$7", "_el$7", "_el$8", "_el$9", "_$use", "description", "fallback", "_el$12", "_tmpl$8", "name", "_el$0", "_tmpl$5", "_el$1", "_el$10", "nextSibling", "_el$11", "_tmpl$6", "default", "_p$", "_v$", "_v$2", "SidebarInner", "getTransform", "_el$13", "_tmpl$9", "transform", "inert", "Sidebar", "Container", "Menu", "User", "_$delegateEvents"]
|
|
6
6
|
}
|
package/docs/display-feedback.md
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Card
|
|
4
4
|
|
|
5
|
-
그림자와 호버 효과가 있는 카드 컨테이너.
|
|
5
|
+
그림자와 호버 효과가 있는 카드 컨테이너. 페이드 인 애니메이션 포함.
|
|
6
6
|
|
|
7
7
|
```tsx
|
|
8
8
|
import { Card } from "@simplysm/solid";
|
|
9
9
|
|
|
10
10
|
<Card>카드 내용</Card>
|
|
11
|
+
<Card class="p-4">커스텀 패딩</Card>
|
|
11
12
|
```
|
|
12
13
|
|
|
14
|
+
`<div>` HTML 속성을 모두 상속한다.
|
|
15
|
+
|
|
13
16
|
---
|
|
14
17
|
|
|
15
18
|
## Alert
|
|
@@ -21,8 +24,16 @@ import { Alert } from "@simplysm/solid";
|
|
|
21
24
|
|
|
22
25
|
<Alert theme="success">저장되었습니다.</Alert>
|
|
23
26
|
<Alert theme="danger">오류가 발생했습니다.</Alert>
|
|
27
|
+
<Alert theme="warning">주의가 필요합니다.</Alert>
|
|
28
|
+
<Alert theme="info">참고 사항입니다.</Alert>
|
|
24
29
|
```
|
|
25
30
|
|
|
31
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
32
|
+
|------|------|--------|------|
|
|
33
|
+
| `theme` | `SemanticTheme` | `"base"` | 색상 테마 |
|
|
34
|
+
|
|
35
|
+
`<div>` HTML 속성을 모두 상속한다.
|
|
36
|
+
|
|
26
37
|
---
|
|
27
38
|
|
|
28
39
|
## Icon
|
|
@@ -31,34 +42,82 @@ Tabler Icons 래퍼.
|
|
|
31
42
|
|
|
32
43
|
```tsx
|
|
33
44
|
import { Icon } from "@simplysm/solid";
|
|
34
|
-
import { IconUser } from "@tabler/icons-solidjs";
|
|
45
|
+
import { IconUser, IconSettings } from "@tabler/icons-solidjs";
|
|
35
46
|
|
|
36
47
|
<Icon icon={IconUser} size="1.5em" />
|
|
48
|
+
<Icon icon={IconSettings} size={24} />
|
|
37
49
|
```
|
|
38
50
|
|
|
51
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
52
|
+
|------|------|--------|------|
|
|
53
|
+
| `icon` | `Component<TablerIconProps>` | (필수) | Tabler 아이콘 컴포넌트 |
|
|
54
|
+
| `size` | `string \| number` | `"1.25em"` | 아이콘 크기 |
|
|
55
|
+
|
|
56
|
+
Tabler `IconProps`의 나머지 속성(`class`, `color` 등)을 모두 상속한다.
|
|
57
|
+
|
|
39
58
|
---
|
|
40
59
|
|
|
41
|
-
## Link
|
|
60
|
+
## Link
|
|
61
|
+
|
|
62
|
+
테마 색상의 링크 컴포넌트.
|
|
42
63
|
|
|
43
64
|
```tsx
|
|
44
|
-
import { Link
|
|
65
|
+
import { Link } from "@simplysm/solid";
|
|
45
66
|
|
|
46
67
|
<Link href="/users">사용자 목록</Link>
|
|
47
|
-
<
|
|
68
|
+
<Link theme="danger" onClick={handleDelete}>삭제</Link>
|
|
69
|
+
<Link disabled>비활성 링크</Link>
|
|
48
70
|
```
|
|
49
71
|
|
|
72
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
73
|
+
|------|------|--------|------|
|
|
74
|
+
| `theme` | `SemanticTheme` | `"primary"` | 색상 테마 |
|
|
75
|
+
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
76
|
+
|
|
77
|
+
`<a>` HTML 속성을 모두 상속한다.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Tag
|
|
82
|
+
|
|
83
|
+
테마 색상의 태그/배지.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { Tag } from "@simplysm/solid";
|
|
87
|
+
|
|
88
|
+
<Tag>기본</Tag>
|
|
89
|
+
<Tag theme="primary">Primary</Tag>
|
|
90
|
+
<Tag theme="success">완료</Tag>
|
|
91
|
+
<Tag theme="danger">긴급</Tag>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
95
|
+
|------|------|--------|------|
|
|
96
|
+
| `theme` | `SemanticTheme` | `"base"` | 색상 테마 |
|
|
97
|
+
|
|
98
|
+
`<span>` HTML 속성을 모두 상속한다.
|
|
99
|
+
|
|
50
100
|
---
|
|
51
101
|
|
|
52
102
|
## Barcode
|
|
53
103
|
|
|
54
|
-
바코드/QR 코드
|
|
104
|
+
바코드/QR 코드 생성 (bwip-js 기반).
|
|
55
105
|
|
|
56
106
|
```tsx
|
|
57
107
|
import { Barcode } from "@simplysm/solid";
|
|
58
108
|
|
|
59
|
-
<Barcode value="
|
|
109
|
+
<Barcode type="qrcode" value="https://example.com" />
|
|
110
|
+
<Barcode type="code128" value="1234567890" />
|
|
111
|
+
<Barcode type="ean13" value="4006381333931" />
|
|
60
112
|
```
|
|
61
113
|
|
|
114
|
+
| Prop | 타입 | 설명 |
|
|
115
|
+
|------|------|------|
|
|
116
|
+
| `type` | `BarcodeType` | 바코드 타입 (필수). `"qrcode"`, `"code128"`, `"ean13"` 등 100+ 타입 |
|
|
117
|
+
| `value` | `string` | 바코드 값 |
|
|
118
|
+
|
|
119
|
+
`<div>` HTML 속성을 모두 상속한다.
|
|
120
|
+
|
|
62
121
|
---
|
|
63
122
|
|
|
64
123
|
## Echarts
|
|
@@ -78,6 +137,13 @@ import { Echarts } from "@simplysm/solid";
|
|
|
78
137
|
/>
|
|
79
138
|
```
|
|
80
139
|
|
|
140
|
+
| Prop | 타입 | 설명 |
|
|
141
|
+
|------|------|------|
|
|
142
|
+
| `option` | `EChartsOption` | ECharts 옵션 (필수) |
|
|
143
|
+
| `busy` | `boolean` | 로딩 상태 (`showLoading`/`hideLoading`) |
|
|
144
|
+
|
|
145
|
+
`<div>` HTML 속성을 모두 상속한다. 내부적으로 SVG 렌더러를 사용하며, 컨테이너 크기 변경 시 자동 리사이즈한다.
|
|
146
|
+
|
|
81
147
|
---
|
|
82
148
|
|
|
83
149
|
## Dialog
|
|
@@ -96,16 +162,24 @@ import { Dialog } from "@simplysm/solid";
|
|
|
96
162
|
</Dialog>
|
|
97
163
|
```
|
|
98
164
|
|
|
99
|
-
| Prop | 타입 | 설명 |
|
|
100
|
-
|
|
101
|
-
| `open` | `boolean` | 열림 상태 |
|
|
102
|
-
| `onOpenChange` | `(v: boolean) => void` | 상태 콜백 |
|
|
103
|
-
| `mode` | `"float" \| "fill"` | 모드 |
|
|
104
|
-
| `resizable` | `boolean` | 리사이즈 가능 |
|
|
105
|
-
| `draggable` | `boolean` | 드래그 가능 |
|
|
106
|
-
| `width
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
165
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
166
|
+
|------|------|--------|------|
|
|
167
|
+
| `open` | `boolean` | | 열림 상태 |
|
|
168
|
+
| `onOpenChange` | `(v: boolean) => void` | | 상태 콜백 |
|
|
169
|
+
| `mode` | `"float" \| "fill"` | `"float"` | 모드 |
|
|
170
|
+
| `resizable` | `boolean` | `false` | 리사이즈 가능 |
|
|
171
|
+
| `draggable` | `boolean` | `false` | 드래그 가능 |
|
|
172
|
+
| `width` | `string` | | 너비 |
|
|
173
|
+
| `height` | `string` | | 높이 |
|
|
174
|
+
| `closeOnEscape` | `boolean` | `true` | ESC 닫기 |
|
|
175
|
+
| `beforeClose` | `() => boolean` | | 닫기 전 확인 (false 반환 시 취소) |
|
|
176
|
+
|
|
177
|
+
### 서브 컴포넌트
|
|
178
|
+
|
|
179
|
+
| 컴포넌트 | 설명 |
|
|
180
|
+
|----------|------|
|
|
181
|
+
| `Dialog.Header` | 다이얼로그 헤더 (닫기 버튼 포함) |
|
|
182
|
+
| `Dialog.Action` | 하단 액션 영역 |
|
|
109
183
|
|
|
110
184
|
### 프로그래밍 방식 다이얼로그
|
|
111
185
|
|
|
@@ -139,6 +213,22 @@ import { Dropdown } from "@simplysm/solid";
|
|
|
139
213
|
</Dropdown>
|
|
140
214
|
```
|
|
141
215
|
|
|
216
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
217
|
+
|------|------|--------|------|
|
|
218
|
+
| `open` | `boolean` | | 열림 상태 |
|
|
219
|
+
| `onOpenChange` | `(v: boolean) => void` | | 상태 콜백 |
|
|
220
|
+
| `position` | `{ x: number; y: number }` | | 절대 위치 (컨텍스트 메뉴용) |
|
|
221
|
+
| `maxHeight` | `number` | `300` | 최대 높이 (px) |
|
|
222
|
+
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
223
|
+
| `keyboardNav` | `boolean` | `false` | 키보드 네비게이션 (Select 등에서 사용) |
|
|
224
|
+
|
|
225
|
+
### 서브 컴포넌트
|
|
226
|
+
|
|
227
|
+
| 컴포넌트 | 설명 |
|
|
228
|
+
|----------|------|
|
|
229
|
+
| `Dropdown.Trigger` | 드롭다운 트리거 |
|
|
230
|
+
| `Dropdown.Content` | 드롭다운 콘텐츠 |
|
|
231
|
+
|
|
142
232
|
---
|
|
143
233
|
|
|
144
234
|
## Collapse
|
|
@@ -148,11 +238,20 @@ import { Dropdown } from "@simplysm/solid";
|
|
|
148
238
|
```tsx
|
|
149
239
|
import { Collapse } from "@simplysm/solid";
|
|
150
240
|
|
|
241
|
+
<Button aria-expanded={expanded()} onClick={() => setExpanded(!expanded())}>
|
|
242
|
+
토글
|
|
243
|
+
</Button>
|
|
151
244
|
<Collapse open={expanded()}>
|
|
152
245
|
<div>접힌 내용</div>
|
|
153
246
|
</Collapse>
|
|
154
247
|
```
|
|
155
248
|
|
|
249
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
250
|
+
|------|------|--------|------|
|
|
251
|
+
| `open` | `boolean` | `false` | 열림 상태 |
|
|
252
|
+
|
|
253
|
+
`<div>` HTML 속성을 모두 상속한다. 높이 애니메이션이 자동 적용된다.
|
|
254
|
+
|
|
156
255
|
---
|
|
157
256
|
|
|
158
257
|
## Tabs
|
|
@@ -168,6 +267,17 @@ import { Tabs } from "@simplysm/solid";
|
|
|
168
267
|
</Tabs>
|
|
169
268
|
```
|
|
170
269
|
|
|
270
|
+
| Prop (Tabs) | 타입 | 설명 |
|
|
271
|
+
|------------|------|------|
|
|
272
|
+
| `value` | `string` | 선택된 탭 값 |
|
|
273
|
+
| `onValueChange` | `(v: string) => void` | 변경 콜백 |
|
|
274
|
+
| `size` | `ComponentSize` | 크기 |
|
|
275
|
+
|
|
276
|
+
| Prop (Tabs.Tab) | 타입 | 설명 |
|
|
277
|
+
|-----------------|------|------|
|
|
278
|
+
| `value` | `string` | 탭 식별 값 |
|
|
279
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
280
|
+
|
|
171
281
|
---
|
|
172
282
|
|
|
173
283
|
## Notification
|
|
@@ -259,8 +369,23 @@ busy.hide();
|
|
|
259
369
|
import { Progress } from "@simplysm/solid";
|
|
260
370
|
|
|
261
371
|
<Progress value={progress()} />
|
|
372
|
+
<Progress value={75} theme="success" />
|
|
373
|
+
|
|
374
|
+
// 커스텀 콘텐츠
|
|
375
|
+
<Progress value={50} theme="primary" size="lg">
|
|
376
|
+
<span>50% 완료</span>
|
|
377
|
+
</Progress>
|
|
262
378
|
```
|
|
263
379
|
|
|
380
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
381
|
+
|------|------|--------|------|
|
|
382
|
+
| `value` | `number` | (필수) | 진행률 (0-100) |
|
|
383
|
+
| `theme` | `SemanticTheme` | `"primary"` | 색상 테마 |
|
|
384
|
+
| `size` | `ComponentSize` | `"md"` | 크기 |
|
|
385
|
+
| `inset` | `boolean` | `false` | 테두리 없음 |
|
|
386
|
+
|
|
387
|
+
`<div>` HTML 속성을 모두 상속한다. children이 있으면 퍼센트 텍스트 대신 커스텀 콘텐츠를 표시한다.
|
|
388
|
+
|
|
264
389
|
---
|
|
265
390
|
|
|
266
391
|
## Print
|
package/docs/features.md
CHANGED
|
@@ -358,6 +358,46 @@ function UserDetail(props: { close?: (result?: boolean) => void; userId: number
|
|
|
358
358
|
const result = await dialog.open(UserDetail, { userId: 123 });
|
|
359
359
|
```
|
|
360
360
|
|
|
361
|
+
### CrudDetail Props
|
|
362
|
+
|
|
363
|
+
| Prop | 타입 | 설명 |
|
|
364
|
+
|------|------|------|
|
|
365
|
+
| `load` | `() => Promise<{ data: TData; info: CrudDetailInfo }>` | 데이터 로드 함수 (필수) |
|
|
366
|
+
| `children` | `(ctx: CrudDetailContext<TData>) => JSX.Element` | 폼 렌더링 (필수) |
|
|
367
|
+
| `submit` | `(data: TData) => Promise<boolean \| undefined>` | 저장 함수 |
|
|
368
|
+
| `toggleDelete` | `(del: boolean) => Promise<boolean \| undefined>` | 삭제/복원 토글 |
|
|
369
|
+
| `editable` | `boolean` | 편집 가능 여부 |
|
|
370
|
+
| `deletable` | `boolean` | 삭제 가능 여부 |
|
|
371
|
+
| `data` | `TData` | 제어 모드: 외부 데이터 |
|
|
372
|
+
| `onDataChange` | `(data: TData) => void` | 제어 모드: 데이터 변경 콜백 |
|
|
373
|
+
| `close` | `(result?: boolean) => void` | Dialog 모드 활성화 |
|
|
374
|
+
| `class` | `string` | CSS 클래스 |
|
|
375
|
+
|
|
376
|
+
### CrudDetailInfo
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
interface CrudDetailInfo {
|
|
380
|
+
isNew: boolean; // 신규 레코드 여부
|
|
381
|
+
isDeleted: boolean; // 삭제 상태
|
|
382
|
+
lastModifiedAt?: DateTime; // 최종 수정 일시
|
|
383
|
+
lastModifiedBy?: string; // 최종 수정자
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### CrudDetailContext
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
interface CrudDetailContext<TData> {
|
|
391
|
+
data: TData; // 현재 데이터 (store)
|
|
392
|
+
setData: SetStoreFunction<TData>; // 데이터 수정 (SolidJS store setter)
|
|
393
|
+
info: () => CrudDetailInfo; // 상세 정보
|
|
394
|
+
busy: () => boolean; // 로딩 중 여부
|
|
395
|
+
hasChanges: () => boolean; // 변경사항 존재 여부
|
|
396
|
+
save: () => Promise<void>; // 저장 실행
|
|
397
|
+
refresh: () => Promise<void>; // 데이터 새로고침
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
361
401
|
### CrudDetail 서브 컴포넌트
|
|
362
402
|
|
|
363
403
|
| 컴포넌트 | 설명 |
|
package/docs/form-controls.md
CHANGED
|
@@ -14,12 +14,14 @@ import { Button } from "@simplysm/solid";
|
|
|
14
14
|
|
|
15
15
|
| Prop | 타입 | 기본값 | 설명 |
|
|
16
16
|
|------|------|--------|------|
|
|
17
|
-
| `theme` | `
|
|
18
|
-
| `variant` | `"solid" \| "outline" \| "ghost"` | `"
|
|
17
|
+
| `theme` | `SemanticTheme` | `"base"` | 색상 테마 |
|
|
18
|
+
| `variant` | `"solid" \| "outline" \| "ghost"` | `"outline"` | 스타일 변형 |
|
|
19
19
|
| `size` | `ComponentSize` | `"md"` | 크기 |
|
|
20
|
-
| `inset` | `boolean` | `false` |
|
|
20
|
+
| `inset` | `boolean` | `false` | 테두리/라운드 없음 |
|
|
21
21
|
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
22
22
|
|
|
23
|
+
`<button>` HTML 속성을 모두 상속한다. `type` 기본값은 `"button"`.
|
|
24
|
+
|
|
23
25
|
---
|
|
24
26
|
|
|
25
27
|
## TextInput
|
|
@@ -39,40 +41,97 @@ import { TextInput } from "@simplysm/solid";
|
|
|
39
41
|
|------|------|------|
|
|
40
42
|
| `value` | `string` | 값 |
|
|
41
43
|
| `onValueChange` | `(v: string) => void` | 변경 콜백 |
|
|
42
|
-
| `type` | `"text" \| "password" \| "email"` | 입력 타입 |
|
|
44
|
+
| `type` | `"text" \| "password" \| "email"` | 입력 타입 (기본: `"text"`) |
|
|
43
45
|
| `format` | `string` | 형식 마스크 (예: `"XXX-XXXX-XXXX"`) |
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
46
|
+
| `placeholder` | `string` | 플레이스홀더 |
|
|
47
|
+
| `title` | `string` | 툴팁 |
|
|
48
|
+
| `autocomplete` | `string` | autocomplete 속성 (기본: `"one-time-code"`) |
|
|
49
|
+
| `size` | `ComponentSize` | 크기 |
|
|
50
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
51
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
52
|
+
| `readOnly` | `boolean` | 읽기 전용 |
|
|
53
|
+
| `required` | `boolean` | 필수 입력 |
|
|
54
|
+
| `minLength` | `number` | 최소 길이 |
|
|
55
|
+
| `maxLength` | `number` | 최대 길이 |
|
|
56
|
+
| `pattern` | `string \| RegExp` | 입력 패턴 (정규식) |
|
|
57
|
+
| `validate` | `(v: string) => string \| undefined` | 커스텀 유효성 검증 |
|
|
47
58
|
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
48
59
|
|
|
60
|
+
### 서브 컴포넌트
|
|
61
|
+
|
|
62
|
+
| 컴포넌트 | 설명 |
|
|
63
|
+
|----------|------|
|
|
64
|
+
| `TextInput.Prefix` | 입력 필드 앞에 표시할 접두사 슬롯 |
|
|
65
|
+
|
|
49
66
|
---
|
|
50
67
|
|
|
51
68
|
## NumberInput
|
|
52
69
|
|
|
53
70
|
```tsx
|
|
71
|
+
import { NumberInput } from "@simplysm/solid";
|
|
72
|
+
|
|
54
73
|
<NumberInput value={amount()} onValueChange={setAmount} min={0} max={100} />
|
|
55
74
|
<NumberInput value={price()} onValueChange={setPrice} useGrouping minimumFractionDigits={2} />
|
|
75
|
+
|
|
76
|
+
// 접두사 슬롯
|
|
77
|
+
<NumberInput value={price()} onValueChange={setPrice}>
|
|
78
|
+
<NumberInput.Prefix>$</NumberInput.Prefix>
|
|
79
|
+
</NumberInput>
|
|
56
80
|
```
|
|
57
81
|
|
|
58
82
|
| Prop | 타입 | 설명 |
|
|
59
83
|
|------|------|------|
|
|
60
84
|
| `value` | `number` | 값 |
|
|
61
85
|
| `onValueChange` | `(v: number \| undefined) => void` | 변경 콜백 |
|
|
62
|
-
| `useGrouping` | `boolean` | 천단위 구분자 (기본: true) |
|
|
86
|
+
| `useGrouping` | `boolean` | 천단위 구분자 (기본: `true`) |
|
|
63
87
|
| `minimumFractionDigits` | `number` | 최소 소수점 자릿수 |
|
|
64
|
-
| `
|
|
88
|
+
| `placeholder` | `string` | 플레이스홀더 |
|
|
89
|
+
| `title` | `string` | 툴팁 |
|
|
90
|
+
| `size` | `ComponentSize` | 크기 |
|
|
91
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
92
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
93
|
+
| `readOnly` | `boolean` | 읽기 전용 |
|
|
94
|
+
| `required` | `boolean` | 필수 입력 |
|
|
95
|
+
| `min` | `number` | 최솟값 |
|
|
96
|
+
| `max` | `number` | 최댓값 |
|
|
97
|
+
| `validate` | `(v: number \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
|
|
98
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
99
|
+
|
|
100
|
+
### 서브 컴포넌트
|
|
101
|
+
|
|
102
|
+
| 컴포넌트 | 설명 |
|
|
103
|
+
|----------|------|
|
|
104
|
+
| `NumberInput.Prefix` | 입력 필드 앞에 표시할 접두사 슬롯 |
|
|
65
105
|
|
|
66
106
|
---
|
|
67
107
|
|
|
68
108
|
## Textarea
|
|
69
109
|
|
|
70
110
|
```tsx
|
|
111
|
+
import { Textarea } from "@simplysm/solid";
|
|
112
|
+
|
|
71
113
|
<Textarea value={memo()} onValueChange={setMemo} minRows={3} />
|
|
72
114
|
```
|
|
73
115
|
|
|
74
116
|
Alt+Enter로 줄바꿈. `minRows`로 최소 높이 설정.
|
|
75
117
|
|
|
118
|
+
| Prop | 타입 | 설명 |
|
|
119
|
+
|------|------|------|
|
|
120
|
+
| `value` | `string` | 값 |
|
|
121
|
+
| `onValueChange` | `(v: string) => void` | 변경 콜백 |
|
|
122
|
+
| `placeholder` | `string` | 플레이스홀더 |
|
|
123
|
+
| `title` | `string` | 툴팁 |
|
|
124
|
+
| `minRows` | `number` | 최소 행 수 (기본: `1`) |
|
|
125
|
+
| `size` | `ComponentSize` | 크기 |
|
|
126
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
127
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
128
|
+
| `readOnly` | `boolean` | 읽기 전용 |
|
|
129
|
+
| `required` | `boolean` | 필수 입력 |
|
|
130
|
+
| `minLength` | `number` | 최소 길이 |
|
|
131
|
+
| `maxLength` | `number` | 최대 길이 |
|
|
132
|
+
| `validate` | `(v: string) => string \| undefined` | 커스텀 유효성 검증 |
|
|
133
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
134
|
+
|
|
76
135
|
---
|
|
77
136
|
|
|
78
137
|
## DatePicker
|
|
@@ -87,29 +146,65 @@ import { DatePicker } from "@simplysm/solid";
|
|
|
87
146
|
|
|
88
147
|
| Prop | 타입 | 설명 |
|
|
89
148
|
|------|------|------|
|
|
90
|
-
| `value` | `DateOnly` | 값 |
|
|
149
|
+
| `value` | `DateOnly` | 값 (`@simplysm/core-common`의 `DateOnly`) |
|
|
91
150
|
| `onValueChange` | `(v: DateOnly \| undefined) => void` | 변경 콜백 |
|
|
92
151
|
| `unit` | `"year" \| "month" \| "date"` | 선택 단위 (기본: `"date"`) |
|
|
93
|
-
| `min
|
|
152
|
+
| `min` | `DateOnly` | 최소 날짜 |
|
|
153
|
+
| `max` | `DateOnly` | 최대 날짜 |
|
|
154
|
+
| `title` | `string` | 툴팁 |
|
|
155
|
+
| `size` | `ComponentSize` | 크기 |
|
|
156
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
157
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
158
|
+
| `readOnly` | `boolean` | 읽기 전용 |
|
|
159
|
+
| `required` | `boolean` | 필수 입력 |
|
|
160
|
+
| `validate` | `(v: DateOnly \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
|
|
161
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
94
162
|
|
|
95
163
|
---
|
|
96
164
|
|
|
97
165
|
## DateTimePicker
|
|
98
166
|
|
|
99
167
|
```tsx
|
|
168
|
+
import { DateTimePicker } from "@simplysm/solid";
|
|
169
|
+
|
|
100
170
|
<DateTimePicker value={dt()} onValueChange={setDt} unit="minute" />
|
|
101
171
|
```
|
|
102
172
|
|
|
103
|
-
|
|
173
|
+
| Prop | 타입 | 설명 |
|
|
174
|
+
|------|------|------|
|
|
175
|
+
| `value` | `DateTime` | 값 (`@simplysm/core-common`의 `DateTime`) |
|
|
176
|
+
| `onValueChange` | `(v: DateTime \| undefined) => void` | 변경 콜백 |
|
|
177
|
+
| `unit` | `"minute" \| "second"` | 시간 단위 (기본: `"minute"`) |
|
|
178
|
+
| `min` | `DateTime` | 최소 일시 |
|
|
179
|
+
| `max` | `DateTime` | 최대 일시 |
|
|
180
|
+
| `title` | `string` | 툴팁 |
|
|
181
|
+
| `size`, `inset`, `disabled`, `readOnly`, `required` | | 공통 |
|
|
182
|
+
| `validate` | `(v: DateTime \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
|
|
183
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
104
184
|
|
|
105
185
|
---
|
|
106
186
|
|
|
107
187
|
## TimePicker
|
|
108
188
|
|
|
109
189
|
```tsx
|
|
190
|
+
import { TimePicker } from "@simplysm/solid";
|
|
191
|
+
|
|
110
192
|
<TimePicker value={time()} onValueChange={setTime} />
|
|
193
|
+
<TimePicker value={time()} onValueChange={setTime} unit="second" />
|
|
111
194
|
```
|
|
112
195
|
|
|
196
|
+
| Prop | 타입 | 설명 |
|
|
197
|
+
|------|------|------|
|
|
198
|
+
| `value` | `Time` | 값 (`@simplysm/core-common`의 `Time`) |
|
|
199
|
+
| `onValueChange` | `(v: Time \| undefined) => void` | 변경 콜백 |
|
|
200
|
+
| `unit` | `"minute" \| "second"` | 시간 단위 (기본: `"minute"`) |
|
|
201
|
+
| `min` | `Time` | 최소 시간 |
|
|
202
|
+
| `max` | `Time` | 최대 시간 |
|
|
203
|
+
| `title` | `string` | 툴팁 |
|
|
204
|
+
| `size`, `inset`, `disabled`, `readOnly`, `required` | | 공통 |
|
|
205
|
+
| `validate` | `(v: Time \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
|
|
206
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
207
|
+
|
|
113
208
|
---
|
|
114
209
|
|
|
115
210
|
## DateRangePicker
|
|
@@ -153,6 +248,8 @@ const [to, setTo] = createSignal<DateOnly>();
|
|
|
153
248
|
## Checkbox / Radio
|
|
154
249
|
|
|
155
250
|
```tsx
|
|
251
|
+
import { Checkbox, Radio, RadioGroup } from "@simplysm/solid";
|
|
252
|
+
|
|
156
253
|
<Checkbox checked={active()} onCheckedChange={setActive}>활성</Checkbox>
|
|
157
254
|
<Checkbox checked={agreed()} onCheckedChange={setAgreed} required>약관 동의</Checkbox>
|
|
158
255
|
|
|
@@ -162,6 +259,32 @@ const [to, setTo] = createSignal<DateOnly>();
|
|
|
162
259
|
</RadioGroup>
|
|
163
260
|
```
|
|
164
261
|
|
|
262
|
+
### Checkbox Props
|
|
263
|
+
|
|
264
|
+
| Prop | 타입 | 설명 |
|
|
265
|
+
|------|------|------|
|
|
266
|
+
| `checked` | `boolean` | 체크 상태 |
|
|
267
|
+
| `onCheckedChange` | `(v: boolean) => void` | 변경 콜백 |
|
|
268
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
269
|
+
| `size` | `ComponentSize` | 크기 |
|
|
270
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
271
|
+
| `inline` | `boolean` | 인라인 배치 |
|
|
272
|
+
| `required` | `boolean` | 필수 체크 |
|
|
273
|
+
| `validate` | `(v: boolean) => string \| undefined` | 커스텀 유효성 검증 |
|
|
274
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
275
|
+
|
|
276
|
+
### RadioGroup Props
|
|
277
|
+
|
|
278
|
+
| Prop | 타입 | 설명 |
|
|
279
|
+
|------|------|------|
|
|
280
|
+
| `value` | `TValue` | 선택 값 |
|
|
281
|
+
| `onValueChange` | `(v: TValue) => void` | 변경 콜백 |
|
|
282
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
283
|
+
| `inline` | `boolean` | 가로 배치 |
|
|
284
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
285
|
+
| `required` | `boolean` | 필수 선택 |
|
|
286
|
+
| `validate` | `(v: TValue \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
|
|
287
|
+
|
|
165
288
|
---
|
|
166
289
|
|
|
167
290
|
## CheckboxGroup
|
|
@@ -188,13 +311,15 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
|
188
311
|
| `inline` | `boolean` | 가로 배치 |
|
|
189
312
|
| `inset` | `boolean` | 테두리 없음 |
|
|
190
313
|
| `required` | `boolean` | 최소 1개 선택 필수 |
|
|
191
|
-
| `validate` | `(v: TValue[]) => string \| undefined` | 커스텀 유효성 |
|
|
314
|
+
| `validate` | `(v: TValue[]) => string \| undefined` | 커스텀 유효성 검증 |
|
|
192
315
|
|
|
193
316
|
---
|
|
194
317
|
|
|
195
318
|
## Select
|
|
196
319
|
|
|
197
320
|
```tsx
|
|
321
|
+
import { Select } from "@simplysm/solid";
|
|
322
|
+
|
|
198
323
|
// 단일 선택 (items 모드)
|
|
199
324
|
<Select
|
|
200
325
|
value={selected()}
|
|
@@ -224,10 +349,9 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
|
224
349
|
/>
|
|
225
350
|
|
|
226
351
|
// Children 모드
|
|
227
|
-
<Select value={v()} onValueChange={setV}>
|
|
352
|
+
<Select value={v()} onValueChange={setV} renderValue={(v) => <span>{v}</span>}>
|
|
228
353
|
<Select.Item value="a">옵션 A</Select.Item>
|
|
229
354
|
<Select.Item value="b">옵션 B</Select.Item>
|
|
230
|
-
<Select.Header>그룹 헤더</Select.Header>
|
|
231
355
|
</Select>
|
|
232
356
|
|
|
233
357
|
// ItemTemplate (items 모드에서 드롭다운 렌더링 커스터마이징)
|
|
@@ -237,7 +361,13 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
|
237
361
|
</Select.ItemTemplate>
|
|
238
362
|
</Select>
|
|
239
363
|
|
|
240
|
-
//
|
|
364
|
+
// Header (드롭다운 상단 커스텀 영역)
|
|
365
|
+
<Select value={v()} onValueChange={setV} renderValue={(v) => <span>{v}</span>}>
|
|
366
|
+
<Select.Header><div>그룹 헤더</div></Select.Header>
|
|
367
|
+
<Select.Item value="a">옵션 A</Select.Item>
|
|
368
|
+
</Select>
|
|
369
|
+
|
|
370
|
+
// Action (트리거 옆 커스텀 액션 버튼)
|
|
241
371
|
<Select items={users} renderValue={(u) => <span>{u.name}</span>}>
|
|
242
372
|
<Select.Action onClick={handleSearch}>
|
|
243
373
|
<Icon icon={IconSearch} />
|
|
@@ -245,18 +375,58 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
|
245
375
|
</Select>
|
|
246
376
|
```
|
|
247
377
|
|
|
378
|
+
### Select Props
|
|
379
|
+
|
|
380
|
+
| Prop | 타입 | 설명 |
|
|
381
|
+
|------|------|------|
|
|
382
|
+
| `value` | `TValue \| TValue[]` | 선택 값 (multiple 시 배열) |
|
|
383
|
+
| `onValueChange` | `(v) => void` | 변경 콜백 |
|
|
384
|
+
| `multiple` | `boolean` | 다중 선택 모드 |
|
|
385
|
+
| `items` | `TValue[]` | 아이템 배열 (items 모드) |
|
|
386
|
+
| `itemChildren` | `(item, index, depth) => TValue[] \| undefined` | 트리 자식 접근자 |
|
|
387
|
+
| `renderValue` | `(v: TValue) => JSX.Element` | 선택된 값 렌더링 |
|
|
388
|
+
| `itemSearchText` | `(item: TValue) => string` | 검색 텍스트 추출 (설정 시 검색 입력 표시) |
|
|
389
|
+
| `isItemHidden` | `(item: TValue) => boolean` | 아이템 숨김 여부 |
|
|
390
|
+
| `tagDirection` | `"horizontal" \| "vertical"` | 다중 선택 태그 방향 |
|
|
391
|
+
| `hideSelectAll` | `boolean` | 전체 선택 버튼 숨김 (다중 선택) |
|
|
392
|
+
| `placeholder` | `string` | 플레이스홀더 |
|
|
393
|
+
| `size` | `ComponentSize` | 크기 |
|
|
394
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
395
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
396
|
+
| `required` | `boolean` | 필수 선택 |
|
|
397
|
+
| `validate` | `(v: unknown) => string \| undefined` | 커스텀 유효성 검증 |
|
|
398
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
399
|
+
|
|
400
|
+
### 서브 컴포넌트
|
|
401
|
+
|
|
402
|
+
| 컴포넌트 | 설명 |
|
|
403
|
+
|----------|------|
|
|
404
|
+
| `Select.Item` | 드롭다운 선택 항목. props: `value`, `disabled` |
|
|
405
|
+
| `Select.Item.Children` | 중첩 아이템 슬롯 (트리 구조) |
|
|
406
|
+
| `Select.ItemTemplate` | items 모드에서 드롭다운 아이템 렌더링 커스터마이징 |
|
|
407
|
+
| `Select.Header` | 드롭다운 상단 커스텀 영역 |
|
|
408
|
+
| `Select.Action` | 트리거 옆 커스텀 액션 버튼 |
|
|
409
|
+
|
|
248
410
|
---
|
|
249
411
|
|
|
250
412
|
## Combobox
|
|
251
413
|
|
|
414
|
+
비동기 검색 기반 자동완성 컴포넌트.
|
|
415
|
+
|
|
252
416
|
```tsx
|
|
417
|
+
import { Combobox } from "@simplysm/solid";
|
|
418
|
+
|
|
253
419
|
<Combobox
|
|
254
420
|
value={user()}
|
|
255
421
|
onValueChange={setUser}
|
|
256
422
|
loadItems={async (query) => await searchUsers(query)}
|
|
257
423
|
renderValue={(u) => <span>{u.name}</span>}
|
|
258
424
|
debounceMs={300}
|
|
259
|
-
|
|
425
|
+
>
|
|
426
|
+
<Combobox.ItemTemplate>
|
|
427
|
+
{(item) => <span>{item.name} ({item.email})</span>}
|
|
428
|
+
</Combobox.ItemTemplate>
|
|
429
|
+
</Combobox>
|
|
260
430
|
|
|
261
431
|
// 커스텀 값 허용
|
|
262
432
|
<Combobox
|
|
@@ -265,13 +435,48 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
|
265
435
|
loadItems={loadItems}
|
|
266
436
|
renderValue={(v) => <span>{v.name}</span>}
|
|
267
437
|
/>
|
|
438
|
+
|
|
439
|
+
// Children 모드
|
|
440
|
+
<Combobox loadItems={loadItems} renderValue={(v) => v.name}>
|
|
441
|
+
<For each={items()}>
|
|
442
|
+
{(item) => <Combobox.Item value={item}>{item.name}</Combobox.Item>}
|
|
443
|
+
</For>
|
|
444
|
+
</Combobox>
|
|
268
445
|
```
|
|
269
446
|
|
|
447
|
+
### Combobox Props
|
|
448
|
+
|
|
449
|
+
| Prop | 타입 | 설명 |
|
|
450
|
+
|------|------|------|
|
|
451
|
+
| `value` | `TValue` | 선택 값 |
|
|
452
|
+
| `onValueChange` | `(v: TValue) => void` | 변경 콜백 |
|
|
453
|
+
| `loadItems` | `(query: string) => TValue[] \| Promise<TValue[]>` | 아이템 검색 함수 (필수) |
|
|
454
|
+
| `renderValue` | `(v: TValue) => JSX.Element` | 선택된 값 렌더링 (필수) |
|
|
455
|
+
| `debounceMs` | `number` | 검색 디바운스 (기본: `300`) |
|
|
456
|
+
| `allowsCustomValue` | `boolean` | 커스텀 값 입력 허용 |
|
|
457
|
+
| `parseCustomValue` | `(text: string) => TValue` | 텍스트를 값으로 변환 |
|
|
458
|
+
| `placeholder` | `string` | 플레이스홀더 |
|
|
459
|
+
| `size` | `ComponentSize` | 크기 |
|
|
460
|
+
| `inset` | `boolean` | 테두리 없음 |
|
|
461
|
+
| `disabled` | `boolean` | 비활성화 |
|
|
462
|
+
| `required` | `boolean` | 필수 선택 |
|
|
463
|
+
| `validate` | `(v: TValue \| undefined) => string \| undefined` | 커스텀 유효성 검증 |
|
|
464
|
+
| `lazyValidation` | `boolean` | blur 시 검증 |
|
|
465
|
+
|
|
466
|
+
### 서브 컴포넌트
|
|
467
|
+
|
|
468
|
+
| 컴포넌트 | 설명 |
|
|
469
|
+
|----------|------|
|
|
470
|
+
| `Combobox.Item` | 드롭다운 선택 항목. props: `value`, `disabled` |
|
|
471
|
+
| `Combobox.ItemTemplate` | 아이템 렌더링 커스터마이징 |
|
|
472
|
+
|
|
270
473
|
---
|
|
271
474
|
|
|
272
475
|
## ColorPicker
|
|
273
476
|
|
|
274
477
|
```tsx
|
|
478
|
+
import { ColorPicker } from "@simplysm/solid";
|
|
479
|
+
|
|
275
480
|
<ColorPicker value={color()} onValueChange={setColor} />
|
|
276
481
|
// value: "#RRGGBB" 형식
|
|
277
482
|
```
|
|
@@ -283,6 +488,8 @@ const [selectedTags, setSelectedTags] = createSignal<string[]>([]);
|
|
|
283
488
|
Tiptap 기반 리치 텍스트 에디터. 서식, 텍스트 스타일, 정렬, 테이블, 이미지, 하이라이트 도구 포함.
|
|
284
489
|
|
|
285
490
|
```tsx
|
|
491
|
+
import { RichTextEditor } from "@simplysm/solid";
|
|
492
|
+
|
|
286
493
|
<RichTextEditor value={html()} onValueChange={setHtml} />
|
|
287
494
|
```
|
|
288
495
|
|
|
@@ -356,6 +563,8 @@ const [filterState, setFilterState] = createSignal({ status: "active", keyword:
|
|
|
356
563
|
라이트/다크/시스템 모드 전환 버튼.
|
|
357
564
|
|
|
358
565
|
```tsx
|
|
566
|
+
import { ThemeToggle } from "@simplysm/solid";
|
|
567
|
+
|
|
359
568
|
<ThemeToggle />
|
|
360
569
|
```
|
|
361
570
|
|
package/docs/layout-data.md
CHANGED
|
@@ -96,6 +96,12 @@ sidebar.setToggle(true); // 열기/닫기 토글
|
|
|
96
96
|
- `toggle=false` (기본): 데스크탑(640px+)에서 열림, 모바일(640px-)에서 닫힘
|
|
97
97
|
- `toggle=true`: 데스크탑에서 닫힘, 모바일에서 오버레이로 열림
|
|
98
98
|
|
|
99
|
+
하위 메뉴 기본 펼침:
|
|
100
|
+
```tsx
|
|
101
|
+
<Sidebar.Menu menus={menus} defaultOpen />
|
|
102
|
+
```
|
|
103
|
+
- `defaultOpen`: 모든 하위 메뉴를 처음부터 펼친 상태로 렌더링한다. 기본값 `false`.
|
|
104
|
+
|
|
99
105
|
---
|
|
100
106
|
|
|
101
107
|
## Topbar
|
package/docs/providers-hooks.md
CHANGED
|
@@ -38,14 +38,23 @@ const theme = useTheme();
|
|
|
38
38
|
theme.mode(); // "light" | "dark" | "system"
|
|
39
39
|
theme.resolvedTheme(); // "light" | "dark" (OS 설정 반영)
|
|
40
40
|
theme.setMode("dark");
|
|
41
|
-
theme.cycleMode(); // light
|
|
41
|
+
theme.cycleMode(); // light -> system -> dark -> light
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
### useTheme 반환 타입
|
|
45
|
+
|
|
46
|
+
| 속성 | 타입 | 설명 |
|
|
47
|
+
|------|------|------|
|
|
48
|
+
| `mode()` | `ThemeMode` | 현재 테마 모드 (`"light" \| "dark" \| "system"`) |
|
|
49
|
+
| `setMode(mode)` | `(mode: ThemeMode) => void` | 테마 모드 설정 |
|
|
50
|
+
| `resolvedTheme()` | `ResolvedTheme` | 실제 적용된 테마 (`"light" \| "dark"`) |
|
|
51
|
+
| `cycleMode()` | `() => void` | 다음 모드로 순환 |
|
|
52
|
+
|
|
44
53
|
---
|
|
45
54
|
|
|
46
55
|
## I18nProvider
|
|
47
56
|
|
|
48
|
-
다국어 지원. 한국어(ko), 영어(en) 내장.
|
|
57
|
+
다국어 지원. 한국어(ko), 영어(en) 내장. 브라우저 언어 자동 감지.
|
|
49
58
|
|
|
50
59
|
```tsx
|
|
51
60
|
import { I18nProvider, useI18n } from "@simplysm/solid";
|
|
@@ -70,6 +79,15 @@ i18n.configure({
|
|
|
70
79
|
});
|
|
71
80
|
```
|
|
72
81
|
|
|
82
|
+
### useI18n 반환 타입
|
|
83
|
+
|
|
84
|
+
| 속성 | 타입 | 설명 |
|
|
85
|
+
|------|------|------|
|
|
86
|
+
| `t(key, params?)` | `(key: string, params?: Record<string, string>) => string` | 번역 조회 |
|
|
87
|
+
| `locale()` | `Accessor<string>` | 현재 로케일 |
|
|
88
|
+
| `setLocale(locale)` | `(locale: string) => void` | 로케일 변경 |
|
|
89
|
+
| `configure(options)` | `(options: I18nConfigureOptions) => void` | 사전 확장/설정 |
|
|
90
|
+
|
|
73
91
|
---
|
|
74
92
|
|
|
75
93
|
## SharedDataProvider
|
|
@@ -159,41 +177,111 @@ await sharedData.wait();
|
|
|
159
177
|
|
|
160
178
|
### createControllableSignal
|
|
161
179
|
|
|
162
|
-
제어/비제어 컴포넌트 패턴 구현.
|
|
180
|
+
제어/비제어 컴포넌트 패턴 구현. `onChange`가 제공되면 제어 모드, 없으면 비제어 모드.
|
|
163
181
|
|
|
164
182
|
```typescript
|
|
165
183
|
import { createControllableSignal } from "@simplysm/solid";
|
|
166
184
|
|
|
167
185
|
const [value, setValue] = createControllableSignal({
|
|
168
|
-
value: () => props.value,
|
|
186
|
+
value: () => props.value ?? "",
|
|
169
187
|
onChange: () => props.onValueChange,
|
|
170
188
|
});
|
|
189
|
+
|
|
190
|
+
// 함수형 setter 지원
|
|
191
|
+
setValue((prev) => prev + "!");
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// 시그니처
|
|
196
|
+
function createControllableSignal<TValue>(options: {
|
|
197
|
+
value: Accessor<TValue>;
|
|
198
|
+
onChange: Accessor<((value: TValue) => void) | undefined>;
|
|
199
|
+
}): [Accessor<TValue>, (newValue: TValue | ((prev: TValue) => TValue)) => TValue];
|
|
171
200
|
```
|
|
172
201
|
|
|
173
202
|
### createControllableStore
|
|
174
203
|
|
|
175
|
-
객체 상태용 제어/비제어 패턴.
|
|
204
|
+
객체 상태용 제어/비제어 패턴. SolidJS store 기반.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { createControllableStore } from "@simplysm/solid";
|
|
208
|
+
|
|
209
|
+
const [items, setItems] = createControllableStore<Item[]>({
|
|
210
|
+
value: () => props.items ?? [],
|
|
211
|
+
onChange: () => props.onItemsChange,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// SetStoreFunction 오버로드 모두 지원
|
|
215
|
+
setItems(0, "name", "Alice");
|
|
216
|
+
setItems(reconcile(newItems));
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// 시그니처
|
|
221
|
+
function createControllableStore<TValue extends object>(options: {
|
|
222
|
+
value: () => TValue;
|
|
223
|
+
onChange: () => ((value: TValue) => void) | undefined;
|
|
224
|
+
}): [TValue, SetStoreFunction<TValue>];
|
|
225
|
+
```
|
|
176
226
|
|
|
177
227
|
### createIMEHandler
|
|
178
228
|
|
|
179
|
-
IME(한글 등) 입력 처리.
|
|
229
|
+
IME(한글 등) 입력 처리. 조합 중 DOM 재생성을 방지한다.
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { createIMEHandler } from "@simplysm/solid";
|
|
233
|
+
|
|
234
|
+
const ime = createIMEHandler((value) => setValue(value));
|
|
235
|
+
|
|
236
|
+
// 이벤트 핸들러
|
|
237
|
+
onCompositionStart={ime.handleCompositionStart}
|
|
238
|
+
onInput={(e) => ime.handleInput(e.currentTarget.value, e.isComposing)}
|
|
239
|
+
onCompositionEnd={(e) => ime.handleCompositionEnd(e.currentTarget.value)}
|
|
240
|
+
|
|
241
|
+
// 조합 중 값 (display 용)
|
|
242
|
+
ime.composingValue()
|
|
243
|
+
|
|
244
|
+
// 조합 강제 완료
|
|
245
|
+
ime.flushComposition()
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### createMountTransition
|
|
249
|
+
|
|
250
|
+
마운트/언마운트 시 애니메이션 상태를 관리한다.
|
|
180
251
|
|
|
181
252
|
```typescript
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
//
|
|
253
|
+
import { createMountTransition } from "@simplysm/solid";
|
|
254
|
+
|
|
255
|
+
const { mounted, animating, unmount } = createMountTransition(() => isVisible());
|
|
256
|
+
|
|
257
|
+
// mounted: DOM에 마운트 여부
|
|
258
|
+
// animating: 진입/퇴장 애니메이션 중 여부
|
|
259
|
+
// unmount: 언마운트 트리거
|
|
187
260
|
```
|
|
188
261
|
|
|
189
262
|
### useLocalStorage
|
|
190
263
|
|
|
191
|
-
반응형 localStorage.
|
|
264
|
+
반응형 localStorage. `ConfigProvider`의 `clientName`을 키 접두사로 사용한다.
|
|
192
265
|
|
|
193
266
|
```typescript
|
|
194
267
|
import { useLocalStorage } from "@simplysm/solid";
|
|
195
268
|
|
|
196
|
-
const [
|
|
269
|
+
const [token, setToken] = useLocalStorage<string>("auth-token");
|
|
270
|
+
|
|
271
|
+
setToken("abc123"); // 저장
|
|
272
|
+
token(); // "abc123"
|
|
273
|
+
setToken(undefined); // 삭제
|
|
274
|
+
|
|
275
|
+
// 함수형 setter
|
|
276
|
+
setToken((prev) => prev ? prev + "-updated" : "new-token");
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
// 시그니처
|
|
281
|
+
function useLocalStorage<TValue>(
|
|
282
|
+
key: string,
|
|
283
|
+
initialValue?: TValue,
|
|
284
|
+
): [Accessor<TValue | undefined>, StorageSetter<TValue>];
|
|
197
285
|
```
|
|
198
286
|
|
|
199
287
|
### useSyncConfig
|
|
@@ -201,30 +289,28 @@ const [theme, setTheme] = useLocalStorage("theme", "light");
|
|
|
201
289
|
클라이언트명 접두사 붙은 localStorage 동기화.
|
|
202
290
|
|
|
203
291
|
```typescript
|
|
292
|
+
import { useSyncConfig } from "@simplysm/solid";
|
|
293
|
+
|
|
204
294
|
const [config, setConfig] = useSyncConfig("my-setting", defaultValue);
|
|
205
295
|
```
|
|
206
296
|
|
|
207
297
|
### useLogger
|
|
208
298
|
|
|
209
299
|
```typescript
|
|
300
|
+
import { useLogger } from "@simplysm/solid";
|
|
301
|
+
|
|
210
302
|
const logger = useLogger();
|
|
211
303
|
```
|
|
212
304
|
|
|
213
305
|
### useRouterLink
|
|
214
306
|
|
|
215
307
|
```typescript
|
|
308
|
+
import { useRouterLink } from "@simplysm/solid";
|
|
309
|
+
|
|
216
310
|
const navigate = useRouterLink();
|
|
217
311
|
navigate("/users");
|
|
218
312
|
```
|
|
219
313
|
|
|
220
|
-
### createMountTransition
|
|
221
|
-
|
|
222
|
-
마운트 애니메이션 상태 관리.
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
const { mounted, animating, unmount } = createMountTransition(() => isVisible());
|
|
226
|
-
```
|
|
227
|
-
|
|
228
314
|
---
|
|
229
315
|
|
|
230
316
|
## createAppStructure
|
|
@@ -287,6 +373,33 @@ app.perms; // 타입 안전한 권한 객체 (app.perms.admin.users
|
|
|
287
373
|
app.getTitleChainByHref("/admin/users"); // ["관리", "사용자 관리"]
|
|
288
374
|
```
|
|
289
375
|
|
|
376
|
+
### AppStructureItem 타입
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// 그룹 항목 (children 보유)
|
|
380
|
+
interface AppStructureGroupItem<TModule> {
|
|
381
|
+
code: string;
|
|
382
|
+
title: string;
|
|
383
|
+
icon?: Component<IconProps>;
|
|
384
|
+
modules?: TModule[];
|
|
385
|
+
requiredModules?: TModule[];
|
|
386
|
+
children: AppStructureItem<TModule>[];
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// 리프 항목 (페이지 컴포넌트)
|
|
390
|
+
interface AppStructureLeafItem<TModule> {
|
|
391
|
+
code: string;
|
|
392
|
+
title: string;
|
|
393
|
+
icon?: Component<IconProps>;
|
|
394
|
+
modules?: TModule[];
|
|
395
|
+
requiredModules?: TModule[];
|
|
396
|
+
component?: Component;
|
|
397
|
+
perms?: ("use" | "edit")[];
|
|
398
|
+
subPerms?: AppStructureSubPerm<TModule>[];
|
|
399
|
+
isNotMenu?: boolean;
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
290
403
|
### AppStructure 반환 타입
|
|
291
404
|
|
|
292
405
|
| 속성 | 타입 | 설명 |
|
|
@@ -355,14 +468,19 @@ themeTokens.primary.border // border-primary-300 ...
|
|
|
355
468
|
|
|
356
469
|
### ripple
|
|
357
470
|
|
|
358
|
-
Material Design 스타일 리플 효과.
|
|
471
|
+
Material Design 스타일 리플 효과. 포인터 다운 시 클릭 위치에서 원형 리플이 확산된다.
|
|
359
472
|
|
|
360
473
|
```tsx
|
|
361
474
|
import { ripple } from "@simplysm/solid";
|
|
475
|
+
void ripple; // TypeScript directive 등록
|
|
362
476
|
|
|
363
|
-
<button use:ripple>클릭</button>
|
|
477
|
+
<button use:ripple={!props.disabled}>클릭</button>
|
|
364
478
|
```
|
|
365
479
|
|
|
480
|
+
- `prefers-reduced-motion: reduce` 설정 시 리플 비활성화
|
|
481
|
+
- 내부적으로 `overflow: hidden` 컨테이너를 생성하여 부모 요소에 영향 없음
|
|
482
|
+
- `static` 포지션인 경우 자동으로 `relative`로 변경 (cleanup 시 복원)
|
|
483
|
+
|
|
366
484
|
---
|
|
367
485
|
|
|
368
486
|
## 헬퍼
|
|
@@ -384,28 +502,15 @@ mergeStyles("color: red", "font-size: 14px"); // "color: red; font-size: 14px"
|
|
|
384
502
|
```typescript
|
|
385
503
|
import { createSlot } from "@simplysm/solid";
|
|
386
504
|
|
|
387
|
-
// 슬롯 정의
|
|
505
|
+
// 1. 슬롯 정의
|
|
388
506
|
const [MySlot, createMySlotAccessor] = createSlot<{ children: JSX.Element }>();
|
|
389
507
|
|
|
390
|
-
// 컴포넌트 내부에서 슬롯 접근
|
|
508
|
+
// 2. 컴포넌트 내부에서 슬롯 접근
|
|
391
509
|
const [slotValue, SlotProvider] = createMySlotAccessor();
|
|
392
510
|
|
|
393
|
-
// 사용
|
|
511
|
+
// 3. 사용
|
|
394
512
|
<SlotProvider>
|
|
395
513
|
<MySlot><span>슬롯 내용</span></MySlot>
|
|
396
|
-
{/* slotValue()
|
|
514
|
+
{/* slotValue()?.children 으로 접근 */}
|
|
397
515
|
</SlotProvider>
|
|
398
516
|
```
|
|
399
|
-
|
|
400
|
-
### startPointerDrag
|
|
401
|
-
|
|
402
|
-
포인터 드래그 인터랙션 관리. 포인터 캡처를 설정하고 move/end 이벤트를 관리한다.
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
import { startPointerDrag } from "@simplysm/solid";
|
|
406
|
-
|
|
407
|
-
startPointerDrag(element, event.pointerId, {
|
|
408
|
-
onMove: (e) => { /* 드래그 중 */ },
|
|
409
|
-
onEnd: (e) => { /* 드래그 종료 */ },
|
|
410
|
-
});
|
|
411
|
-
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.96",
|
|
4
4
|
"description": "Simplysm package - SolidJS library",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"tabbable": "^6.4.0",
|
|
53
53
|
"tailwind-merge": "^3.5.0",
|
|
54
54
|
"tailwindcss": "^3.4.19",
|
|
55
|
-
"@simplysm/core-browser": "13.0.
|
|
56
|
-
"@simplysm/core-common": "13.0.
|
|
57
|
-
"@simplysm/service-
|
|
58
|
-
"@simplysm/service-
|
|
55
|
+
"@simplysm/core-browser": "13.0.96",
|
|
56
|
+
"@simplysm/core-common": "13.0.96",
|
|
57
|
+
"@simplysm/service-client": "13.0.96",
|
|
58
|
+
"@simplysm/service-common": "13.0.96"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@solidjs/testing-library": "^0.8.10"
|
|
@@ -180,11 +180,17 @@ export interface SidebarMenuProps extends Omit<JSX.HTMLAttributes<HTMLDivElement
|
|
|
180
180
|
* Menu items array
|
|
181
181
|
*/
|
|
182
182
|
menus: AppMenu[];
|
|
183
|
+
/**
|
|
184
|
+
* When true, all nested menu lists are expanded on initial render.
|
|
185
|
+
* @default false
|
|
186
|
+
*/
|
|
187
|
+
defaultOpen?: boolean;
|
|
183
188
|
}
|
|
184
189
|
|
|
185
190
|
// Internal Context: share initial open state
|
|
186
191
|
interface MenuContextValue {
|
|
187
192
|
initialOpenItems: Accessor<Set<AppMenu>>;
|
|
193
|
+
defaultOpen: boolean;
|
|
188
194
|
}
|
|
189
195
|
|
|
190
196
|
const MenuContext = createContext<MenuContextValue>();
|
|
@@ -215,7 +221,7 @@ const MenuContext = createContext<MenuContextValue>();
|
|
|
215
221
|
* ```
|
|
216
222
|
*/
|
|
217
223
|
const SidebarMenu: Component<SidebarMenuProps> = (props) => {
|
|
218
|
-
const [local, rest] = splitProps(props, ["menus", "class"]);
|
|
224
|
+
const [local, rest] = splitProps(props, ["menus", "class", "defaultOpen"]);
|
|
219
225
|
|
|
220
226
|
const location = useLocation();
|
|
221
227
|
|
|
@@ -249,7 +255,7 @@ const SidebarMenu: Component<SidebarMenuProps> = (props) => {
|
|
|
249
255
|
const getClassName = () => twMerge("flex-1 overflow-y-auto", local.class);
|
|
250
256
|
|
|
251
257
|
return (
|
|
252
|
-
<MenuContext.Provider value={{ initialOpenItems }}>
|
|
258
|
+
<MenuContext.Provider value={{ initialOpenItems, defaultOpen: local.defaultOpen ?? false }}>
|
|
253
259
|
<div {...rest} data-sidebar-menu class={getClassName()}>
|
|
254
260
|
<div class={clsx("px-3.5 py-1 text-sm font-bold", text.muted, "uppercase tracking-wider")}>MENU</div>
|
|
255
261
|
<List inset>
|
|
@@ -281,7 +287,7 @@ const MenuItem: Component<MenuItemProps> = (props) => {
|
|
|
281
287
|
// Calculate open state (compare by object reference)
|
|
282
288
|
const shouldBeOpen = () => menuContext.initialOpenItems().has(props.menu);
|
|
283
289
|
|
|
284
|
-
const [open, setOpen] = createSignal(
|
|
290
|
+
const [open, setOpen] = createSignal(menuContext.defaultOpen);
|
|
285
291
|
|
|
286
292
|
// Update open state in response to pathname change
|
|
287
293
|
createEffect(() => {
|