sellmate-design-system-react 9.0.0-beta.10 → 9.0.0-beta.12
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 +3 -3
- package/dist/components/SBadge/README.md +24 -0
- package/dist/components/SBadge/SBadge.d.ts +1 -1
- package/dist/components/SBarcodeInput/README.md +8 -0
- package/dist/components/SButton/README.md +34 -0
- package/dist/components/SCalendar/README.md +13 -0
- package/dist/components/SCallout/README.md +15 -0
- package/dist/components/SCheckbox/README.md +8 -0
- package/dist/components/SChipFilter/README.md +276 -3
- package/dist/components/SChipFilter/SChipFilter.d.ts +78 -37
- package/dist/components/SChipFilter/index.d.ts +1 -1
- package/dist/components/SChipInput/README.md +14 -0
- package/dist/components/SCircleProgress/README.md +8 -0
- package/dist/components/SConfirmModal/README.md +16 -0
- package/dist/components/SDatePicker/README.md +14 -0
- package/dist/components/SDateRangePicker/README.md +14 -0
- package/dist/components/SDraggableItem/README.md +36 -0
- package/dist/components/SDraggableList/README.md +24 -0
- package/dist/components/SDrawer/README.md +8 -0
- package/dist/components/SDropdownButton/README.md +19 -0
- package/dist/components/SExpansionItem/README.md +36 -0
- package/dist/components/SField/README.md +20 -0
- package/dist/components/SFilePicker/README.md +14 -0
- package/dist/components/SFooter/README.md +21 -0
- package/dist/components/SForm/README.md +11 -0
- package/dist/components/SGhostButton/README.md +14 -2
- package/dist/components/SGnb/README.md +45 -0
- package/dist/components/SGuide/README.md +15 -0
- package/dist/components/SImage/README.md +14 -0
- package/dist/components/SKeyValueTable/README.md +83 -0
- package/dist/components/SLayout/README.md +16 -0
- package/dist/components/SLinearProgress/README.md +8 -0
- package/dist/components/SListItem/README.md +41 -0
- package/dist/components/SLoadingModal/README.md +8 -0
- package/dist/components/SNumberInput/README.md +8 -0
- package/dist/components/SPage/README.md +38 -0
- package/dist/components/SPopover/README.md +15 -0
- package/dist/components/SPopup/README.md +19 -0
- package/dist/components/SPortal/README.md +14 -0
- package/dist/components/SRadio/README.md +20 -0
- package/dist/components/SRadioButton/README.md +18 -0
- package/dist/components/SScrollArea/README.md +14 -0
- package/dist/components/SSearchInput/README.md +13 -0
- package/dist/components/SSectionHeaderCard/README.md +32 -0
- package/dist/components/SSelect/README.md +21 -2
- package/dist/components/SSplitter/README.md +15 -0
- package/dist/components/SStepper/README.md +26 -0
- package/dist/components/STable/README.md +103 -0
- package/dist/components/STabs/README.md +12 -0
- package/dist/components/STag/README.md +47 -0
- package/dist/components/STextLink/README.md +14 -0
- package/dist/components/STimePicker/README.md +14 -0
- package/dist/components/STimeRangePicker/README.md +26 -0
- package/dist/components/SToast/README.md +24 -0
- package/dist/components/SToggle/README.md +8 -0
- package/dist/components/STooltip/README.md +20 -0
- package/dist/components/STree/README.md +38 -0
- package/dist/index.cjs +170 -186
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +170 -186
- package/dist/index.js.map +1 -1
- package/dist/lib/story-docs.d.ts +19 -3
- package/dist/llms-full.txt +1444 -15
- package/dist/llms.txt +3 -3
- package/dist/styles.css +5 -16
- package/package.json +1 -1
|
@@ -40,6 +40,26 @@
|
|
|
40
40
|
| `show` | `() => void` | 툴팁을 표시합니다. |
|
|
41
41
|
| `hide` | `() => void` | 툴팁을 숨깁니다. |
|
|
42
42
|
|
|
43
|
+
## Types
|
|
44
|
+
|
|
45
|
+
### STooltipTrigger
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
export type STooltipTrigger = 'hover' | 'click' | 'none';
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### STooltipPlacement
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
export type STooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### STooltipType
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
export type STooltipType = 'default' | 'danger' | 'warning' | 'accent';
|
|
61
|
+
```
|
|
62
|
+
|
|
43
63
|
## Dependencies
|
|
44
64
|
|
|
45
65
|
### Used by
|
|
@@ -56,6 +56,44 @@
|
|
|
56
56
|
| `onValueChange` | `(value: string[], node: STreeNode) => void` | 선택 변경 |
|
|
57
57
|
| `onExpandedChange` | `(expandedIds: string[], node: STreeNode) => void` | 펼침 변경 |
|
|
58
58
|
|
|
59
|
+
## Types
|
|
60
|
+
|
|
61
|
+
### STreeNode
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
export interface STreeNode {
|
|
65
|
+
/** 노드 고유 ID */
|
|
66
|
+
id: string;
|
|
67
|
+
/** 노드 라벨 */
|
|
68
|
+
label: ReactNode;
|
|
69
|
+
/** 하위 노드 */
|
|
70
|
+
children?: STreeNode[];
|
|
71
|
+
/** 비활성 상태 */
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### STreeSize
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
export type STreeSize = 'sm' | 'md';
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### STreeItemRenderState
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
export interface STreeItemRenderState {
|
|
86
|
+
node: STreeNode;
|
|
87
|
+
depth: number;
|
|
88
|
+
size: STreeSize;
|
|
89
|
+
expanded: boolean;
|
|
90
|
+
selected: boolean;
|
|
91
|
+
indeterminate: boolean;
|
|
92
|
+
disabled: boolean;
|
|
93
|
+
hasChildren: boolean;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
59
97
|
## Dependencies
|
|
60
98
|
|
|
61
99
|
### Depends on
|
package/dist/index.cjs
CHANGED
|
@@ -3349,6 +3349,7 @@ var BADGE_COLORS = [
|
|
|
3349
3349
|
"orange",
|
|
3350
3350
|
"yellow",
|
|
3351
3351
|
"green",
|
|
3352
|
+
"lightblue",
|
|
3352
3353
|
"blue",
|
|
3353
3354
|
"darkblue",
|
|
3354
3355
|
"indigo",
|
|
@@ -7010,7 +7011,7 @@ function SModalContainer({
|
|
|
7010
7011
|
"div",
|
|
7011
7012
|
{
|
|
7012
7013
|
className: cn(
|
|
7013
|
-
"relative flex max-h-[
|
|
7014
|
+
"relative flex max-h-[calc(100dvh-48px)] max-w-[calc(100dvw-48px)] flex-col overflow-hidden rounded-[var(--cmp-modal-radius)] bg-[var(--cmp-modal-bg)] shadow-normal-md",
|
|
7014
7015
|
shaking && "animate-modal-shake",
|
|
7015
7016
|
className
|
|
7016
7017
|
),
|
|
@@ -7267,7 +7268,7 @@ function SActionModal({
|
|
|
7267
7268
|
showClose: true,
|
|
7268
7269
|
width,
|
|
7269
7270
|
height,
|
|
7270
|
-
className: "w-fit min-w-[min(480px,calc(100dvw-48px))] min-h-[min(320px,
|
|
7271
|
+
className: "w-fit min-w-[min(480px,calc(100dvw-48px))] min-h-[min(320px,calc(100dvh-48px))]",
|
|
7271
7272
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-auto flex-col", children: [
|
|
7272
7273
|
/* @__PURE__ */ jsxRuntime.jsx(SOverlayHeader, { title: modalTitle, description, reserveCloseSpace: true }),
|
|
7273
7274
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto px-[var(--cmp-modal-action-body-paddingX)] pb-[var(--cmp-modal-action-body-paddingBottom)]", children }),
|
|
@@ -10208,6 +10209,122 @@ var SField = /* @__PURE__ */ react.forwardRef(function SField2({
|
|
|
10208
10209
|
);
|
|
10209
10210
|
});
|
|
10210
10211
|
|
|
10212
|
+
// src/lib/autofill.ts
|
|
10213
|
+
var AUTOFILL_RESET_CLASS = "autofill:[-webkit-text-fill-color:currentColor] autofill:[box-shadow:0_0_0_1000px_var(--sys-color-field-bg-default)_inset] autofill:[transition:background-color_5000s_ease-in-out_0s] [&:-webkit-autofill]:[-webkit-text-fill-color:currentColor] [&:-webkit-autofill]:[box-shadow:0_0_0_1000px_var(--sys-color-field-bg-default)_inset] [&:-webkit-autofill]:[transition:background-color_5000s_ease-in-out_0s]";
|
|
10214
|
+
var FONT = {
|
|
10215
|
+
sm: {
|
|
10216
|
+
fontSize: 12,
|
|
10217
|
+
lineHeight: 20,
|
|
10218
|
+
paddingX: "var(--cmp-textinput-sm-paddingX)",
|
|
10219
|
+
gap: "var(--cmp-textinput-sm-gap)"
|
|
10220
|
+
},
|
|
10221
|
+
md: {
|
|
10222
|
+
fontSize: 14,
|
|
10223
|
+
lineHeight: 24,
|
|
10224
|
+
paddingX: "var(--cmp-textinput-md-paddingX)",
|
|
10225
|
+
gap: "var(--cmp-textinput-md-gap)"
|
|
10226
|
+
}
|
|
10227
|
+
};
|
|
10228
|
+
var SSearchInput = /* @__PURE__ */ react.forwardRef(function SSearchInput2({
|
|
10229
|
+
value,
|
|
10230
|
+
onValueChange,
|
|
10231
|
+
onChange,
|
|
10232
|
+
onSearch,
|
|
10233
|
+
size = "sm",
|
|
10234
|
+
placeholder = "\uACB0\uACFC \uB0B4 \uAC80\uC0C9",
|
|
10235
|
+
clearable = false,
|
|
10236
|
+
disabled = false,
|
|
10237
|
+
width,
|
|
10238
|
+
focused,
|
|
10239
|
+
hovered,
|
|
10240
|
+
inputClass,
|
|
10241
|
+
inputStyle,
|
|
10242
|
+
className,
|
|
10243
|
+
style,
|
|
10244
|
+
onKeyDown,
|
|
10245
|
+
...rest
|
|
10246
|
+
}, ref) {
|
|
10247
|
+
const f = FONT[size];
|
|
10248
|
+
const hasValue = value !== void 0 && value !== null && String(value) !== "";
|
|
10249
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10250
|
+
SField,
|
|
10251
|
+
{
|
|
10252
|
+
size,
|
|
10253
|
+
width,
|
|
10254
|
+
focused,
|
|
10255
|
+
hovered,
|
|
10256
|
+
disabled,
|
|
10257
|
+
className,
|
|
10258
|
+
style,
|
|
10259
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10260
|
+
"div",
|
|
10261
|
+
{
|
|
10262
|
+
className: "flex h-full w-full items-center",
|
|
10263
|
+
style: {
|
|
10264
|
+
gap: f.gap,
|
|
10265
|
+
padding: `0 ${f.paddingX}`,
|
|
10266
|
+
fontSize: f.fontSize,
|
|
10267
|
+
lineHeight: `${f.lineHeight}px`
|
|
10268
|
+
},
|
|
10269
|
+
children: [
|
|
10270
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10271
|
+
SIcon,
|
|
10272
|
+
{
|
|
10273
|
+
name: "search",
|
|
10274
|
+
size: 16,
|
|
10275
|
+
color: disabled ? "var(--sys-color-disabled-icon)" : "var(--cmp-textinput-icon-default)",
|
|
10276
|
+
className: "flex-shrink-0"
|
|
10277
|
+
}
|
|
10278
|
+
),
|
|
10279
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10280
|
+
"input",
|
|
10281
|
+
{
|
|
10282
|
+
ref,
|
|
10283
|
+
type: "search",
|
|
10284
|
+
value: value ?? "",
|
|
10285
|
+
disabled,
|
|
10286
|
+
placeholder,
|
|
10287
|
+
onChange: (e) => {
|
|
10288
|
+
onChange?.(e);
|
|
10289
|
+
onValueChange?.(e.target.value);
|
|
10290
|
+
},
|
|
10291
|
+
onKeyDown: (e) => {
|
|
10292
|
+
onKeyDown?.(e);
|
|
10293
|
+
if (e.key === "Enter" && !e.nativeEvent.isComposing) {
|
|
10294
|
+
onSearch?.(e.currentTarget.value);
|
|
10295
|
+
}
|
|
10296
|
+
},
|
|
10297
|
+
className: cn(
|
|
10298
|
+
// type="search" 의 브라우저 기본 취소 버튼은 clearable 과 겹치므로 지운다
|
|
10299
|
+
"h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:hidden",
|
|
10300
|
+
AUTOFILL_RESET_CLASS,
|
|
10301
|
+
inputClass
|
|
10302
|
+
),
|
|
10303
|
+
style: {
|
|
10304
|
+
// fontSize/lineHeight 는 컨테이너에서 상속 (원본 font-size: inherit)
|
|
10305
|
+
color: disabled ? "var(--cmp-textinput-text-disabled)" : "var(--sys-color-field-text-default)",
|
|
10306
|
+
...inputStyle
|
|
10307
|
+
},
|
|
10308
|
+
...rest
|
|
10309
|
+
}
|
|
10310
|
+
),
|
|
10311
|
+
clearable && hasValue && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10312
|
+
SGhostButton,
|
|
10313
|
+
{
|
|
10314
|
+
icon: "close",
|
|
10315
|
+
size: "xxs",
|
|
10316
|
+
ariaLabel: "\uC9C0\uC6B0\uAE30",
|
|
10317
|
+
className: "flex-shrink-0",
|
|
10318
|
+
onClick: () => onValueChange?.("")
|
|
10319
|
+
}
|
|
10320
|
+
)
|
|
10321
|
+
]
|
|
10322
|
+
}
|
|
10323
|
+
)
|
|
10324
|
+
}
|
|
10325
|
+
);
|
|
10326
|
+
});
|
|
10327
|
+
|
|
10211
10328
|
// src/components/SSelect/select.config.ts
|
|
10212
10329
|
function flattenOptions(options, depth = 1) {
|
|
10213
10330
|
const out = [];
|
|
@@ -10626,31 +10743,17 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
10626
10743
|
{
|
|
10627
10744
|
ref: searchBarRef,
|
|
10628
10745
|
className: "sticky top-0 z-[1] bg-[var(--cmp-listBox-bg)] px-[8px] py-[4px]",
|
|
10629
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
}
|
|
10641
|
-
),
|
|
10642
|
-
search !== "" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
10643
|
-
SGhostButton,
|
|
10644
|
-
{
|
|
10645
|
-
icon: "close",
|
|
10646
|
-
size: "xxs",
|
|
10647
|
-
intent: "default",
|
|
10648
|
-
ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
|
|
10649
|
-
onClick: () => setSearch(""),
|
|
10650
|
-
className: "shrink-0"
|
|
10651
|
-
}
|
|
10652
|
-
)
|
|
10653
|
-
] })
|
|
10746
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10747
|
+
SSearchInput,
|
|
10748
|
+
{
|
|
10749
|
+
ref: searchInputRef,
|
|
10750
|
+
value: search,
|
|
10751
|
+
onValueChange: setSearch,
|
|
10752
|
+
onKeyDown: handleKeyDown,
|
|
10753
|
+
placeholder: "\uAC80\uC0C9",
|
|
10754
|
+
clearable: true
|
|
10755
|
+
}
|
|
10756
|
+
)
|
|
10654
10757
|
}
|
|
10655
10758
|
),
|
|
10656
10759
|
hasItems ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -11530,9 +11633,6 @@ var STableBar = /* @__PURE__ */ react.forwardRef(function STableBar2({ total, se
|
|
|
11530
11633
|
}
|
|
11531
11634
|
);
|
|
11532
11635
|
});
|
|
11533
|
-
|
|
11534
|
-
// src/lib/autofill.ts
|
|
11535
|
-
var AUTOFILL_RESET_CLASS = "autofill:[-webkit-text-fill-color:currentColor] autofill:[box-shadow:0_0_0_1000px_var(--sys-color-field-bg-default)_inset] autofill:[transition:background-color_5000s_ease-in-out_0s] [&:-webkit-autofill]:[-webkit-text-fill-color:currentColor] [&:-webkit-autofill]:[box-shadow:0_0_0_1000px_var(--sys-color-field-bg-default)_inset] [&:-webkit-autofill]:[transition:background-color_5000s_ease-in-out_0s]";
|
|
11536
11636
|
var HIDE_DELAY_MS2 = 100;
|
|
11537
11637
|
function mergeRefs(...refs) {
|
|
11538
11638
|
return (node) => {
|
|
@@ -11594,7 +11694,7 @@ function useTruncatedValueTooltip({
|
|
|
11594
11694
|
] }) : null
|
|
11595
11695
|
};
|
|
11596
11696
|
}
|
|
11597
|
-
var
|
|
11697
|
+
var FONT2 = {
|
|
11598
11698
|
sm: { fontSize: 12, lineHeight: 20, paddingX: "var(--cmp-textinput-sm-paddingX)" },
|
|
11599
11699
|
md: { fontSize: 14, lineHeight: 24, paddingX: "var(--cmp-textinput-md-paddingX)" }
|
|
11600
11700
|
};
|
|
@@ -11635,7 +11735,7 @@ var SInput = /* @__PURE__ */ react.forwardRef(function SInput2({
|
|
|
11635
11735
|
}, ref) {
|
|
11636
11736
|
const [visible, setVisible] = react.useState(false);
|
|
11637
11737
|
const [ruleError, setRuleError] = react.useState("");
|
|
11638
|
-
const f =
|
|
11738
|
+
const f = FONT2[size];
|
|
11639
11739
|
const isPassword = type === "password";
|
|
11640
11740
|
const inputType = isPassword ? visible ? "text" : "password" : type;
|
|
11641
11741
|
const hasValue = value !== void 0 && value !== null && String(value) !== "";
|
|
@@ -14503,119 +14603,6 @@ function SRadioButton({
|
|
|
14503
14603
|
}
|
|
14504
14604
|
);
|
|
14505
14605
|
}
|
|
14506
|
-
var FONT2 = {
|
|
14507
|
-
sm: {
|
|
14508
|
-
fontSize: 12,
|
|
14509
|
-
lineHeight: 20,
|
|
14510
|
-
paddingX: "var(--cmp-textinput-sm-paddingX)",
|
|
14511
|
-
gap: "var(--cmp-textinput-sm-gap)"
|
|
14512
|
-
},
|
|
14513
|
-
md: {
|
|
14514
|
-
fontSize: 14,
|
|
14515
|
-
lineHeight: 24,
|
|
14516
|
-
paddingX: "var(--cmp-textinput-md-paddingX)",
|
|
14517
|
-
gap: "var(--cmp-textinput-md-gap)"
|
|
14518
|
-
}
|
|
14519
|
-
};
|
|
14520
|
-
var SSearchInput = /* @__PURE__ */ react.forwardRef(function SSearchInput2({
|
|
14521
|
-
value,
|
|
14522
|
-
onValueChange,
|
|
14523
|
-
onChange,
|
|
14524
|
-
onSearch,
|
|
14525
|
-
size = "sm",
|
|
14526
|
-
placeholder = "\uACB0\uACFC \uB0B4 \uAC80\uC0C9",
|
|
14527
|
-
clearable = false,
|
|
14528
|
-
disabled = false,
|
|
14529
|
-
width,
|
|
14530
|
-
focused,
|
|
14531
|
-
hovered,
|
|
14532
|
-
inputClass,
|
|
14533
|
-
inputStyle,
|
|
14534
|
-
className,
|
|
14535
|
-
style,
|
|
14536
|
-
onKeyDown,
|
|
14537
|
-
...rest
|
|
14538
|
-
}, ref) {
|
|
14539
|
-
const f = FONT2[size];
|
|
14540
|
-
const hasValue = value !== void 0 && value !== null && String(value) !== "";
|
|
14541
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
14542
|
-
SField,
|
|
14543
|
-
{
|
|
14544
|
-
size,
|
|
14545
|
-
width,
|
|
14546
|
-
focused,
|
|
14547
|
-
hovered,
|
|
14548
|
-
disabled,
|
|
14549
|
-
className,
|
|
14550
|
-
style,
|
|
14551
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
14552
|
-
"div",
|
|
14553
|
-
{
|
|
14554
|
-
className: "flex h-full w-full items-center",
|
|
14555
|
-
style: {
|
|
14556
|
-
gap: f.gap,
|
|
14557
|
-
padding: `0 ${f.paddingX}`,
|
|
14558
|
-
fontSize: f.fontSize,
|
|
14559
|
-
lineHeight: `${f.lineHeight}px`
|
|
14560
|
-
},
|
|
14561
|
-
children: [
|
|
14562
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14563
|
-
SIcon,
|
|
14564
|
-
{
|
|
14565
|
-
name: "search",
|
|
14566
|
-
size: 16,
|
|
14567
|
-
color: disabled ? "var(--sys-color-disabled-icon)" : "var(--cmp-textinput-icon-default)",
|
|
14568
|
-
className: "flex-shrink-0"
|
|
14569
|
-
}
|
|
14570
|
-
),
|
|
14571
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14572
|
-
"input",
|
|
14573
|
-
{
|
|
14574
|
-
ref,
|
|
14575
|
-
type: "search",
|
|
14576
|
-
value: value ?? "",
|
|
14577
|
-
disabled,
|
|
14578
|
-
placeholder,
|
|
14579
|
-
onChange: (e) => {
|
|
14580
|
-
onChange?.(e);
|
|
14581
|
-
onValueChange?.(e.target.value);
|
|
14582
|
-
},
|
|
14583
|
-
onKeyDown: (e) => {
|
|
14584
|
-
onKeyDown?.(e);
|
|
14585
|
-
if (e.key === "Enter" && !e.nativeEvent.isComposing) {
|
|
14586
|
-
onSearch?.(e.currentTarget.value);
|
|
14587
|
-
}
|
|
14588
|
-
},
|
|
14589
|
-
className: cn(
|
|
14590
|
-
// type="search" 의 브라우저 기본 취소 버튼은 clearable 과 겹치므로 지운다
|
|
14591
|
-
"h-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:hidden",
|
|
14592
|
-
AUTOFILL_RESET_CLASS,
|
|
14593
|
-
inputClass
|
|
14594
|
-
),
|
|
14595
|
-
style: {
|
|
14596
|
-
// fontSize/lineHeight 는 컨테이너에서 상속 (원본 font-size: inherit)
|
|
14597
|
-
color: disabled ? "var(--cmp-textinput-text-disabled)" : "var(--sys-color-field-text-default)",
|
|
14598
|
-
...inputStyle
|
|
14599
|
-
},
|
|
14600
|
-
...rest
|
|
14601
|
-
}
|
|
14602
|
-
),
|
|
14603
|
-
clearable && hasValue && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
14604
|
-
SGhostButton,
|
|
14605
|
-
{
|
|
14606
|
-
icon: "close",
|
|
14607
|
-
size: "xxs",
|
|
14608
|
-
ariaLabel: "\uC9C0\uC6B0\uAE30",
|
|
14609
|
-
className: "flex-shrink-0",
|
|
14610
|
-
onClick: () => onValueChange?.("")
|
|
14611
|
-
}
|
|
14612
|
-
)
|
|
14613
|
-
]
|
|
14614
|
-
}
|
|
14615
|
-
)
|
|
14616
|
-
}
|
|
14617
|
-
);
|
|
14618
|
-
});
|
|
14619
14606
|
var CHIPFILTER_LISTBOX_WIDTH = 240;
|
|
14620
14607
|
var CHIPFILTER_DATE_PRESET_LISTBOX_WIDTH = 246;
|
|
14621
14608
|
var CHIPFILTER = {
|
|
@@ -14708,10 +14695,10 @@ var createPeriodValue = (unit) => ({
|
|
|
14708
14695
|
});
|
|
14709
14696
|
var resolveFieldDefault = (field) => {
|
|
14710
14697
|
if (field.defaultValue !== void 0) return field.defaultValue;
|
|
14711
|
-
if (
|
|
14698
|
+
if (field.type === "date")
|
|
14699
|
+
return isInlineDateField(field) || field.required ? todayIso() : void 0;
|
|
14712
14700
|
if (!field.required) return void 0;
|
|
14713
14701
|
if (field.type === "single") return field.options?.[0]?.value;
|
|
14714
|
-
if (field.type === "date") return todayIso();
|
|
14715
14702
|
if (field.type === "period") {
|
|
14716
14703
|
const unit = getFieldPresets(field).find((preset) => !preset.custom)?.value;
|
|
14717
14704
|
return unit ? createPeriodValue(unit) : void 0;
|
|
@@ -14738,10 +14725,18 @@ var isAtDefaultValue = (field, value) => {
|
|
|
14738
14725
|
const def = resolveFieldDefault(field);
|
|
14739
14726
|
return def !== void 0 && valuesEqual(value, def);
|
|
14740
14727
|
};
|
|
14728
|
+
var resetTargetValue = (field) => {
|
|
14729
|
+
const def = resolveFieldDefault(field);
|
|
14730
|
+
return def !== void 0 ? def : null;
|
|
14731
|
+
};
|
|
14732
|
+
var isAtResetTarget = (field, value) => {
|
|
14733
|
+
const target = resetTargetValue(field);
|
|
14734
|
+
if (isEmptyValue(value) && isEmptyValue(target)) return true;
|
|
14735
|
+
return valuesEqual(value, target);
|
|
14736
|
+
};
|
|
14741
14737
|
var isInlineField = (field) => isInlineDateField(field) || field.type === "custom";
|
|
14742
|
-
var isFixedField = (field) => field.
|
|
14738
|
+
var isFixedField = (field) => field.fixed === true || field.required === true;
|
|
14743
14739
|
var isAddableField = (field) => !isFixedField(field);
|
|
14744
|
-
var isGroupedFields = (fields) => fields.length > 0 && "fields" in fields[0];
|
|
14745
14740
|
var isGroupSatisfied = (group, values) => {
|
|
14746
14741
|
if (!group.rule) return true;
|
|
14747
14742
|
const keys = group.fields.map((f) => f.key);
|
|
@@ -14821,7 +14816,7 @@ var chipDisplayValue = (field, value) => {
|
|
|
14821
14816
|
return preset && !preset.custom ? `${preset.label}(${text})` : text;
|
|
14822
14817
|
};
|
|
14823
14818
|
var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
14824
|
-
fields:
|
|
14819
|
+
fields: groups = [],
|
|
14825
14820
|
value,
|
|
14826
14821
|
onValueChange,
|
|
14827
14822
|
onFilterChange,
|
|
@@ -14837,16 +14832,11 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
14837
14832
|
className,
|
|
14838
14833
|
style
|
|
14839
14834
|
}, ref) {
|
|
14840
|
-
const usingGroupedFields = isGroupedFields(fieldsProp);
|
|
14841
|
-
const groups = react.useMemo(
|
|
14842
|
-
() => usingGroupedFields ? fieldsProp : [{ fields: fieldsProp }],
|
|
14843
|
-
[usingGroupedFields, fieldsProp]
|
|
14844
|
-
);
|
|
14845
14835
|
const fields = react.useMemo(() => groups.flatMap((group) => group.fields), [groups]);
|
|
14846
14836
|
const values = normalizeValues(value);
|
|
14847
14837
|
const portalContainer = usePortalContainer();
|
|
14848
14838
|
const [internalActiveKeys, setInternalActiveKeys] = react.useState(
|
|
14849
|
-
() => fields.filter(
|
|
14839
|
+
() => fields.filter(isFixedField).map((field) => field.key)
|
|
14850
14840
|
);
|
|
14851
14841
|
const [openKey, setOpenKey] = react.useState(null);
|
|
14852
14842
|
const [addOpen, setAddOpen] = react.useState(false);
|
|
@@ -14888,9 +14878,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
14888
14878
|
setInternalActiveKeys((current) => {
|
|
14889
14879
|
const known = new Set(fields.map((field) => field.key));
|
|
14890
14880
|
const kept = current.filter((key) => known.has(key));
|
|
14891
|
-
const additions = fields.filter(
|
|
14892
|
-
(field) => (isFixedField(field) || field.defaultActive !== false) && !kept.includes(field.key)
|
|
14893
|
-
).map((field) => field.key);
|
|
14881
|
+
const additions = fields.filter((field) => isFixedField(field) && !kept.includes(field.key)).map((field) => field.key);
|
|
14894
14882
|
return [...kept, ...additions];
|
|
14895
14883
|
});
|
|
14896
14884
|
}, [activeKeys, fields]);
|
|
@@ -14923,7 +14911,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
14923
14911
|
groups.forEach((group, groupIndex) => {
|
|
14924
14912
|
group.fields.forEach((field) => groupIndexByKey.set(field.key, groupIndex));
|
|
14925
14913
|
});
|
|
14926
|
-
const
|
|
14914
|
+
const canReset = fields.some((field) => !isAtResetTarget(field, values[field.key]));
|
|
14927
14915
|
const hasAddButton = fields.some(isAddableField);
|
|
14928
14916
|
const hasRightActions = hasAddButton || showReset;
|
|
14929
14917
|
const currentOpenField = fields.find((field) => field.key === openKey);
|
|
@@ -14962,8 +14950,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
14962
14950
|
};
|
|
14963
14951
|
const reset = react.useCallback(() => {
|
|
14964
14952
|
const next = fields.reduce((acc, field) => {
|
|
14965
|
-
|
|
14966
|
-
acc[field.key] = def !== void 0 ? def : null;
|
|
14953
|
+
acc[field.key] = resetTargetValue(field);
|
|
14967
14954
|
return acc;
|
|
14968
14955
|
}, {});
|
|
14969
14956
|
onValueChange?.(next);
|
|
@@ -15021,7 +15008,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15021
15008
|
const flushRun = () => {
|
|
15022
15009
|
if (runBuffer.length === 0) return;
|
|
15023
15010
|
const group = runGroupIndex != null ? groups[runGroupIndex] : void 0;
|
|
15024
|
-
const message =
|
|
15011
|
+
const message = group?.rule ? group.tooltipMessage ?? defaultGroupTooltipMessage(group.rule, group.fields) : void 0;
|
|
15025
15012
|
if (message) {
|
|
15026
15013
|
nodes.push(
|
|
15027
15014
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15045,7 +15032,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15045
15032
|
const warning = field.warning || invalidGroups.has(groupIndex);
|
|
15046
15033
|
const prevField = index > 0 ? activeFields[index - 1] : null;
|
|
15047
15034
|
const prevGroupIndex = prevField ? groupIndexByKey.get(prevField.key) ?? 0 : null;
|
|
15048
|
-
const needsLeadingDivider = index === 0 ? false : inline || prevField != null && isInlineField(prevField) || groupIndex !== prevGroupIndex;
|
|
15035
|
+
const needsLeadingDivider = index === 0 ? false : inline || prevField != null && isInlineField(prevField) || groupIndex !== prevGroupIndex && groups[groupIndex]?.divider === true;
|
|
15049
15036
|
if (groupIndex !== runGroupIndex) {
|
|
15050
15037
|
flushRun();
|
|
15051
15038
|
runGroupIndex = groupIndex;
|
|
@@ -15059,7 +15046,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15059
15046
|
}
|
|
15060
15047
|
clearValue(field.key);
|
|
15061
15048
|
};
|
|
15062
|
-
const node = isInlineDateField(field) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
15049
|
+
const node = field.type === "date" && isInlineDateField(field) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
15063
15050
|
InlineDatePresetFilter,
|
|
15064
15051
|
{
|
|
15065
15052
|
field,
|
|
@@ -15085,7 +15072,14 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15085
15072
|
"aria-label": `${field.label} \uD544\uD130 \uC81C\uAC70`,
|
|
15086
15073
|
className: "inline-flex size-[16px] shrink-0 items-center justify-center rounded-[var(--cmp-ghostButton-radius-sm)] border-none bg-transparent p-0",
|
|
15087
15074
|
onClick: handleClear,
|
|
15088
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15075
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15076
|
+
SIcon,
|
|
15077
|
+
{
|
|
15078
|
+
name: "close",
|
|
15079
|
+
size: 12,
|
|
15080
|
+
color: "var(--cmp-ghostButton-default-content)"
|
|
15081
|
+
}
|
|
15082
|
+
)
|
|
15089
15083
|
}
|
|
15090
15084
|
)
|
|
15091
15085
|
] }, field.key) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15159,32 +15153,22 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
|
|
|
15159
15153
|
}
|
|
15160
15154
|
) })
|
|
15161
15155
|
] }),
|
|
15162
|
-
showReset && /* @__PURE__ */ jsxRuntime.
|
|
15163
|
-
|
|
15156
|
+
showReset && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15157
|
+
STextLink,
|
|
15164
15158
|
{
|
|
15165
|
-
|
|
15166
|
-
|
|
15159
|
+
size: "sm",
|
|
15160
|
+
icon: "reset",
|
|
15161
|
+
iconColor: "grey_80",
|
|
15162
|
+
label: "\uAC80\uC0C9 \uCD08\uAE30\uD654",
|
|
15163
|
+
labelClass: "text-grey-80",
|
|
15164
|
+
disabled: disabled || !canReset,
|
|
15167
15165
|
onClick: reset,
|
|
15168
15166
|
className: cn(
|
|
15169
|
-
"
|
|
15167
|
+
"shrink-0",
|
|
15170
15168
|
// 부모 flex gap(6px)은 칩 사이 간격 기준이라, 필터 추가 버튼과의 12px 간격을 맞추려면
|
|
15171
15169
|
// 부족한 만큼(12px - gap)을 추가로 띄운다. 필터 추가가 없을 땐 divider와 이미 12px이라 불필요.
|
|
15172
15170
|
hasAddButton && "ml-[calc(12px-var(--cmp-chipFilter-chip-group))]"
|
|
15173
|
-
)
|
|
15174
|
-
style: {
|
|
15175
|
-
color: disabled || !hasValue ? "var(--cmp-textLink-content-disabled)" : "var(--cmp-textLink-content-default)"
|
|
15176
|
-
},
|
|
15177
|
-
children: [
|
|
15178
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15179
|
-
SIcon,
|
|
15180
|
-
{
|
|
15181
|
-
name: "reset",
|
|
15182
|
-
size: 16,
|
|
15183
|
-
color: disabled || !hasValue ? "var(--cmp-textLink-icon-disabled)" : "var(--cmp-textLink-icon-default)"
|
|
15184
|
-
}
|
|
15185
|
-
),
|
|
15186
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\uAC80\uC0C9 \uCD08\uAE30\uD654" })
|
|
15187
|
-
]
|
|
15171
|
+
)
|
|
15188
15172
|
}
|
|
15189
15173
|
)
|
|
15190
15174
|
] })
|