sellmate-design-system-react 9.0.0-beta.17 → 9.0.0-beta.18
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/AGENTS.md +70 -0
- package/dist/components/SChipFilter/README.md +14 -3
- package/dist/components/SChipFilter/SChipFilter.d.ts +10 -3
- package/dist/components/SChipFilter/index.d.ts +1 -1
- package/dist/components/SDatePicker/README.md +5 -1
- package/dist/components/SDatePicker/SDatePicker.d.ts +20 -3
- package/dist/components/SDateRangePicker/README.md +2 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +9 -2
- package/dist/components/SDivider/README.md +2 -0
- package/dist/components/SGhostButton/README.md +2 -0
- package/dist/components/SIcon/SIcon.d.ts +1 -1
- package/dist/components/SIcon/icons.gen.d.ts +2 -0
- package/dist/components/STable/README.md +7 -1
- package/dist/components/STable/STable.d.ts +39 -5
- package/dist/components/STextLink/README.md +3 -0
- package/dist/components/STextLink/STextLink.d.ts +2 -0
- package/dist/index.cjs +315 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +315 -58
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +99 -6
- package/dist/llms.txt +70 -0
- package/dist/styles.css +6 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1203,6 +1203,45 @@ var Icon_close = (p) => {
|
|
|
1203
1203
|
}
|
|
1204
1204
|
);
|
|
1205
1205
|
};
|
|
1206
|
+
var Icon_company = (p) => {
|
|
1207
|
+
const { size = 24, ...rest } = p;
|
|
1208
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1209
|
+
"svg",
|
|
1210
|
+
{
|
|
1211
|
+
width: size,
|
|
1212
|
+
height: size,
|
|
1213
|
+
viewBox: "0 0 24 24",
|
|
1214
|
+
fill: "none",
|
|
1215
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1216
|
+
...rest,
|
|
1217
|
+
children: [
|
|
1218
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1219
|
+
"path",
|
|
1220
|
+
{
|
|
1221
|
+
d: "M14.25 8.5C14.6642 8.5 15 8.83579 15 9.25C15 9.66421 14.6642 10 14.25 10H9.75C9.33579 10 9 9.66421 9 9.25C9 8.83579 9.33579 8.5 9.75 8.5H14.25Z",
|
|
1222
|
+
fill: "currentColor"
|
|
1223
|
+
}
|
|
1224
|
+
),
|
|
1225
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1226
|
+
"path",
|
|
1227
|
+
{
|
|
1228
|
+
d: "M14.25 5.5C14.6642 5.5 15 5.83579 15 6.25C15 6.66421 14.6642 7 14.25 7H9.75C9.33579 7 9 6.66421 9 6.25C9 5.83579 9.33579 5.5 9.75 5.5H14.25Z",
|
|
1229
|
+
fill: "currentColor"
|
|
1230
|
+
}
|
|
1231
|
+
),
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1233
|
+
"path",
|
|
1234
|
+
{
|
|
1235
|
+
fillRule: "evenodd",
|
|
1236
|
+
clipRule: "evenodd",
|
|
1237
|
+
d: "M16 2.25C16.9665 2.25 17.75 3.0335 17.75 4V6.25H20.25C21.2165 6.25 22 7.0335 22 8V20C22 20.9665 21.2165 21.75 20.25 21.75H3.75C2.7835 21.75 2 20.9665 2 20V10C2 9.0335 2.7835 8.25 3.75 8.25H6.25V4C6.25 3.0335 7.0335 2.25 8 2.25H16ZM3.75 9.75C3.61193 9.75 3.5 9.86193 3.5 10V20C3.5 20.1381 3.61193 20.25 3.75 20.25H6.25V9.75H3.75ZM8 3.75C7.86193 3.75 7.75 3.86193 7.75 4V20.25H9.25V16C9.25 15.0335 10.0335 14.25 11 14.25H13C13.9665 14.25 14.75 15.0335 14.75 16V20.25H16.25V4C16.25 3.86193 16.1381 3.75 16 3.75H8ZM11 15.75C10.8619 15.75 10.75 15.8619 10.75 16V20.25H13.25V16C13.25 15.8619 13.1381 15.75 13 15.75H11ZM17.75 20.25H20.25C20.3881 20.25 20.5 20.1381 20.5 20V8C20.5 7.86193 20.3881 7.75 20.25 7.75H17.75V20.25Z",
|
|
1238
|
+
fill: "currentColor"
|
|
1239
|
+
}
|
|
1240
|
+
)
|
|
1241
|
+
]
|
|
1242
|
+
}
|
|
1243
|
+
);
|
|
1244
|
+
};
|
|
1206
1245
|
var Icon_copy = (p) => {
|
|
1207
1246
|
const { size = 24, ...rest } = p;
|
|
1208
1247
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2426,6 +2465,27 @@ var Icon_row = (p) => {
|
|
|
2426
2465
|
}
|
|
2427
2466
|
);
|
|
2428
2467
|
};
|
|
2468
|
+
var Icon_rowDense = (p) => {
|
|
2469
|
+
const { size = 24, ...rest } = p;
|
|
2470
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2471
|
+
"svg",
|
|
2472
|
+
{
|
|
2473
|
+
width: size,
|
|
2474
|
+
height: size,
|
|
2475
|
+
viewBox: "0 0 24 24",
|
|
2476
|
+
fill: "none",
|
|
2477
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2478
|
+
...rest,
|
|
2479
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2480
|
+
"path",
|
|
2481
|
+
{
|
|
2482
|
+
d: "M7.25 2C7.66421 2 8 2.33579 8 2.75V21.25C8 21.6642 7.66421 22 7.25 22H5.75C5.33579 22 5 21.6642 5 21.25V2.75C5 2.33579 5.33579 2 5.75 2H7.25ZM12.75 2C13.1642 2 13.5 2.33579 13.5 2.75V21.25C13.5 21.6642 13.1642 22 12.75 22H11.25C10.8358 22 10.5 21.6642 10.5 21.25V2.75C10.5 2.33579 10.8358 2 11.25 2H12.75ZM18.25 2C18.6642 2 19 2.33579 19 2.75V21.25C19 21.6642 18.6642 22 18.25 22H16.75C16.3358 22 16 21.6642 16 21.25V2.75C16 2.33579 16.3358 2 16.75 2H18.25Z",
|
|
2483
|
+
fill: "currentColor"
|
|
2484
|
+
}
|
|
2485
|
+
)
|
|
2486
|
+
}
|
|
2487
|
+
);
|
|
2488
|
+
};
|
|
2429
2489
|
var Icon_save = (p) => {
|
|
2430
2490
|
const { size = 24, ...rest } = p;
|
|
2431
2491
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3074,6 +3134,7 @@ var ICONS = {
|
|
|
3074
3134
|
clockFill: Icon_clockFill,
|
|
3075
3135
|
clockOutline: Icon_clockOutline,
|
|
3076
3136
|
close: Icon_close,
|
|
3137
|
+
company: Icon_company,
|
|
3077
3138
|
copy: Icon_copy,
|
|
3078
3139
|
coupon: Icon_coupon,
|
|
3079
3140
|
dashboard: Icon_dashboard,
|
|
@@ -3111,6 +3172,7 @@ var ICONS = {
|
|
|
3111
3172
|
reset: Icon_reset,
|
|
3112
3173
|
robot: Icon_robot,
|
|
3113
3174
|
row: Icon_row,
|
|
3175
|
+
rowDense: Icon_rowDense,
|
|
3114
3176
|
save: Icon_save,
|
|
3115
3177
|
search: Icon_search,
|
|
3116
3178
|
send: Icon_send,
|
|
@@ -6104,6 +6166,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
|
|
|
6104
6166
|
label = "",
|
|
6105
6167
|
icon,
|
|
6106
6168
|
iconColor,
|
|
6169
|
+
iconRotate,
|
|
6107
6170
|
labelClass,
|
|
6108
6171
|
rightArrow = "none",
|
|
6109
6172
|
underline = false,
|
|
@@ -6146,7 +6209,7 @@ var STextLink = /* @__PURE__ */ react.forwardRef(function STextLink2({
|
|
|
6146
6209
|
style: { gap: s.gap, color: contentColor, ...style },
|
|
6147
6210
|
...rest,
|
|
6148
6211
|
children: [
|
|
6149
|
-
icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.iconSize, color: resolvedIconColor }),
|
|
6212
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: s.iconSize, color: resolvedIconColor, rotate: iconRotate }),
|
|
6150
6213
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6151
6214
|
"span",
|
|
6152
6215
|
{
|
|
@@ -11124,11 +11187,13 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11124
11187
|
noDataSlot,
|
|
11125
11188
|
isLoading = false,
|
|
11126
11189
|
dense = false,
|
|
11190
|
+
onDenseChange,
|
|
11127
11191
|
noHover = false,
|
|
11128
11192
|
pagination,
|
|
11129
11193
|
onPageChange,
|
|
11130
11194
|
useInternalPagination = false,
|
|
11131
11195
|
useRowsPerPageSelect = false,
|
|
11196
|
+
useDensityToggle = false,
|
|
11132
11197
|
rowsPerPageOption = DEFAULT_ROWS_PER_PAGE_OPTION,
|
|
11133
11198
|
onRowsPerPageChange,
|
|
11134
11199
|
useVirtualScroll = false,
|
|
@@ -11524,21 +11589,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11524
11589
|
col.align === "right" && "justify-end"
|
|
11525
11590
|
),
|
|
11526
11591
|
children: col.renderHeader ? col.renderHeader(col, i) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11527
|
-
col.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: col.icon, size: 16, color: col.iconColor }),
|
|
11528
11592
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: col.label }),
|
|
11529
|
-
isSortable && // 미정렬은 updown 을 default(회색)로 — 정렬할 수 있다는 것 자체가
|
|
11530
|
-
// 헤더에 보여야 한다. 정렬 중이면 action 색으로 올려 활성임을 알린다.
|
|
11531
|
-
// 라벨이 truncate 돼도 버튼은 남도록 shrink-0.
|
|
11532
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11533
|
-
SGhostButton,
|
|
11534
|
-
{
|
|
11535
|
-
size: "xxs",
|
|
11536
|
-
intent: sortDir ? "action" : "default",
|
|
11537
|
-
icon: sortDir === "asc" ? "arrowUp" : sortDir === "desc" ? "arrowDown" : "updown",
|
|
11538
|
-
ariaLabel: `${col.label} \uC815\uB82C`,
|
|
11539
|
-
onClick: () => toggleSort(col)
|
|
11540
|
-
}
|
|
11541
|
-
) }),
|
|
11542
11593
|
col.helpText && col.helpText.length > 0 && // 라벨이 좁아져 truncate 되더라도 아이콘까지 함께 줄어들면 안 되므로
|
|
11543
11594
|
// shrink-0 래퍼로 감싼다 (STooltip 의 className 은 본문 쪽으로 간다).
|
|
11544
11595
|
// 아이콘·크기·색은 SKeyValueTable 헤더 도움말과 동일하게 맞춘다.
|
|
@@ -11552,6 +11603,50 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11552
11603
|
placement: "top",
|
|
11553
11604
|
message: col.helpText
|
|
11554
11605
|
}
|
|
11606
|
+
) }),
|
|
11607
|
+
col.editable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11608
|
+
SIcon,
|
|
11609
|
+
{
|
|
11610
|
+
name: "pageEdit",
|
|
11611
|
+
size: 12,
|
|
11612
|
+
color: "var(--sys-color-link-accent)",
|
|
11613
|
+
label: "\uC218\uC815 \uAC00\uB2A5",
|
|
11614
|
+
className: "shrink-0"
|
|
11615
|
+
}
|
|
11616
|
+
),
|
|
11617
|
+
col.navigable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11618
|
+
SIcon,
|
|
11619
|
+
{
|
|
11620
|
+
name: "pageMove",
|
|
11621
|
+
size: 12,
|
|
11622
|
+
color: "var(--sys-color-link-accent)",
|
|
11623
|
+
label: "\uB2E4\uB978 \uD654\uBA74\uC73C\uB85C \uC774\uB3D9",
|
|
11624
|
+
className: "shrink-0"
|
|
11625
|
+
}
|
|
11626
|
+
),
|
|
11627
|
+
col.required && // 라벨이 truncate 돼도 필수 표시는 남아야 하므로 shrink-0.
|
|
11628
|
+
// 아이콘·크기·색은 SKeyValueTable 헤더 필수 표시와 동일하게 맞춘다.
|
|
11629
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11630
|
+
SIcon,
|
|
11631
|
+
{
|
|
11632
|
+
name: "asterisk",
|
|
11633
|
+
size: 12,
|
|
11634
|
+
color: "var(--sys-color-fg-accent)",
|
|
11635
|
+
className: "shrink-0"
|
|
11636
|
+
}
|
|
11637
|
+
),
|
|
11638
|
+
isSortable && // 미정렬은 updown 을 default(회색)로 — 정렬할 수 있다는 것 자체가
|
|
11639
|
+
// 헤더에 보여야 한다. 정렬 중이면 action 색으로 올려 활성임을 알린다.
|
|
11640
|
+
// 라벨이 truncate 돼도 버튼은 남도록 shrink-0.
|
|
11641
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11642
|
+
SGhostButton,
|
|
11643
|
+
{
|
|
11644
|
+
size: "xxs",
|
|
11645
|
+
intent: sortDir ? "action" : "default",
|
|
11646
|
+
icon: sortDir === "asc" ? "arrowUp" : sortDir === "desc" ? "arrowDown" : "updown",
|
|
11647
|
+
ariaLabel: `${col.label} \uC815\uB82C`,
|
|
11648
|
+
onClick: () => toggleSort(col)
|
|
11649
|
+
}
|
|
11555
11650
|
) })
|
|
11556
11651
|
] })
|
|
11557
11652
|
}
|
|
@@ -11709,16 +11804,32 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
11709
11804
|
),
|
|
11710
11805
|
children: [
|
|
11711
11806
|
/* @__PURE__ */ jsxRuntime.jsx(SPagination, { currentPage: displayPage, lastPage, onPageChange: changePage }),
|
|
11712
|
-
useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11807
|
+
(useDensityToggle || useRowsPerPageSelect) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute right-[10px] top-1/2 flex -translate-y-1/2 items-center gap-[12px]", children: [
|
|
11808
|
+
useDensityToggle && // 라벨·아이콘은 현재 밀도가 아니라 **누르면 되는 상태**를 가리킨다 (dense 면 "넓게 보기").
|
|
11809
|
+
// row·rowDense 는 세로 막대라 90도 돌려 가로 행으로 쓴다.
|
|
11810
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11811
|
+
STextLink,
|
|
11812
|
+
{
|
|
11813
|
+
size: "sm",
|
|
11814
|
+
icon: dense ? "row" : "rowDense",
|
|
11815
|
+
iconRotate: 90,
|
|
11816
|
+
iconColor: "var(--sys-color-fg-quaternary)",
|
|
11817
|
+
label: dense ? "\uB113\uAC8C \uBCF4\uAE30" : "\uC881\uAC8C \uBCF4\uAE30",
|
|
11818
|
+
onClick: () => onDenseChange?.(!dense)
|
|
11819
|
+
}
|
|
11820
|
+
),
|
|
11821
|
+
useDensityToggle && useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.jsx(SDivider, { vertical: true, className: "my-[6px]" }),
|
|
11822
|
+
useRowsPerPageSelect && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11823
|
+
SSelect2,
|
|
11824
|
+
{
|
|
11825
|
+
options: rowsPerPageOption,
|
|
11826
|
+
value: useInternalPagination ? innerRowsPerPage : pagination?.rowsPerPage,
|
|
11827
|
+
emitValue: true,
|
|
11828
|
+
onValueChange: (v) => changeRowsPerPage(Number(v)),
|
|
11829
|
+
width: 128
|
|
11830
|
+
}
|
|
11831
|
+
)
|
|
11832
|
+
] })
|
|
11722
11833
|
]
|
|
11723
11834
|
}
|
|
11724
11835
|
)
|
|
@@ -12814,6 +12925,11 @@ function SCalendar({
|
|
|
12814
12925
|
}
|
|
12815
12926
|
);
|
|
12816
12927
|
}
|
|
12928
|
+
var MODE_NOUN = {
|
|
12929
|
+
date: "\uB0A0\uC9DC",
|
|
12930
|
+
month: "\uC6D4",
|
|
12931
|
+
year: "\uC5F0\uB3C4"
|
|
12932
|
+
};
|
|
12817
12933
|
var DATEPICKER_MODE_LIST_HEIGHT = 240;
|
|
12818
12934
|
var DATEPICKER_MODE_ITEM_HEIGHT = 28;
|
|
12819
12935
|
var YEAR_LIST_EDGE_BUFFER = 24;
|
|
@@ -13085,7 +13201,9 @@ function SDatePicker({
|
|
|
13085
13201
|
placeholder,
|
|
13086
13202
|
selectable,
|
|
13087
13203
|
disabled = false,
|
|
13204
|
+
clearable = false,
|
|
13088
13205
|
width,
|
|
13206
|
+
maxWidth,
|
|
13089
13207
|
name,
|
|
13090
13208
|
rules,
|
|
13091
13209
|
status,
|
|
@@ -13128,7 +13246,8 @@ function SDatePicker({
|
|
|
13128
13246
|
fieldMinW: 168,
|
|
13129
13247
|
// 값 길이가 YYYY-MM-DD 로 정해져 있어, width="100%" 를 받아도 행 전체로
|
|
13130
13248
|
// 늘어나지 않게 상한을 건다 (SKeyValueTable 이 모든 컨트롤에 100% 를 넘긴다).
|
|
13131
|
-
// px 가 아니라 등급이라 --cmp-field-width-* 가 바뀌면 함께
|
|
13249
|
+
// px 가 아니라 등급이라 --cmp-field-width-* 가 바뀌면 함께 따라간다.
|
|
13250
|
+
// 이 기본 상한이 걸리적거리는 자리(폭이 이미 좁게 정해진 팝오버 등)는 maxWidth prop 으로 덮는다
|
|
13132
13251
|
fieldMaxW: "lg",
|
|
13133
13252
|
fontSize: 14,
|
|
13134
13253
|
lineHeight: 24,
|
|
@@ -13149,6 +13268,10 @@ function SDatePicker({
|
|
|
13149
13268
|
if (rules && rules.length > 0) setRuleError(runRules(date, rules));
|
|
13150
13269
|
setOpen(false);
|
|
13151
13270
|
};
|
|
13271
|
+
const clear = () => {
|
|
13272
|
+
onValueChange?.(null);
|
|
13273
|
+
if (rules && rules.length > 0) setRuleError(runRules(null, rules));
|
|
13274
|
+
};
|
|
13152
13275
|
const selectListboxValue = (nextValue) => {
|
|
13153
13276
|
onValueChange?.(nextValue);
|
|
13154
13277
|
if (rules && rules.length > 0) setRuleError(runRules(nextValue, rules));
|
|
@@ -13172,20 +13295,31 @@ function SDatePicker({
|
|
|
13172
13295
|
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
13173
13296
|
width,
|
|
13174
13297
|
minWidth: dims.fieldMinW,
|
|
13175
|
-
maxWidth: dims.fieldMaxW,
|
|
13298
|
+
maxWidth: maxWidth ?? dims.fieldMaxW,
|
|
13176
13299
|
disabled,
|
|
13177
13300
|
className,
|
|
13178
13301
|
style,
|
|
13179
13302
|
children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover10__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
13180
13303
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover10__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13181
|
-
"
|
|
13304
|
+
"div",
|
|
13182
13305
|
{
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
disabled,
|
|
13306
|
+
role: "button",
|
|
13307
|
+
"aria-disabled": disabled,
|
|
13308
|
+
tabIndex: disabled ? -1 : 0,
|
|
13309
|
+
"data-name": name,
|
|
13186
13310
|
onFocus: () => setFocused(true),
|
|
13187
13311
|
onBlur: () => setFocused(false),
|
|
13188
|
-
|
|
13312
|
+
onKeyDown: (event) => {
|
|
13313
|
+
if (disabled) return;
|
|
13314
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
13315
|
+
event.preventDefault();
|
|
13316
|
+
setOpen(!open);
|
|
13317
|
+
}
|
|
13318
|
+
},
|
|
13319
|
+
className: cn(
|
|
13320
|
+
"flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
|
|
13321
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
13322
|
+
),
|
|
13189
13323
|
style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
|
|
13190
13324
|
children: [
|
|
13191
13325
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13209,6 +13343,18 @@ function SDatePicker({
|
|
|
13209
13343
|
},
|
|
13210
13344
|
children: hasValue ? value : resolvedPlaceholder
|
|
13211
13345
|
}
|
|
13346
|
+
),
|
|
13347
|
+
clearable && hasValue && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
13348
|
+
SGhostButton,
|
|
13349
|
+
{
|
|
13350
|
+
icon: "close",
|
|
13351
|
+
size: "xxs",
|
|
13352
|
+
ariaLabel: `${MODE_NOUN[mode]} \uC9C0\uC6B0\uAE30`,
|
|
13353
|
+
onClick: (event) => {
|
|
13354
|
+
event.stopPropagation();
|
|
13355
|
+
clear();
|
|
13356
|
+
}
|
|
13357
|
+
}
|
|
13212
13358
|
)
|
|
13213
13359
|
]
|
|
13214
13360
|
}
|
|
@@ -13588,6 +13734,7 @@ function SDateRangePicker({
|
|
|
13588
13734
|
maxRange,
|
|
13589
13735
|
useTimePicker = false,
|
|
13590
13736
|
disabled = false,
|
|
13737
|
+
clearable = false,
|
|
13591
13738
|
width,
|
|
13592
13739
|
name,
|
|
13593
13740
|
rules,
|
|
@@ -13655,6 +13802,11 @@ function SDateRangePicker({
|
|
|
13655
13802
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
13656
13803
|
if (!useTimePicker) setOpen(false);
|
|
13657
13804
|
};
|
|
13805
|
+
const clear = () => {
|
|
13806
|
+
setPendingStart(null);
|
|
13807
|
+
onValueChange?.(null);
|
|
13808
|
+
if (rules && rules.length > 0) setRuleError(runRules(null, rules));
|
|
13809
|
+
};
|
|
13658
13810
|
const resolvedPlaceholder = useTimePicker && placeholder === "YYYY-MM-DD ~ YYYY-MM-DD" ? "YYYY-MM-DD HH:mm ~ YYYY-MM-DD HH:mm" : placeholder;
|
|
13659
13811
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13660
13812
|
SField,
|
|
@@ -13690,12 +13842,23 @@ function SDateRangePicker({
|
|
|
13690
13842
|
},
|
|
13691
13843
|
children: [
|
|
13692
13844
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover10__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13693
|
-
"
|
|
13845
|
+
"div",
|
|
13694
13846
|
{
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
disabled,
|
|
13698
|
-
|
|
13847
|
+
role: "button",
|
|
13848
|
+
"aria-disabled": disabled,
|
|
13849
|
+
tabIndex: disabled ? -1 : 0,
|
|
13850
|
+
"data-name": name,
|
|
13851
|
+
onKeyDown: (event) => {
|
|
13852
|
+
if (disabled) return;
|
|
13853
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
13854
|
+
event.preventDefault();
|
|
13855
|
+
setOpen(!open);
|
|
13856
|
+
}
|
|
13857
|
+
},
|
|
13858
|
+
className: cn(
|
|
13859
|
+
"flex h-full w-full items-center overflow-hidden bg-transparent outline-none",
|
|
13860
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
13861
|
+
),
|
|
13699
13862
|
style: { padding: `0 ${dims.padX}px`, gap: dims.gap, borderRadius: dims.radius },
|
|
13700
13863
|
children: [
|
|
13701
13864
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13726,6 +13889,18 @@ function SDateRangePicker({
|
|
|
13726
13889
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
|
|
13727
13890
|
] }) : resolvedPlaceholder
|
|
13728
13891
|
}
|
|
13892
|
+
),
|
|
13893
|
+
clearable && hasDisplay && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
13894
|
+
SGhostButton,
|
|
13895
|
+
{
|
|
13896
|
+
icon: "close",
|
|
13897
|
+
size: "xxs",
|
|
13898
|
+
ariaLabel: "\uAE30\uAC04 \uC9C0\uC6B0\uAE30",
|
|
13899
|
+
onClick: (event) => {
|
|
13900
|
+
event.stopPropagation();
|
|
13901
|
+
clear();
|
|
13902
|
+
}
|
|
13903
|
+
}
|
|
13729
13904
|
)
|
|
13730
13905
|
]
|
|
13731
13906
|
}
|
|
@@ -14990,6 +15165,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
14990
15165
|
);
|
|
14991
15166
|
const [openKey, setOpenKey] = react.useState(null);
|
|
14992
15167
|
const [addOpen, setAddOpen] = react.useState(false);
|
|
15168
|
+
const pendingOpenKeyRef = react.useRef(null);
|
|
14993
15169
|
const triggerRefs = react.useRef(/* @__PURE__ */ new Map());
|
|
14994
15170
|
const initializedDefaultsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
14995
15171
|
const prevOpenKeyRef = react.useRef(null);
|
|
@@ -15065,6 +15241,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15065
15241
|
const hasAddButton = fields.some(isAddableField);
|
|
15066
15242
|
const hasRightActions = hasAddButton || showReset;
|
|
15067
15243
|
const currentOpenField = fields.find((field) => field.key === openKey);
|
|
15244
|
+
const menuOpen = openKey != null || addOpen;
|
|
15068
15245
|
const editorPopoverStyle = react.useMemo(() => {
|
|
15069
15246
|
if (currentOpenField?.type === "keyword") {
|
|
15070
15247
|
return { width: CHIPFILTER_LISTBOX_WIDTH };
|
|
@@ -15123,7 +15300,13 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15123
15300
|
onAddFilter?.(key);
|
|
15124
15301
|
setAddOpen(false);
|
|
15125
15302
|
const field = fields.find((f) => f.key === key);
|
|
15126
|
-
if (field && !isInlineField(field))
|
|
15303
|
+
if (field && !isInlineField(field)) {
|
|
15304
|
+
pendingOpenKeyRef.current = key;
|
|
15305
|
+
requestAnimationFrame(() => {
|
|
15306
|
+
triggerRefs.current.get(key)?.focus();
|
|
15307
|
+
setOpenKey(key);
|
|
15308
|
+
});
|
|
15309
|
+
}
|
|
15127
15310
|
};
|
|
15128
15311
|
const rootStyle = react.useMemo(
|
|
15129
15312
|
() => ({
|
|
@@ -15166,6 +15349,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15166
15349
|
{
|
|
15167
15350
|
message,
|
|
15168
15351
|
open: invalidGroups.has(runGroupIndex),
|
|
15352
|
+
placement: menuOpen ? "top" : "bottom",
|
|
15169
15353
|
children: runBuffer
|
|
15170
15354
|
},
|
|
15171
15355
|
`group-${runGroupIndex}`
|
|
@@ -15179,14 +15363,16 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15179
15363
|
activeFields.forEach((field, index) => {
|
|
15180
15364
|
const inline = isInlineField(field);
|
|
15181
15365
|
const groupIndex = groupIndexByKey.get(field.key) ?? 0;
|
|
15182
|
-
const warning =
|
|
15366
|
+
const warning = invalidGroups.has(groupIndex);
|
|
15183
15367
|
const prevField = index > 0 ? activeFields[index - 1] : null;
|
|
15184
15368
|
const prevGroupIndex = prevField ? groupIndexByKey.get(prevField.key) ?? 0 : null;
|
|
15185
15369
|
const needsLeadingDivider = index === 0 ? false : inline || prevField != null && isInlineField(prevField) || groupIndex !== prevGroupIndex && groups[groupIndex]?.divider === true;
|
|
15370
|
+
const hoistDivider = needsLeadingDivider && groupIndex !== runGroupIndex;
|
|
15186
15371
|
if (groupIndex !== runGroupIndex) {
|
|
15187
15372
|
flushRun();
|
|
15188
15373
|
runGroupIndex = groupIndex;
|
|
15189
15374
|
}
|
|
15375
|
+
if (hoistDivider) nodes.push(/* @__PURE__ */ jsxRuntime.jsx(Divider, { inset: true }, `${field.key}-divider`));
|
|
15190
15376
|
const addable = isAddableField(field);
|
|
15191
15377
|
const showClear = addable || !isAtDefaultValue(field, values[field.key]);
|
|
15192
15378
|
const handleClear = () => {
|
|
@@ -15250,7 +15436,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15250
15436
|
field.key
|
|
15251
15437
|
);
|
|
15252
15438
|
runBuffer.push(
|
|
15253
|
-
needsLeadingDivider ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
15439
|
+
needsLeadingDivider && !hoistDivider ? /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
15254
15440
|
/* @__PURE__ */ jsxRuntime.jsx(Divider, { inset: true }),
|
|
15255
15441
|
node
|
|
15256
15442
|
] }, `${field.key}-wrap`) : node
|
|
@@ -15298,6 +15484,11 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15298
15484
|
side: "bottom",
|
|
15299
15485
|
align: "start",
|
|
15300
15486
|
sideOffset: 4,
|
|
15487
|
+
onCloseAutoFocus: (event) => {
|
|
15488
|
+
if (pendingOpenKeyRef.current == null) return;
|
|
15489
|
+
pendingOpenKeyRef.current = null;
|
|
15490
|
+
event.preventDefault();
|
|
15491
|
+
},
|
|
15301
15492
|
className: cn("z-50 min-w-[180px]", FLOATING_SLIDE_ANIM),
|
|
15302
15493
|
children: /* @__PURE__ */ jsxRuntime.jsx(ListBox, { children: inactiveFields.length > 0 ? inactiveFields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(MenuItem, { onClick: () => addField(field.key), children: field.label }, field.key)) : /* @__PURE__ */ jsxRuntime.jsx(EmptyItem, { children: "\uCD94\uAC00\uD560 \uD544\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) })
|
|
15303
15494
|
}
|
|
@@ -15348,6 +15539,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15348
15539
|
value: values[currentOpenField.key],
|
|
15349
15540
|
disabled: disabled || currentOpenField.disabled,
|
|
15350
15541
|
onValueChange: (next) => emitValue(currentOpenField.key, next),
|
|
15542
|
+
onValueCommit: (next) => emitValueAndSearch(currentOpenField.key, next),
|
|
15351
15543
|
onClose: () => setOpenKey(null)
|
|
15352
15544
|
}
|
|
15353
15545
|
)
|
|
@@ -15375,9 +15567,20 @@ function Divider({ inset, top } = {}) {
|
|
|
15375
15567
|
function GroupTooltip({
|
|
15376
15568
|
message,
|
|
15377
15569
|
open,
|
|
15570
|
+
placement,
|
|
15378
15571
|
children
|
|
15379
15572
|
}) {
|
|
15380
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15573
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15574
|
+
STooltip2,
|
|
15575
|
+
{
|
|
15576
|
+
trigger: "none",
|
|
15577
|
+
open,
|
|
15578
|
+
placement,
|
|
15579
|
+
tooltipType: "warning",
|
|
15580
|
+
message: [message],
|
|
15581
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-[var(--cmp-chipFilter-chip-group)]", children })
|
|
15582
|
+
}
|
|
15583
|
+
);
|
|
15381
15584
|
}
|
|
15382
15585
|
function FilterChip({
|
|
15383
15586
|
field,
|
|
@@ -15487,6 +15690,7 @@ function EditorPanel({
|
|
|
15487
15690
|
value,
|
|
15488
15691
|
disabled,
|
|
15489
15692
|
onValueChange,
|
|
15693
|
+
onValueCommit,
|
|
15490
15694
|
onClose
|
|
15491
15695
|
}) {
|
|
15492
15696
|
const wrapsInPaddedTop = field.type === "date" || field.type === "period";
|
|
@@ -15506,7 +15710,8 @@ function EditorPanel({
|
|
|
15506
15710
|
field,
|
|
15507
15711
|
value,
|
|
15508
15712
|
disabled,
|
|
15509
|
-
onValueChange
|
|
15713
|
+
onValueChange,
|
|
15714
|
+
onValueCommit
|
|
15510
15715
|
}
|
|
15511
15716
|
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
15512
15717
|
FilterEditor,
|
|
@@ -15514,7 +15719,8 @@ function EditorPanel({
|
|
|
15514
15719
|
field,
|
|
15515
15720
|
value,
|
|
15516
15721
|
disabled,
|
|
15517
|
-
onValueChange
|
|
15722
|
+
onValueChange,
|
|
15723
|
+
onValueCommit
|
|
15518
15724
|
}
|
|
15519
15725
|
),
|
|
15520
15726
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -15566,7 +15772,8 @@ function FilterEditor({
|
|
|
15566
15772
|
field,
|
|
15567
15773
|
value,
|
|
15568
15774
|
disabled,
|
|
15569
|
-
onValueChange
|
|
15775
|
+
onValueChange,
|
|
15776
|
+
onValueCommit
|
|
15570
15777
|
}) {
|
|
15571
15778
|
if (field.type === "period") {
|
|
15572
15779
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15597,7 +15804,8 @@ function FilterEditor({
|
|
|
15597
15804
|
field,
|
|
15598
15805
|
value: isKeywordValue(value) ? value : keywordEntries(value),
|
|
15599
15806
|
disabled,
|
|
15600
|
-
onValueChange
|
|
15807
|
+
onValueChange,
|
|
15808
|
+
onValueCommit
|
|
15601
15809
|
}
|
|
15602
15810
|
);
|
|
15603
15811
|
}
|
|
@@ -15639,7 +15847,9 @@ function DatePresetEditor({
|
|
|
15639
15847
|
onValueChange,
|
|
15640
15848
|
selectable: field.selectable,
|
|
15641
15849
|
disabled,
|
|
15642
|
-
placeholder: field.placeholder
|
|
15850
|
+
placeholder: field.placeholder,
|
|
15851
|
+
width: "100%",
|
|
15852
|
+
maxWidth: "100%"
|
|
15643
15853
|
}
|
|
15644
15854
|
);
|
|
15645
15855
|
}
|
|
@@ -15699,7 +15909,8 @@ function PeriodPresetEditor({
|
|
|
15699
15909
|
onValueChange: updateInputValue,
|
|
15700
15910
|
selectable: field.selectable,
|
|
15701
15911
|
disabled,
|
|
15702
|
-
width: "100%"
|
|
15912
|
+
width: "100%",
|
|
15913
|
+
maxWidth: "100%"
|
|
15703
15914
|
}
|
|
15704
15915
|
);
|
|
15705
15916
|
}
|
|
@@ -15712,7 +15923,8 @@ function PeriodPresetEditor({
|
|
|
15712
15923
|
onValueChange: updateInputValue,
|
|
15713
15924
|
selectable: field.selectable,
|
|
15714
15925
|
disabled,
|
|
15715
|
-
width: "100%"
|
|
15926
|
+
width: "100%",
|
|
15927
|
+
maxWidth: "100%"
|
|
15716
15928
|
}
|
|
15717
15929
|
);
|
|
15718
15930
|
}
|
|
@@ -15759,7 +15971,8 @@ function PeriodPresetEditor({
|
|
|
15759
15971
|
onValueChange: updateInputValue,
|
|
15760
15972
|
selectable: field.selectable,
|
|
15761
15973
|
disabled,
|
|
15762
|
-
width: "100%"
|
|
15974
|
+
width: "100%",
|
|
15975
|
+
maxWidth: "100%"
|
|
15763
15976
|
}
|
|
15764
15977
|
);
|
|
15765
15978
|
}
|
|
@@ -15909,6 +16122,7 @@ function InlineDatePresetFilter({
|
|
|
15909
16122
|
) : badge)
|
|
15910
16123
|
] });
|
|
15911
16124
|
}
|
|
16125
|
+
var CSV_PASTE_SEPARATOR = /[,\r\n\t]+/;
|
|
15912
16126
|
var MATCH_MODE_OPTIONS = [
|
|
15913
16127
|
{ value: "contains", label: "\uD3EC\uD568" },
|
|
15914
16128
|
{ value: "exact", label: "\uC77C\uCE58" }
|
|
@@ -15921,20 +16135,61 @@ function KeywordEditor({
|
|
|
15921
16135
|
field,
|
|
15922
16136
|
value,
|
|
15923
16137
|
disabled,
|
|
15924
|
-
onValueChange
|
|
16138
|
+
onValueChange,
|
|
16139
|
+
onValueCommit
|
|
15925
16140
|
}) {
|
|
15926
16141
|
const entries3 = keywordEntries(value);
|
|
15927
16142
|
const [draft, setDraft] = react.useState("");
|
|
15928
16143
|
const [mode, setMode] = react.useState(
|
|
15929
16144
|
isKeywordValue(value) ? value.mode : "contains"
|
|
15930
16145
|
);
|
|
15931
|
-
const
|
|
15932
|
-
|
|
16146
|
+
const inputRef = react.useRef(null);
|
|
16147
|
+
react.useEffect(() => {
|
|
16148
|
+
if (disabled) return;
|
|
16149
|
+
inputRef.current?.focus();
|
|
16150
|
+
}, [disabled]);
|
|
16151
|
+
const emit3 = (nextEntries, nextMode = mode) => {
|
|
16152
|
+
onValueChange(field.matchModes ? { keywords: nextEntries, mode: nextMode } : nextEntries);
|
|
15933
16153
|
};
|
|
15934
|
-
const
|
|
16154
|
+
const commit = (nextEntries) => {
|
|
16155
|
+
onValueCommit(field.matchModes ? { keywords: nextEntries, mode } : nextEntries);
|
|
16156
|
+
};
|
|
16157
|
+
const changeMode = (next) => {
|
|
16158
|
+
setMode(next);
|
|
16159
|
+
emit3(entries3, next);
|
|
16160
|
+
};
|
|
16161
|
+
const newEntries = (candidates) => candidates.reduce((acc, raw) => {
|
|
15935
16162
|
const next = raw.trim();
|
|
15936
|
-
if (next === "" || entries3.includes(next)) return;
|
|
15937
|
-
|
|
16163
|
+
if (next === "" || entries3.includes(next) || acc.includes(next)) return acc;
|
|
16164
|
+
return [...acc, next];
|
|
16165
|
+
}, []);
|
|
16166
|
+
const addEntry = (raw) => {
|
|
16167
|
+
const added = newEntries([raw]);
|
|
16168
|
+
if (added.length === 0) {
|
|
16169
|
+
setDraft("");
|
|
16170
|
+
return;
|
|
16171
|
+
}
|
|
16172
|
+
commit([...entries3, ...added]);
|
|
16173
|
+
setDraft("");
|
|
16174
|
+
};
|
|
16175
|
+
const changeDraft = (next) => {
|
|
16176
|
+
if (field.input !== "csv" || !next.includes(",")) {
|
|
16177
|
+
setDraft(next);
|
|
16178
|
+
return;
|
|
16179
|
+
}
|
|
16180
|
+
const parts = next.split(",");
|
|
16181
|
+
const tail = parts.pop() ?? "";
|
|
16182
|
+
const added = newEntries(parts);
|
|
16183
|
+
if (added.length > 0) commit([...entries3, ...added]);
|
|
16184
|
+
setDraft(tail);
|
|
16185
|
+
};
|
|
16186
|
+
const onPaste = (event) => {
|
|
16187
|
+
if (field.input !== "csv") return;
|
|
16188
|
+
const text = event.clipboardData.getData("text");
|
|
16189
|
+
if (!CSV_PASTE_SEPARATOR.test(text)) return;
|
|
16190
|
+
event.preventDefault();
|
|
16191
|
+
const added = newEntries((draft + text).split(CSV_PASTE_SEPARATOR));
|
|
16192
|
+
if (added.length > 0) commit([...entries3, ...added]);
|
|
15938
16193
|
setDraft("");
|
|
15939
16194
|
};
|
|
15940
16195
|
const removeEntry = (entry) => {
|
|
@@ -15966,7 +16221,7 @@ function KeywordEditor({
|
|
|
15966
16221
|
options: field.excludeMode ? [...MATCH_MODE_OPTIONS, EXCLUDE_MATCH_MODE_OPTION] : MATCH_MODE_OPTIONS,
|
|
15967
16222
|
value: mode,
|
|
15968
16223
|
disabled,
|
|
15969
|
-
onValueChange: (next) =>
|
|
16224
|
+
onValueChange: (next) => changeMode(next)
|
|
15970
16225
|
}
|
|
15971
16226
|
)
|
|
15972
16227
|
] }),
|
|
@@ -15975,10 +16230,12 @@ function KeywordEditor({
|
|
|
15975
16230
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15976
16231
|
"input",
|
|
15977
16232
|
{
|
|
16233
|
+
ref: inputRef,
|
|
15978
16234
|
value: draft,
|
|
15979
16235
|
disabled,
|
|
15980
|
-
placeholder: field.placeholder ?? "\uC785\uB825 \uD6C4 Enter\uB85C \uCD94\uAC00",
|
|
15981
|
-
onChange: (event) =>
|
|
16236
|
+
placeholder: field.placeholder ?? (field.input === "csv" ? "\uB2E4\uC911 \uD0A4\uC6CC\uB4DC\uB294 \uCF64\uB9C8(,)\uB85C \uAD6C\uBD84" : "\uC785\uB825 \uD6C4 Enter\uB85C \uCD94\uAC00"),
|
|
16237
|
+
onChange: (event) => changeDraft(event.target.value),
|
|
16238
|
+
onPaste,
|
|
15982
16239
|
onKeyDown,
|
|
15983
16240
|
className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--sys-color-field-text-default)] outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed"
|
|
15984
16241
|
}
|