@mondrianai/runyourai-design-system 0.0.31 → 0.0.32

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.d.mts CHANGED
@@ -193,8 +193,8 @@ type DropdownMenuItemConfig = {
193
193
  /** radio 아이템의 선택값 / React key. 미지정 시 문자열 label 또는 index를 사용 */
194
194
  value?: string;
195
195
  /**
196
- * 현재 선택된 항목 강조. default 아이템에 selected 배경(bg-accent)을 적용한다.
197
- * (checkbox/radio는 자체 체크 상태로 강조되므로 무시된다)
196
+ * default 항목의 선택 상태. 지정하면 체크 영역을 확보하고 선택 시 체크만 표시한다.
197
+ * 고정 선택 배경은 없다. checkbox/radio는 자체 checked/value를 사용한다.
198
198
  */
199
199
  selected?: boolean;
200
200
  icon?: React$1.ReactNode;
@@ -769,7 +769,7 @@ interface SegmentedControlProps<T extends string> {
769
769
  className?: string;
770
770
  }
771
771
  /**
772
- * 세그먼트 컨트롤(값/필터 선택) — Tabs `variant="pill"`과 동일 스타일.
772
+ * 세그먼트 컨트롤(값/필터 선택) — 결제 현황 기준의 공통 스타일.
773
773
  * 균등분할이 필요하면 `block`. 라벨이 칸보다 길면 말줄임되고, 그 경우에만 hover 시 툴팁으로 전체 표시.
774
774
  */
775
775
  declare function SegmentedControl<T extends string>({ value, onChange, items, block, className, }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
package/dist/index.d.ts CHANGED
@@ -193,8 +193,8 @@ type DropdownMenuItemConfig = {
193
193
  /** radio 아이템의 선택값 / React key. 미지정 시 문자열 label 또는 index를 사용 */
194
194
  value?: string;
195
195
  /**
196
- * 현재 선택된 항목 강조. default 아이템에 selected 배경(bg-accent)을 적용한다.
197
- * (checkbox/radio는 자체 체크 상태로 강조되므로 무시된다)
196
+ * default 항목의 선택 상태. 지정하면 체크 영역을 확보하고 선택 시 체크만 표시한다.
197
+ * 고정 선택 배경은 없다. checkbox/radio는 자체 checked/value를 사용한다.
198
198
  */
199
199
  selected?: boolean;
200
200
  icon?: React$1.ReactNode;
@@ -769,7 +769,7 @@ interface SegmentedControlProps<T extends string> {
769
769
  className?: string;
770
770
  }
771
771
  /**
772
- * 세그먼트 컨트롤(값/필터 선택) — Tabs `variant="pill"`과 동일 스타일.
772
+ * 세그먼트 컨트롤(값/필터 선택) — 결제 현황 기준의 공통 스타일.
773
773
  * 균등분할이 필요하면 `block`. 라벨이 칸보다 길면 말줄임되고, 그 경우에만 hover 시 툴팁으로 전체 표시.
774
774
  */
775
775
  declare function SegmentedControl<T extends string>({ value, onChange, items, block, className, }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
package/dist/index.js CHANGED
@@ -1489,7 +1489,7 @@ var TooltipContent = React7.forwardRef(
1489
1489
  sideOffset,
1490
1490
  className: cn(
1491
1491
  "z-50 w-max",
1492
- "bg-primary rounded-md px-2.5 py-1.5",
1492
+ "min-h-7.5 rounded-xl border border-neutral-700 bg-neutral-800 px-2.5 py-1.5 shadow-dropdown",
1493
1493
  "animate-in fade-in-0 zoom-in-95",
1494
1494
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
1495
1495
  "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
@@ -1498,7 +1498,7 @@ var TooltipContent = React7.forwardRef(
1498
1498
  ),
1499
1499
  style: __spreadValues({ maxWidth }, style)
1500
1500
  }, props), {
1501
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "block text-xs font-normal leading-snug tracking-tight text-primary-foreground whitespace-normal break-words", children })
1501
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "block text-xs font-normal leading-4 tracking-tight text-neutral-50 whitespace-normal break-words", children })
1502
1502
  })
1503
1503
  ) });
1504
1504
  }
@@ -1558,10 +1558,16 @@ function TooltipWithIcon({
1558
1558
  ) });
1559
1559
  }
1560
1560
 
1561
+ // src/components/ui/menu-styles.ts
1562
+ var menuPanelClass = "rounded-xl";
1563
+ var menuListClass = "p-1";
1564
+ var menuItemClass = "min-h-8 rounded-md px-2 py-1.5 my-0 text-sm leading-5";
1565
+
1561
1566
  // src/components/ui/dropdown-menu.tsx
1562
1567
  var import_jsx_runtime13 = require("react/jsx-runtime");
1563
1568
  var baseItemClass = cn(
1564
- "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 my-0.5 text-sm outline-none",
1569
+ menuItemClass,
1570
+ "relative flex cursor-pointer select-none items-center gap-2 outline-none",
1565
1571
  "transition-colors duration-100",
1566
1572
  "focus:bg-accent focus:text-accent-foreground",
1567
1573
  "data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
@@ -1573,14 +1579,15 @@ var destructiveItemClass = cn(
1573
1579
  '[&_svg:not([class*="text-"])]:text-destructive!'
1574
1580
  );
1575
1581
  var indentItemClass = cn(
1576
- "relative flex cursor-pointer select-none items-center gap-2 rounded-sm py-1.5 my-0.5 pr-2 pl-8 text-sm outline-none",
1582
+ menuItemClass,
1583
+ "relative flex cursor-pointer select-none items-center gap-2 pl-8 outline-none",
1577
1584
  "transition-colors duration-100",
1578
1585
  "focus:bg-accent focus:text-accent-foreground",
1579
- "data-[state=checked]:bg-accent data-[state=checked]:text-accent-foreground",
1580
1586
  "data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50"
1581
1587
  );
1582
1588
  var subTriggerClass = cn(
1583
- "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 my-0.5 text-sm outline-none",
1589
+ menuItemClass,
1590
+ "relative flex cursor-pointer select-none items-center gap-2 outline-none",
1584
1591
  "transition-colors duration-100",
1585
1592
  "focus:bg-accent focus:text-accent-foreground",
1586
1593
  "data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
@@ -1589,9 +1596,11 @@ var subTriggerClass = cn(
1589
1596
  '[&_svg:not([class*="text-"])]:text-muted-foreground'
1590
1597
  );
1591
1598
  var contentClass = cn(
1599
+ menuPanelClass,
1600
+ menuListClass,
1592
1601
  "z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-44",
1593
1602
  "origin-(--radix-dropdown-menu-content-transform-origin)",
1594
- "overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
1603
+ "overflow-x-hidden overflow-y-auto border bg-popover text-popover-foreground shadow-md",
1595
1604
  "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
1596
1605
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
1597
1606
  "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
@@ -1658,10 +1667,7 @@ function renderItem(item, index) {
1658
1667
  onSelect: (e) => e.preventDefault(),
1659
1668
  className: indentItemClass,
1660
1669
  children: [
1661
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: [
1662
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.CheckIcon, { className: "size-4 text-foreground/20" }),
1663
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui6.DropdownMenu.ItemIndicator, { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.CheckIcon, { className: "size-4" }) })
1664
- ] }),
1670
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui6.DropdownMenu.ItemIndicator, { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.CheckIcon, { className: "size-4" }) }) }),
1665
1671
  item.label
1666
1672
  ]
1667
1673
  }
@@ -1680,10 +1686,11 @@ function renderItem(item, index) {
1680
1686
  "data-selected": item.selected || void 0,
1681
1687
  className: cn(
1682
1688
  baseItemClass,
1683
- item.selected && "bg-accent text-accent-foreground",
1689
+ item.selected !== void 0 && "pl-8",
1684
1690
  item.variant === "destructive" && destructiveItemClass
1685
1691
  ),
1686
1692
  children: [
1693
+ item.selected && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": "true", className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.CheckIcon, { className: "size-4 text-foreground" }) }),
1687
1694
  item.icon,
1688
1695
  item.label,
1689
1696
  item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ml-auto text-xs tracking-widest text-muted-foreground", children: item.shortcut })
@@ -1720,10 +1727,7 @@ function renderGroups(groups) {
1720
1727
  onSelect: (e) => e.preventDefault(),
1721
1728
  className: indentItemClass,
1722
1729
  children: [
1723
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: [
1724
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "size-2 rounded-full bg-foreground/20" }),
1725
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui6.DropdownMenu.ItemIndicator, { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "size-2 rounded-full bg-current" }) })
1726
- ] }),
1730
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "pointer-events-none absolute left-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui6.DropdownMenu.ItemIndicator, { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.CheckIcon, { className: "size-4" }) }) }),
1727
1731
  item.label
1728
1732
  ]
1729
1733
  }
@@ -2316,7 +2320,8 @@ function Combobox({
2316
2320
  sideOffset: 4,
2317
2321
  style: { width: "var(--radix-popover-trigger-width)" },
2318
2322
  className: cn(
2319
- "z-50 overflow-hidden rounded-md border border-border bg-popover",
2323
+ menuPanelClass,
2324
+ "z-50 overflow-hidden border border-border bg-popover",
2320
2325
  "shadow-dropdown",
2321
2326
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
2322
2327
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
@@ -2337,7 +2342,7 @@ function Combobox({
2337
2342
  }
2338
2343
  )
2339
2344
  ] }),
2340
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "p-1 flex flex-col overflow-y-auto", style: { maxHeight: 384 }, children: [
2345
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn(menuListClass, "flex flex-col overflow-y-auto"), style: { maxHeight: 384 }, children: [
2341
2346
  filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "px-2 py-1.5 text-sm text-muted-foreground text-center", children: "\uACB0\uACFC \uC5C6\uC74C" }) : filtered.map((opt) => {
2342
2347
  const isSelected = opt.value === value;
2343
2348
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
@@ -2346,10 +2351,10 @@ function Combobox({
2346
2351
  type: "button",
2347
2352
  onClick: () => handleSelect(opt.value),
2348
2353
  className: cn(
2349
- "flex w-full items-center gap-2 rounded-sm px-2 py-1.5",
2350
- "text-sm font-normal leading-5 tracking-tight",
2354
+ menuItemClass,
2355
+ "flex w-full items-center gap-2 font-normal tracking-tight",
2351
2356
  "cursor-pointer transition-colors",
2352
- isSelected ? "bg-accent text-accent-foreground" : "text-popover-foreground hover:bg-accent hover:text-accent-foreground"
2357
+ "text-popover-foreground hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground"
2353
2358
  ),
2354
2359
  children: [
2355
2360
  opt.icon && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 flex items-center", children: opt.icon }),
@@ -2368,7 +2373,7 @@ function Combobox({
2368
2373
  footer.onClick();
2369
2374
  setOpen(false);
2370
2375
  },
2371
- className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm font-normal leading-5 tracking-tight text-muted-foreground hover:bg-accent hover:text-accent-foreground cursor-pointer transition-colors",
2376
+ className: cn(menuItemClass, "flex w-full items-center gap-2 font-normal tracking-tight text-muted-foreground hover:bg-accent hover:text-accent-foreground cursor-pointer transition-colors"),
2372
2377
  children: [
2373
2378
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "plus", className: "size-4 text-muted-foreground" }),
2374
2379
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 min-w-0 truncate text-left", children: footer.label })
@@ -4820,12 +4825,13 @@ function Segment({
4820
4825
  {
4821
4826
  ref,
4822
4827
  type: "button",
4828
+ "aria-pressed": isActive,
4823
4829
  onClick,
4824
4830
  className: cn(
4825
- "cursor-pointer truncate rounded-md px-3 py-1.5 text-sm font-medium tracking-tight transition-all",
4831
+ "h-7 cursor-pointer truncate rounded-md px-4 py-1 text-sm leading-5 tracking-tight transition-colors",
4826
4832
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4827
4833
  block && "min-w-0 flex-1",
4828
- isActive ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
4834
+ isActive ? "bg-background font-medium text-foreground shadow-segmented" : "font-normal text-muted-foreground hover:text-foreground"
4829
4835
  ),
4830
4836
  children: item.label
4831
4837
  }
@@ -4842,7 +4848,7 @@ function SegmentedControl({
4842
4848
  "div",
4843
4849
  {
4844
4850
  className: cn(
4845
- "items-center gap-1 rounded-lg bg-muted p-1",
4851
+ "h-8.5 items-center gap-0 rounded-lg bg-secondary p-0.75",
4846
4852
  block ? "flex w-full" : "inline-flex",
4847
4853
  className
4848
4854
  ),
@@ -5052,6 +5058,7 @@ function Select(props) {
5052
5058
  return map;
5053
5059
  }, [options, baseId]);
5054
5060
  const [activeValue, setActiveValue] = React23.useState(null);
5061
+ const [keyboardNavigation, setKeyboardNavigation] = React23.useState(false);
5055
5062
  const activeIndex = activeValue ? options.findIndex((o) => o.value === activeValue) : -1;
5056
5063
  const activeId = activeValue && optionIds.has(activeValue) ? optionIds.get(activeValue) : void 0;
5057
5064
  React23.useEffect(() => {
@@ -5098,6 +5105,9 @@ function Select(props) {
5098
5105
  function handleListKeyDown(e) {
5099
5106
  const count = options.length;
5100
5107
  if (count === 0) return;
5108
+ if (["ArrowDown", "ArrowUp", "Home", "End", "Enter", " "].includes(e.key) || e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {
5109
+ setKeyboardNavigation(true);
5110
+ }
5101
5111
  switch (e.key) {
5102
5112
  case "ArrowDown":
5103
5113
  e.preventDefault();
@@ -5129,6 +5139,7 @@ function Select(props) {
5129
5139
  }
5130
5140
  function handleTriggerKeyDown(e) {
5131
5141
  if (disabled || open) return;
5142
+ if (["ArrowDown", "ArrowUp", "Enter", " "].includes(e.key)) setKeyboardNavigation(true);
5132
5143
  if (e.key === "ArrowDown" || e.key === "ArrowUp") {
5133
5144
  e.preventDefault();
5134
5145
  setOpen(true);
@@ -5144,6 +5155,7 @@ function Select(props) {
5144
5155
  "aria-expanded": open,
5145
5156
  "aria-controls": open ? listboxId : void 0,
5146
5157
  onKeyDown: handleTriggerKeyDown,
5158
+ onPointerDown: () => setKeyboardNavigation(false),
5147
5159
  disabled,
5148
5160
  className: cn(
5149
5161
  "flex h-9 w-full items-center justify-between rounded-lg border border-border px-3 py-2",
@@ -5172,10 +5184,7 @@ function Select(props) {
5172
5184
  Icon,
5173
5185
  {
5174
5186
  name: "chevron-down",
5175
- className: cn(
5176
- "size-4 shrink-0 text-muted-foreground transition-transform duration-200",
5177
- open && "rotate-180"
5178
- )
5187
+ className: "size-4 shrink-0 text-muted-foreground"
5179
5188
  }
5180
5189
  )
5181
5190
  ]
@@ -5192,8 +5201,9 @@ function Select(props) {
5192
5201
  (_a2 = listRef.current) == null ? void 0 : _a2.focus();
5193
5202
  },
5194
5203
  className: cn(
5204
+ menuPanelClass,
5195
5205
  "min-w-[var(--radix-popover-trigger-width)] max-w-80",
5196
- "z-50 rounded-lg border border-border bg-popover overflow-hidden",
5206
+ "z-50 border border-border bg-popover overflow-hidden",
5197
5207
  "shadow-dropdown",
5198
5208
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
5199
5209
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
@@ -5210,7 +5220,7 @@ function Select(props) {
5210
5220
  "aria-activedescendant": activeId,
5211
5221
  tabIndex: -1,
5212
5222
  onKeyDown: handleListKeyDown,
5213
- className: "p-1 flex flex-col max-h-96 overflow-y-auto outline-none [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-gray-300",
5223
+ className: cn(menuListClass, "flex flex-col max-h-96 overflow-y-auto outline-none [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-gray-300"),
5214
5224
  children: groups.map((group, gi) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
5215
5225
  "div",
5216
5226
  {
@@ -5230,14 +5240,17 @@ function Select(props) {
5230
5240
  id: optionIds.get(opt.value),
5231
5241
  role: "option",
5232
5242
  "aria-selected": isSelected,
5233
- "data-active": isActive || void 0,
5243
+ "data-active": isActive && keyboardNavigation || void 0,
5234
5244
  onClick: () => handleSelect(opt.value),
5235
- onPointerMove: () => setActiveValue(opt.value),
5245
+ onPointerMove: () => {
5246
+ setKeyboardNavigation(false);
5247
+ setActiveValue(opt.value);
5248
+ },
5236
5249
  className: cn(
5237
- "flex w-full items-center justify-between rounded-sm px-2 py-1.5",
5238
- "text-sm font-normal leading-5 tracking-tight",
5250
+ menuItemClass,
5251
+ "flex w-full items-center justify-between font-normal tracking-tight",
5239
5252
  "cursor-pointer transition-colors outline-none",
5240
- isSelected ? "bg-accent text-accent-foreground" : "text-popover-foreground",
5253
+ "text-popover-foreground",
5241
5254
  "data-[active]:bg-accent data-[active]:text-accent-foreground",
5242
5255
  "hover:bg-accent hover:text-accent-foreground"
5243
5256
  ),
@@ -5839,7 +5852,7 @@ var Slider = React25.forwardRef(
5839
5852
  visibleSet.has(i) ? "opacity-100" : "opacity-0"
5840
5853
  ),
5841
5854
  children: [
5842
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "block rounded-md bg-primary px-2.5 py-1.5 text-xs font-normal leading-snug tracking-tight text-primary-foreground whitespace-nowrap", children: val }),
5855
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "block min-h-7.5 rounded-xl border border-neutral-700 bg-neutral-800 px-2.5 py-1.5 text-xs font-normal leading-4 tracking-tight text-neutral-50 whitespace-nowrap shadow-dropdown", children: val }),
5843
5856
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5844
5857
  "svg",
5845
5858
  {
@@ -5855,7 +5868,7 @@ var Slider = React25.forwardRef(
5855
5868
  "path",
5856
5869
  {
5857
5870
  d: "M9.29289 4.29289L5 0H15L10.7071 4.29289C10.3166 4.68342 9.68342 4.68342 9.29289 4.29289Z",
5858
- className: "fill-primary"
5871
+ className: "fill-neutral-800"
5859
5872
  }
5860
5873
  )
5861
5874
  }