sellmate-design-system-react 9.0.0-beta.105 → 9.0.0-beta.107
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 +7 -0
- package/dist/components/SGnb/SGnb.d.ts +3 -0
- package/dist/components/SGnb/gnb.config.d.ts +24 -0
- package/dist/components/SSelect/README.md +17 -0
- package/dist/components/SSelect/SSelect.d.ts +1 -1
- package/dist/components/SSelect/select.config.d.ts +12 -0
- package/dist/components/STag/README.md +2 -0
- package/dist/index.cjs +265 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +265 -42
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +24 -0
- package/dist/llms.txt +7 -0
- package/dist/styles.css +9 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -2555,6 +2555,13 @@ import { SLocaleProvider, SModalOutlet } from 'sellmate-design-system-react';
|
|
|
2555
2555
|
|
|
2556
2556
|
**접으면 레일·메뉴가 통째로 빠져나가면서 그 슬롯들도 함께 사라진다.** 접힌 상태에서도 남겨야 할 것은 `foldedTop`·`foldedFooter` 로 따로 준다 — `header="fix"` 로 접혔을 때만 나타나며, 폭이 좁은 폴드 레일이므로 아이콘 버튼 하나 정도로 줄인다.
|
|
2557
2557
|
|
|
2558
|
+
**접힌 GNB 를 호버로 잠깐 펼치는 동작은 컴포넌트가 한다 — 앱이 따로 만들지 않는다.** 접힌 채 화면 왼쪽 가장자리(`header` 와 무관하게 `fix`·`full` 모두)에 마우스를 가져가면 페이지를 밀지 않고 그 위에 겹쳐 펼쳐지고, GNB 를 벗어나면 다시 접힌다. 키보드 포커스가 펼쳐진 GNB 안에 있으면 접히지 않는다. 이 동작을 켜고 끄는 prop 은 없다.
|
|
2559
|
+
|
|
2560
|
+
- **`folded` 는 그대로이고 `onFoldedChange` 도 오지 않는다.** 호버로 펼친 것은 보이는 모양뿐이라 앱의 접힘 상태·페이지 폭에 영향이 없다. 펼친 채로 두려면 폴드 버튼으로 편다 — 그때 `folded` 가 바뀐다.
|
|
2561
|
+
- **접힌 화면의 왼쪽 가장자리에는 호버 영역(투명 띠)이 깔린다.** 그 자리에 클릭해야 하는 것(페이지 왼쪽 끝에 붙인 버튼 등)을 두지 않는다. 띠의 폭은 컴포넌트가 정하므로 숫자를 직접 주지 않는다.
|
|
2562
|
+
- **펼쳐지는 동안 `foldedTop`·`foldedFooter` 와 접힌 레일의 `system` 은 펼친 모양(`menuTop`·`menuFooter`·메뉴 컬럼 바닥)으로 바뀐다.** 접힌 레일에서 열어 둔 계정·알림 패널은 그때 닫힌다(§4-1 `system`).
|
|
2563
|
+
- **터치에는 hover 가 없어 동작하지 않는다.** 터치 화면에서도 접힌 GNB 를 펴야 하면 폴드 버튼으로 연다.
|
|
2564
|
+
|
|
2558
2565
|
```tsx
|
|
2559
2566
|
{/* 접히면 menuTop·menuFooter 가 함께 빠지므로, 폴드 레일에 남길 것만 foldedTop 으로 따로 준다 */}
|
|
2560
2567
|
<SGnb
|
|
@@ -201,6 +201,9 @@ export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>
|
|
|
201
201
|
* 접힘/펼침은 GNB_FOLD_MS 동안의 슬라이드다 — 레일·메뉴가 함께 왼쪽으로 빠져나가고 펼치면 오른쪽에서 들어온다.
|
|
202
202
|
* 페이지 쪽 폭은 fix 면 이 컴포넌트의 폭 전환이, full 이면 SLayout 의 메뉴 열 전환이 같은 길이로 맞춘다.
|
|
203
203
|
*
|
|
204
|
+
* 접힌 채 화면 왼쪽 가장자리(투명 띠)에 마우스를 가져가면 페이지를 밀지 않고 위에 겹쳐 펼쳐지고,
|
|
205
|
+
* GNB 를 벗어나면(키보드 포커스가 안에 있으면 유지) 다시 접힌다. `folded` 는 바뀌지 않는다.
|
|
206
|
+
*
|
|
204
207
|
* SLayout 안에서 쓰면 type·header·folded 를 context 에서 읽어 앱이 중복으로 넘길 필요가 없고,
|
|
205
208
|
* 자기 치수(컬럼 폭·상단바 높이·전환 길이)를 registerNav 로 되올려 프레임이 그 값으로 그리드를 깐다.
|
|
206
209
|
*
|
|
@@ -118,6 +118,30 @@ export declare const GNB_FOLD_MS = 200;
|
|
|
118
118
|
* 폴드와 같은 값을 써서 두 모션이 한 언어로 읽히게 한다.
|
|
119
119
|
*/
|
|
120
120
|
export declare const GNB_EXPAND_MS = 200;
|
|
121
|
+
/**
|
|
122
|
+
* 접힌 GNB 의 호버 오버레이(peek) — 접힌 채 화면 왼쪽 가장자리에 마우스를 가져가면 GNB 가
|
|
123
|
+
* 페이지를 밀지 않고 위에 겹쳐 펼쳐진다. 전용 토큰이 없어 상수로 둔다.
|
|
124
|
+
* - 진입 지연: 가장자리를 스치기만 한 경우에 펼쳐지지 않게 한다.
|
|
125
|
+
* - 이탈 지연: 경계를 살짝 벗어났다 돌아오는 동안 깜빡이며 접히지 않게 한다.
|
|
126
|
+
* - 가장자리 폭: 여는 호버 영역인 화면 왼쪽 투명 띠의 폭. header="full" 은 접으면 메뉴가 화면 밖으로 나가
|
|
127
|
+
* 잡을 자리가 없고, header="fix" 는 접힌 레일 전체를 영역으로 삼으면 레일의 버튼으로 가는 길에 스치기만 해도
|
|
128
|
+
* 펼쳐져 누르려던 버튼이 바뀌므로 둘 다 띠로 연다.
|
|
129
|
+
*/
|
|
130
|
+
export declare const GNB_PEEK_ENTER_DELAY_MS = 120;
|
|
131
|
+
export declare const GNB_PEEK_LEAVE_DELAY_MS = 250;
|
|
132
|
+
export declare const GNB_PEEK_EDGE_WIDTH = 12;
|
|
133
|
+
/**
|
|
134
|
+
* 호버 오버레이가 뜨는 z-index. 두 쪽 사이에 끼어야 한다.
|
|
135
|
+
* - 위로 못 넘는 것: 페이지 안의 로컬 값(SPageHeader·sticky 헤더 등 한 자리~30 대) — 오버레이가 그 아래로 가라앉으면 안 된다.
|
|
136
|
+
* - 아래로 못 내려가는 것: 전역 포털 레이어(`Z_INDEX.baseFloating`=50) — GNB 안에서 뜬 계정 목록·런처·라벨 칩이
|
|
137
|
+
* 오버레이에 가려지면 안 된다.
|
|
138
|
+
*/
|
|
139
|
+
export declare const GNB_PEEK_Z_INDEX = 40;
|
|
140
|
+
/**
|
|
141
|
+
* 호버 오버레이의 그림자. 시안 값이 공용 그림자 토큰(--shadow-*)에 없어 상수로 둔다.
|
|
142
|
+
* 오버레이는 왼쪽 가장자리에 붙어 사방으로 고르게 퍼지는 그림자를 쓴다(오프셋 없음).
|
|
143
|
+
*/
|
|
144
|
+
export declare const GNB_PEEK_SHADOW = "0px 0px 64px 0px rgba(34,34,34,0.12), 0px 0px 24px 0px rgba(34,34,34,0.08)";
|
|
121
145
|
/**
|
|
122
146
|
* 메뉴 고정 폭. 두 header 모두 메뉴는 이 폭으로 좌측에 붙는다(토큰 없음 → 상수).
|
|
123
147
|
* header="full" 에서 SLayout 이 "메뉴 오른쪽 = 페이지" 영역을 잡을 때도 이 값을 쓴다.
|
|
@@ -87,6 +87,11 @@ export type SSelectChangeValue = any;
|
|
|
87
87
|
export interface SSelectOption {
|
|
88
88
|
value: string | number;
|
|
89
89
|
label: string;
|
|
90
|
+
/**
|
|
91
|
+
* 주면 `label` 을 STag 로 그린다 — 목록 행과 단일 선택 트리거에 적용. 칩·multi 의 쉼표 트리거는 글자로 둔다.
|
|
92
|
+
* 태그는 글자만 받으므로 HTML 라벨과 함께 주면 태그를 걷어낸 글자로 그려진다.
|
|
93
|
+
*/
|
|
94
|
+
tag?: SSelectOptionTag;
|
|
90
95
|
disabled?: boolean;
|
|
91
96
|
children?: SSelectOption[];
|
|
92
97
|
}
|
|
@@ -106,6 +111,16 @@ export type SSelectType =
|
|
|
106
111
|
export type SSelectValueDisplay = 'text' | 'chip';
|
|
107
112
|
```
|
|
108
113
|
|
|
114
|
+
### SSelectOptionTag
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
/**
|
|
118
|
+
* 옵션 라벨을 STag 로 그릴 때 넘기는 값. 글자는 옵션의 `label` 이고, 크기는 SSelect 의 `size` 가
|
|
119
|
+
* 정한다(`md` 면 `sm`, 그 외 `xs`) — 그래서 `size`·`label` 은 받지 않는다. 나머지(`color`·`deep`·`shape`·`icon`…)는 STag 와 같다.
|
|
120
|
+
*/
|
|
121
|
+
export type SSelectOptionTag = Omit<STagProps, 'size' | 'label'>;
|
|
122
|
+
```
|
|
123
|
+
|
|
109
124
|
## Dependencies
|
|
110
125
|
|
|
111
126
|
### Used by
|
|
@@ -122,6 +137,7 @@ export type SSelectValueDisplay = 'text' | 'chip';
|
|
|
122
137
|
- [SIcon](../SIcon)
|
|
123
138
|
- [SPortal](../SPortal)
|
|
124
139
|
- [SSearchInput](../SSearchInput)
|
|
140
|
+
- [STag](../STag)
|
|
125
141
|
|
|
126
142
|
### Graph
|
|
127
143
|
|
|
@@ -134,6 +150,7 @@ graph TD;
|
|
|
134
150
|
SSelect --> SIcon
|
|
135
151
|
SSelect --> SPortal
|
|
136
152
|
SSelect --> SSearchInput
|
|
153
|
+
SSelect --> STag
|
|
137
154
|
SKeyValueTable --> SSelect
|
|
138
155
|
STable --> SSelect
|
|
139
156
|
style SSelect fill:#f9f,stroke:#333,stroke-width:4px
|
|
@@ -6,7 +6,7 @@ import { type SColor } from '../../lib/color';
|
|
|
6
6
|
import { type STooltipProps } from '../STooltip';
|
|
7
7
|
import { type SSelectOption, type SSelectType, type SSelectValueDisplay } from './select.config';
|
|
8
8
|
import { type SFieldWidth } from '../../lib/field-width';
|
|
9
|
-
export type { SSelectOption, SSelectType, SSelectValueDisplay } from './select.config';
|
|
9
|
+
export type { SSelectOption, SSelectOptionTag, SSelectType, SSelectValueDisplay, } from './select.config';
|
|
10
10
|
export interface SSelectHandle {
|
|
11
11
|
/** 트리거(combobox)에 포커스 (sdFocus) */
|
|
12
12
|
focus: () => void;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
import { type STagProps } from '../STag';
|
|
2
|
+
/**
|
|
3
|
+
* 옵션 라벨을 STag 로 그릴 때 넘기는 값. 글자는 옵션의 `label` 이고, 크기는 SSelect 의 `size` 가
|
|
4
|
+
* 정한다(`md` 면 `sm`, 그 외 `xs`) — 그래서 `size`·`label` 은 받지 않는다. 나머지(`color`·`deep`·`shape`·`icon`…)는 STag 와 같다.
|
|
5
|
+
*/
|
|
6
|
+
export type SSelectOptionTag = Omit<STagProps, 'size' | 'label'>;
|
|
1
7
|
export interface SSelectOption {
|
|
2
8
|
value: string | number;
|
|
3
9
|
label: string;
|
|
10
|
+
/**
|
|
11
|
+
* 주면 `label` 을 STag 로 그린다 — 목록 행과 단일 선택 트리거에 적용. 칩·multi 의 쉼표 트리거는 글자로 둔다.
|
|
12
|
+
* 태그는 글자만 받으므로 HTML 라벨과 함께 주면 태그를 걷어낸 글자로 그려진다.
|
|
13
|
+
*/
|
|
14
|
+
tag?: SSelectOptionTag;
|
|
4
15
|
disabled?: boolean;
|
|
5
16
|
children?: SSelectOption[];
|
|
6
17
|
}
|
|
@@ -10,6 +21,7 @@ export type SSelectValueDisplay = 'text' | 'chip';
|
|
|
10
21
|
export interface FlatOption {
|
|
11
22
|
value: string;
|
|
12
23
|
label: string;
|
|
24
|
+
tag?: SSelectOptionTag;
|
|
13
25
|
disabled: boolean;
|
|
14
26
|
depth: number;
|
|
15
27
|
/** children 을 가진 그룹 노드 — 그 자체가 값이 되는 것은 `tree` 타입뿐이다 */
|
|
@@ -79,6 +79,7 @@ export const TAG_COLORS = [
|
|
|
79
79
|
- [SLauncherListBox](../SLauncherListBox)
|
|
80
80
|
- [SNumberInput](../SNumberInput)
|
|
81
81
|
- [SRadioCard](../SRadioCard)
|
|
82
|
+
- [SSelect](../SSelect)
|
|
82
83
|
- [SSystemActionButton](../SSystemActionButton)
|
|
83
84
|
- [STabs](../STabs)
|
|
84
85
|
- [STextLink](../STextLink)
|
|
@@ -102,6 +103,7 @@ graph TD;
|
|
|
102
103
|
SLauncherListBox --> STag
|
|
103
104
|
SNumberInput --> STag
|
|
104
105
|
SRadioCard --> STag
|
|
106
|
+
SSelect --> STag
|
|
105
107
|
SSystemActionButton --> STag
|
|
106
108
|
STabs --> STag
|
|
107
109
|
STextLink --> STag
|
package/dist/index.cjs
CHANGED
|
@@ -3107,43 +3107,52 @@ var Icon_helpFill = (p) => {
|
|
|
3107
3107
|
}
|
|
3108
3108
|
);
|
|
3109
3109
|
};
|
|
3110
|
+
var HELP_OUTLINE_VARIANTS = {
|
|
3111
|
+
16: {
|
|
3112
|
+
stroke: 1.25,
|
|
3113
|
+
ring: "M14.6666 8.00004C14.6666 4.31814 11.6819 1.33337 7.99998 1.33337C4.31808 1.33337 1.33331 4.31814 1.33331 8.00004C1.33331 11.6819 4.31808 14.6667 7.99998 14.6667C11.6819 14.6667 14.6666 11.6819 14.6666 8.00004Z",
|
|
3114
|
+
mark: "M5.99988 6.06806C5.99988 5.462 6.39988 4.24988 7.99988 4.24988C9.59988 4.24988 9.99988 5.462 9.99988 6.06806C9.99988 6.58025 9.71419 7.52529 8.65996 7.80576C8.30414 7.90042 7.99988 8.18472 7.99988 8.55291V9.24988",
|
|
3115
|
+
dot: "M7.99986 10.4999C8.36805 10.4999 8.66652 10.7984 8.66652 11.1665C8.66652 11.5347 8.36805 11.8332 7.99986 11.8332C7.63167 11.8332 7.33319 11.5347 7.33319 11.1665C7.33319 10.7984 7.63167 10.4999 7.99986 10.4999Z"
|
|
3116
|
+
},
|
|
3117
|
+
20: {
|
|
3118
|
+
stroke: 1.25,
|
|
3119
|
+
ring: "M18.3334 9.99996C18.3334 5.39759 14.6024 1.66663 10 1.66663C5.39765 1.66663 1.66669 5.39759 1.66669 9.99996C1.66669 14.6023 5.39765 18.3333 10 18.3333C14.6024 18.3333 18.3334 14.6023 18.3334 9.99996Z",
|
|
3120
|
+
mark: "M7.49988 7.58498C7.49988 6.82741 7.99988 5.31226 9.99988 5.31226C11.9999 5.31226 12.4999 6.82741 12.4999 7.58498C12.4999 8.22522 12.1428 9.40652 10.825 9.75711C10.3802 9.87543 9.99988 10.2308 9.99988 10.691V11.5623",
|
|
3121
|
+
dot: "M9.99984 13.1248C10.4601 13.1248 10.8332 13.4979 10.8332 13.9581C10.8332 14.4183 10.4601 14.7914 9.99984 14.7914C9.5396 14.7914 9.1665 14.4183 9.1665 13.9581C9.1665 13.4979 9.5396 13.1248 9.99984 13.1248Z"
|
|
3122
|
+
},
|
|
3123
|
+
24: {
|
|
3124
|
+
stroke: 1.5,
|
|
3125
|
+
ring: "M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12Z",
|
|
3126
|
+
mark: "M8.99982 9.10203C8.99982 8.19294 9.59982 6.37476 11.9998 6.37476C14.3998 6.37476 14.9998 8.19294 14.9998 9.10203C14.9998 9.87031 14.5713 11.2879 12.9899 11.7086C12.4562 11.8506 11.9998 12.277 11.9998 12.8293V13.8748",
|
|
3127
|
+
dot: "M11.9998 15.7498C12.5521 15.7498 12.9998 16.1975 12.9998 16.7498C12.9998 17.302 12.5521 17.7498 11.9998 17.7498C11.4475 17.7498 10.9998 17.302 10.9998 16.7498C10.9998 16.1975 11.4475 15.7498 11.9998 15.7498Z"
|
|
3128
|
+
}
|
|
3129
|
+
};
|
|
3130
|
+
var helpOutlineGrid = (size) => {
|
|
3131
|
+
const px = typeof size === "number" ? size : /^\d+(\.\d+)?(px)?$/.test(size) ? parseFloat(size) : void 0;
|
|
3132
|
+
if (px === void 0) return 24;
|
|
3133
|
+
if (px <= 16) return 16;
|
|
3134
|
+
if (px <= 20) return 20;
|
|
3135
|
+
return 24;
|
|
3136
|
+
};
|
|
3110
3137
|
var Icon_helpOutline = (p) => {
|
|
3111
3138
|
const { size = 24, strokeWidth, ...rest } = p;
|
|
3112
|
-
const
|
|
3139
|
+
const grid = helpOutlineGrid(size);
|
|
3140
|
+
const v = HELP_OUTLINE_VARIANTS[grid];
|
|
3141
|
+
const native = Number(size) === grid || size === `${grid}px`;
|
|
3142
|
+
const stroke = native ? { stroke: "currentColor", strokeWidth: v.stroke } : { ...strokeProps(strokeWidth), strokeWidth: strokeWidth ?? v.stroke };
|
|
3113
3143
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3114
3144
|
"svg",
|
|
3115
3145
|
{
|
|
3116
3146
|
width: size,
|
|
3117
3147
|
height: size,
|
|
3118
|
-
viewBox:
|
|
3148
|
+
viewBox: `0 0 ${grid} ${grid}`,
|
|
3119
3149
|
fill: "none",
|
|
3120
3150
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3121
3151
|
...rest,
|
|
3122
3152
|
children: [
|
|
3123
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
d: "M22.1998 11.9998C22.1998 6.3665 17.6331 1.7998 11.9998 1.7998C6.3665 1.7998 1.7998 6.3665 1.7998 11.9998C1.7998 17.6331 6.3665 22.1998 11.9998 22.1998C17.6331 22.1998 22.1998 17.6331 22.1998 11.9998Z",
|
|
3127
|
-
strokeLinecap: "round",
|
|
3128
|
-
...stroke
|
|
3129
|
-
}
|
|
3130
|
-
),
|
|
3131
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3132
|
-
"path",
|
|
3133
|
-
{
|
|
3134
|
-
d: "M8.99982 9.10203C8.99982 8.19294 9.59982 6.37476 11.9998 6.37476C14.3998 6.37476 14.9998 8.19294 14.9998 9.10203C14.9998 9.87031 14.5713 11.2879 12.9899 11.7086C12.4562 11.8506 11.9998 12.277 11.9998 12.8293V13.8748",
|
|
3135
|
-
strokeLinecap: "round",
|
|
3136
|
-
strokeLinejoin: "round",
|
|
3137
|
-
...stroke
|
|
3138
|
-
}
|
|
3139
|
-
),
|
|
3140
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3141
|
-
"path",
|
|
3142
|
-
{
|
|
3143
|
-
d: "M11.9998 15.7498C12.5521 15.7498 12.9998 16.1975 12.9998 16.7498C12.9998 17.302 12.5521 17.7498 11.9998 17.7498C11.4475 17.7498 10.9998 17.302 10.9998 16.7498C10.9998 16.1975 11.4475 15.7498 11.9998 15.7498Z",
|
|
3144
|
-
fill: "currentColor"
|
|
3145
|
-
}
|
|
3146
|
-
)
|
|
3153
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: v.ring, strokeLinecap: "round", ...stroke }),
|
|
3154
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: v.mark, strokeLinecap: "round", strokeLinejoin: "round", ...stroke }),
|
|
3155
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: v.dot, fill: "currentColor" })
|
|
3147
3156
|
]
|
|
3148
3157
|
}
|
|
3149
3158
|
);
|
|
@@ -5652,7 +5661,11 @@ var STag = /* @__PURE__ */ react.forwardRef(function STag2({
|
|
|
5652
5661
|
// 레이블에 line-height 가 필요 없다. 오히려 line-height 를 주면 브라우저가
|
|
5653
5662
|
// 폰트 ascent/descent 를 정수 px 로 반올림한 뒤 남는 half-leading 을 내림 처리해
|
|
5654
5663
|
// 베이스라인이 최대 1px 위로 밀린다(xs 에서 특히 눈에 띈다).
|
|
5655
|
-
|
|
5664
|
+
// truncate: 폭이 모자라면(`width` 지정, 부모의 max-w 등) 글자에 말줄임이 걸린다. text-overflow 는
|
|
5665
|
+
// inline-flex 에서 듣지 않아 block 으로 둔다 — flex 아이템이라 폭·정렬은 그대로다.
|
|
5666
|
+
// overflow:hidden 이 line-height:1 의 줄 상자 밖으로 나온 글자(디센더)를 자르지 않도록
|
|
5667
|
+
// py 로 잘리는 영역만 넓히고 -my 로 레이아웃 높이는 되돌린다.
|
|
5668
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "-my-[2px] block min-w-0 truncate py-[2px] leading-none", children: label }),
|
|
5656
5669
|
icon && !iconLeft && iconNode
|
|
5657
5670
|
]
|
|
5658
5671
|
}
|
|
@@ -13825,6 +13838,11 @@ var GNB_RAIL = {
|
|
|
13825
13838
|
var GNB_RAIL_WIDTH = 68;
|
|
13826
13839
|
var GNB_FOLD_MS = 200;
|
|
13827
13840
|
var GNB_EXPAND_MS = 200;
|
|
13841
|
+
var GNB_PEEK_ENTER_DELAY_MS = 120;
|
|
13842
|
+
var GNB_PEEK_LEAVE_DELAY_MS = 250;
|
|
13843
|
+
var GNB_PEEK_EDGE_WIDTH = 12;
|
|
13844
|
+
var GNB_PEEK_Z_INDEX = 40;
|
|
13845
|
+
var GNB_PEEK_SHADOW = "0px 0px 64px 0px rgba(34,34,34,0.12), 0px 0px 24px 0px rgba(34,34,34,0.08)";
|
|
13828
13846
|
var GNB_MENU_WIDTH = 214;
|
|
13829
13847
|
var GNB_MENU_MIN_WIDTH = 200;
|
|
13830
13848
|
var GNB_MENU_MAX_WIDTH = 240;
|
|
@@ -13921,6 +13939,10 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
13921
13939
|
ariaLabel = "global navigation",
|
|
13922
13940
|
className,
|
|
13923
13941
|
style,
|
|
13942
|
+
onPointerEnter: onPointerEnterProp,
|
|
13943
|
+
onPointerLeave: onPointerLeaveProp,
|
|
13944
|
+
onFocus: onFocusProp,
|
|
13945
|
+
onBlur: onBlurProp,
|
|
13924
13946
|
...rest
|
|
13925
13947
|
}, ref) {
|
|
13926
13948
|
const layout = react.useContext(SLayoutContext);
|
|
@@ -14277,7 +14299,80 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
14277
14299
|
event.preventDefault();
|
|
14278
14300
|
commitMenuWidth(next);
|
|
14279
14301
|
};
|
|
14280
|
-
const
|
|
14302
|
+
const [peeking, setPeeking] = react.useState(false);
|
|
14303
|
+
const peekingRef = react.useRef(false);
|
|
14304
|
+
const peekHoverRef = react.useRef(false);
|
|
14305
|
+
const peekFocusRef = react.useRef(false);
|
|
14306
|
+
const peekTimerRef = react.useRef(null);
|
|
14307
|
+
const clearPeekTimer = () => {
|
|
14308
|
+
if (peekTimerRef.current === null) return;
|
|
14309
|
+
clearTimeout(peekTimerRef.current);
|
|
14310
|
+
peekTimerRef.current = null;
|
|
14311
|
+
};
|
|
14312
|
+
const commitPeek = (next) => {
|
|
14313
|
+
peekingRef.current = next;
|
|
14314
|
+
if (next) peekFocusRef.current = false;
|
|
14315
|
+
setPeeking(next);
|
|
14316
|
+
};
|
|
14317
|
+
const schedulePeek = () => {
|
|
14318
|
+
clearPeekTimer();
|
|
14319
|
+
const want = peekHoverRef.current || peekingRef.current && peekFocusRef.current;
|
|
14320
|
+
if (want === peekingRef.current) return;
|
|
14321
|
+
peekTimerRef.current = setTimeout(
|
|
14322
|
+
() => {
|
|
14323
|
+
peekTimerRef.current = null;
|
|
14324
|
+
commitPeek(want);
|
|
14325
|
+
},
|
|
14326
|
+
want ? GNB_PEEK_ENTER_DELAY_MS : GNB_PEEK_LEAVE_DELAY_MS
|
|
14327
|
+
);
|
|
14328
|
+
};
|
|
14329
|
+
react.useEffect(() => {
|
|
14330
|
+
if (folded) return;
|
|
14331
|
+
clearPeekTimer();
|
|
14332
|
+
peekHoverRef.current = false;
|
|
14333
|
+
peekFocusRef.current = false;
|
|
14334
|
+
commitPeek(false);
|
|
14335
|
+
}, [folded]);
|
|
14336
|
+
react.useEffect(() => clearPeekTimer, []);
|
|
14337
|
+
const handlePeekEdgeEnter = (event) => {
|
|
14338
|
+
if (!folded || event.pointerType === "touch") return;
|
|
14339
|
+
peekHoverRef.current = true;
|
|
14340
|
+
schedulePeek();
|
|
14341
|
+
};
|
|
14342
|
+
const handlePeekEnter = (event) => {
|
|
14343
|
+
if (!peekingRef.current) return;
|
|
14344
|
+
handlePeekEdgeEnter(event);
|
|
14345
|
+
};
|
|
14346
|
+
const handlePeekLeave = () => {
|
|
14347
|
+
peekHoverRef.current = false;
|
|
14348
|
+
schedulePeek();
|
|
14349
|
+
};
|
|
14350
|
+
const handlePeekFocus = (event) => {
|
|
14351
|
+
peekFocusRef.current = event.target.matches(":focus-visible");
|
|
14352
|
+
schedulePeek();
|
|
14353
|
+
};
|
|
14354
|
+
const handlePeekBlur = (event) => {
|
|
14355
|
+
if (event.currentTarget.contains(event.relatedTarget)) return;
|
|
14356
|
+
peekFocusRef.current = false;
|
|
14357
|
+
schedulePeek();
|
|
14358
|
+
};
|
|
14359
|
+
const [peekClosing, setPeekClosing] = react.useState(false);
|
|
14360
|
+
const wasPeekingRef = react.useRef(false);
|
|
14361
|
+
react.useEffect(() => {
|
|
14362
|
+
if (peeking) {
|
|
14363
|
+
wasPeekingRef.current = true;
|
|
14364
|
+
setPeekClosing(false);
|
|
14365
|
+
return void 0;
|
|
14366
|
+
}
|
|
14367
|
+
if (!wasPeekingRef.current) return void 0;
|
|
14368
|
+
wasPeekingRef.current = false;
|
|
14369
|
+
setPeekClosing(true);
|
|
14370
|
+
const timer = setTimeout(() => setPeekClosing(false), GNB_FOLD_MS);
|
|
14371
|
+
return () => clearTimeout(timer);
|
|
14372
|
+
}, [peeking]);
|
|
14373
|
+
const peekOverlay = folded && peeking;
|
|
14374
|
+
const visuallyFolded = folded && !peeking;
|
|
14375
|
+
const railFolded = visuallyFolded && header === "fix";
|
|
14281
14376
|
react.useEffect(() => {
|
|
14282
14377
|
if (!railFolded || !launcherOpen) return;
|
|
14283
14378
|
setLauncherOpen(false);
|
|
@@ -14324,14 +14419,50 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
14324
14419
|
{ width: "100%", ...style }
|
|
14325
14420
|
) : {
|
|
14326
14421
|
// fix 를 닫으면 48px 레일로 좁혀진다.
|
|
14327
|
-
width:
|
|
14422
|
+
width: visuallyFolded ? GNB_COMMON.foldWidth : bodyWidth,
|
|
14423
|
+
// 호버 오버레이: 폭은 펼치되 음수 margin 으로 레이아웃 자리는 레일 폭 그대로 둔다 — 페이지가 밀리지 않는다.
|
|
14424
|
+
// 폭과 margin 이 같은 길이·곡선으로 움직여 둘의 합(=페이지가 보는 자리)은 전환 내내 변하지 않는다.
|
|
14425
|
+
marginRight: peekOverlay ? `calc(${GNB_COMMON.foldWidth} - ${bodyWidth}px)` : "0px",
|
|
14426
|
+
// 페이지 위에 뜬다(접히는 전환이 끝날 때까지). 그 밖에는 주지 않는다 — 주면 펼친 GNB 에도 stacking context 가 새로 생긴다.
|
|
14427
|
+
// (폴드 버튼으로 펴서 folded 가 풀리면 접히는 중이 아니다 — 펼친 GNB 에는 주지 않는다)
|
|
14428
|
+
zIndex: peekOverlay || peekClosing && folded ? GNB_PEEK_Z_INDEX : void 0,
|
|
14429
|
+
boxShadow: peekOverlay ? GNB_PEEK_SHADOW : "none",
|
|
14328
14430
|
// 폭을 끄는 중에는 전환을 끈다 — 접힘용 전환이 걸려 있으면 컬럼이 손보다 늦게 따라온다.
|
|
14329
|
-
transition: resizing ? "none" : `width ${GNB_FOLD_MS}ms ease-out`,
|
|
14431
|
+
transition: resizing ? "none" : `width ${GNB_FOLD_MS}ms ease-out, margin-right ${GNB_FOLD_MS}ms ease-out, box-shadow ${GNB_FOLD_MS}ms ease-out`,
|
|
14330
14432
|
backgroundColor: C.panelBg,
|
|
14331
14433
|
borderRight: rightBorder,
|
|
14332
14434
|
...style
|
|
14333
14435
|
};
|
|
14334
14436
|
const hideAfterSlide = (hidden) => `visibility 0s linear ${hidden ? `${GNB_FOLD_MS}ms` : "0s"}`;
|
|
14437
|
+
const peekEdge = visuallyFolded ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
14438
|
+
"div",
|
|
14439
|
+
{
|
|
14440
|
+
"aria-hidden": true,
|
|
14441
|
+
"data-gnb-peek-edge": "",
|
|
14442
|
+
className: "absolute inset-y-0 left-0 z-[2]",
|
|
14443
|
+
style: { width: GNB_PEEK_EDGE_WIDTH },
|
|
14444
|
+
onPointerEnter: handlePeekEdgeEnter,
|
|
14445
|
+
onPointerLeave: handlePeekLeave
|
|
14446
|
+
}
|
|
14447
|
+
) : null;
|
|
14448
|
+
const rootPeekProps = {
|
|
14449
|
+
onPointerEnter: (event) => {
|
|
14450
|
+
onPointerEnterProp?.(event);
|
|
14451
|
+
if (!isFull) handlePeekEnter(event);
|
|
14452
|
+
},
|
|
14453
|
+
onPointerLeave: (event) => {
|
|
14454
|
+
onPointerLeaveProp?.(event);
|
|
14455
|
+
if (!isFull) handlePeekLeave();
|
|
14456
|
+
},
|
|
14457
|
+
onFocus: (event) => {
|
|
14458
|
+
onFocusProp?.(event);
|
|
14459
|
+
if (!isFull) handlePeekFocus(event);
|
|
14460
|
+
},
|
|
14461
|
+
onBlur: (event) => {
|
|
14462
|
+
onBlurProp?.(event);
|
|
14463
|
+
if (!isFull) handlePeekBlur(event);
|
|
14464
|
+
}
|
|
14465
|
+
};
|
|
14335
14466
|
const sideFoldStyle = railFolded ? {
|
|
14336
14467
|
opacity: 0,
|
|
14337
14468
|
position: "absolute",
|
|
@@ -14481,7 +14612,9 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
14481
14612
|
"data-header": header,
|
|
14482
14613
|
"data-color": color,
|
|
14483
14614
|
...rest,
|
|
14615
|
+
...rootPeekProps,
|
|
14484
14616
|
children: [
|
|
14617
|
+
!isFull && peekEdge,
|
|
14485
14618
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14486
14619
|
"div",
|
|
14487
14620
|
{
|
|
@@ -14516,19 +14649,33 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
|
|
|
14516
14649
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
14517
14650
|
"div",
|
|
14518
14651
|
{
|
|
14519
|
-
className: cn(
|
|
14520
|
-
|
|
14652
|
+
className: cn(
|
|
14653
|
+
"relative",
|
|
14654
|
+
(!isFull || !folded) && "overflow-hidden",
|
|
14655
|
+
!isFullFrame && "min-h-0 flex-1"
|
|
14656
|
+
),
|
|
14657
|
+
style: {
|
|
14658
|
+
...isFullFrame ? { gridArea: "nav" } : null,
|
|
14659
|
+
// 접힌 동안 띠와 펼쳐진 본문이 페이지 위에 서도록 이 칸을 올린다
|
|
14660
|
+
...isFull && folded ? { zIndex: GNB_PEEK_Z_INDEX } : null
|
|
14661
|
+
},
|
|
14521
14662
|
children: [
|
|
14663
|
+
isFull && peekEdge,
|
|
14522
14664
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
14523
14665
|
"div",
|
|
14524
14666
|
{
|
|
14525
14667
|
className: "flex h-full flex-row",
|
|
14526
14668
|
style: {
|
|
14527
14669
|
width: bodyWidth,
|
|
14528
|
-
transform:
|
|
14529
|
-
visibility:
|
|
14530
|
-
|
|
14670
|
+
transform: visuallyFolded ? "translateX(-100%)" : "none",
|
|
14671
|
+
visibility: visuallyFolded ? "hidden" : "visible",
|
|
14672
|
+
boxShadow: peekOverlay ? GNB_PEEK_SHADOW : "none",
|
|
14673
|
+
transition: `transform ${GNB_FOLD_MS}ms ease-out, box-shadow ${GNB_FOLD_MS}ms ease-out, ${hideAfterSlide(visuallyFolded)}`
|
|
14531
14674
|
},
|
|
14675
|
+
onPointerEnter: isFull ? handlePeekEnter : void 0,
|
|
14676
|
+
onPointerLeave: isFull ? handlePeekLeave : void 0,
|
|
14677
|
+
onFocus: isFull ? handlePeekFocus : void 0,
|
|
14678
|
+
onBlur: isFull ? handlePeekBlur : void 0,
|
|
14532
14679
|
children: [
|
|
14533
14680
|
showRail && // 레일 컬럼 — 스크롤되는 아이템 목록(nav)을 가운데 두고 위아래에 고정 슬롯(top/footer)을 붙인다.
|
|
14534
14681
|
// 두 슬롯은 내비게이션이 아니므로 nav(landmark) 밖에 두고, 컬럼 폭·구분선·배경은 이 래퍼가
|
|
@@ -17530,6 +17677,7 @@ function flattenOptions(options, depth = 1, inheritDisabled = true) {
|
|
|
17530
17677
|
out.push({
|
|
17531
17678
|
value: String(o.value),
|
|
17532
17679
|
label: o.label,
|
|
17680
|
+
tag: o.tag,
|
|
17533
17681
|
disabled: !!o.disabled || allChildrenDisabled,
|
|
17534
17682
|
depth,
|
|
17535
17683
|
isGroup: true,
|
|
@@ -17540,6 +17688,7 @@ function flattenOptions(options, depth = 1, inheritDisabled = true) {
|
|
|
17540
17688
|
out.push({
|
|
17541
17689
|
value: String(o.value),
|
|
17542
17690
|
label: o.label,
|
|
17691
|
+
tag: o.tag,
|
|
17543
17692
|
disabled: !!o.disabled,
|
|
17544
17693
|
depth,
|
|
17545
17694
|
isGroup: false,
|
|
@@ -17744,9 +17893,15 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
17744
17893
|
const effectiveDisabled = disabled || allOptionsDisabled;
|
|
17745
17894
|
const searchVisible = showSearch && (partialOptions || selectable.length >= SEARCH_THRESHOLD);
|
|
17746
17895
|
const labelByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.label])), [flat]);
|
|
17896
|
+
const tagByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.tag])), [flat]);
|
|
17747
17897
|
const rawByValue = react.useMemo(() => new Map(flat.map((o) => [o.value, o.raw])), [flat]);
|
|
17748
17898
|
const optionByValue = react.useMemo(
|
|
17749
|
-
() => new Map(
|
|
17899
|
+
() => new Map(
|
|
17900
|
+
flat.map((o) => [
|
|
17901
|
+
o.value,
|
|
17902
|
+
{ value: o.raw, label: o.label, ...o.tag && { tag: o.tag } }
|
|
17903
|
+
])
|
|
17904
|
+
),
|
|
17750
17905
|
[flat]
|
|
17751
17906
|
);
|
|
17752
17907
|
const selected = react.useMemo(() => {
|
|
@@ -17759,7 +17914,11 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
17759
17914
|
if (value == null) return map;
|
|
17760
17915
|
for (const v of Array.isArray(value) ? value : [value]) {
|
|
17761
17916
|
if (v != null && typeof v === "object") {
|
|
17762
|
-
map.set(String(v.value), {
|
|
17917
|
+
map.set(String(v.value), {
|
|
17918
|
+
value: v.value,
|
|
17919
|
+
label: v.label,
|
|
17920
|
+
...v.tag && { tag: v.tag }
|
|
17921
|
+
});
|
|
17763
17922
|
}
|
|
17764
17923
|
}
|
|
17765
17924
|
return map;
|
|
@@ -18100,6 +18259,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
18100
18259
|
});
|
|
18101
18260
|
}
|
|
18102
18261
|
}
|
|
18262
|
+
const tagSize = size === "md" ? "sm" : "xs";
|
|
18103
18263
|
const isPlaceholder = selected.length === 0;
|
|
18104
18264
|
const showTriggerSpinner = loading2 && !effectiveDisabled;
|
|
18105
18265
|
const showClear = clearable && !effectiveDisabled && !isPlaceholder;
|
|
@@ -18444,7 +18604,15 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
18444
18604
|
))
|
|
18445
18605
|
}
|
|
18446
18606
|
)
|
|
18447
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
18607
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
18608
|
+
TriggerLabel,
|
|
18609
|
+
{
|
|
18610
|
+
label: triggerText,
|
|
18611
|
+
tag: multi ? void 0 : tagByValue.get(selected[0]) ?? valueOptions.get(selected[0])?.tag,
|
|
18612
|
+
tagSize,
|
|
18613
|
+
tagDisabled: effectiveDisabled
|
|
18614
|
+
}
|
|
18615
|
+
),
|
|
18448
18616
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-[8px]", children: [
|
|
18449
18617
|
showClear && /* @__PURE__ */ jsxRuntime.jsx(TriggerRemoveButton, { ariaLabel: t.clear, onRemove: handleClear }),
|
|
18450
18618
|
showTriggerSpinner ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "inline-flex shrink-0", "data-select-trigger-spinner": true, children: /* @__PURE__ */ jsxRuntime.jsx(SCircleProgress, { indeterminate: true, type: "neutral", size: 12 }) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -18537,6 +18705,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
18537
18705
|
hasItems ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
18538
18706
|
ItemList,
|
|
18539
18707
|
{
|
|
18708
|
+
tagSize,
|
|
18540
18709
|
listboxId,
|
|
18541
18710
|
activeOptionId,
|
|
18542
18711
|
items: visibleItems,
|
|
@@ -18594,6 +18763,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
|
|
|
18594
18763
|
});
|
|
18595
18764
|
var SSelect2 = /* @__PURE__ */ withDisplayName(SSelectImpl, "SSelect");
|
|
18596
18765
|
function ItemList({
|
|
18766
|
+
tagSize,
|
|
18597
18767
|
listboxId,
|
|
18598
18768
|
activeOptionId,
|
|
18599
18769
|
items,
|
|
@@ -18776,6 +18946,9 @@ function ItemList({
|
|
|
18776
18946
|
OptionLabel,
|
|
18777
18947
|
{
|
|
18778
18948
|
label: o.label,
|
|
18949
|
+
tag: o.tag,
|
|
18950
|
+
tagSize,
|
|
18951
|
+
tagDisabled: rowDisabled,
|
|
18779
18952
|
className: treeLabelClass("sm", {
|
|
18780
18953
|
// 고른 줄은 굵게 — multi_tree 는 일부만 고른 그룹도 굵다 (STree 와 같다)
|
|
18781
18954
|
emphasized: checkState !== false,
|
|
@@ -18910,7 +19083,16 @@ function ItemList({
|
|
|
18910
19083
|
focused: focusedValue === o.value
|
|
18911
19084
|
}
|
|
18912
19085
|
),
|
|
18913
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19086
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19087
|
+
OptionLabel,
|
|
19088
|
+
{
|
|
19089
|
+
label: o.label,
|
|
19090
|
+
tag: o.tag,
|
|
19091
|
+
tagSize,
|
|
19092
|
+
tagDisabled: o.disabled,
|
|
19093
|
+
className: "flex-1 truncate"
|
|
19094
|
+
}
|
|
19095
|
+
)
|
|
18914
19096
|
]
|
|
18915
19097
|
},
|
|
18916
19098
|
rowKey
|
|
@@ -18942,11 +19124,52 @@ function TreeRowsMotion({ opening, children }) {
|
|
|
18942
19124
|
react.useEffect(() => () => animationRef.current?.cancel(), []);
|
|
18943
19125
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: "overflow-hidden", "aria-hidden": opening ? void 0 : true, children });
|
|
18944
19126
|
}
|
|
18945
|
-
function OptionLabel({
|
|
19127
|
+
function OptionLabel({
|
|
19128
|
+
label,
|
|
19129
|
+
tag,
|
|
19130
|
+
tagSize,
|
|
19131
|
+
tagDisabled,
|
|
19132
|
+
className
|
|
19133
|
+
}) {
|
|
19134
|
+
if (tag) {
|
|
19135
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19136
|
+
"span",
|
|
19137
|
+
{
|
|
19138
|
+
className: cn(
|
|
19139
|
+
className,
|
|
19140
|
+
"min-w-0 overflow-hidden",
|
|
19141
|
+
tagDisabled && "opacity-(--opacity-050)"
|
|
19142
|
+
),
|
|
19143
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
19144
|
+
STag,
|
|
19145
|
+
{
|
|
19146
|
+
...tag,
|
|
19147
|
+
size: tagSize,
|
|
19148
|
+
label: isHtmlLabel(label) ? extractText(label) : label,
|
|
19149
|
+
className: cn("max-w-full min-w-0", tag.className)
|
|
19150
|
+
}
|
|
19151
|
+
)
|
|
19152
|
+
}
|
|
19153
|
+
);
|
|
19154
|
+
}
|
|
18946
19155
|
return isHtmlLabel(label) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className, dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(label) } }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: label });
|
|
18947
19156
|
}
|
|
18948
|
-
function TriggerLabel({
|
|
18949
|
-
|
|
19157
|
+
function TriggerLabel({
|
|
19158
|
+
label,
|
|
19159
|
+
tag,
|
|
19160
|
+
tagSize,
|
|
19161
|
+
tagDisabled
|
|
19162
|
+
}) {
|
|
19163
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19164
|
+
OptionLabel,
|
|
19165
|
+
{
|
|
19166
|
+
label,
|
|
19167
|
+
tag,
|
|
19168
|
+
tagSize,
|
|
19169
|
+
tagDisabled,
|
|
19170
|
+
className: "truncate"
|
|
19171
|
+
}
|
|
19172
|
+
);
|
|
18950
19173
|
}
|
|
18951
19174
|
function TriggerRemoveButton({ ariaLabel, onRemove }) {
|
|
18952
19175
|
return /* @__PURE__ */ jsxRuntime.jsx(
|