sellmate-design-system-react 9.0.0-beta.4 → 9.0.0-beta.6
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/dist/components/STree/README.md +1 -0
- package/dist/components/STree/STree.d.ts +2 -0
- package/dist/index.cjs +84 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +84 -28
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +1 -0
- package/dist/styles.css +23 -6
- package/package.json +1 -1
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
| `expandedIds?` | `string[]` | — | 펼쳐진 노드 ID 목록 |
|
|
41
41
|
| `defaultExpandedIds?` | `string[]` | — | 비제어 펼침 초기값 |
|
|
42
42
|
| `selectable?` | `boolean` | `true` | 체크박스 표시 여부 |
|
|
43
|
+
| `useAll?` | `boolean` | `false` | 체크박스 사용 시 최상단 전체 선택 아이템 표시 여부 |
|
|
43
44
|
| `guideline?` | `boolean` | `true` | depth 연결선 표시 여부 |
|
|
44
45
|
| `border?` | `boolean` | `true` | 아이템 하단 border 표시 여부 |
|
|
45
46
|
| `cascadeSelection?` | `boolean` | `true` | 부모 선택 시 하위 노드까지 함께 토글 |
|
|
@@ -61,6 +61,8 @@ export interface STreeProps extends Omit<HTMLAttributes<HTMLDivElement>, 'childr
|
|
|
61
61
|
defaultExpandedIds?: string[];
|
|
62
62
|
/** 체크박스 표시 여부 */
|
|
63
63
|
selectable?: boolean;
|
|
64
|
+
/** 체크박스 사용 시 최상단 전체 선택 아이템 표시 여부 */
|
|
65
|
+
useAll?: boolean;
|
|
64
66
|
/** depth 연결선 표시 여부 */
|
|
65
67
|
guideline?: boolean;
|
|
66
68
|
/** 아이템 하단 border 표시 여부 */
|
package/dist/index.cjs
CHANGED
|
@@ -4623,18 +4623,19 @@ function collectSelectableIds(node) {
|
|
|
4623
4623
|
function toSelectedSet(value) {
|
|
4624
4624
|
return new Set(value ?? []);
|
|
4625
4625
|
}
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4626
|
+
var TREE_ALL_NODE = { id: "__all__", label: "\uC804\uCCB4" };
|
|
4627
|
+
function getSelectionState(node, selectedSet, cascadeSelection) {
|
|
4628
|
+
if (!cascadeSelection) {
|
|
4629
|
+
return { selected: selectedSet.has(node.id), indeterminate: false };
|
|
4629
4630
|
}
|
|
4630
4631
|
const selectableChildren = (node.children ?? []).filter(
|
|
4631
4632
|
(child) => collectSelectableIds(child).length > 0
|
|
4632
4633
|
);
|
|
4633
4634
|
if (selectableChildren.length === 0) {
|
|
4634
|
-
return { selected:
|
|
4635
|
+
return { selected: selectedSet.has(node.id), indeterminate: false };
|
|
4635
4636
|
}
|
|
4636
4637
|
const childStates = selectableChildren.map(
|
|
4637
|
-
(child) => getSelectionState(child, selectedSet)
|
|
4638
|
+
(child) => getSelectionState(child, selectedSet, cascadeSelection)
|
|
4638
4639
|
);
|
|
4639
4640
|
const selectedCount = childStates.filter((state2) => state2.selected).length;
|
|
4640
4641
|
return {
|
|
@@ -4679,6 +4680,40 @@ function TreeConnector({
|
|
|
4679
4680
|
] })
|
|
4680
4681
|
] });
|
|
4681
4682
|
}
|
|
4683
|
+
function STreeAllItem({
|
|
4684
|
+
selected,
|
|
4685
|
+
indeterminate,
|
|
4686
|
+
border,
|
|
4687
|
+
onSelect
|
|
4688
|
+
}) {
|
|
4689
|
+
const checkboxValue = indeterminate ? null : selected;
|
|
4690
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4691
|
+
"div",
|
|
4692
|
+
{
|
|
4693
|
+
role: "treeitem",
|
|
4694
|
+
"aria-level": 1,
|
|
4695
|
+
"aria-selected": selected,
|
|
4696
|
+
onClick: onSelect,
|
|
4697
|
+
className: cn(
|
|
4698
|
+
"group/tree-item box-border flex h-[32px] w-full cursor-pointer items-center overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left hover:bg-(--cmp-tree-item-bg-hover)",
|
|
4699
|
+
border && "border-b border-(--cmp-tree-item-border-default)"
|
|
4700
|
+
),
|
|
4701
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "box-border flex h-full min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap) py-(--cmp-tree-item-paddingY)", children: [
|
|
4702
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { onClick: (event) => event.stopPropagation(), className: "flex shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(SCheckbox, { value: checkboxValue, onValueChange: () => onSelect() }) }),
|
|
4703
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4704
|
+
"span",
|
|
4705
|
+
{
|
|
4706
|
+
className: cn(
|
|
4707
|
+
"block min-w-0 flex-1 truncate text-[14px] leading-[24px]",
|
|
4708
|
+
selected || indeterminate ? "font-bold text-(--cmp-tree-item-text-selected)" : "font-medium text-(--cmp-tree-item-text-default)"
|
|
4709
|
+
),
|
|
4710
|
+
children: "\uC804\uCCB4"
|
|
4711
|
+
}
|
|
4712
|
+
)
|
|
4713
|
+
] })
|
|
4714
|
+
}
|
|
4715
|
+
);
|
|
4716
|
+
}
|
|
4682
4717
|
var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
4683
4718
|
node,
|
|
4684
4719
|
depth = 1,
|
|
@@ -4729,7 +4764,7 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
4729
4764
|
"aria-disabled": node.disabled || void 0,
|
|
4730
4765
|
onClick: handleRowClick,
|
|
4731
4766
|
className: cn(
|
|
4732
|
-
"group/tree-item flex
|
|
4767
|
+
"group/tree-item box-border flex h-[32px] w-full items-center gap-(--cmp-tree-item-rowGap) overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left",
|
|
4733
4768
|
border && "border-b border-(--cmp-tree-item-border-default)",
|
|
4734
4769
|
!node.disabled && "hover:bg-(--cmp-tree-item-bg-hover)",
|
|
4735
4770
|
node.disabled && "cursor-not-allowed opacity-60",
|
|
@@ -4748,7 +4783,7 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
4748
4783
|
ancestorLast
|
|
4749
4784
|
}
|
|
4750
4785
|
),
|
|
4751
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap) py-(--cmp-tree-item-paddingY)", children: [
|
|
4786
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "box-border flex h-full min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap) py-(--cmp-tree-item-paddingY)", children: [
|
|
4752
4787
|
hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4753
4788
|
SGhostButton,
|
|
4754
4789
|
{
|
|
@@ -4784,25 +4819,17 @@ var STreeItemImpl = /* @__PURE__ */ react.forwardRef(function STreeItem({
|
|
|
4784
4819
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4785
4820
|
"span",
|
|
4786
4821
|
{
|
|
4822
|
+
onClick: (event) => {
|
|
4823
|
+
if (!selectable) return;
|
|
4824
|
+
event.stopPropagation();
|
|
4825
|
+
if (!node.disabled && selectable) onTreeSelect?.(node, event);
|
|
4826
|
+
},
|
|
4787
4827
|
className: cn(
|
|
4788
|
-
"min-w-0 flex-1 text-[14px] leading-[24px]",
|
|
4789
|
-
selected || indeterminate ? "font-bold text-(--cmp-tree-item-text-selected)" : "font-medium text-(--cmp-tree-item-text-default)"
|
|
4828
|
+
"block min-w-0 flex-1 truncate text-[14px] leading-[24px]",
|
|
4829
|
+
selected || indeterminate ? "font-bold text-(--cmp-tree-item-text-selected)" : "font-medium text-(--cmp-tree-item-text-default)",
|
|
4830
|
+
node.disabled ? "cursor-not-allowed" : selectable ? "cursor-pointer" : void 0
|
|
4790
4831
|
),
|
|
4791
|
-
children:
|
|
4792
|
-
"span",
|
|
4793
|
-
{
|
|
4794
|
-
onClick: (event) => {
|
|
4795
|
-
if (!selectable) return;
|
|
4796
|
-
event.stopPropagation();
|
|
4797
|
-
if (!node.disabled && selectable) onTreeSelect?.(node, event);
|
|
4798
|
-
},
|
|
4799
|
-
className: cn(
|
|
4800
|
-
"inline-block max-w-full truncate",
|
|
4801
|
-
node.disabled ? "cursor-not-allowed" : selectable ? "cursor-pointer" : void 0
|
|
4802
|
-
),
|
|
4803
|
-
children: node.label
|
|
4804
|
-
}
|
|
4805
|
-
)
|
|
4832
|
+
children: node.label
|
|
4806
4833
|
}
|
|
4807
4834
|
),
|
|
4808
4835
|
trailingNode
|
|
@@ -4819,6 +4846,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
4819
4846
|
expandedIds,
|
|
4820
4847
|
defaultExpandedIds,
|
|
4821
4848
|
selectable = true,
|
|
4849
|
+
useAll = false,
|
|
4822
4850
|
cascadeSelection = true,
|
|
4823
4851
|
guideline = true,
|
|
4824
4852
|
border = true,
|
|
@@ -4837,6 +4865,11 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
4837
4865
|
const currentExpandedIds = expandedIds ?? internalExpandedIds;
|
|
4838
4866
|
const selectedSet = react.useMemo(() => toSelectedSet(currentValue), [currentValue]);
|
|
4839
4867
|
const expandedSet = react.useMemo(() => new Set(currentExpandedIds), [currentExpandedIds]);
|
|
4868
|
+
const selectableIds = react.useMemo(() => items.flatMap(collectSelectableIds), [items]);
|
|
4869
|
+
const allSelected = selectableIds.length > 0 && selectableIds.every((id) => selectedSet.has(id));
|
|
4870
|
+
const someSelected = selectableIds.some((id) => selectedSet.has(id));
|
|
4871
|
+
const allIndeterminate = someSelected && !allSelected;
|
|
4872
|
+
const showAllItem = selectable && useAll;
|
|
4840
4873
|
const updateExpanded = (node) => {
|
|
4841
4874
|
const next = new Set(currentExpandedIds);
|
|
4842
4875
|
if (next.has(node.id)) next.delete(node.id);
|
|
@@ -4848,7 +4881,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
4848
4881
|
const updateSelected = (node) => {
|
|
4849
4882
|
if (node.disabled) return;
|
|
4850
4883
|
const targetIds = cascadeSelection ? collectSelectableIds(node) : [node.id];
|
|
4851
|
-
const everySelected = getSelectionState(node, selectedSet).selected;
|
|
4884
|
+
const everySelected = getSelectionState(node, selectedSet, cascadeSelection).selected;
|
|
4852
4885
|
const next = new Set(selectedSet);
|
|
4853
4886
|
targetIds.forEach((id) => {
|
|
4854
4887
|
if (everySelected) next.delete(id);
|
|
@@ -4858,10 +4891,22 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
4858
4891
|
if (value === void 0) setInternalValue(orderedIds);
|
|
4859
4892
|
onValueChange?.(orderedIds, node);
|
|
4860
4893
|
};
|
|
4894
|
+
const updateAllSelected = (event) => {
|
|
4895
|
+
event?.stopPropagation();
|
|
4896
|
+
if (selectableIds.length === 0) return;
|
|
4897
|
+
const next = new Set(selectedSet);
|
|
4898
|
+
selectableIds.forEach((id) => {
|
|
4899
|
+
if (allSelected) next.delete(id);
|
|
4900
|
+
else next.add(id);
|
|
4901
|
+
});
|
|
4902
|
+
const orderedIds = collectIds(items).filter((id) => next.has(id));
|
|
4903
|
+
if (value === void 0) setInternalValue(orderedIds);
|
|
4904
|
+
onValueChange?.(orderedIds, TREE_ALL_NODE);
|
|
4905
|
+
};
|
|
4861
4906
|
const renderNodes = (nodes, depth = 1, ancestorLast = []) => nodes.map((node, index) => {
|
|
4862
4907
|
const isLast = index === nodes.length - 1;
|
|
4863
4908
|
const isExpanded = expandedSet.has(node.id);
|
|
4864
|
-
const { selected, indeterminate } = getSelectionState(node, selectedSet);
|
|
4909
|
+
const { selected, indeterminate } = getSelectionState(node, selectedSet, cascadeSelection);
|
|
4865
4910
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
4866
4911
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4867
4912
|
STreeItem2,
|
|
@@ -4895,14 +4940,25 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
|
|
|
4895
4940
|
) : null
|
|
4896
4941
|
] }, node.id);
|
|
4897
4942
|
});
|
|
4898
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
4943
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4899
4944
|
"div",
|
|
4900
4945
|
{
|
|
4901
4946
|
ref,
|
|
4902
4947
|
role: "tree",
|
|
4903
4948
|
className: cn("flex w-full flex-col items-start bg-(--cmp-tree-item-bg-default)", className),
|
|
4904
4949
|
...rest,
|
|
4905
|
-
children:
|
|
4950
|
+
children: [
|
|
4951
|
+
showAllItem && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4952
|
+
STreeAllItem,
|
|
4953
|
+
{
|
|
4954
|
+
selected: allSelected,
|
|
4955
|
+
indeterminate: allIndeterminate,
|
|
4956
|
+
border,
|
|
4957
|
+
onSelect: updateAllSelected
|
|
4958
|
+
}
|
|
4959
|
+
),
|
|
4960
|
+
renderNodes(items)
|
|
4961
|
+
]
|
|
4906
4962
|
}
|
|
4907
4963
|
);
|
|
4908
4964
|
});
|