sellmate-design-system-react 0.4.0 → 0.5.0
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/SGnb/SGnb.cjs +238 -79
- package/dist/components/SGnb/SGnb.cjs.map +1 -1
- package/dist/components/SGnb/SGnb.d.ts +17 -4
- package/dist/components/SGnb/SGnb.js +238 -79
- package/dist/components/SGnb/SGnb.js.map +1 -1
- package/dist/components/SGnb/gnb.config.d.ts +46 -12
- package/dist/components/SGnb/index.d.ts +1 -1
- package/dist/components/SLayout/SLayout.cjs +20 -19
- package/dist/components/SLayout/SLayout.cjs.map +1 -1
- package/dist/components/SLayout/SLayout.d.ts +4 -0
- package/dist/components/SLayout/SLayout.js +20 -19
- package/dist/components/SLayout/SLayout.js.map +1 -1
- package/dist/components/SPage/SPage.cjs +21 -20
- package/dist/components/SPage/SPage.cjs.map +1 -1
- package/dist/components/SPage/SPage.js +21 -20
- package/dist/components/SPage/SPage.js.map +1 -1
- package/dist/components/STabs/STabs.cjs +15 -26
- package/dist/components/STabs/STabs.cjs.map +1 -1
- package/dist/components/STabs/STabs.d.ts +1 -1
- package/dist/components/STabs/STabs.js +15 -26
- package/dist/components/STabs/STabs.js.map +1 -1
- package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
- package/dist/components/STimePicker/STimePicker.js.map +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.cjs +3 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.js +3 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
- package/dist/index.cjs +261 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +258 -108
- package/dist/index.js.map +1 -1
- package/dist/styles.css +12 -4
- package/dist/theme.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4876,73 +4876,70 @@ function SLoadingModal({
|
|
|
4876
4876
|
}
|
|
4877
4877
|
|
|
4878
4878
|
// src/components/SGnb/gnb.config.ts
|
|
4879
|
-
var
|
|
4880
|
-
var box = (p) => `var(--cmp-
|
|
4881
|
-
var
|
|
4882
|
-
var
|
|
4879
|
+
var gnb = (p) => `var(--cmp-gnb-${p})`;
|
|
4880
|
+
var box = (p) => `var(--cmp-gnb-box-${p})`;
|
|
4881
|
+
var belt = (p) => `var(--cmp-gnb-belt-${p})`;
|
|
4882
|
+
var light = (p) => `var(--cmp-gnb-light-${p})`;
|
|
4883
|
+
var dark = (p) => `var(--cmp-gnb-dark-${p})`;
|
|
4884
|
+
var HEADER_TOP = {
|
|
4885
|
+
topHeight: gnb("top-height"),
|
|
4886
|
+
topPaddingX: gnb("top-paddingX"),
|
|
4887
|
+
topGap: gnb("top-gap"),
|
|
4888
|
+
logoHeight: gnb("logo-height")
|
|
4889
|
+
};
|
|
4883
4890
|
var GNB_HEADER = {
|
|
4884
|
-
fix:
|
|
4885
|
-
|
|
4886
|
-
topPaddingX: belt("top-paddingX"),
|
|
4887
|
-
topGap: belt("top-gap"),
|
|
4888
|
-
logoHeight: belt("logo-height")
|
|
4889
|
-
},
|
|
4890
|
-
full: {
|
|
4891
|
-
topHeight: box("top-height"),
|
|
4892
|
-
topPaddingX: box("paddingX"),
|
|
4893
|
-
topGap: box("gap"),
|
|
4894
|
-
// 상단바 gap (버튼 간 세부 gap 은 --cmp-gnbBox-button-gap)
|
|
4895
|
-
logoHeight: box("logo-height")
|
|
4896
|
-
}
|
|
4891
|
+
fix: HEADER_TOP,
|
|
4892
|
+
full: HEADER_TOP
|
|
4897
4893
|
};
|
|
4898
4894
|
var GNB_MENU = {
|
|
4899
4895
|
box: {
|
|
4900
|
-
//
|
|
4901
|
-
bodyPaddingY:
|
|
4902
|
-
itemMarginX:
|
|
4903
|
-
|
|
4896
|
+
// 바디 패딩·세로 패딩·chevron 은 gnb 로 통합된 공통 토큰
|
|
4897
|
+
bodyPaddingY: gnb("body-padding"),
|
|
4898
|
+
itemMarginX: gnb("body-padding"),
|
|
4899
|
+
// 전방향 토큰 → 아이템 좌우 여백에도 사용
|
|
4900
|
+
itemPaddingY: gnb("item-paddingY"),
|
|
4904
4901
|
itemPaddingRight: box("item-paddingRight"),
|
|
4905
4902
|
itemGap: box("item-gap"),
|
|
4906
4903
|
itemRadius: box("item-radius"),
|
|
4907
|
-
itemArrow:
|
|
4904
|
+
itemArrow: gnb("item-chevron-size"),
|
|
4908
4905
|
depth1PaddingLeft: box("item-depth1-paddingLeft"),
|
|
4909
4906
|
depth2PaddingLeft: box("item-depth2-paddingLeft"),
|
|
4910
4907
|
depth3PaddingLeft: box("item-depth3-paddingLeft"),
|
|
4911
4908
|
depth1Icon: box("item-depth1-icon"),
|
|
4912
4909
|
depth1FontSize: 14,
|
|
4913
|
-
// token:
|
|
4910
|
+
// token: gnb.box.item.typography.selected.fontSize
|
|
4914
4911
|
depth1LineHeight: 24,
|
|
4915
|
-
// token:
|
|
4912
|
+
// token: gnb.box.item.typography.selected.lineHeight
|
|
4916
4913
|
depth1FontWeight: 700,
|
|
4917
4914
|
itemFontSize: 14,
|
|
4918
|
-
// token:
|
|
4915
|
+
// token: gnb.box.item.typography.default.fontSize
|
|
4919
4916
|
itemLineHeight: 24
|
|
4920
|
-
// token:
|
|
4917
|
+
// token: gnb.box.item.typography.default.lineHeight
|
|
4921
4918
|
},
|
|
4922
4919
|
belt: {
|
|
4923
|
-
bodyPaddingY:
|
|
4920
|
+
bodyPaddingY: gnb("body-padding"),
|
|
4924
4921
|
itemMarginX: "0px",
|
|
4925
4922
|
// belt 토큰에 가로 여백 없음 → 풀폭 행 (들여쓰기는 depth*-paddingLeft 전담)
|
|
4926
|
-
itemPaddingY:
|
|
4923
|
+
itemPaddingY: gnb("item-paddingY"),
|
|
4927
4924
|
itemPaddingRight: belt("item-paddingRight"),
|
|
4928
4925
|
itemGap: belt("item-gap"),
|
|
4929
4926
|
itemRadius: "0px",
|
|
4930
4927
|
// belt 토큰에 radius 없음 → 풀폭 행
|
|
4931
|
-
itemArrow:
|
|
4928
|
+
itemArrow: gnb("item-chevron-size"),
|
|
4932
4929
|
depth1PaddingLeft: belt("item-depth1-paddingLeft"),
|
|
4933
4930
|
depth2PaddingLeft: belt("item-depth2-paddingLeft"),
|
|
4934
4931
|
depth3PaddingLeft: belt("item-depth3-paddingLeft"),
|
|
4935
|
-
depth1Icon:
|
|
4936
|
-
// belt
|
|
4932
|
+
depth1Icon: belt("item-depth1-icon"),
|
|
4933
|
+
// belt 전용 depth1 아이콘 토큰(16)
|
|
4937
4934
|
depth1FontSize: 13,
|
|
4938
|
-
// token:
|
|
4935
|
+
// token: gnb.belt.item.depth1.typography.fontSize
|
|
4939
4936
|
depth1LineHeight: 22,
|
|
4940
|
-
// token:
|
|
4937
|
+
// token: gnb.belt.item.depth1.typography.lineHeight
|
|
4941
4938
|
depth1FontWeight: 700,
|
|
4942
4939
|
itemFontSize: 12,
|
|
4943
|
-
// token:
|
|
4940
|
+
// token: gnb.belt.item.typography.default.fontSize
|
|
4944
4941
|
itemLineHeight: 20
|
|
4945
|
-
// token:
|
|
4942
|
+
// token: gnb.belt.item.typography.default.lineHeight
|
|
4946
4943
|
}
|
|
4947
4944
|
};
|
|
4948
4945
|
var GNB_COLORS = {
|
|
@@ -4955,7 +4952,9 @@ var GNB_COLORS = {
|
|
|
4955
4952
|
itemColorDefault: light("item-fg-default"),
|
|
4956
4953
|
itemColorHover: light("item-fg-hover"),
|
|
4957
4954
|
itemColorActive: light("item-fg-selected"),
|
|
4958
|
-
itemChevron: light("item-chevron")
|
|
4955
|
+
itemChevron: light("item-chevron"),
|
|
4956
|
+
itemIcon: "grey_65",
|
|
4957
|
+
railFgDefault: light("rail-fg-default")
|
|
4959
4958
|
},
|
|
4960
4959
|
dark: {
|
|
4961
4960
|
panelBg: dark("bg"),
|
|
@@ -4966,19 +4965,41 @@ var GNB_COLORS = {
|
|
|
4966
4965
|
itemColorDefault: dark("item-fg-default"),
|
|
4967
4966
|
itemColorHover: dark("item-fg-hover"),
|
|
4968
4967
|
itemColorActive: dark("item-fg-selected"),
|
|
4969
|
-
itemChevron: dark("item-chevron")
|
|
4968
|
+
itemChevron: dark("item-chevron"),
|
|
4969
|
+
itemIcon: "grey_55",
|
|
4970
|
+
railFgDefault: dark("rail-fg-default")
|
|
4970
4971
|
}
|
|
4971
4972
|
};
|
|
4972
4973
|
var GNB_COMMON = {
|
|
4973
4974
|
/** 접힘 레일 폭. header="full" 은 접으면 메뉴만 사라져 레일이 없으므로 fix 전용. */
|
|
4974
|
-
foldWidth:
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4975
|
+
foldWidth: gnb("fold-width")
|
|
4976
|
+
};
|
|
4977
|
+
var GNB_RAIL = {
|
|
4978
|
+
padding: gnb("rail-padding"),
|
|
4979
|
+
gap: gnb("rail-gap"),
|
|
4980
|
+
itemWidth: gnb("rail-item-width"),
|
|
4981
|
+
itemPaddingTop: gnb("rail-item-paddingTop"),
|
|
4982
|
+
itemPaddingBottom: gnb("rail-item-paddingBottom"),
|
|
4983
|
+
itemRadius: gnb("rail-item-radius"),
|
|
4984
|
+
itemIcon: gnb("rail-item-icon"),
|
|
4985
|
+
// 타이포 (theme.css 에 gnb 타이포 변수 없음 → 토큰 값 직접 명시)
|
|
4986
|
+
itemFontSize: 11,
|
|
4987
|
+
// token: gnb.rail.item.typography.default.fontSize
|
|
4988
|
+
itemLineHeight: 18,
|
|
4989
|
+
// token: gnb.rail.item.typography.default.lineHeight
|
|
4990
|
+
itemFontWeight: 500,
|
|
4991
|
+
// token: gnb.rail.item.typography.default.fontWeight
|
|
4992
|
+
itemFontWeightSelected: 700
|
|
4993
|
+
// token: gnb.rail.item.typography.selected.fontWeight
|
|
4994
|
+
};
|
|
4995
|
+
var GNB_RAIL_WIDTH = 68;
|
|
4996
|
+
var GNB_FOLD_MS = 200;
|
|
4997
|
+
var GNB_EXPAND_MS = 200;
|
|
4981
4998
|
var GNB_MENU_WIDTH = 240;
|
|
4999
|
+
function findGnbRailValue(items, value) {
|
|
5000
|
+
if (items.some((item) => item.value === value)) return value;
|
|
5001
|
+
return findGnbAncestors(items, value)[0];
|
|
5002
|
+
}
|
|
4982
5003
|
function findGnbAncestors(items, value) {
|
|
4983
5004
|
const walk = (list, trail) => {
|
|
4984
5005
|
for (const item of list) {
|
|
@@ -5001,6 +5022,7 @@ function useSLayout() {
|
|
|
5001
5022
|
var SLayout = forwardRef(function SLayout2({
|
|
5002
5023
|
type = "box",
|
|
5003
5024
|
header = "fix",
|
|
5025
|
+
useRail = false,
|
|
5004
5026
|
folded,
|
|
5005
5027
|
defaultFolded = false,
|
|
5006
5028
|
onFoldedChange,
|
|
@@ -5020,13 +5042,17 @@ var SLayout = forwardRef(function SLayout2({
|
|
|
5020
5042
|
[isControlled, onFoldedChange]
|
|
5021
5043
|
);
|
|
5022
5044
|
const ctx = useMemo(
|
|
5023
|
-
() => ({ type, header, folded: currentFolded, setFolded }),
|
|
5024
|
-
[type, header, currentFolded, setFolded]
|
|
5045
|
+
() => ({ type, header, useRail, folded: currentFolded, setFolded }),
|
|
5046
|
+
[type, header, useRail, currentFolded, setFolded]
|
|
5025
5047
|
);
|
|
5026
5048
|
const isFullHeader = header === "full";
|
|
5049
|
+
const gnbColumnWidth = useRail ? GNB_RAIL_WIDTH + GNB_MENU_WIDTH : GNB_MENU_WIDTH;
|
|
5027
5050
|
const frameStyle = isFullHeader ? {
|
|
5028
|
-
gridTemplateColumns: `${currentFolded ? 0 :
|
|
5029
|
-
gridTemplateRows: `${GNB_HEADER[header].topHeight} 1fr
|
|
5051
|
+
gridTemplateColumns: `${currentFolded ? 0 : gnbColumnWidth}px 1fr`,
|
|
5052
|
+
gridTemplateRows: `${GNB_HEADER[header].topHeight} 1fr`,
|
|
5053
|
+
// 메뉴가 미끄러지는 동안 페이지 열도 같은 길이로 따라와야 한 덩어리로 읽힌다.
|
|
5054
|
+
// (fix 는 SGnb 가 제 폭을 직접 전환하므로 프레임이 손댈 게 없다)
|
|
5055
|
+
transition: `grid-template-columns ${GNB_FOLD_MS}ms ease-out`
|
|
5030
5056
|
} : void 0;
|
|
5031
5057
|
return /* @__PURE__ */ jsx(SLayoutContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
|
|
5032
5058
|
"div",
|
|
@@ -5051,8 +5077,10 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5051
5077
|
header: headerProp,
|
|
5052
5078
|
color = "light",
|
|
5053
5079
|
items,
|
|
5080
|
+
useRail: useRailProp,
|
|
5054
5081
|
value = "",
|
|
5055
5082
|
onValueChange,
|
|
5083
|
+
onRailChange,
|
|
5056
5084
|
folded: foldedProp,
|
|
5057
5085
|
onFoldChange,
|
|
5058
5086
|
onLauncherClick,
|
|
@@ -5066,6 +5094,7 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5066
5094
|
const type = typeProp ?? layout?.type ?? "box";
|
|
5067
5095
|
const header = headerProp ?? layout?.header ?? "fix";
|
|
5068
5096
|
const folded = foldedProp ?? layout?.folded ?? false;
|
|
5097
|
+
const useRail = useRailProp ?? layout?.useRail ?? false;
|
|
5069
5098
|
const H = GNB_HEADER[header];
|
|
5070
5099
|
const M = GNB_MENU[type];
|
|
5071
5100
|
const C = GNB_COLORS[color];
|
|
@@ -5073,6 +5102,9 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5073
5102
|
() => new Set(findGnbAncestors(items, value))
|
|
5074
5103
|
);
|
|
5075
5104
|
const [hoveredKey, setHoveredKey] = useState(null);
|
|
5105
|
+
const [activeRail, setActiveRail] = useState(
|
|
5106
|
+
() => findGnbRailValue(items, value) ?? items[0]?.value
|
|
5107
|
+
);
|
|
5076
5108
|
useEffect(() => {
|
|
5077
5109
|
const ancestors = findGnbAncestors(items, value);
|
|
5078
5110
|
if (ancestors.length === 0) return;
|
|
@@ -5083,6 +5115,15 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5083
5115
|
return next;
|
|
5084
5116
|
});
|
|
5085
5117
|
}, [items, value]);
|
|
5118
|
+
useEffect(() => {
|
|
5119
|
+
const owner = findGnbRailValue(items, value);
|
|
5120
|
+
if (owner !== void 0) setActiveRail(owner);
|
|
5121
|
+
}, [items, value]);
|
|
5122
|
+
useEffect(() => {
|
|
5123
|
+
setActiveRail(
|
|
5124
|
+
(prev) => prev !== void 0 && items.some((item) => item.value === prev) ? prev : items[0]?.value
|
|
5125
|
+
);
|
|
5126
|
+
}, [items]);
|
|
5086
5127
|
const toggleExpand = (key) => {
|
|
5087
5128
|
setExpandedKeys((prev) => {
|
|
5088
5129
|
const next = new Set(prev);
|
|
@@ -5099,16 +5140,58 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5099
5140
|
}
|
|
5100
5141
|
onValueChange?.(item.value);
|
|
5101
5142
|
};
|
|
5143
|
+
const handleRailClick = (item) => {
|
|
5144
|
+
if (item.disabled) return;
|
|
5145
|
+
setActiveRail(item.value);
|
|
5146
|
+
onRailChange?.(item.value);
|
|
5147
|
+
if (!item.children || item.children.length === 0) onValueChange?.(item.value);
|
|
5148
|
+
};
|
|
5102
5149
|
const handleFoldToggle = () => {
|
|
5103
5150
|
const next = !folded;
|
|
5104
5151
|
onFoldChange?.(next);
|
|
5105
5152
|
if (foldedProp === void 0) layout?.setFolded(next);
|
|
5106
5153
|
};
|
|
5107
|
-
const
|
|
5154
|
+
const renderRailItem = (item) => {
|
|
5155
|
+
const isActive = item.value === activeRail;
|
|
5156
|
+
const isHovered = hoveredKey === item.value && !item.disabled;
|
|
5157
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
5158
|
+
"button",
|
|
5159
|
+
{
|
|
5160
|
+
type: "button",
|
|
5161
|
+
disabled: item.disabled,
|
|
5162
|
+
"aria-current": isActive ? "true" : void 0,
|
|
5163
|
+
className: "box-border flex select-none flex-col items-center border-none bg-transparent transition-colors duration-150",
|
|
5164
|
+
style: {
|
|
5165
|
+
width: GNB_RAIL.itemWidth,
|
|
5166
|
+
paddingTop: GNB_RAIL.itemPaddingTop,
|
|
5167
|
+
paddingBottom: GNB_RAIL.itemPaddingBottom,
|
|
5168
|
+
borderRadius: GNB_RAIL.itemRadius,
|
|
5169
|
+
backgroundColor: isActive ? C.itemBgSelected : isHovered ? C.itemBgHover : C.itemBgDefault,
|
|
5170
|
+
color: isActive ? C.itemColorActive : C.railFgDefault,
|
|
5171
|
+
// <button> 의 UA 폰트를 끊고 앱 폰트를 잇는다 (메뉴 아이템과 같은 이유)
|
|
5172
|
+
fontFamily: "inherit",
|
|
5173
|
+
fontSize: GNB_RAIL.itemFontSize,
|
|
5174
|
+
lineHeight: `${GNB_RAIL.itemLineHeight}px`,
|
|
5175
|
+
fontWeight: isActive ? GNB_RAIL.itemFontWeightSelected : GNB_RAIL.itemFontWeight,
|
|
5176
|
+
opacity: item.disabled ? 0.4 : 1,
|
|
5177
|
+
cursor: item.disabled ? "not-allowed" : "pointer"
|
|
5178
|
+
},
|
|
5179
|
+
onClick: () => handleRailClick(item),
|
|
5180
|
+
onMouseEnter: () => setHoveredKey(item.value),
|
|
5181
|
+
onMouseLeave: () => setHoveredKey((prev) => prev === item.value ? null : prev),
|
|
5182
|
+
children: [
|
|
5183
|
+
item.icon && /* @__PURE__ */ jsx(SIcon, { name: item.icon, size: GNB_RAIL.itemIcon, className: "shrink-0" }),
|
|
5184
|
+
/* @__PURE__ */ jsx("span", { className: "w-full overflow-hidden text-ellipsis whitespace-nowrap text-center", children: item.label })
|
|
5185
|
+
]
|
|
5186
|
+
}
|
|
5187
|
+
) }, item.value);
|
|
5188
|
+
};
|
|
5189
|
+
const renderItem = (item, depth, branchHasIcon = false) => {
|
|
5108
5190
|
const hasChildren = !!(item.children && item.children.length > 0);
|
|
5109
5191
|
const isSelected = !hasChildren && item.value === value;
|
|
5110
5192
|
const isExpanded = expandedKeys.has(item.value);
|
|
5111
5193
|
const isHovered = hoveredKey === item.value && !item.disabled;
|
|
5194
|
+
const iconBranch = depth === 1 ? !!item.icon : branchHasIcon;
|
|
5112
5195
|
const itemStyle = {
|
|
5113
5196
|
gap: M.itemGap,
|
|
5114
5197
|
paddingTop: M.itemPaddingY,
|
|
@@ -5145,8 +5228,11 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5145
5228
|
onMouseEnter: () => setHoveredKey(item.value),
|
|
5146
5229
|
onMouseLeave: () => setHoveredKey((prev) => prev === item.value ? null : prev),
|
|
5147
5230
|
children: [
|
|
5148
|
-
depth === 1 && item.icon && /* @__PURE__ */ jsx(SIcon, { name: item.icon, size: M.depth1Icon, className: "shrink-0" }),
|
|
5149
|
-
/* @__PURE__ */
|
|
5231
|
+
depth === 1 && item.icon && /* @__PURE__ */ jsx(SIcon, { name: item.icon, size: M.depth1Icon, color: C.itemIcon, className: "shrink-0" }),
|
|
5232
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap flex flex-no-wrap items-center", children: [
|
|
5233
|
+
depth > 1 && iconBranch ? /* @__PURE__ */ jsx("div", { className: "w-[20px] h-[24px] flex items-center justify-center mr-[8px]", children: "-" }) : null,
|
|
5234
|
+
item.label
|
|
5235
|
+
] }),
|
|
5150
5236
|
item.tag !== void 0 && item.tag !== "" && /* @__PURE__ */ jsx(
|
|
5151
5237
|
STag,
|
|
5152
5238
|
{
|
|
@@ -5164,28 +5250,53 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5164
5250
|
size: M.itemArrow,
|
|
5165
5251
|
color: C.itemChevron,
|
|
5166
5252
|
rotate: isExpanded ? 180 : 0,
|
|
5167
|
-
className: "shrink-0 transition-transform duration-
|
|
5253
|
+
className: "shrink-0 transition-transform duration-200"
|
|
5168
5254
|
}
|
|
5169
5255
|
)
|
|
5170
5256
|
]
|
|
5171
5257
|
}
|
|
5172
5258
|
),
|
|
5173
|
-
hasChildren &&
|
|
5259
|
+
hasChildren && /* @__PURE__ */ jsx(
|
|
5260
|
+
"div",
|
|
5261
|
+
{
|
|
5262
|
+
className: "grid",
|
|
5263
|
+
style: {
|
|
5264
|
+
gridTemplateRows: isExpanded ? "1fr" : "0fr",
|
|
5265
|
+
transition: `grid-template-rows ${GNB_EXPAND_MS}ms ease-out`
|
|
5266
|
+
},
|
|
5267
|
+
children: /* @__PURE__ */ jsx(
|
|
5268
|
+
"ul",
|
|
5269
|
+
{
|
|
5270
|
+
className: "m-0 flex min-h-0 list-none flex-col overflow-hidden p-0",
|
|
5271
|
+
style: {
|
|
5272
|
+
visibility: isExpanded ? "visible" : "hidden",
|
|
5273
|
+
transition: `visibility 0s linear ${isExpanded ? "0s" : `${GNB_EXPAND_MS}ms`}`
|
|
5274
|
+
},
|
|
5275
|
+
children: item.children.map((child) => renderItem(child, depth + 1, iconBranch))
|
|
5276
|
+
}
|
|
5277
|
+
)
|
|
5278
|
+
}
|
|
5279
|
+
)
|
|
5174
5280
|
] }, item.value)
|
|
5175
5281
|
);
|
|
5176
5282
|
};
|
|
5283
|
+
const railItems = useRail ? items : [];
|
|
5284
|
+
const menuItems = useRail ? items.find((item) => item.value === activeRail)?.children ?? [] : items;
|
|
5285
|
+
const bodyWidth = useRail ? GNB_RAIL_WIDTH + GNB_MENU_WIDTH : GNB_MENU_WIDTH;
|
|
5177
5286
|
const railFolded = folded && header === "fix";
|
|
5178
|
-
const rootWidth = header === "full" ? "100%" : folded ? GNB_COMMON.foldWidth :
|
|
5287
|
+
const rootWidth = header === "full" ? "100%" : folded ? GNB_COMMON.foldWidth : bodyWidth;
|
|
5179
5288
|
const rootStyle = {
|
|
5180
5289
|
width: rootWidth,
|
|
5290
|
+
transition: `width ${GNB_FOLD_MS}ms ease-out`,
|
|
5181
5291
|
...header === "full" ? { gridArea: "1 / 1 / -1 / -1", pointerEvents: "none" } : { backgroundColor: C.panelBg },
|
|
5182
5292
|
...style
|
|
5183
5293
|
};
|
|
5294
|
+
const hideAfterSlide = (hidden) => `visibility 0s linear ${hidden ? `${GNB_FOLD_MS}ms` : "0s"}`;
|
|
5184
5295
|
return /* @__PURE__ */ jsxs(
|
|
5185
5296
|
"div",
|
|
5186
5297
|
{
|
|
5187
5298
|
ref,
|
|
5188
|
-
className: cn("box-border flex h-full shrink-0 flex-col", className),
|
|
5299
|
+
className: cn("box-border flex h-full shrink-0 flex-col overflow-hidden", className),
|
|
5189
5300
|
style: rootStyle,
|
|
5190
5301
|
"data-type": type,
|
|
5191
5302
|
"data-header": header,
|
|
@@ -5195,30 +5306,47 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5195
5306
|
/* @__PURE__ */ jsxs(
|
|
5196
5307
|
"div",
|
|
5197
5308
|
{
|
|
5198
|
-
className:
|
|
5309
|
+
className: "relative box-border flex shrink-0 items-center overflow-hidden",
|
|
5199
5310
|
style: {
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
padding: railFolded ? `${GNB_COMMON.buttonGap} 0` : `0 ${H.topPaddingX}`,
|
|
5311
|
+
height: H.topHeight,
|
|
5312
|
+
padding: `0 ${railFolded ? GNB_RAIL.padding : H.topPaddingX}`,
|
|
5203
5313
|
borderBottom: `1px solid ${C.topBorder}`,
|
|
5204
5314
|
backgroundColor: C.panelBg,
|
|
5205
5315
|
pointerEvents: "auto",
|
|
5316
|
+
transition: `padding ${GNB_FOLD_MS}ms ease-out`,
|
|
5206
5317
|
// 아이콘 버튼은 자체 ghostButton 토큰을 쓰므로, 이 색은 logo 슬롯 상속용
|
|
5207
5318
|
color: C.itemColorDefault
|
|
5208
5319
|
},
|
|
5209
5320
|
children: [
|
|
5210
|
-
onLauncherClick && /* @__PURE__ */
|
|
5211
|
-
|
|
5321
|
+
(onLauncherClick || logo) && /* @__PURE__ */ jsxs(
|
|
5322
|
+
"div",
|
|
5212
5323
|
{
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5324
|
+
className: "absolute inset-y-0 flex items-center",
|
|
5325
|
+
style: {
|
|
5326
|
+
left: H.topPaddingX,
|
|
5327
|
+
gap: H.topGap,
|
|
5328
|
+
opacity: railFolded ? 0 : 1,
|
|
5329
|
+
transition: `opacity ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(railFolded)}, transform ${GNB_FOLD_MS}ms ease-out`,
|
|
5330
|
+
// 메뉴와 같은 방향으로 빠지되, 좁은 레일 안에서 꼬리가 비치지 않게 페이드가 거리를 대신한다
|
|
5331
|
+
transform: railFolded ? `translateX(-${H.topPaddingX})` : "none",
|
|
5332
|
+
visibility: railFolded ? "hidden" : "visible"
|
|
5333
|
+
},
|
|
5334
|
+
children: [
|
|
5335
|
+
onLauncherClick && /* @__PURE__ */ jsx(
|
|
5336
|
+
SGhostButton,
|
|
5337
|
+
{
|
|
5338
|
+
icon: "launcher",
|
|
5339
|
+
size: "xs",
|
|
5340
|
+
intent: color === "dark" ? "inverse" : "default",
|
|
5341
|
+
ariaLabel: "app launcher",
|
|
5342
|
+
onClick: onLauncherClick,
|
|
5343
|
+
className: "shrink-0"
|
|
5344
|
+
}
|
|
5345
|
+
),
|
|
5346
|
+
logo && /* @__PURE__ */ jsx("div", { className: "flex items-center", style: { height: H.logoHeight }, children: logo })
|
|
5347
|
+
]
|
|
5219
5348
|
}
|
|
5220
5349
|
),
|
|
5221
|
-
!railFolded && logo && /* @__PURE__ */ jsx("div", { className: "flex items-center", style: { height: H.logoHeight }, children: logo }),
|
|
5222
5350
|
/* @__PURE__ */ jsx(
|
|
5223
5351
|
SGhostButton,
|
|
5224
5352
|
{
|
|
@@ -5228,30 +5356,61 @@ var SGnb = forwardRef(function SGnb2({
|
|
|
5228
5356
|
ariaLabel: "toggle navigation",
|
|
5229
5357
|
ariaPressed: folded,
|
|
5230
5358
|
onClick: handleFoldToggle,
|
|
5231
|
-
className:
|
|
5359
|
+
className: "ml-auto shrink-0"
|
|
5232
5360
|
}
|
|
5233
5361
|
)
|
|
5234
5362
|
]
|
|
5235
5363
|
}
|
|
5236
5364
|
),
|
|
5237
|
-
|
|
5238
|
-
"
|
|
5365
|
+
/* @__PURE__ */ jsxs(
|
|
5366
|
+
"div",
|
|
5239
5367
|
{
|
|
5240
|
-
"
|
|
5241
|
-
className: "flex flex-col overflow-y-auto",
|
|
5368
|
+
className: "flex flex-row",
|
|
5242
5369
|
style: {
|
|
5243
|
-
width:
|
|
5370
|
+
width: bodyWidth,
|
|
5244
5371
|
alignSelf: "flex-start",
|
|
5245
5372
|
flexGrow: 1,
|
|
5246
5373
|
flexShrink: 1,
|
|
5247
5374
|
flexBasis: "auto",
|
|
5248
5375
|
minHeight: 0,
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
pointerEvents: "auto"
|
|
5376
|
+
transform: folded ? "translateX(-100%)" : "none",
|
|
5377
|
+
visibility: folded ? "hidden" : "visible",
|
|
5378
|
+
transition: `transform ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(folded)}`
|
|
5253
5379
|
},
|
|
5254
|
-
children:
|
|
5380
|
+
children: [
|
|
5381
|
+
useRail && // 레일도 내비게이션 landmark — nav 로 세워야 aria-label(레일)이 스크린리더에 노출된다
|
|
5382
|
+
// (role 없는 ul 의 aria-label 은 영역명으로 읽히지 않는다). 메뉴 nav 와는 레이블로 구분된다.
|
|
5383
|
+
/* @__PURE__ */ jsx(
|
|
5384
|
+
"nav",
|
|
5385
|
+
{
|
|
5386
|
+
"aria-label": `${ariaLabel} rail`,
|
|
5387
|
+
className: "flex shrink-0 flex-col overflow-y-auto",
|
|
5388
|
+
style: {
|
|
5389
|
+
width: GNB_RAIL_WIDTH,
|
|
5390
|
+
padding: GNB_RAIL.padding,
|
|
5391
|
+
borderRight: `1px solid ${C.topBorder}`,
|
|
5392
|
+
backgroundColor: C.panelBg,
|
|
5393
|
+
pointerEvents: "auto"
|
|
5394
|
+
},
|
|
5395
|
+
children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", style: { gap: GNB_RAIL.gap }, children: railItems.map(renderRailItem) })
|
|
5396
|
+
}
|
|
5397
|
+
),
|
|
5398
|
+
/* @__PURE__ */ jsx(
|
|
5399
|
+
"nav",
|
|
5400
|
+
{
|
|
5401
|
+
"aria-label": ariaLabel,
|
|
5402
|
+
className: "flex shrink-0 flex-col overflow-y-auto",
|
|
5403
|
+
style: {
|
|
5404
|
+
width: GNB_MENU_WIDTH,
|
|
5405
|
+
paddingTop: M.bodyPaddingY,
|
|
5406
|
+
paddingBottom: M.bodyPaddingY,
|
|
5407
|
+
backgroundColor: C.panelBg,
|
|
5408
|
+
pointerEvents: "auto"
|
|
5409
|
+
},
|
|
5410
|
+
children: /* @__PURE__ */ jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item) => renderItem(item, 1)) })
|
|
5411
|
+
}
|
|
5412
|
+
)
|
|
5413
|
+
]
|
|
5255
5414
|
}
|
|
5256
5415
|
)
|
|
5257
5416
|
]
|
|
@@ -5265,7 +5424,7 @@ var SPage = forwardRef(function SPage2({ className, style, children, ...rest },
|
|
|
5265
5424
|
"main",
|
|
5266
5425
|
{
|
|
5267
5426
|
ref,
|
|
5268
|
-
className: cn("box-border min-h-0 min-w-0 flex-1 overflow-auto p-
|
|
5427
|
+
className: cn("box-border min-h-0 min-w-0 flex-1 overflow-auto p-20", className),
|
|
5269
5428
|
style: { ...gridStyle, ...style },
|
|
5270
5429
|
...rest,
|
|
5271
5430
|
children
|
|
@@ -5307,6 +5466,7 @@ function STabs({
|
|
|
5307
5466
|
}) {
|
|
5308
5467
|
const s = TAB_MAIN_SIZE[size];
|
|
5309
5468
|
const blue = TAB_MAIN_COLORS.selected.border;
|
|
5469
|
+
const isVertical = isSub && vertical;
|
|
5310
5470
|
const tabRefs = useRef([]);
|
|
5311
5471
|
const moveTo = (target) => {
|
|
5312
5472
|
if (target < 0 || target >= tabs.length) return;
|
|
@@ -5314,19 +5474,17 @@ function STabs({
|
|
|
5314
5474
|
tabRefs.current[target]?.focus();
|
|
5315
5475
|
};
|
|
5316
5476
|
const containerStyle = { ...style };
|
|
5317
|
-
if (!isSub) {
|
|
5318
|
-
if (vertical) containerStyle.borderRight = `1px solid ${blue}`;
|
|
5319
|
-
else containerStyle.borderBottom = `1px solid ${blue}`;
|
|
5320
|
-
}
|
|
5477
|
+
if (!isSub) containerStyle.borderBottom = `1px solid ${blue}`;
|
|
5321
5478
|
return /* @__PURE__ */ jsx(
|
|
5322
5479
|
"div",
|
|
5323
5480
|
{
|
|
5324
5481
|
role: "tablist",
|
|
5325
|
-
"aria-orientation":
|
|
5482
|
+
"aria-orientation": isVertical ? "vertical" : "horizontal",
|
|
5326
5483
|
className: cn(
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5484
|
+
// main(가로): baseline(하단 divider)이 100% 너비로 채워지도록 w-full
|
|
5485
|
+
isSub ? "inline-flex w-fit" : "flex w-full",
|
|
5486
|
+
isVertical ? "flex-col items-stretch" : "flex-row",
|
|
5487
|
+
isSub ? isVertical ? "gap-[16px]" : "gap-[24px]" : "gap-[4px]",
|
|
5330
5488
|
className
|
|
5331
5489
|
),
|
|
5332
5490
|
style: containerStyle,
|
|
@@ -5355,22 +5513,12 @@ function STabs({
|
|
|
5355
5513
|
color: selected ? TAB_MAIN_COLORS.selected.text : TAB_MAIN_COLORS.default.text,
|
|
5356
5514
|
border: `1px solid ${border}`,
|
|
5357
5515
|
// 폴더형: 미선택 탭은 baseline 위에, 선택 탭은 baseline(파란선)을 1px 덮어 연결된 것처럼 보이게
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
borderRight: selected ? `1px solid ${selectedBg}` : "none",
|
|
5365
|
-
marginRight: selected ? -1 : 0
|
|
5366
|
-
} : {
|
|
5367
|
-
borderTopLeftRadius: 6,
|
|
5368
|
-
borderTopRightRadius: 6,
|
|
5369
|
-
borderBottomLeftRadius: 0,
|
|
5370
|
-
borderBottomRightRadius: 0,
|
|
5371
|
-
borderBottom: selected ? `1px solid ${selectedBg}` : "none",
|
|
5372
|
-
marginBottom: selected ? -1 : 0
|
|
5373
|
-
}
|
|
5516
|
+
borderTopLeftRadius: 6,
|
|
5517
|
+
borderTopRightRadius: 6,
|
|
5518
|
+
borderBottomLeftRadius: 0,
|
|
5519
|
+
borderBottomRightRadius: 0,
|
|
5520
|
+
borderBottom: selected ? `1px solid ${selectedBg}` : "none",
|
|
5521
|
+
marginBottom: selected ? -1 : 0
|
|
5374
5522
|
};
|
|
5375
5523
|
}
|
|
5376
5524
|
return /* @__PURE__ */ jsxs(
|
|
@@ -5390,8 +5538,8 @@ function STabs({
|
|
|
5390
5538
|
select();
|
|
5391
5539
|
return;
|
|
5392
5540
|
}
|
|
5393
|
-
const nextKey =
|
|
5394
|
-
const prevKey =
|
|
5541
|
+
const nextKey = isVertical ? "ArrowDown" : "ArrowRight";
|
|
5542
|
+
const prevKey = isVertical ? "ArrowUp" : "ArrowLeft";
|
|
5395
5543
|
if (e.key === nextKey) {
|
|
5396
5544
|
e.preventDefault();
|
|
5397
5545
|
moveTo((i + 1) % tabs.length);
|
|
@@ -10262,7 +10410,9 @@ function RangeTimeSelector({
|
|
|
10262
10410
|
};
|
|
10263
10411
|
const commit = (side, hour, minute, direction = "unknown") => {
|
|
10264
10412
|
const next = formatTimeValue(hour, minute);
|
|
10265
|
-
onChange(
|
|
10413
|
+
onChange(
|
|
10414
|
+
normalizeNextRange(side === "start" ? [next, range[1]] : [range[0], next], side, direction)
|
|
10415
|
+
);
|
|
10266
10416
|
};
|
|
10267
10417
|
const getTimeMinutes2 = (time) => {
|
|
10268
10418
|
const { hour, minute } = parseTimeValue(time);
|
|
@@ -10654,6 +10804,6 @@ function STimeRangePicker({
|
|
|
10654
10804
|
);
|
|
10655
10805
|
}
|
|
10656
10806
|
|
|
10657
|
-
export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLayout, SLayoutContext, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, isColorKey, loading, resolveColor, useSLayout };
|
|
10807
|
+
export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLayout, SLayoutContext, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
|
|
10658
10808
|
//# sourceMappingURL=index.js.map
|
|
10659
10809
|
//# sourceMappingURL=index.js.map
|