@x-plat/design-system 0.14.2 → 0.14.4

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.
Files changed (74) hide show
  1. package/dist/components/AutoResizeTextArea/index.d.cts +1 -1
  2. package/dist/components/AutoResizeTextArea/index.d.ts +1 -1
  3. package/dist/components/Badge/index.d.cts +1 -1
  4. package/dist/components/Badge/index.d.ts +1 -1
  5. package/dist/components/ChatInput/index.d.cts +1 -1
  6. package/dist/components/ChatInput/index.d.ts +1 -1
  7. package/dist/components/CheckBox/index.cjs +3 -3
  8. package/dist/components/CheckBox/index.d.cts +2 -2
  9. package/dist/components/CheckBox/index.d.ts +2 -2
  10. package/dist/components/CheckBox/index.js +3 -3
  11. package/dist/components/DatePicker/index.d.cts +1 -1
  12. package/dist/components/DatePicker/index.d.ts +1 -1
  13. package/dist/components/Dropdown/index.cjs +16 -13
  14. package/dist/components/Dropdown/index.css +3 -1
  15. package/dist/components/Dropdown/index.js +16 -13
  16. package/dist/components/FieldMessage/index.d.cts +1 -1
  17. package/dist/components/FieldMessage/index.d.ts +1 -1
  18. package/dist/components/FileUpload/index.d.cts +1 -1
  19. package/dist/components/FileUpload/index.d.ts +1 -1
  20. package/dist/components/ImageSelector/index.d.cts +1 -1
  21. package/dist/components/ImageSelector/index.d.ts +1 -1
  22. package/dist/components/Input/index.d.cts +1 -1
  23. package/dist/components/Input/index.d.ts +1 -1
  24. package/dist/components/NotificationBadge/index.d.cts +1 -1
  25. package/dist/components/NotificationBadge/index.d.ts +1 -1
  26. package/dist/components/Pagination/index.d.cts +1 -1
  27. package/dist/components/Pagination/index.d.ts +1 -1
  28. package/dist/components/PopOver/index.cjs +15 -14
  29. package/dist/components/PopOver/index.css +3 -1
  30. package/dist/components/PopOver/index.js +15 -14
  31. package/dist/components/Progress/index.d.cts +1 -1
  32. package/dist/components/Progress/index.d.ts +1 -1
  33. package/dist/components/Radio/index.d.cts +2 -2
  34. package/dist/components/Radio/index.d.ts +2 -2
  35. package/dist/components/Select/index.cjs +16 -12
  36. package/dist/components/Select/index.css +1 -1
  37. package/dist/components/Select/index.d.cts +1 -1
  38. package/dist/components/Select/index.d.ts +1 -1
  39. package/dist/components/Select/index.js +16 -12
  40. package/dist/components/Spinner/index.d.cts +1 -1
  41. package/dist/components/Spinner/index.d.ts +1 -1
  42. package/dist/components/Stat/index.d.cts +1 -1
  43. package/dist/components/Stat/index.d.ts +1 -1
  44. package/dist/components/Steps/index.d.cts +1 -1
  45. package/dist/components/Steps/index.d.ts +1 -1
  46. package/dist/components/Switch/index.d.cts +2 -2
  47. package/dist/components/Switch/index.d.ts +2 -2
  48. package/dist/components/TextArea/index.d.cts +1 -1
  49. package/dist/components/TextArea/index.d.ts +1 -1
  50. package/dist/components/TimePicker/index.cjs +17 -13
  51. package/dist/components/TimePicker/index.css +3 -1
  52. package/dist/components/TimePicker/index.d.cts +1 -1
  53. package/dist/components/TimePicker/index.d.ts +1 -1
  54. package/dist/components/TimePicker/index.js +17 -13
  55. package/dist/components/index.cjs +22 -22
  56. package/dist/components/index.css +4 -4
  57. package/dist/components/index.d.cts +2 -2
  58. package/dist/components/index.d.ts +2 -2
  59. package/dist/components/index.js +22 -22
  60. package/dist/index.cjs +24 -22
  61. package/dist/index.css +4 -4
  62. package/dist/index.d.cts +3 -3
  63. package/dist/index.d.ts +3 -3
  64. package/dist/index.js +23 -22
  65. package/dist/{status-njWqQWFV.d.cts → status-C70BBv2S.d.cts} +3 -1
  66. package/dist/{status-njWqQWFV.d.ts → status-C70BBv2S.d.ts} +3 -1
  67. package/dist/tokens/index.cjs +5 -0
  68. package/dist/tokens/index.d.cts +3 -0
  69. package/dist/tokens/index.d.ts +3 -0
  70. package/dist/tokens/index.js +4 -0
  71. package/dist/{validation-Dqo1zqhT.d.cts → validation-BYpAI6Ct.d.cts} +1 -1
  72. package/dist/{validation-Dqo1zqhT.d.ts → validation-BYpAI6Ct.d.ts} +1 -1
  73. package/guidelines/MIGRATION.md +50 -1
  74. package/package.json +1 -1
@@ -2889,12 +2889,12 @@ var ChatInput_default = ChatInput;
2889
2889
  // src/tokens/colors.ts
2890
2890
  import { semantic } from "@x-plat/tokens-core";
2891
2891
 
2892
- // src/tokens/index.ts
2893
- import { cssVar } from "@x-plat/tokens-core";
2894
-
2895
2892
  // src/tokens/interface/status.ts
2896
2893
  var normalizeStatus = (value) => value === "brand" ? "primary" : value;
2897
2894
 
2895
+ // src/tokens/index.ts
2896
+ import { cssVar } from "@x-plat/tokens-core";
2897
+
2898
2898
  // src/components/CheckBox/CheckBox.tsx
2899
2899
  import { jsx as jsx309, jsxs as jsxs198 } from "react/jsx-runtime";
2900
2900
  var CheckBox = (props) => {
@@ -3874,23 +3874,22 @@ var Portal_default = Portal;
3874
3874
  // src/tokens/hooks/useAutoPosition.ts
3875
3875
  import React19 from "react";
3876
3876
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3877
- const [position, setPosition] = React19.useState({
3878
- position: {},
3879
- direction: "bottom"
3880
- });
3877
+ const [direction, setDirection] = React19.useState("bottom");
3878
+ const directionRef = React19.useRef("bottom");
3881
3879
  const calculatePosition = React19.useCallback(() => {
3882
- if (!triggerRef.current || !popRef.current) return;
3880
+ const pop = popRef.current;
3881
+ if (!triggerRef.current || !pop) return;
3883
3882
  const triggerRect = triggerRef.current.getBoundingClientRect();
3884
- const popW = popRef.current.offsetWidth;
3885
- const popH = popRef.current.offsetHeight;
3883
+ const popW = pop.offsetWidth;
3884
+ const popH = pop.offsetHeight;
3886
3885
  const viewportHeight = window.innerHeight;
3887
3886
  const viewportWidth = window.innerWidth;
3888
3887
  if (popH === 0 || popW === 0) return;
3889
- let direction = "bottom";
3888
+ let next = "bottom";
3890
3889
  let top;
3891
3890
  let left;
3892
3891
  if (triggerRect.bottom + popH > viewportHeight && triggerRect.top - popH > 0) {
3893
- direction = "top";
3892
+ next = "top";
3894
3893
  top = triggerRect.top - popH;
3895
3894
  } else {
3896
3895
  top = triggerRect.bottom;
@@ -3900,7 +3899,12 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3900
3899
  left = triggerRect.right - popW;
3901
3900
  }
3902
3901
  if (left < 8) left = 8;
3903
- setPosition({ position: { top, left }, direction });
3902
+ pop.style.top = `${top + window.scrollY}px`;
3903
+ pop.style.left = `${left + window.scrollX}px`;
3904
+ if (next !== directionRef.current) {
3905
+ directionRef.current = next;
3906
+ setDirection(next);
3907
+ }
3904
3908
  }, [triggerRef, popRef]);
3905
3909
  React19.useLayoutEffect(() => {
3906
3910
  if (!enabled) return;
@@ -3931,7 +3935,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3931
3935
  window.removeEventListener("scroll", onScrollOrResize, true);
3932
3936
  };
3933
3937
  }, [calculatePosition, enabled]);
3934
- return position;
3938
+ return { direction };
3935
3939
  };
3936
3940
  var useAutoPosition_default = useAutoPosition;
3937
3941
 
@@ -3969,7 +3973,7 @@ var Dropdown = (props) => {
3969
3973
  const [visible, setVisible] = React21.useState(false);
3970
3974
  const triggerRef = React21.useRef(null);
3971
3975
  const menuRef = React21.useRef(null);
3972
- const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
3976
+ const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
3973
3977
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
3974
3978
  useEscapeKey(isOpen, () => {
3975
3979
  setIsOpen(false);
@@ -4005,7 +4009,6 @@ var Dropdown = (props) => {
4005
4009
  {
4006
4010
  ref: menuRef,
4007
4011
  className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
4008
- style: { top: position.top, left: position.left },
4009
4012
  role: "menu",
4010
4013
  children: items.map((item) => /* @__PURE__ */ jsx322(
4011
4014
  "button",
@@ -5939,9 +5942,6 @@ var PopOver = (props) => {
5939
5942
  eventTrigger && "visible"
5940
5943
  ),
5941
5944
  ref: popRef,
5942
- style: {
5943
- ...position.position
5944
- },
5945
5945
  children: PopOverEl
5946
5946
  }
5947
5947
  ) })
@@ -6284,7 +6284,7 @@ var SelectRoot = (props) => {
6284
6284
  {
6285
6285
  className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
6286
6286
  ref: contentRef,
6287
- style: { ...position.position, width: triggerRef.current?.offsetWidth },
6287
+ style: { width: triggerRef.current?.offsetWidth },
6288
6288
  role: "listbox",
6289
6289
  children: [
6290
6290
  searchable && /* @__PURE__ */ jsx337("div", { className: "select-search", children: /* @__PURE__ */ jsx337(
@@ -7129,7 +7129,7 @@ var TimePicker = (props) => {
7129
7129
  close();
7130
7130
  triggerRef.current?.focus({ preventScroll: true });
7131
7131
  });
7132
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
7132
+ useAutoPosition_default(triggerRef, contentRef, mounted);
7133
7133
  React40.useEffect(() => {
7134
7134
  if (disabled && isOpen) setOpen(false);
7135
7135
  }, [disabled, isOpen]);
@@ -7176,7 +7176,7 @@ var TimePicker = (props) => {
7176
7176
  {
7177
7177
  ref: contentRef,
7178
7178
  className: clsx_default("lib-xplat-time-picker-content", size, visible ? "enter" : "exit"),
7179
- style: { ...position.position, width: triggerRef.current?.offsetWidth },
7179
+ style: { width: triggerRef.current?.offsetWidth },
7180
7180
  role: "listbox",
7181
7181
  children: options.map((t) => /* @__PURE__ */ jsx351(
7182
7182
  "div",
package/dist/index.cjs CHANGED
@@ -401,6 +401,7 @@ __export(index_exports, {
401
401
  hasError: () => hasError,
402
402
  isInRange: () => isInRange,
403
403
  isSameDay: () => isSameDay,
404
+ normalizeStatus: () => normalizeStatus,
404
405
  semantic: () => import_tokens_core.semantic,
405
406
  useCalendar: () => useCalendar,
406
407
  useSideBarContext: () => useSideBarContext,
@@ -7402,12 +7403,12 @@ var gridColumns = {
7402
7403
  // src/tokens/colors.ts
7403
7404
  var import_tokens_core = require("@x-plat/tokens-core");
7404
7405
 
7405
- // src/tokens/index.ts
7406
- var import_tokens_core2 = require("@x-plat/tokens-core");
7407
-
7408
7406
  // src/tokens/interface/status.ts
7409
7407
  var normalizeStatus = (value) => value === "brand" ? "primary" : value;
7410
7408
 
7409
+ // src/tokens/index.ts
7410
+ var import_tokens_core2 = require("@x-plat/tokens-core");
7411
+
7411
7412
  // src/components/CheckBox/CheckBox.tsx
7412
7413
  var import_jsx_runtime309 = require("react/jsx-runtime");
7413
7414
  var CheckBox = (props) => {
@@ -8387,23 +8388,22 @@ var Portal_default = Portal;
8387
8388
  // src/tokens/hooks/useAutoPosition.ts
8388
8389
  var import_react19 = __toESM(require("react"), 1);
8389
8390
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
8390
- const [position, setPosition] = import_react19.default.useState({
8391
- position: {},
8392
- direction: "bottom"
8393
- });
8391
+ const [direction, setDirection] = import_react19.default.useState("bottom");
8392
+ const directionRef = import_react19.default.useRef("bottom");
8394
8393
  const calculatePosition = import_react19.default.useCallback(() => {
8395
- if (!triggerRef.current || !popRef.current) return;
8394
+ const pop = popRef.current;
8395
+ if (!triggerRef.current || !pop) return;
8396
8396
  const triggerRect = triggerRef.current.getBoundingClientRect();
8397
- const popW = popRef.current.offsetWidth;
8398
- const popH = popRef.current.offsetHeight;
8397
+ const popW = pop.offsetWidth;
8398
+ const popH = pop.offsetHeight;
8399
8399
  const viewportHeight = window.innerHeight;
8400
8400
  const viewportWidth = window.innerWidth;
8401
8401
  if (popH === 0 || popW === 0) return;
8402
- let direction = "bottom";
8402
+ let next = "bottom";
8403
8403
  let top;
8404
8404
  let left;
8405
8405
  if (triggerRect.bottom + popH > viewportHeight && triggerRect.top - popH > 0) {
8406
- direction = "top";
8406
+ next = "top";
8407
8407
  top = triggerRect.top - popH;
8408
8408
  } else {
8409
8409
  top = triggerRect.bottom;
@@ -8413,7 +8413,12 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
8413
8413
  left = triggerRect.right - popW;
8414
8414
  }
8415
8415
  if (left < 8) left = 8;
8416
- setPosition({ position: { top, left }, direction });
8416
+ pop.style.top = `${top + window.scrollY}px`;
8417
+ pop.style.left = `${left + window.scrollX}px`;
8418
+ if (next !== directionRef.current) {
8419
+ directionRef.current = next;
8420
+ setDirection(next);
8421
+ }
8417
8422
  }, [triggerRef, popRef]);
8418
8423
  import_react19.default.useLayoutEffect(() => {
8419
8424
  if (!enabled) return;
@@ -8444,7 +8449,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
8444
8449
  window.removeEventListener("scroll", onScrollOrResize, true);
8445
8450
  };
8446
8451
  }, [calculatePosition, enabled]);
8447
- return position;
8452
+ return { direction };
8448
8453
  };
8449
8454
  var useAutoPosition_default = useAutoPosition;
8450
8455
 
@@ -8482,7 +8487,7 @@ var Dropdown = (props) => {
8482
8487
  const [visible, setVisible] = import_react21.default.useState(false);
8483
8488
  const triggerRef = import_react21.default.useRef(null);
8484
8489
  const menuRef = import_react21.default.useRef(null);
8485
- const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
8490
+ const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
8486
8491
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
8487
8492
  useEscapeKey(isOpen, () => {
8488
8493
  setIsOpen(false);
@@ -8518,7 +8523,6 @@ var Dropdown = (props) => {
8518
8523
  {
8519
8524
  ref: menuRef,
8520
8525
  className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
8521
- style: { top: position.top, left: position.left },
8522
8526
  role: "menu",
8523
8527
  children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime322.jsx)(
8524
8528
  "button",
@@ -10452,9 +10456,6 @@ var PopOver = (props) => {
10452
10456
  eventTrigger && "visible"
10453
10457
  ),
10454
10458
  ref: popRef,
10455
- style: {
10456
- ...position.position
10457
- },
10458
10459
  children: PopOverEl
10459
10460
  }
10460
10461
  ) })
@@ -10797,7 +10798,7 @@ var SelectRoot = (props) => {
10797
10798
  {
10798
10799
  className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
10799
10800
  ref: contentRef,
10800
- style: { ...position.position, width: triggerRef.current?.offsetWidth },
10801
+ style: { width: triggerRef.current?.offsetWidth },
10801
10802
  role: "listbox",
10802
10803
  children: [
10803
10804
  searchable && /* @__PURE__ */ (0, import_jsx_runtime337.jsx)("div", { className: "select-search", children: /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(
@@ -11642,7 +11643,7 @@ var TimePicker = (props) => {
11642
11643
  close();
11643
11644
  triggerRef.current?.focus({ preventScroll: true });
11644
11645
  });
11645
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
11646
+ useAutoPosition_default(triggerRef, contentRef, mounted);
11646
11647
  import_react40.default.useEffect(() => {
11647
11648
  if (disabled && isOpen) setOpen(false);
11648
11649
  }, [disabled, isOpen]);
@@ -11689,7 +11690,7 @@ var TimePicker = (props) => {
11689
11690
  {
11690
11691
  ref: contentRef,
11691
11692
  className: clsx_default("lib-xplat-time-picker-content", size, visible ? "enter" : "exit"),
11692
- style: { ...position.position, width: triggerRef.current?.offsetWidth },
11693
+ style: { width: triggerRef.current?.offsetWidth },
11693
11694
  role: "listbox",
11694
11695
  children: options.map((t) => /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
11695
11696
  "div",
@@ -12841,6 +12842,7 @@ var SideBar_default = SideBar;
12841
12842
  hasError,
12842
12843
  isInRange,
12843
12844
  isSameDay,
12845
+ normalizeStatus,
12844
12846
  semantic,
12845
12847
  useCalendar,
12846
12848
  useSideBarContext,
package/dist/index.css CHANGED
@@ -3273,7 +3273,7 @@
3273
3273
  cursor: pointer;
3274
3274
  }
3275
3275
  .lib-xplat-dropdown-menu {
3276
- position: fixed;
3276
+ position: absolute;
3277
3277
  z-index: 1000;
3278
3278
  min-width: 160px;
3279
3279
  background: var(--semantic-surface-neutral-primary);
@@ -4160,7 +4160,7 @@
4160
4160
  user-select: none;
4161
4161
  }
4162
4162
  .lib-xplat-pop-over-content {
4163
- position: fixed;
4163
+ position: absolute;
4164
4164
  z-index: 1000;
4165
4165
  cursor: default;
4166
4166
  transition: transform 0.2s ease, opacity 0.2s ease;
@@ -4500,7 +4500,7 @@
4500
4500
  letter-spacing: var(--semantic-typo-label-2-m-ls);
4501
4501
  }
4502
4502
  .lib-xplat-select-content {
4503
- position: fixed;
4503
+ position: absolute;
4504
4504
  z-index: 1000;
4505
4505
  padding: var(--spacing-space-1) 0;
4506
4506
  border-radius: var(--spacing-radius-md);
@@ -5620,7 +5620,7 @@
5620
5620
  color: var(--semantic-text-disabled);
5621
5621
  }
5622
5622
  .lib-xplat-time-picker-content {
5623
- position: fixed;
5623
+ position: absolute;
5624
5624
  z-index: 1000;
5625
5625
  max-height: 220px;
5626
5626
  overflow-y: auto;
package/dist/index.d.cts CHANGED
@@ -56,9 +56,9 @@ export { Header } from './layout/Header/index.cjs';
56
56
  export { Layout } from './layout/Layout/index.cjs';
57
57
  export { SideBar, SideBarContext, useSideBarContext } from './layout/SideBar/index.cjs';
58
58
  export { TokenVar, cssVar, semantic } from '@x-plat/tokens-core';
59
+ export { B as ButtonAttributes, I as InputAttributes, T as TextareaAttributes } from './attributes-DJIWir_0.cjs';
59
60
  export { ActivityIcon, AirplayIcon, AlertCircleIcon, AlertOctagonIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, AnchorIcon, ApertureIcon, ArchiveIcon, ArrowDownCircleIcon, ArrowDownIcon, ArrowDownLeftIcon, ArrowDownRightIcon, ArrowLeftCircleIcon, ArrowLeftIcon, ArrowRightCircleIcon, ArrowRightIcon, ArrowUpCircleIcon, ArrowUpIcon, ArrowUpLeftIcon, ArrowUpRightIcon, AtSignIcon, AwardIcon, BarChart2Icon, BarChartIcon, BatteryChargingIcon, BatteryIcon, BellIcon, BellOffIcon, BluetoothIcon, BoldIcon, BookIcon, BookOpenIcon, BookmarkIcon, BoxIcon, BriefcaseIcon, CalendarIcon, CalenderIcon, CallActiveIcon, CallForwardedIcon, CallIcon, CallIncomingIcon, CallMissedIcon, CallOffIcon, CallOutgoingIcon, CameraIcon, CameraOffIcon, CastIcon, CheckCircleIcon, CheckIcon, CheckSquareIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsDownIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpIcon, ChromeIcon, CircleIcon, ClipboardIcon, ClockIcon, CloseEyeIcon, CloudDrizzleIcon, CloudIcon, CloudLightningIcon, CloudOffIcon, CloudRainIcon, CloudSnowIcon, CodeIcon, CodepenIcon, CodesandboxIcon, CoffeeIcon, ColorProps, ColorToken, ColumnsIcon, CommandIcon, CompassIcon, CopyIcon, CornerDownLeftIcon, CornerDownRightIcon, CornerLeftDownIcon, CornerLeftUpIcon, CornerRightDownIcon, CornerRightUpIcon, CornerUpLeftIcon, CornerUpRightIcon, CpuIcon, CreditCardIcon, CropIcon, CrosshairIcon, DatabaseIcon, CallIcon as DefaultCall, DeleteIcon, DiscIcon, DivideCircleIcon, DivideIcon, DivideSquareIcon, DollarSignIcon, DownloadCloudIcon, DownloadIcon, DribbbleIcon, DropletIcon, Edit2Icon, Edit3Icon, EditIcon, ErrorIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FacebookIcon, FastForwardIcon, FeatherIcon, FigmaIcon, FileIcon, FileMinusIcon, FilePlusIcon, FileTextIcon, FilmIcon, FilterIcon, FlagIcon, FolderIcon, FolderMinusIcon, FolderPlusIcon, FramerIcon, FrownIcon, GierIcon, GiftIcon, GitBranchIcon, GitCommitIcon, GitMergeIcon, GitPullRequestIcon, GithubIcon, GitlabIcon, GlobeIcon, GridIcon, HardDriveIcon, HashIcon, HeadphonesIcon, HeartIcon, HelpCircleIcon, HexagonIcon, HomeIcon, ImageIcon, InboxIcon, InfoIcon, InstagramIcon, ItalicIcon, KeyIcon, LayersIcon, LayoutIcon, LifeBuoyIcon, Link2Icon, LinkIcon, LinkedinIcon, ListIcon, LoaderIcon, LockIcon, LogInIcon, LogOutIcon, MailIcon, MapIcon, MapPinIcon, Maximize2Icon, MaximizeIcon, MehIcon, MenuIcon, MessageCircleIcon, MessageSquareIcon, MicIcon, MicOffIcon, Minimize2Icon, MinimizeIcon, MinusCircleIcon, MinusIcon, MinusSquareIcon, MonitorIcon, MoonIcon, MoreHorizontalIcon, MoreVerticalIcon, MousePointerIcon, MoveIcon, MusicIcon, Navigation2Icon, NavigationIcon, OctagonIcon, OpenEyeIcon, PackageIcon, PaperclipIcon, PauseCircleIcon, PauseIcon, PenToolIcon, PercentIcon, PieChartIcon, PlayCircleIcon, PlayIcon, PlusCircleIcon, PlusIcon, PlusSquareIcon, PocketIcon, PowerIcon, PrinterIcon, ProfileIcon, RadioIcon, RefreshCcwIcon, RefreshCwIcon, RepeatIcon, RewindIcon, RotateCcwIcon, RotateCwIcon, RssIcon, SaveIcon, ScissorsIcon, SearchIcon, SemanticColorToken, SendIcon, ServerIcon, SettingsIcon, Share2Icon, ShareIcon, ShieldIcon, ShieldOffIcon, ShoppingBagIcon, ShoppingCartIcon, ShuffleIcon, SidebarIcon, SkipBackIcon, SkipForwardIcon, SlackIcon, SlashIcon, SlidersIcon, SmartphoneIcon, SmileIcon, SpeakerIcon, SquareIcon, StarIcon, StopCircleIcon, SuccessIcon, SunIcon, SunriseIcon, SunsetIcon, TableIcon, TabletIcon, TagIcon, TargetIcon, TerminalIcon, ThermometerIcon, ThumbsDownIcon, ThumbsUpIcon, ToggleLeftIcon, ToggleRightIcon, ToolIcon, Trash2Icon, TrashIcon, TrelloIcon, TrendingDownIcon, TrendingUpIcon, TriangleIcon, TruckIcon, TvIcon, TwitchIcon, TwitterIcon, TypeIcon, UmbrellaIcon, UnderlineIcon, UnlockIcon, UploadCloudIcon, UploadIcon, UserCheckIcon, UserIcon, UserMinusIcon, UserPlusIcon, UserXIcon, UsersIcon, VideoIcon, VideoOffIcon, VoicemailIcon, Volume1Icon, Volume2Icon, VolumeIcon, VolumeXIcon, WatchIcon, WifiIcon, WifiOffIcon, WindIcon, XCircleIcon, XIcon, XOctagonIcon, XSquareIcon, YoutubeIcon, ZapIcon, ZapOffIcon, ZoomInIcon, ZoomOutIcon } from './tokens/index.cjs';
61
+ export { L as LegacyStatusType, S as StatusType, a as StatusTypeInput, n as normalizeStatus } from './status-C70BBv2S.cjs';
62
+ export { V as Validation, a as ValidationStatus } from './validation-BYpAI6Ct.cjs';
60
63
  import 'react';
61
- import './attributes-DJIWir_0.cjs';
62
- import './validation-Dqo1zqhT.cjs';
63
64
  import 'react/jsx-runtime';
64
- import './status-njWqQWFV.cjs';
package/dist/index.d.ts CHANGED
@@ -56,9 +56,9 @@ export { Header } from './layout/Header/index.js';
56
56
  export { Layout } from './layout/Layout/index.js';
57
57
  export { SideBar, SideBarContext, useSideBarContext } from './layout/SideBar/index.js';
58
58
  export { TokenVar, cssVar, semantic } from '@x-plat/tokens-core';
59
+ export { B as ButtonAttributes, I as InputAttributes, T as TextareaAttributes } from './attributes-DJIWir_0.js';
59
60
  export { ActivityIcon, AirplayIcon, AlertCircleIcon, AlertOctagonIcon, AlertTriangleIcon, AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, AnchorIcon, ApertureIcon, ArchiveIcon, ArrowDownCircleIcon, ArrowDownIcon, ArrowDownLeftIcon, ArrowDownRightIcon, ArrowLeftCircleIcon, ArrowLeftIcon, ArrowRightCircleIcon, ArrowRightIcon, ArrowUpCircleIcon, ArrowUpIcon, ArrowUpLeftIcon, ArrowUpRightIcon, AtSignIcon, AwardIcon, BarChart2Icon, BarChartIcon, BatteryChargingIcon, BatteryIcon, BellIcon, BellOffIcon, BluetoothIcon, BoldIcon, BookIcon, BookOpenIcon, BookmarkIcon, BoxIcon, BriefcaseIcon, CalendarIcon, CalenderIcon, CallActiveIcon, CallForwardedIcon, CallIcon, CallIncomingIcon, CallMissedIcon, CallOffIcon, CallOutgoingIcon, CameraIcon, CameraOffIcon, CastIcon, CheckCircleIcon, CheckIcon, CheckSquareIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsDownIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpIcon, ChromeIcon, CircleIcon, ClipboardIcon, ClockIcon, CloseEyeIcon, CloudDrizzleIcon, CloudIcon, CloudLightningIcon, CloudOffIcon, CloudRainIcon, CloudSnowIcon, CodeIcon, CodepenIcon, CodesandboxIcon, CoffeeIcon, ColorProps, ColorToken, ColumnsIcon, CommandIcon, CompassIcon, CopyIcon, CornerDownLeftIcon, CornerDownRightIcon, CornerLeftDownIcon, CornerLeftUpIcon, CornerRightDownIcon, CornerRightUpIcon, CornerUpLeftIcon, CornerUpRightIcon, CpuIcon, CreditCardIcon, CropIcon, CrosshairIcon, DatabaseIcon, CallIcon as DefaultCall, DeleteIcon, DiscIcon, DivideCircleIcon, DivideIcon, DivideSquareIcon, DollarSignIcon, DownloadCloudIcon, DownloadIcon, DribbbleIcon, DropletIcon, Edit2Icon, Edit3Icon, EditIcon, ErrorIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FacebookIcon, FastForwardIcon, FeatherIcon, FigmaIcon, FileIcon, FileMinusIcon, FilePlusIcon, FileTextIcon, FilmIcon, FilterIcon, FlagIcon, FolderIcon, FolderMinusIcon, FolderPlusIcon, FramerIcon, FrownIcon, GierIcon, GiftIcon, GitBranchIcon, GitCommitIcon, GitMergeIcon, GitPullRequestIcon, GithubIcon, GitlabIcon, GlobeIcon, GridIcon, HardDriveIcon, HashIcon, HeadphonesIcon, HeartIcon, HelpCircleIcon, HexagonIcon, HomeIcon, ImageIcon, InboxIcon, InfoIcon, InstagramIcon, ItalicIcon, KeyIcon, LayersIcon, LayoutIcon, LifeBuoyIcon, Link2Icon, LinkIcon, LinkedinIcon, ListIcon, LoaderIcon, LockIcon, LogInIcon, LogOutIcon, MailIcon, MapIcon, MapPinIcon, Maximize2Icon, MaximizeIcon, MehIcon, MenuIcon, MessageCircleIcon, MessageSquareIcon, MicIcon, MicOffIcon, Minimize2Icon, MinimizeIcon, MinusCircleIcon, MinusIcon, MinusSquareIcon, MonitorIcon, MoonIcon, MoreHorizontalIcon, MoreVerticalIcon, MousePointerIcon, MoveIcon, MusicIcon, Navigation2Icon, NavigationIcon, OctagonIcon, OpenEyeIcon, PackageIcon, PaperclipIcon, PauseCircleIcon, PauseIcon, PenToolIcon, PercentIcon, PieChartIcon, PlayCircleIcon, PlayIcon, PlusCircleIcon, PlusIcon, PlusSquareIcon, PocketIcon, PowerIcon, PrinterIcon, ProfileIcon, RadioIcon, RefreshCcwIcon, RefreshCwIcon, RepeatIcon, RewindIcon, RotateCcwIcon, RotateCwIcon, RssIcon, SaveIcon, ScissorsIcon, SearchIcon, SemanticColorToken, SendIcon, ServerIcon, SettingsIcon, Share2Icon, ShareIcon, ShieldIcon, ShieldOffIcon, ShoppingBagIcon, ShoppingCartIcon, ShuffleIcon, SidebarIcon, SkipBackIcon, SkipForwardIcon, SlackIcon, SlashIcon, SlidersIcon, SmartphoneIcon, SmileIcon, SpeakerIcon, SquareIcon, StarIcon, StopCircleIcon, SuccessIcon, SunIcon, SunriseIcon, SunsetIcon, TableIcon, TabletIcon, TagIcon, TargetIcon, TerminalIcon, ThermometerIcon, ThumbsDownIcon, ThumbsUpIcon, ToggleLeftIcon, ToggleRightIcon, ToolIcon, Trash2Icon, TrashIcon, TrelloIcon, TrendingDownIcon, TrendingUpIcon, TriangleIcon, TruckIcon, TvIcon, TwitchIcon, TwitterIcon, TypeIcon, UmbrellaIcon, UnderlineIcon, UnlockIcon, UploadCloudIcon, UploadIcon, UserCheckIcon, UserIcon, UserMinusIcon, UserPlusIcon, UserXIcon, UsersIcon, VideoIcon, VideoOffIcon, VoicemailIcon, Volume1Icon, Volume2Icon, VolumeIcon, VolumeXIcon, WatchIcon, WifiIcon, WifiOffIcon, WindIcon, XCircleIcon, XIcon, XOctagonIcon, XSquareIcon, YoutubeIcon, ZapIcon, ZapOffIcon, ZoomInIcon, ZoomOutIcon } from './tokens/index.js';
61
+ export { L as LegacyStatusType, S as StatusType, a as StatusTypeInput, n as normalizeStatus } from './status-C70BBv2S.js';
62
+ export { V as Validation, a as ValidationStatus } from './validation-BYpAI6Ct.js';
60
63
  import 'react';
61
- import './attributes-DJIWir_0.js';
62
- import './validation-Dqo1zqhT.js';
63
64
  import 'react/jsx-runtime';
64
- import './status-njWqQWFV.js';
package/dist/index.js CHANGED
@@ -6992,12 +6992,12 @@ var gridColumns = {
6992
6992
  // src/tokens/colors.ts
6993
6993
  import { semantic } from "@x-plat/tokens-core";
6994
6994
 
6995
- // src/tokens/index.ts
6996
- import { cssVar } from "@x-plat/tokens-core";
6997
-
6998
6995
  // src/tokens/interface/status.ts
6999
6996
  var normalizeStatus = (value) => value === "brand" ? "primary" : value;
7000
6997
 
6998
+ // src/tokens/index.ts
6999
+ import { cssVar } from "@x-plat/tokens-core";
7000
+
7001
7001
  // src/components/CheckBox/CheckBox.tsx
7002
7002
  import { jsx as jsx309, jsxs as jsxs198 } from "react/jsx-runtime";
7003
7003
  var CheckBox = (props) => {
@@ -7977,23 +7977,22 @@ var Portal_default = Portal;
7977
7977
  // src/tokens/hooks/useAutoPosition.ts
7978
7978
  import React19 from "react";
7979
7979
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
7980
- const [position, setPosition] = React19.useState({
7981
- position: {},
7982
- direction: "bottom"
7983
- });
7980
+ const [direction, setDirection] = React19.useState("bottom");
7981
+ const directionRef = React19.useRef("bottom");
7984
7982
  const calculatePosition = React19.useCallback(() => {
7985
- if (!triggerRef.current || !popRef.current) return;
7983
+ const pop = popRef.current;
7984
+ if (!triggerRef.current || !pop) return;
7986
7985
  const triggerRect = triggerRef.current.getBoundingClientRect();
7987
- const popW = popRef.current.offsetWidth;
7988
- const popH = popRef.current.offsetHeight;
7986
+ const popW = pop.offsetWidth;
7987
+ const popH = pop.offsetHeight;
7989
7988
  const viewportHeight = window.innerHeight;
7990
7989
  const viewportWidth = window.innerWidth;
7991
7990
  if (popH === 0 || popW === 0) return;
7992
- let direction = "bottom";
7991
+ let next = "bottom";
7993
7992
  let top;
7994
7993
  let left;
7995
7994
  if (triggerRect.bottom + popH > viewportHeight && triggerRect.top - popH > 0) {
7996
- direction = "top";
7995
+ next = "top";
7997
7996
  top = triggerRect.top - popH;
7998
7997
  } else {
7999
7998
  top = triggerRect.bottom;
@@ -8003,7 +8002,12 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
8003
8002
  left = triggerRect.right - popW;
8004
8003
  }
8005
8004
  if (left < 8) left = 8;
8006
- setPosition({ position: { top, left }, direction });
8005
+ pop.style.top = `${top + window.scrollY}px`;
8006
+ pop.style.left = `${left + window.scrollX}px`;
8007
+ if (next !== directionRef.current) {
8008
+ directionRef.current = next;
8009
+ setDirection(next);
8010
+ }
8007
8011
  }, [triggerRef, popRef]);
8008
8012
  React19.useLayoutEffect(() => {
8009
8013
  if (!enabled) return;
@@ -8034,7 +8038,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
8034
8038
  window.removeEventListener("scroll", onScrollOrResize, true);
8035
8039
  };
8036
8040
  }, [calculatePosition, enabled]);
8037
- return position;
8041
+ return { direction };
8038
8042
  };
8039
8043
  var useAutoPosition_default = useAutoPosition;
8040
8044
 
@@ -8072,7 +8076,7 @@ var Dropdown = (props) => {
8072
8076
  const [visible, setVisible] = React21.useState(false);
8073
8077
  const triggerRef = React21.useRef(null);
8074
8078
  const menuRef = React21.useRef(null);
8075
- const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
8079
+ const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
8076
8080
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
8077
8081
  useEscapeKey(isOpen, () => {
8078
8082
  setIsOpen(false);
@@ -8108,7 +8112,6 @@ var Dropdown = (props) => {
8108
8112
  {
8109
8113
  ref: menuRef,
8110
8114
  className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
8111
- style: { top: position.top, left: position.left },
8112
8115
  role: "menu",
8113
8116
  children: items.map((item) => /* @__PURE__ */ jsx322(
8114
8117
  "button",
@@ -10042,9 +10045,6 @@ var PopOver = (props) => {
10042
10045
  eventTrigger && "visible"
10043
10046
  ),
10044
10047
  ref: popRef,
10045
- style: {
10046
- ...position.position
10047
- },
10048
10048
  children: PopOverEl
10049
10049
  }
10050
10050
  ) })
@@ -10387,7 +10387,7 @@ var SelectRoot = (props) => {
10387
10387
  {
10388
10388
  className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
10389
10389
  ref: contentRef,
10390
- style: { ...position.position, width: triggerRef.current?.offsetWidth },
10390
+ style: { width: triggerRef.current?.offsetWidth },
10391
10391
  role: "listbox",
10392
10392
  children: [
10393
10393
  searchable && /* @__PURE__ */ jsx337("div", { className: "select-search", children: /* @__PURE__ */ jsx337(
@@ -11232,7 +11232,7 @@ var TimePicker = (props) => {
11232
11232
  close();
11233
11233
  triggerRef.current?.focus({ preventScroll: true });
11234
11234
  });
11235
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
11235
+ useAutoPosition_default(triggerRef, contentRef, mounted);
11236
11236
  React40.useEffect(() => {
11237
11237
  if (disabled && isOpen) setOpen(false);
11238
11238
  }, [disabled, isOpen]);
@@ -11279,7 +11279,7 @@ var TimePicker = (props) => {
11279
11279
  {
11280
11280
  ref: contentRef,
11281
11281
  className: clsx_default("lib-xplat-time-picker-content", size, visible ? "enter" : "exit"),
11282
- style: { ...position.position, width: triggerRef.current?.offsetWidth },
11282
+ style: { width: triggerRef.current?.offsetWidth },
11283
11283
  role: "listbox",
11284
11284
  children: options.map((t) => /* @__PURE__ */ jsx351(
11285
11285
  "div",
@@ -12430,6 +12430,7 @@ export {
12430
12430
  hasError,
12431
12431
  isInRange,
12432
12432
  isSameDay,
12433
+ normalizeStatus,
12433
12434
  semantic,
12434
12435
  useCalendar,
12435
12436
  useSideBarContext,
@@ -16,5 +16,7 @@ type StatusType = "primary" | "success" | "error" | "warning" | "info";
16
16
  type LegacyStatusType = "brand";
17
17
  /** 컴포넌트가 받는 타입. 새 이름과 예전 이름을 모두 허용한다 */
18
18
  type StatusTypeInput = StatusType | LegacyStatusType;
19
+ /** `brand` 로 들어온 값을 `primary` 로 정규화한다 */
20
+ declare const normalizeStatus: <T extends string>(value: T | LegacyStatusType) => Exclude<T, LegacyStatusType> | "primary";
19
21
 
20
- export type { LegacyStatusType as L, StatusTypeInput as S };
22
+ export { type LegacyStatusType as L, type StatusType as S, type StatusTypeInput as a, normalizeStatus as n };
@@ -16,5 +16,7 @@ type StatusType = "primary" | "success" | "error" | "warning" | "info";
16
16
  type LegacyStatusType = "brand";
17
17
  /** 컴포넌트가 받는 타입. 새 이름과 예전 이름을 모두 허용한다 */
18
18
  type StatusTypeInput = StatusType | LegacyStatusType;
19
+ /** `brand` 로 들어온 값을 `primary` 로 정규화한다 */
20
+ declare const normalizeStatus: <T extends string>(value: T | LegacyStatusType) => Exclude<T, LegacyStatusType> | "primary";
19
21
 
20
- export type { LegacyStatusType as L, StatusTypeInput as S };
22
+ export { type LegacyStatusType as L, type StatusType as S, type StatusTypeInput as a, normalizeStatus as n };
@@ -319,6 +319,7 @@ __export(tokens_exports, {
319
319
  breakpoints: () => breakpoints,
320
320
  cssVar: () => import_tokens_core2.cssVar,
321
321
  gridColumns: () => gridColumns,
322
+ normalizeStatus: () => normalizeStatus,
322
323
  semantic: () => import_tokens_core.semantic
323
324
  });
324
325
  module.exports = __toCommonJS(tokens_exports);
@@ -339,6 +340,9 @@ var gridColumns = {
339
340
  // src/tokens/colors.ts
340
341
  var import_tokens_core = require("@x-plat/tokens-core");
341
342
 
343
+ // src/tokens/interface/status.ts
344
+ var normalizeStatus = (value) => value === "brand" ? "primary" : value;
345
+
342
346
  // src/tokens/svg/action/CopyIcon.tsx
343
347
  var import_jsx_runtime = require("react/jsx-runtime");
344
348
  var CopyIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -6110,5 +6114,6 @@ var import_tokens_core2 = require("@x-plat/tokens-core");
6110
6114
  breakpoints,
6111
6115
  cssVar,
6112
6116
  gridColumns,
6117
+ normalizeStatus,
6113
6118
  semantic
6114
6119
  });
@@ -1,5 +1,8 @@
1
1
  export { B as BREAKPOINT_KEYS_ORDERED, a as BreakpointKey, G as GridColumnConfig, b as GridSpanFor, c as breakpoints, g as gridColumns } from '../breakpoints-CKkNxA-y.cjs';
2
2
  export { TokenVar, cssVar, semantic } from '@x-plat/tokens-core';
3
+ export { B as ButtonAttributes, I as InputAttributes, T as TextareaAttributes } from '../attributes-DJIWir_0.cjs';
4
+ export { L as LegacyStatusType, S as StatusType, a as StatusTypeInput, n as normalizeStatus } from '../status-C70BBv2S.cjs';
5
+ export { V as Validation, a as ValidationStatus } from '../validation-BYpAI6Ct.cjs';
3
6
  import React from 'react';
4
7
 
5
8
  type SemanticTextToken = "semantic-text-primary" | "semantic-text-secondary" | "semantic-text-tertiary" | "semantic-text-brand-primary" | "semantic-text-brand-secondary" | "semantic-text-disabled" | "semantic-text-inverse" | "semantic-text-success" | "semantic-text-error" | "semantic-text-warning" | "semantic-text-info" | "semantic-text-link" | "semantic-text-accent-red" | "semantic-text-accent-blue";
@@ -1,5 +1,8 @@
1
1
  export { B as BREAKPOINT_KEYS_ORDERED, a as BreakpointKey, G as GridColumnConfig, b as GridSpanFor, c as breakpoints, g as gridColumns } from '../breakpoints-CKkNxA-y.js';
2
2
  export { TokenVar, cssVar, semantic } from '@x-plat/tokens-core';
3
+ export { B as ButtonAttributes, I as InputAttributes, T as TextareaAttributes } from '../attributes-DJIWir_0.js';
4
+ export { L as LegacyStatusType, S as StatusType, a as StatusTypeInput, n as normalizeStatus } from '../status-C70BBv2S.js';
5
+ export { V as Validation, a as ValidationStatus } from '../validation-BYpAI6Ct.js';
3
6
  import React from 'react';
4
7
 
5
8
  type SemanticTextToken = "semantic-text-primary" | "semantic-text-secondary" | "semantic-text-tertiary" | "semantic-text-brand-primary" | "semantic-text-brand-secondary" | "semantic-text-disabled" | "semantic-text-inverse" | "semantic-text-success" | "semantic-text-error" | "semantic-text-warning" | "semantic-text-info" | "semantic-text-link" | "semantic-text-accent-red" | "semantic-text-accent-blue";
@@ -14,6 +14,9 @@ var gridColumns = {
14
14
  // src/tokens/colors.ts
15
15
  import { semantic } from "@x-plat/tokens-core";
16
16
 
17
+ // src/tokens/interface/status.ts
18
+ var normalizeStatus = (value) => value === "brand" ? "primary" : value;
19
+
17
20
  // src/tokens/svg/action/CopyIcon.tsx
18
21
  import { jsx, jsxs } from "react/jsx-runtime";
19
22
  var CopyIcon = () => /* @__PURE__ */ jsxs(
@@ -5784,5 +5787,6 @@ export {
5784
5787
  breakpoints,
5785
5788
  cssVar,
5786
5789
  gridColumns,
5790
+ normalizeStatus,
5787
5791
  semantic
5788
5792
  };
@@ -10,4 +10,4 @@ interface Validation {
10
10
  message: string;
11
11
  }
12
12
 
13
- export type { Validation as V };
13
+ export type { Validation as V, ValidationStatus as a };
@@ -10,4 +10,4 @@ interface Validation {
10
10
  message: string;
11
11
  }
12
12
 
13
- export type { Validation as V };
13
+ export type { Validation as V, ValidationStatus as a };
@@ -286,6 +286,44 @@ Dropdown · PopOver · TimePicker 가 전부 애니메이션 없이 툭 튀어
286
286
 
287
287
  ---
288
288
 
289
+ ## Next.js App Router 에서 반드시 걸리는 것
290
+
291
+ **DS 는 `'use client'` 를 달고 나가지 않는다.** 컴포넌트들이 `useState` ·
292
+ `useEffect` · `useId` · 컨텍스트를 쓰므로 **서버 컴포넌트가 DS 를 끌어가면
293
+ 터진다.** 버전과 무관하게 항상 그렇다.
294
+
295
+ 곧장 import 하는 것은 금방 알아채지만, **진짜 어려운 것은 배럴을 타고 들어가는
296
+ 경우다.**
297
+
298
+ ```ts
299
+ // shared/context/index.ts — 배럴이 DS 를 재수출한다
300
+ export * from "./AuthContext";
301
+ export { SideBar } from "@x-plat/design-system"; // ← 이 한 줄이
302
+
303
+ // app/layout.tsx — 서버 컴포넌트
304
+ import { AuthProvider } from "@/shared/context"; // ← 여기를 터뜨린다
305
+ ```
306
+
307
+ `AuthProvider` 만 가져왔는데도 배럴 전체가 평가되면서 DS 가 딸려 온다. 증상이
308
+ "DS 를 쓴 화면이 안 된다" 가 아니라 **"그 배럴을 쓰는 서버 컴포넌트가 안 된다"**
309
+ 로 나타나서 원인을 찾기 어렵다.
310
+
311
+ **해결은 DS 를 감싸는 파일 한 곳을 두고 거기에만 `'use client'` 를 다는 것이다.**
312
+
313
+ ```ts
314
+ // shared/ui/ds.ts
315
+ "use client";
316
+ export { Button, Input, Select, SideBar /* 쓰는 것만 */ } from "@x-plat/design-system";
317
+ ```
318
+
319
+ 앱은 이 파일에서만 가져다 쓴다. `agent-admin` 과 `xplat-template` 이 둘 다
320
+ 이 방식으로 해결했다.
321
+
322
+ > 일반 배럴(`shared/context` 같은 것)에서 DS 를 재수출하지 말 것. 그 배럴을
323
+ > 쓰는 서버 컴포넌트가 전부 클라이언트로 끌려간다.
324
+
325
+ ---
326
+
289
327
  ## 실제 이관에서 걸린 것 / 안 걸린 것
290
328
 
291
329
  `xplat-shop-templat` (pnpm 모노레포, 워크스페이스 4개) 을 **0.6.1 → 0.12.0** 으로
@@ -308,7 +346,18 @@ Dropdown · PopOver · TimePicker 가 전부 애니메이션 없이 툭 튀어
308
346
 
309
347
  ---
310
348
 
311
- ## 아직 확인되지 않은 것
349
+ ## 확인 상태
350
+
351
+ 이 저장소를 만지는 에이전트 세션들에는 브라우저가 없다. 빌드·타입·lint·
352
+ 정적 검사까지는 돌지만 **눈으로 본 것과 추론한 것은 다르다.** 어느 쪽인지
353
+ 적어 둔다.
354
+
355
+ | | 상태 |
356
+ |---|---|
357
+ | 오버레이 열림/닫힘 애니메이션 (0.14.2) | **사람이 화면에서 확인함** — 셀렉트가 부드럽게 내려온다 |
358
+ | `Layout` 타입 (0.14.2) | 소비자 흉내 프로젝트로 타입 검사 통과 |
359
+ | `ToggleChip` 커서·초점 테두리 | 마크업·CSS 만 확인. 눌러 본 사람 없음 |
360
+ | Editor | 아래 |
312
361
 
313
362
  **Editor 는 브라우저에서 검증되지 않았다.** `contentEditable`·`execCommand`·IME 는
314
363
  자동 테스트로 흉내 낼 수 없다. 특히 아래 넷은 직접 눌러 봐야 한다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-plat/design-system",
3
- "version": "0.14.2",
3
+ "version": "0.14.4",
4
4
  "description": "XPLAT UI Design System",
5
5
  "author": "XPLAT WOONG",
6
6
  "main": "dist/index.cjs",