sellmate-design-system-react 9.0.0-beta.59 → 9.0.0-beta.60
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 +24 -4
- package/dist/components/STable/STable.d.ts +10 -3
- package/dist/components/STree/README.md +1 -1
- package/dist/components/STree/STree.d.ts +1 -1
- package/dist/components/STree/STree.examples.d.ts +2 -0
- package/dist/index.cjs +7 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -10
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +25 -5
- package/dist/llms.txt +24 -4
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -1067,20 +1067,38 @@ const columns: STableColumn[] = [
|
|
|
1067
1067
|
라벨 [helpText ?] [editable] [navigable] [required *] [sortable 정렬버튼]
|
|
1068
1068
|
```
|
|
1069
1069
|
|
|
1070
|
-
|
|
1070
|
+
**둘을 가르는 기준은 "무엇을 하느냐"가 아니라 "현재 화면을 떠나느냐"다.**
|
|
1071
|
+
|
|
1072
|
+
| 셀을 눌렀을 때 | 표식 |
|
|
1073
|
+
| --- | --- |
|
|
1074
|
+
| 셀에서 바로 고친다 | `editable` |
|
|
1075
|
+
| 모달·바텀시트를 띄워 고친다 | `editable` |
|
|
1076
|
+
| 새 창·새 팝업을 띄운다, 페이지를 이동한다 | `navigable` |
|
|
1077
|
+
| 모달로 보여주기만 한다 (고치지 않는다) | 둘 다 없음 |
|
|
1078
|
+
|
|
1079
|
+
**모달은 `navigable` 이 아니다.** 현재 화면 위에 겹쳐 뜰 뿐 화면을 떠나는 것이 아니다 — 거기서 값을 고치면 고치는 자리가 셀이든 모달이든 `editable` 이다. 반대로 새 창·새 팝업은 거기서 값을 고치더라도 `navigable` 이다. 화면을 떠나기 때문이다.
|
|
1080
|
+
|
|
1081
|
+
둘 다 **표식일 뿐 버튼이 아니다** — 아이콘·크기·색은 컴포넌트가 고정하고 클릭은 받지 않는다.
|
|
1071
1082
|
|
|
1072
1083
|
```tsx
|
|
1073
1084
|
const columns: STableColumn[] = [
|
|
1085
|
+
// 새 창으로 상세를 연다 → navigable
|
|
1074
1086
|
{ name: 'name', label: '상품명', field: 'name', width: 200,
|
|
1075
1087
|
navigable: true,
|
|
1076
|
-
render: (row: SRow) => <STextLink label={row.name} onClick={() =>
|
|
1088
|
+
render: (row: SRow) => <STextLink label={row.name} onClick={() => openDetailWindow(row.id)} /> },
|
|
1089
|
+
// 셀에서 바로 고친다 → editable
|
|
1077
1090
|
{ name: 'stock', label: '재고', field: 'stock', width: 160, contentType: 'control',
|
|
1078
1091
|
editable: true, required: true,
|
|
1079
1092
|
render: (row: SRow) => <SNumberInput value={row.stock} width="100%" /> },
|
|
1093
|
+
// 수정 모달을 띄워 고친다 → 화면을 떠나지 않으므로 navigable 이 아니라 editable
|
|
1094
|
+
{ name: 'memo', label: '메모', field: 'memo', width: 200,
|
|
1095
|
+
editable: true,
|
|
1096
|
+
render: (row: SRow) => <STextLink label={row.memo} onClick={() => openMemoModal(row.id)} /> },
|
|
1080
1097
|
];
|
|
1081
1098
|
```
|
|
1082
1099
|
|
|
1083
|
-
- **실제로 그렇게 동작하는 열에만 켠다.** 표식만 켜고 셀은 텍스트 그대로 두면, 고칠 수 있다고 해 놓고 고칠 방법이 없고 넘어갈 수 있다고 해 놓고 누를 것이 없다. `editable` 이면 셀에 입력
|
|
1100
|
+
- **실제로 그렇게 동작하는 열에만 켠다.** 표식만 켜고 셀은 텍스트 그대로 두면, 고칠 수 있다고 해 놓고 고칠 방법이 없고 넘어갈 수 있다고 해 놓고 누를 것이 없다. `editable` 이면 셀에 고치는 수단(입력 컨트롤이나 수정 모달을 여는 링크·클릭)이, `navigable` 이면 셀에 새 화면을 여는 링크·클릭이 있어야 한다.
|
|
1101
|
+
- **한 열에 둘 다 켜는 것은 두 동작이 모두 있을 때만이다** — 예를 들어 셀에서 값을 고치면서 라벨을 누르면 새 창으로 상세가 열리는 열. 판단이 서지 않으면 하나만 켠다.
|
|
1084
1102
|
- **표식으로 동작을 대신하지 않는다.** 고치는 UI 도 넘어가는 동작도 셀(`column.render`) 몫이다.
|
|
1085
1103
|
- **`renderHeader` 로 헤더를 통째로 교체하면 표식도 `required` 도 그려지지 않는다** — 헤더 전체가 소비 앱 책임이 되므로 순서·크기·색을 손으로 맞추게 된다.
|
|
1086
1104
|
|
|
@@ -1765,6 +1783,8 @@ const [from, setFrom] = useState<string | null>(null);
|
|
|
1765
1783
|
|
|
1766
1784
|
선택은 다르다. 앱이 `selectedId` 스칼라 하나를 들면 상호배제가 구조적으로 보장되고, 그 값은 URL·store 로 복원돼야 한다. 리스트가 사본을 들면 그 순간 진실이 둘이 되어 어긋난다.
|
|
1767
1785
|
|
|
1786
|
+
같은 이유로 `STree` 노드의 `disabled` 는 **선택만** 막는다. 체크박스는 잠기고 전체 선택·부모 선택에서 빠지지만, 캐럿·행 클릭·키보드로 접고 펴는 것은 그대로 된다 — 부모가 disabled 라고 자식에 닿는 길까지 막지 않는다.
|
|
1787
|
+
|
|
1768
1788
|
```tsx
|
|
1769
1789
|
const [selectedId, setSelectedId] = useState<string>();
|
|
1770
1790
|
|
|
@@ -2668,7 +2688,7 @@ export default function TransferOrderPopupPage() {
|
|
|
2668
2688
|
- [ ] 일부 행만 고를 수 있는 표라면 `isRowSelectable` 로 잠갔는가 — 체크박스를 밖에서 직접 잠그거나 전체 선택을 손으로 보정하지 않았는가 (§3-4)
|
|
2669
2689
|
- [ ] 표 본문의 스크롤이 필요하면 `onScroll` · `ref.getScrollElement()` 를 썼는가 — 내부 마크업을 겨냥한 선택자로 스크롤 컨테이너를 찾지 않았는가 (§3-4)
|
|
2670
2690
|
- [ ] 스크롤 위치를 저장했다 되돌린다면 **행 번호**(`getFirstVisibleRow` → `scrollToRow`)로 했는가, `scrollTop` 픽셀을 저장하지는 않았는가 (§3-4 — 가상 스크롤에서는 좌표계가 실측으로 움직여 다른 행이 나온다)
|
|
2671
|
-
- [ ] `editable` · `navigable` 표식을 켠 열이 **셀에서도 실제로 그렇게 동작하는가** (입력 컨트롤 · 링크가 있는가), 표식을 붙인 열의 폭을 함께 넓혔는가 (§3-4)
|
|
2691
|
+
- [ ] `editable` · `navigable` 표식을 켠 열이 **셀에서도 실제로 그렇게 동작하는가** (입력 컨트롤 · 링크가 있는가), **모달로 처리하는 열에 `navigable` 을 켜지는 않았는가** (화면을 떠나지 않으므로 `editable` 이다), 표식을 붙인 열의 폭을 함께 넓혔는가 (§3-4)
|
|
2672
2692
|
- [ ] 금액·수량 등 양을 나타내는 숫자에 빠짐없이 `toLocaleString()` 을 썼는가 (번호·코드는 제외)
|
|
2673
2693
|
- [ ] 날짜를 `YYYY-MM-DD` 로 표기했는가 (`toLocaleDateString()` ❌, §1-4)
|
|
2674
2694
|
- [ ] 필드 폭을 등급(`'xs' | 'sm' | 'md' | 'lg' | 'xl'`)으로 줬는가 — px 직접 지정 ❌ (§4-3)
|
|
@@ -75,7 +75,10 @@ interface STableColumnBase {
|
|
|
75
75
|
*/
|
|
76
76
|
required?: boolean;
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* **지금 이 화면에 머문 채로** 값을 고치는 열. 라벨 뒤에 `pageEdit` 표식이 붙는다.
|
|
79
|
+
*
|
|
80
|
+
* 셀에서 바로 고치는 것도, 수정 모달·바텀시트를 띄워 고치는 것도 모두 이쪽이다 —
|
|
81
|
+
* 모달은 현재 화면 **위에** 겹쳐 뜰 뿐 화면을 떠나는 것이 아니라서 `navigable` 이 아니다.
|
|
79
82
|
*
|
|
80
83
|
* **표식일 뿐 버튼이 아니다** — 실제로 고치는 UI 는 셀(`render`)이 그린다. 표식만 켜 두면
|
|
81
84
|
* 고칠 수 있다고 해 놓고 고칠 방법이 없는 열이 된다.
|
|
@@ -84,9 +87,13 @@ interface STableColumnBase {
|
|
|
84
87
|
*/
|
|
85
88
|
editable?: boolean;
|
|
86
89
|
/**
|
|
87
|
-
*
|
|
90
|
+
* 눌러서 **이 화면을 떠나** 다른 화면으로 가는 열 — 새 창·새 팝업으로 띄우거나 페이지를
|
|
91
|
+
* 이동한다. 라벨 뒤에 `pageMove` 표식이 붙는다.
|
|
92
|
+
*
|
|
93
|
+
* 모달로 처리하는 열은 화면을 떠나지 않으므로 여기에 해당하지 않는다. 모달에서 값을 고치면
|
|
94
|
+
* `editable`, 고치지 않고 보여주기만 하면 둘 다 붙이지 않는다.
|
|
88
95
|
*
|
|
89
|
-
* **표식일 뿐 버튼이 아니다** —
|
|
96
|
+
* **표식일 뿐 버튼이 아니다** — 화면을 여는 것은 셀(`render`)의 링크·클릭이 한다.
|
|
90
97
|
*
|
|
91
98
|
* `renderHeader` 로 헤더를 통째로 교체하면 그리지 않는다 (헤더 전체가 소비 앱 책임).
|
|
92
99
|
*/
|
|
@@ -2,3 +2,5 @@ import type { STreeNode } from './STree';
|
|
|
2
2
|
export declare const treeUsageItems: STreeNode[];
|
|
3
3
|
export declare const treeUsageDefaultValue: string[];
|
|
4
4
|
export declare const treeUsageExpandedIds: string[];
|
|
5
|
+
/** 부모가 disabled 여도 자식은 접고 펼 수 있고, 자식 중 정상 노드는 고를 수 있다 */
|
|
6
|
+
export declare const treeDisabledItems: STreeNode[];
|
package/dist/index.cjs
CHANGED
|
@@ -7084,7 +7084,6 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
7084
7084
|
onTreeSelect?.(node, event);
|
|
7085
7085
|
};
|
|
7086
7086
|
const handleRowClick = (event) => {
|
|
7087
|
-
if (node.disabled) return;
|
|
7088
7087
|
if (hasChildren) onToggle?.(node, event);
|
|
7089
7088
|
};
|
|
7090
7089
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -7101,9 +7100,8 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
7101
7100
|
"group/tree-item box-border flex w-full items-center gap-(--cmp-tree-item-rowGap) overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left",
|
|
7102
7101
|
typography.rowHeight,
|
|
7103
7102
|
border && "border-b border-(--cmp-tree-item-border-default)",
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
!node.disabled && hasChildren && "cursor-pointer",
|
|
7103
|
+
"hover:bg-(--cmp-tree-item-bg-hover)",
|
|
7104
|
+
hasChildren && "cursor-pointer",
|
|
7107
7105
|
className
|
|
7108
7106
|
),
|
|
7109
7107
|
...rest,
|
|
@@ -7127,10 +7125,8 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
7127
7125
|
size: "xxs",
|
|
7128
7126
|
ariaLabel: expanded ? "collapse tree item" : "expand tree item",
|
|
7129
7127
|
ariaExpanded: expanded,
|
|
7130
|
-
disabled: node.disabled,
|
|
7131
7128
|
onClick: (event) => {
|
|
7132
7129
|
event.stopPropagation();
|
|
7133
|
-
if (node.disabled) return;
|
|
7134
7130
|
onToggle?.(node, event);
|
|
7135
7131
|
}
|
|
7136
7132
|
}
|
|
@@ -7163,6 +7159,7 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
7163
7159
|
className: cn(
|
|
7164
7160
|
"block min-w-0 flex-1 truncate py-(--cmp-tree-item-paddingY) text-(--cmp-tree-item-text-default)",
|
|
7165
7161
|
labelTypo,
|
|
7162
|
+
node.disabled && "opacity-60",
|
|
7166
7163
|
node.disabled ? "cursor-not-allowed" : selectable ? "cursor-pointer" : void 0
|
|
7167
7164
|
),
|
|
7168
7165
|
children: node.label
|
|
@@ -7288,13 +7285,13 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
7288
7285
|
break;
|
|
7289
7286
|
}
|
|
7290
7287
|
case "ArrowRight": {
|
|
7291
|
-
if (!hasChildren
|
|
7288
|
+
if (!hasChildren) return;
|
|
7292
7289
|
if (!row.expanded) updateExpanded(row.node);
|
|
7293
7290
|
else if (visibleRows[index + 1]) focusRow(visibleRows[index + 1].id);
|
|
7294
7291
|
break;
|
|
7295
7292
|
}
|
|
7296
7293
|
case "ArrowLeft": {
|
|
7297
|
-
if (hasChildren && row.expanded
|
|
7294
|
+
if (hasChildren && row.expanded) updateExpanded(row.node);
|
|
7298
7295
|
else if (row.parentId != null) focusRow(row.parentId);
|
|
7299
7296
|
else return;
|
|
7300
7297
|
break;
|
|
@@ -7312,7 +7309,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
7312
7309
|
case " ": {
|
|
7313
7310
|
if (row.id === TREE_ALL_NODE.id) updateAllSelected();
|
|
7314
7311
|
else if (selectable) updateSelected(row.node);
|
|
7315
|
-
else if (hasChildren
|
|
7312
|
+
else if (hasChildren) updateExpanded(row.node);
|
|
7316
7313
|
else return;
|
|
7317
7314
|
break;
|
|
7318
7315
|
}
|
|
@@ -16265,7 +16262,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
|
|
|
16265
16262
|
name: "pageMove",
|
|
16266
16263
|
size: 12,
|
|
16267
16264
|
color: "var(--sys-color-link-accent)",
|
|
16268
|
-
label: "\
|
|
16265
|
+
label: "\uC0C8 \uD654\uBA74\uC5D0\uC11C \uC5F4\uAE30",
|
|
16269
16266
|
className: "shrink-0"
|
|
16270
16267
|
}
|
|
16271
16268
|
),
|