@bigtablet/design-system 3.19.0 → 3.19.2

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/index.css CHANGED
@@ -1068,6 +1068,10 @@ body:has(.bottom_nav) {
1068
1068
  border-radius: 12px;
1069
1069
  box-shadow: var(--bt-elevation-level2);
1070
1070
  padding: 4px 0;
1071
+ box-sizing: border-box;
1072
+ overflow-y: auto;
1073
+ scrollbar-width: thin;
1074
+ scrollbar-color: var(--bt-color-border-hover) transparent;
1071
1075
  will-change: transform, opacity;
1072
1076
  }
1073
1077
  [data-theme=dark] .menu {
@@ -1882,6 +1886,9 @@ body:has(.bottom_nav) {
1882
1886
  box-sizing: border-box;
1883
1887
  min-width: min(200px, 100%);
1884
1888
  max-width: min(320px, 100%);
1889
+ overflow-y: auto;
1890
+ scrollbar-width: thin;
1891
+ scrollbar-color: var(--bt-color-border-hover) transparent;
1885
1892
  color: var(--bt-color-text-body);
1886
1893
  font-size: 14px;
1887
1894
  font-weight: 400;
@@ -1929,6 +1936,10 @@ body:has(.bottom_nav) {
1929
1936
  }
1930
1937
  .tooltip {
1931
1938
  display: block;
1939
+ box-sizing: border-box;
1940
+ overflow-y: auto;
1941
+ scrollbar-width: thin;
1942
+ scrollbar-color: var(--bt-color-border-hover) transparent;
1932
1943
  background: var(--bt-color-accent-strong);
1933
1944
  color: var(--bt-color-accent-on-surface);
1934
1945
  padding: 6px 10px;
@@ -2395,6 +2406,12 @@ body:has(.bottom_nav) {
2395
2406
  .field_label_row .field_label {
2396
2407
  margin-right: auto;
2397
2408
  }
2409
+ .field_label_action {
2410
+ display: flex;
2411
+ flex-shrink: 0;
2412
+ align-items: center;
2413
+ height: 18px;
2414
+ }
2398
2415
  .field_required {
2399
2416
  margin-left: 2px;
2400
2417
  color: var(--bt-color-status-error-on-surface);
@@ -4777,6 +4794,8 @@ body:has(.bottom_nav) {
4777
4794
  position: fixed;
4778
4795
  z-index: 1000;
4779
4796
  box-sizing: border-box;
4797
+ display: flex;
4798
+ flex-direction: column;
4780
4799
  width: max-content;
4781
4800
  background: var(--bt-color-bg-solid);
4782
4801
  border: 1px solid var(--bt-color-border-default);
@@ -4794,6 +4813,7 @@ body:has(.bottom_nav) {
4794
4813
  }
4795
4814
  .combobox_list {
4796
4815
  max-height: 18rem;
4816
+ min-height: 0;
4797
4817
  overflow-y: auto;
4798
4818
  scrollbar-width: thin;
4799
4819
  scrollbar-color: var(--bt-color-border-hover) transparent;
@@ -5023,6 +5043,8 @@ body:has(.bottom_nav) {
5023
5043
  position: fixed;
5024
5044
  z-index: 1000;
5025
5045
  box-sizing: border-box;
5046
+ display: flex;
5047
+ flex-direction: column;
5026
5048
  width: max-content;
5027
5049
  background: var(--bt-color-bg-solid);
5028
5050
  border: 1px solid var(--bt-color-border-default);
@@ -5078,6 +5100,7 @@ body:has(.bottom_nav) {
5078
5100
  }
5079
5101
  .dropdown_options {
5080
5102
  max-height: 18rem;
5103
+ min-height: 0;
5081
5104
  overflow-y: auto;
5082
5105
  scrollbar-width: thin;
5083
5106
  scrollbar-color: var(--bt-color-border-hover) transparent;
package/dist/index.d.ts CHANGED
@@ -181,6 +181,11 @@ interface UseListboxPopupResult {
181
181
  * 이 값으로 좌표를 잡는데 패널 폭을 트리거 폭으로 두면 오른쪽이 잘린다.
182
182
  */
183
183
  maxWidth: number;
184
+ /**
185
+ * 배치된 방향의 가용 높이 상한(px). 목록이 길고 뷰포트가 낮으면 이걸 안 걸었을 때
186
+ * 패널이 화면 밖으로 나간다(#621).
187
+ */
188
+ maxHeight: number;
184
189
  /** 최초 측정 전에는 false - 이때 숨겨 (0,0) 깜빡임을 막는다 */
185
190
  ready: boolean;
186
191
  };
package/dist/index.js CHANGED
@@ -254,6 +254,22 @@ var mainAxisStart = (side, anchor, floating, gap) => {
254
254
  return anchor.left + anchor.width + gap;
255
255
  }
256
256
  };
257
+ var mainAxisSpace = (side, anchor, viewport, gap, padding) => {
258
+ const top = clamp(anchor.top, 0, viewport.height);
259
+ const bottom = clamp(anchor.top + anchor.height, 0, viewport.height);
260
+ const left = clamp(anchor.left, 0, viewport.width);
261
+ const right = clamp(anchor.left + anchor.width, 0, viewport.width);
262
+ switch (side) {
263
+ case "top":
264
+ return top - gap - padding;
265
+ case "bottom":
266
+ return viewport.height - bottom - gap - padding;
267
+ case "left":
268
+ return left - gap - padding;
269
+ case "right":
270
+ return viewport.width - right - gap - padding;
271
+ }
272
+ };
257
273
  var fitsMainAxis = (side, anchor, floating, viewport, gap, padding) => {
258
274
  const start = mainAxisStart(side, anchor, floating, gap);
259
275
  switch (side) {
@@ -277,9 +293,14 @@ function computeAnchoredPosition(anchor, floating, viewport, options) {
277
293
  height: floating.height
278
294
  };
279
295
  let side = options.placement;
280
- if (!fitsMainAxis(side, anchor, sized, viewport, gap, padding) && fitsMainAxis(OPPOSITE[side], anchor, sized, viewport, gap, padding)) {
281
- side = OPPOSITE[side];
296
+ if (!fitsMainAxis(side, anchor, sized, viewport, gap, padding)) {
297
+ const opposite = OPPOSITE[side];
298
+ if (fitsMainAxis(opposite, anchor, sized, viewport, gap, padding) || mainAxisSpace(opposite, anchor, viewport, gap, padding) > mainAxisSpace(side, anchor, viewport, gap, padding)) {
299
+ side = opposite;
300
+ }
282
301
  }
302
+ const maxHeight = isVertical(side) ? Math.max(mainAxisSpace(side, anchor, viewport, gap, padding), 0) : viewport.height - padding * 2;
303
+ sized.height = Math.min(sized.height, maxHeight);
283
304
  const align = options.align ?? "center";
284
305
  let x;
285
306
  let y;
@@ -287,12 +308,14 @@ function computeAnchoredPosition(anchor, floating, viewport, options) {
287
308
  y = mainAxisStart(side, anchor, sized, gap);
288
309
  x = align === "start" ? anchor.left : align === "end" ? anchor.left + anchor.width - sized.width : anchor.left + anchor.width / 2 - sized.width / 2;
289
310
  x = clamp(x, padding, viewport.width - padding - sized.width);
311
+ y = clamp(y, padding, viewport.height - padding - floating.height);
290
312
  } else {
291
313
  x = mainAxisStart(side, anchor, sized, gap);
292
314
  y = align === "start" ? anchor.top : align === "end" ? anchor.top + anchor.height - sized.height : anchor.top + anchor.height / 2 - sized.height / 2;
293
315
  y = clamp(y, padding, viewport.height - padding - sized.height);
316
+ x = clamp(x, padding, viewport.width - padding - floating.width);
294
317
  }
295
- return { x, y, placement: side, maxWidth };
318
+ return { x, y, placement: side, maxWidth, maxHeight };
296
319
  }
297
320
  function useAnchoredPosition({
298
321
  open,
@@ -308,6 +331,7 @@ function useAnchoredPosition({
308
331
  y: 0,
309
332
  placement,
310
333
  maxWidth: 0,
334
+ maxHeight: 0,
311
335
  ready: false,
312
336
  anchorWidth: 0
313
337
  });
@@ -670,6 +694,7 @@ function useListboxPopup({
670
694
  y: anchored.y,
671
695
  width: anchored.anchorWidth,
672
696
  maxWidth: anchored.maxWidth,
697
+ maxHeight: anchored.maxHeight,
673
698
  ready: anchored.ready
674
699
  },
675
700
  activeIndex,
@@ -1346,6 +1371,9 @@ var Menu = ({ items, trigger, align = "start" }) => {
1346
1371
  position: "fixed",
1347
1372
  left: pos.x,
1348
1373
  top: pos.y,
1374
+ // 배치된 방향에 남은 높이. 항목이 많은 메뉴가 낮은 뷰포트에서 화면 밖으로
1375
+ // 나가지 않게 한다(#621). 넘치는 만큼은 메뉴 안에서 스크롤한다.
1376
+ maxHeight: pos.ready ? pos.maxHeight : void 0,
1349
1377
  visibility: pos.ready ? void 0 : "hidden"
1350
1378
  },
1351
1379
  className: cn("menu", `menu_align_${align}`),
@@ -2016,7 +2044,7 @@ var Popover = ({
2016
2044
  tabIndex: -1,
2017
2045
  "aria-label": ariaLabel,
2018
2046
  "aria-labelledby": ariaLabelledby,
2019
- style,
2047
+ style: { ...style, maxHeight: pos.ready ? pos.maxHeight : void 0 },
2020
2048
  className: cn("popover", className),
2021
2049
  children: content
2022
2050
  }
@@ -2132,7 +2160,16 @@ var Tooltip = ({
2132
2160
  },
2133
2161
  onMouseEnter: cancelHide,
2134
2162
  onMouseLeave: hide,
2135
- children: /* @__PURE__ */ jsx(animated.span, { id: tooltipId, role: "tooltip", style, className: "tooltip", children: content })
2163
+ children: /* @__PURE__ */ jsx(
2164
+ animated.span,
2165
+ {
2166
+ id: tooltipId,
2167
+ role: "tooltip",
2168
+ style: { ...style, maxHeight: pos.ready ? pos.maxHeight : void 0 },
2169
+ className: "tooltip",
2170
+ children: content
2171
+ }
2172
+ )
2136
2173
  }
2137
2174
  ),
2138
2175
  document.body
@@ -2879,7 +2916,7 @@ var Field = ({
2879
2916
  return /* @__PURE__ */ jsxs("div", { className: cn("field", !!error && "field_error", className), ...props, children: [
2880
2917
  labelAction ? /* @__PURE__ */ jsxs("div", { className: "field_label_row", children: [
2881
2918
  labelElement,
2882
- labelAction
2919
+ /* @__PURE__ */ jsx("span", { className: "field_label_action", children: labelAction })
2883
2920
  ] }) : labelElement,
2884
2921
  /* @__PURE__ */ jsx(FieldContext.Provider, { value: control, children }),
2885
2922
  showHelp && /* @__PURE__ */ jsx("div", { id: helpId, className: "field_help", children: help }),
@@ -4303,6 +4340,8 @@ var Combobox = ({
4303
4340
  minWidth: popup.position.width || void 0,
4304
4341
  // 트리거가 뷰포트보다 넓으면 좌표만 줄어들고 패널은 그대로 넘친다.
4305
4342
  maxWidth: popup.position.ready ? popup.position.maxWidth : void 0,
4343
+ // 배치된 방향에 남은 높이 - Dropdown 과 같은 이유(#621).
4344
+ maxHeight: popup.position.ready ? popup.position.maxHeight : void 0,
4306
4345
  visibility: popup.position.ready ? void 0 : "hidden"
4307
4346
  },
4308
4347
  children: !hasList ? /* @__PURE__ */ jsx("p", { className: "combobox_message", role: "status", children: showIdle ? idleMessage : emptyMessage }) : /* @__PURE__ */ jsx(
@@ -4526,6 +4565,9 @@ var Dropdown = (props) => {
4526
4565
  minWidth: position.width || void 0,
4527
4566
  // 트리거가 뷰포트보다 넓으면 좌표만 줄어들고 패널은 그대로 넘친다.
4528
4567
  maxWidth: position.ready ? position.maxWidth : void 0,
4568
+ // 배치된 방향에 남은 높이. 안 걸면 긴 목록이 낮은 뷰포트에서 화면 밖으로
4569
+ // 나간다(#621). 패널이 세로 flex 라 목록이 이 안에서 줄고 스크롤한다.
4570
+ maxHeight: position.ready ? position.maxHeight : void 0,
4529
4571
  // 최초 측정 전에는 숨긴다 - (0,0) 에서 한 프레임 깜빡이는 것을 막는다.
4530
4572
  visibility: position.ready ? void 0 : "hidden"
4531
4573
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigtablet/design-system",
3
- "version": "3.19.0",
3
+ "version": "3.19.2",
4
4
  "description": "Bigtablet Design System UI Components",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",