@loword/loword-design-system 0.4.2 → 0.5.1

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.
@@ -50,7 +50,7 @@ const LDModal = (options) => {
50
50
  return (_jsx(LDModalView, { open: open, onOpenChange: (next) => {
51
51
  if (!next)
52
52
  close(undefined);
53
- }, name: options.name, title: options.title, description: options.description, size: options.size, icon: options.icon, scrollBehavior: options.scrollBehavior, closeOnOverlayClick: options.closeOnOverlayClick, style: options.style, buttons: list ? { direction: options.buttonsDirection, list } : undefined, classNames: options.classNames, children: content }));
53
+ }, name: options.name, title: options.title, description: options.description, size: options.size, icon: options.icon, scrollBehavior: options.scrollBehavior, closeOnOverlayClick: options.closeOnOverlayClick, closeOnEsc: options.closeOnEsc, style: options.style, buttons: list ? { direction: options.buttonsDirection, list } : undefined, classNames: options.classNames, children: content }));
54
54
  };
55
55
  root.render(_jsx(ModalHost, {}));
56
56
  });
@@ -52,12 +52,14 @@ export interface LDModalViewProps {
52
52
  scrollBehavior?: 'inside' | 'outside';
53
53
  /** 오버레이(모달 바깥) 클릭으로 닫기 허용 여부 */
54
54
  closeOnOverlayClick?: boolean;
55
+ /** ESC 키로 닫기 허용 여부 */
56
+ closeOnEsc?: boolean;
55
57
  /** 인라인 스타일 (모달 패널에 적용) */
56
58
  style?: React.CSSProperties;
57
59
  /** 버튼 클릭 시 해당 버튼의 value를 전달하는 콜백 */
58
60
  onButtonClick?: (value: unknown) => void;
59
61
  classNames?: TModalClassNames;
60
62
  }
61
- declare const LDModalView: ({ open, defaultOpen, onOpenChange, name, title, description, children, size, icon, buttons, scrollBehavior, closeOnOverlayClick, classNames, style, onButtonClick, }: LDModalViewProps) => import("react/jsx-runtime").JSX.Element;
63
+ declare const LDModalView: ({ open, defaultOpen, onOpenChange, name, title, description, children, size, icon, buttons, scrollBehavior, closeOnOverlayClick, closeOnEsc, classNames, style, onButtonClick, }: LDModalViewProps) => import("react/jsx-runtime").JSX.Element;
62
64
  export default LDModalView;
63
65
  //# sourceMappingURL=LDModalView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LDModalView.d.ts","sourceRoot":"","sources":["../../../src/components/LDModal/LDModalView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,OAAO,CAAC;AAK/C,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC7B,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,KAAK,EAAE,CAAC,CAAC;IACT,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACzD,eAAe;IACf,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvC,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yBAAyB;IACzB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,2BAA2B;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY;IACZ,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,gBAAgB;IAChB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,aAAa;IACb,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gBAAgB;IAChB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,eAAe;IACf,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,aAAa;IACb,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACtC,gCAAgC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,0BAA0B;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,oCAAoC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AA6CD,QAAA,MAAM,WAAW,GAAI,sKAgBlB,gBAAgB,4CAsLlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"LDModalView.d.ts","sourceRoot":"","sources":["../../../src/components/LDModal/LDModalView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,OAAO,CAAC;AAK/C,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC7B,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,KAAK,EAAE,CAAC,CAAC;IACT,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACzD,eAAe;IACf,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvC,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yBAAyB;IACzB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,2BAA2B;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY;IACZ,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,gBAAgB;IAChB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,aAAa;IACb,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gBAAgB;IAChB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,eAAe;IACf,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,aAAa;IACb,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACtC,gCAAgC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,oCAAoC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AA6CD,QAAA,MAAM,WAAW,GAAI,kLAiBlB,gBAAgB,4CAoLlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -42,7 +42,7 @@ const statusIconSizeClasses = {
42
42
  large: 'size-12.5',
43
43
  xlarge: 'size-12.5',
44
44
  };
45
- const LDModalView = ({ open, defaultOpen, onOpenChange, name, title, description, children, size = 'small', icon, buttons, scrollBehavior = 'inside', closeOnOverlayClick = true, classNames, style, onButtonClick, }) => {
45
+ const LDModalView = ({ open, defaultOpen, onOpenChange, name, title, description, children, size = 'small', icon, buttons, scrollBehavior = 'inside', closeOnOverlayClick = true, closeOnEsc = true, classNames, style, onButtonClick, }) => {
46
46
  const overlayRef = useRef(false);
47
47
  const hasHeader = name || title || description || icon;
48
48
  const handleClick = async (button) => {
@@ -57,14 +57,14 @@ const LDModalView = ({ open, defaultOpen, onOpenChange, name, title, description
57
57
  return (_jsxs(ModalBase.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, children: [_jsx(ModalBase.Overlay, { className: classNames?.overlay }), _jsx(ModalBase.Content, { className: cn({
58
58
  ['top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2']: scrollBehavior === 'inside',
59
59
  ['inset-0 flex items-start justify-center overflow-y-auto py-20']: scrollBehavior === 'outside',
60
- }, classNames?.content), onPointerDownOutside: closeOnOverlayClick ? undefined : (e) => e.preventDefault(), onMouseDown: (e) => (overlayRef.current = e.target === e.currentTarget), onClick: (e) => {
60
+ }, classNames?.content), onPointerDownOutside: closeOnOverlayClick ? undefined : (e) => e.preventDefault(), onEscapeKeyDown: closeOnEsc ? undefined : (e) => e.preventDefault(), onMouseDown: (e) => (overlayRef.current = e.target === e.currentTarget), onClick: (e) => {
61
61
  if (closeOnOverlayClick &&
62
62
  scrollBehavior === 'outside' &&
63
63
  e.target === e.currentTarget &&
64
64
  overlayRef.current)
65
65
  onOpenChange?.(false);
66
66
  overlayRef.current = false;
67
- }, children: _jsxs("div", { className: cn('relative rounded-2xl bg-white p-5', sizeClasses[size], 'mobile:max-w-[calc(100vw-40px)]', scrollBehavior === 'inside' && 'flex max-h-[90dvh] flex-col', classNames?.layout), style: style, onClick: (e) => e.stopPropagation(), children: [_jsx(ModalBase.Close, { asChild: true, className: cn('absolute top-4 right-5 cursor-pointer text-neutral500 outline-hidden', classNames?.close), children: _jsx(LDButton, { variant: "ghost", color: "neutral", leftIcon: _jsx(X, { className: "size-4" }), compact: true }) }), _jsxs("div", { className: cn('flex w-full shrink-0 flex-col', scrollBehavior === 'inside' && 'min-h-0 flex-1', layoutGapSizeClasses[size], !hasHeader && noHeaderPaddingTopSizeClasses[size], classNames?.panel), children: [_jsx(Show, { when: hasHeader, children: _jsxs("div", { className: "flex w-full shrink-0 flex-col items-center gap-5 py-5 text-center", children: [_jsx(Show, { when: icon === 'success', children: _jsx("div", { className: cn('flex items-center justify-center rounded-full bg-hyper-blue', statusIconSizeClasses[size]), children: _jsx(Check, { className: "text-white" }) }) }), _jsx(Show, { when: icon === 'fail', children: _jsx("div", { className: cn('flex items-center justify-center rounded-full bg-danger600', statusIconSizeClasses[size]), children: _jsx(CircleAlert, { className: "text-white" }) }) }), _jsx(Show, { when: name, children: _jsx("span", { className: "display16 bold whitespace-pre-wrap text-neutral500", children: name }) }), _jsx(Show, { when: title, children: _jsx(ModalBase.Title, { className: cn('text-center display28 bold whitespace-pre-wrap', classNames?.title), children: title }) }), _jsx(Show, { when: description, children: _jsx(ModalBase.Description, { className: cn('text-center display14 whitespace-pre-wrap text-neutral500', classNames?.description), children: description }) })] }) }), _jsx(Show, { when: children, children: _jsx("div", { className: cn(scrollBehavior === 'inside' &&
67
+ }, children: _jsxs("div", { className: cn('relative rounded-2xl bg-white p-5', sizeClasses[size], 'mobile:max-w-[calc(100vw-40px)]', scrollBehavior === 'inside' && 'flex max-h-[90dvh] flex-col', classNames?.layout), style: style, onClick: (e) => e.stopPropagation(), children: [_jsx(ModalBase.Close, { asChild: true, className: cn('absolute top-5 right-5 z-10 flex cursor-pointer text-neutral500 outline-hidden transition-colors after:absolute after:top-1/2 after:left-1/2 after:size-10 after:-translate-1/2 hover:text-neutral700', classNames?.close), children: _jsx("button", { type: "button", "aria-label": "\uB2EB\uAE30", children: _jsx(X, { className: "size-4 tablet:size-5 pc:size-6" }) }) }), _jsxs("div", { className: cn('flex w-full shrink-0 flex-col', scrollBehavior === 'inside' && 'min-h-0 flex-1', layoutGapSizeClasses[size], !hasHeader && noHeaderPaddingTopSizeClasses[size], classNames?.panel), children: [_jsx(Show, { when: hasHeader, children: _jsxs("div", { className: "flex w-full shrink-0 flex-col items-center gap-5 py-5 text-center", children: [_jsx(Show, { when: icon === 'success', children: _jsx("div", { className: cn('flex items-center justify-center rounded-full bg-hyper-blue', statusIconSizeClasses[size]), children: _jsx(Check, { className: "text-white" }) }) }), _jsx(Show, { when: icon === 'fail', children: _jsx("div", { className: cn('flex items-center justify-center rounded-full bg-danger600', statusIconSizeClasses[size]), children: _jsx(CircleAlert, { className: "text-white" }) }) }), _jsx(Show, { when: name, children: _jsx("span", { className: "display16 bold whitespace-pre-wrap text-neutral500", children: name }) }), _jsx(Show, { when: title, children: _jsx(ModalBase.Title, { className: cn('text-center display28 bold whitespace-pre-wrap', classNames?.title), children: title }) }), _jsx(Show, { when: description, children: _jsx(ModalBase.Description, { className: cn('text-center display14 whitespace-pre-wrap text-neutral500', classNames?.description), children: description }) })] }) }), _jsx(Show, { when: children, children: _jsx("div", { className: cn(scrollBehavior === 'inside' &&
68
68
  'min-h-10 flex-1 overflow-y-auto'), children: children }) }), _jsx(Show, { when: buttons?.list?.length, children: _jsx("div", { className: cn('flex mobile:flex-1 mobile:flex-col mobile:items-center', buttons?.direction === 'column' ? 'flex-col' : 'flex-row', buttonsGapSizeClasses[size]), children: buttons?.list?.map((button, index) => {
69
69
  const isFirst = index === 0;
70
70
  return (_jsx("div", { className: "flex w-full flex-1", children: _jsx(LDButton, { type: "button", onClick: () => handleClick(button), variant: button.variant ?? (isFirst ? 'solid' : 'outline'), color: button.color ?? (isFirst ? 'point' : 'neutral'), size: buttonSizeClasses[size], block: true, children: button.label }) }, String(button.value)));
package/dist/index.css CHANGED
@@ -9,6 +9,7 @@
9
9
  "Courier New", monospace;
10
10
  --color-red-500: oklch(63.7% 0.237 25.331);
11
11
  --color-yellow-400: oklch(85.2% 0.199 91.936);
12
+ --color-blue-100: oklch(93.2% 0.032 255.585);
12
13
  --color-blue-400: oklch(70.7% 0.165 254.624);
13
14
  --color-blue-500: oklch(62.3% 0.214 259.815);
14
15
  --color-blue-600: oklch(54.6% 0.245 262.881);
@@ -432,6 +433,9 @@
432
433
  .absolute {
433
434
  position: absolute;
434
435
  }
436
+ .absolute\! {
437
+ position: absolute !important;
438
+ }
435
439
  .fixed {
436
440
  position: fixed;
437
441
  }
@@ -480,12 +484,18 @@
480
484
  .top-4 {
481
485
  top: calc(var(--spacing) * 4);
482
486
  }
487
+ .top-5 {
488
+ top: calc(var(--spacing) * 5);
489
+ }
483
490
  .top-16 {
484
491
  top: calc(var(--spacing) * 16);
485
492
  }
486
493
  .top-20 {
487
494
  top: calc(var(--spacing) * 20);
488
495
  }
496
+ .top-\[17px\] {
497
+ top: 17px;
498
+ }
489
499
  .top-\[40\%\] {
490
500
  top: 40%;
491
501
  }
@@ -1229,9 +1239,6 @@
1229
1239
  .mt-2 {
1230
1240
  margin-top: calc(var(--spacing) * 2);
1231
1241
  }
1232
- .mt-3 {
1233
- margin-top: calc(var(--spacing) * 3);
1234
- }
1235
1242
  .mt-md {
1236
1243
  margin-top: var(--spacing_20);
1237
1244
  }
@@ -1247,9 +1254,6 @@
1247
1254
  .-mb-px {
1248
1255
  margin-bottom: -1px;
1249
1256
  }
1250
- .mb-1 {
1251
- margin-bottom: calc(var(--spacing) * 1);
1252
- }
1253
1257
  .mb-2 {
1254
1258
  margin-bottom: calc(var(--spacing) * 2);
1255
1259
  }
@@ -1489,6 +1493,9 @@
1489
1493
  .h-1\.5 {
1490
1494
  height: calc(var(--spacing) * 1.5);
1491
1495
  }
1496
+ .h-1\.5\! {
1497
+ height: calc(var(--spacing) * 1.5) !important;
1498
+ }
1492
1499
  .h-2 {
1493
1500
  height: calc(var(--spacing) * 2);
1494
1501
  }
@@ -1742,6 +1749,9 @@
1742
1749
  .w-16 {
1743
1750
  width: calc(var(--spacing) * 16);
1744
1751
  }
1752
+ .w-19\! {
1753
+ width: calc(var(--spacing) * 19) !important;
1754
+ }
1745
1755
  .w-20 {
1746
1756
  width: calc(var(--spacing) * 20);
1747
1757
  }
@@ -2018,6 +2028,9 @@
2018
2028
  .grid-cols-3 {
2019
2029
  grid-template-columns: repeat(3, minmax(0, 1fr));
2020
2030
  }
2031
+ .grid-cols-5 {
2032
+ grid-template-columns: repeat(5, minmax(0, 1fr));
2033
+ }
2021
2034
  .grid-cols-7 {
2022
2035
  grid-template-columns: repeat(7, minmax(0, 1fr));
2023
2036
  }
@@ -2213,6 +2226,9 @@
2213
2226
  .rounded-\[10px\] {
2214
2227
  border-radius: 10px;
2215
2228
  }
2229
+ .rounded-\[10px\]\! {
2230
+ border-radius: 10px !important;
2231
+ }
2216
2232
  .rounded-\[12px\] {
2217
2233
  border-radius: 12px;
2218
2234
  }
@@ -2243,9 +2259,9 @@
2243
2259
  .rounded-xs {
2244
2260
  border-radius: var(--radius-xs);
2245
2261
  }
2246
- .rounded-t-2xl {
2247
- border-top-left-radius: var(--radius-2xl);
2248
- border-top-right-radius: var(--radius-2xl);
2262
+ .rounded-t-\[10px\] {
2263
+ border-top-left-radius: 10px;
2264
+ border-top-right-radius: 10px;
2249
2265
  }
2250
2266
  .rounded-t-lg {
2251
2267
  border-top-left-radius: var(--radius-lg);
@@ -2255,9 +2271,9 @@
2255
2271
  border-top-left-radius: var(--radius-md);
2256
2272
  border-top-right-radius: var(--radius-md);
2257
2273
  }
2258
- .rounded-l-2xl {
2259
- border-top-left-radius: var(--radius-2xl);
2260
- border-bottom-left-radius: var(--radius-2xl);
2274
+ .rounded-l-\[10px\] {
2275
+ border-top-left-radius: 10px;
2276
+ border-bottom-left-radius: 10px;
2261
2277
  }
2262
2278
  .rounded-l-lg {
2263
2279
  border-top-left-radius: var(--radius-lg);
@@ -2270,9 +2286,9 @@
2270
2286
  .rounded-tl-lg {
2271
2287
  border-top-left-radius: var(--radius-lg);
2272
2288
  }
2273
- .rounded-r-2xl {
2274
- border-top-right-radius: var(--radius-2xl);
2275
- border-bottom-right-radius: var(--radius-2xl);
2289
+ .rounded-r-\[10px\] {
2290
+ border-top-right-radius: 10px;
2291
+ border-bottom-right-radius: 10px;
2276
2292
  }
2277
2293
  .rounded-r-lg {
2278
2294
  border-top-right-radius: var(--radius-lg);
@@ -2285,9 +2301,9 @@
2285
2301
  .rounded-tr-lg {
2286
2302
  border-top-right-radius: var(--radius-lg);
2287
2303
  }
2288
- .rounded-b-2xl {
2289
- border-bottom-right-radius: var(--radius-2xl);
2290
- border-bottom-left-radius: var(--radius-2xl);
2304
+ .rounded-b-\[10px\] {
2305
+ border-bottom-right-radius: 10px;
2306
+ border-bottom-left-radius: 10px;
2291
2307
  }
2292
2308
  .rounded-b-lg {
2293
2309
  border-bottom-right-radius: var(--radius-lg);
@@ -2361,6 +2377,9 @@
2361
2377
  --tw-border-style: solid;
2362
2378
  border-style: solid;
2363
2379
  }
2380
+ .border-blue-500 {
2381
+ border-color: var(--color-blue-500);
2382
+ }
2364
2383
  .border-blue500 {
2365
2384
  border-color: var(--color-blue500);
2366
2385
  }
@@ -2439,6 +2458,9 @@
2439
2458
  background-color: color-mix(in oklab, var(--color-black) 40%, transparent);
2440
2459
  }
2441
2460
  }
2461
+ .bg-blue-100 {
2462
+ background-color: var(--color-blue-100);
2463
+ }
2442
2464
  .bg-blue-500 {
2443
2465
  background-color: var(--color-blue-500);
2444
2466
  }
@@ -2511,6 +2533,9 @@
2511
2533
  .bg-neutral100 {
2512
2534
  background-color: var(--color-neutral100);
2513
2535
  }
2536
+ .bg-neutral100\! {
2537
+ background-color: var(--color-neutral100) !important;
2538
+ }
2514
2539
  .bg-neutral200 {
2515
2540
  background-color: var(--color-neutral200);
2516
2541
  }
@@ -2632,6 +2657,9 @@
2632
2657
  .p-0 {
2633
2658
  padding: calc(var(--spacing) * 0);
2634
2659
  }
2660
+ .p-0\.5 {
2661
+ padding: calc(var(--spacing) * 0.5);
2662
+ }
2635
2663
  .p-0\.75 {
2636
2664
  padding: calc(var(--spacing) * 0.75);
2637
2665
  }
@@ -2779,9 +2807,6 @@
2779
2807
  .pt-1 {
2780
2808
  padding-top: calc(var(--spacing) * 1);
2781
2809
  }
2782
- .pt-2 {
2783
- padding-top: calc(var(--spacing) * 2);
2784
- }
2785
2810
  .pt-4 {
2786
2811
  padding-top: calc(var(--spacing) * 4);
2787
2812
  }
@@ -3230,6 +3255,9 @@
3230
3255
  .opacity-100 {
3231
3256
  opacity: 100%;
3232
3257
  }
3258
+ .opacity-100\! {
3259
+ opacity: 100% !important;
3260
+ }
3233
3261
  .shadow {
3234
3262
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
3235
3263
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -3627,6 +3655,12 @@
3627
3655
  inset-block: calc(var(--spacing) * 0);
3628
3656
  }
3629
3657
  }
3658
+ .after\:top-1\/2 {
3659
+ &::after {
3660
+ content: var(--tw-content);
3661
+ top: calc(1 / 2 * 100%);
3662
+ }
3663
+ }
3630
3664
  .after\:top-full {
3631
3665
  &::after {
3632
3666
  content: var(--tw-content);
@@ -3639,12 +3673,25 @@
3639
3673
  right: 100%;
3640
3674
  }
3641
3675
  }
3676
+ .after\:left-1\/2 {
3677
+ &::after {
3678
+ content: var(--tw-content);
3679
+ left: calc(1 / 2 * 100%);
3680
+ }
3681
+ }
3642
3682
  .after\:left-full {
3643
3683
  &::after {
3644
3684
  content: var(--tw-content);
3645
3685
  left: 100%;
3646
3686
  }
3647
3687
  }
3688
+ .after\:size-10 {
3689
+ &::after {
3690
+ content: var(--tw-content);
3691
+ width: calc(var(--spacing) * 10);
3692
+ height: calc(var(--spacing) * 10);
3693
+ }
3694
+ }
3648
3695
  .after\:h-0\.5 {
3649
3696
  &::after {
3650
3697
  content: var(--tw-content);
@@ -3657,6 +3704,14 @@
3657
3704
  width: calc(var(--spacing) * 0.5);
3658
3705
  }
3659
3706
  }
3707
+ .after\:-translate-1\/2 {
3708
+ &::after {
3709
+ content: var(--tw-content);
3710
+ --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
3711
+ --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
3712
+ translate: var(--tw-translate-x) var(--tw-translate-y);
3713
+ }
3714
+ }
3660
3715
  .after\:bg-transparent {
3661
3716
  &::after {
3662
3717
  content: var(--tw-content);
@@ -4668,21 +4723,6 @@
4668
4723
  visibility: hidden;
4669
4724
  }
4670
4725
  }
4671
- .mobile\:absolute {
4672
- @media (max-width: calc(768px - 1px)) {
4673
- position: absolute;
4674
- }
4675
- }
4676
- .mobile\:top-1\/2 {
4677
- @media (max-width: calc(768px - 1px)) {
4678
- top: calc(1 / 2 * 100%);
4679
- }
4680
- }
4681
- .mobile\:left-1\/2 {
4682
- @media (max-width: calc(768px - 1px)) {
4683
- left: calc(1 / 2 * 100%);
4684
- }
4685
- }
4686
4726
  .mobile\:block {
4687
4727
  @media (max-width: calc(768px - 1px)) {
4688
4728
  display: block;
@@ -4738,13 +4778,6 @@
4738
4778
  flex: 1;
4739
4779
  }
4740
4780
  }
4741
- .mobile\:-translate-1\/2 {
4742
- @media (max-width: calc(768px - 1px)) {
4743
- --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
4744
- --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
4745
- translate: var(--tw-translate-x) var(--tw-translate-y);
4746
- }
4747
- }
4748
4781
  .mobile\:flex-col {
4749
4782
  @media (max-width: calc(768px - 1px)) {
4750
4783
  flex-direction: column;
@@ -4831,6 +4864,14 @@
4831
4864
  font-weight: var(--font-medium);
4832
4865
  }
4833
4866
  }
4867
+ .tablet\:size-5 {
4868
+ @media (min-width: 768px) {
4869
+ @media (max-width: calc(992px - 1px)) {
4870
+ width: calc(var(--spacing) * 5);
4871
+ height: calc(var(--spacing) * 5);
4872
+ }
4873
+ }
4874
+ }
4834
4875
  .tablet-down\:display12 {
4835
4876
  @media (max-width: calc(992px - 1px)) {
4836
4877
  font-size: var(--text-display12);
@@ -4852,6 +4893,12 @@
4852
4893
  letter-spacing: var(--tracking-display16);
4853
4894
  }
4854
4895
  }
4896
+ .pc\:size-6 {
4897
+ @media (min-width: 992px) {
4898
+ width: calc(var(--spacing) * 6);
4899
+ height: calc(var(--spacing) * 6);
4900
+ }
4901
+ }
4855
4902
  .\[\&_svg\]\:icon-2xs {
4856
4903
  & svg {
4857
4904
  width: var(--control-icon-2xs);
@@ -5524,7 +5571,7 @@
5524
5571
  }
5525
5572
  .ProseMirror img {
5526
5573
  max-width: 100%;
5527
- height: auto;
5574
+ height: auto !important;
5528
5575
  display: block;
5529
5576
  margin: 1rem auto;
5530
5577
  }
@@ -5542,7 +5589,6 @@
5542
5589
  }
5543
5590
  .ProseMirror img {
5544
5591
  cursor: pointer;
5545
- border: 2px solid transparent;
5546
5592
  transition: border-color 0.2s;
5547
5593
  }
5548
5594
  .ProseMirror img:hover {
@@ -5611,6 +5657,54 @@
5611
5657
  .ProseMirror [data-resize-wrapper] img {
5612
5658
  margin: 0 !important;
5613
5659
  }
5660
+ .ProseMirror [data-resize-wrapper] {
5661
+ width: fit-content;
5662
+ }
5663
+ .ProseMirror .tableWrapper {
5664
+ overflow-x: auto;
5665
+ margin: 1rem 0;
5666
+ }
5667
+ .ProseMirror table {
5668
+ width: 100%;
5669
+ margin: 0;
5670
+ table-layout: fixed;
5671
+ border-collapse: collapse;
5672
+ }
5673
+ .ProseMirror table td, .ProseMirror table th {
5674
+ position: relative;
5675
+ min-width: 1em;
5676
+ padding: 0.5rem 0.75rem;
5677
+ border: 1px solid var(--color-neutral200);
5678
+ vertical-align: top;
5679
+ }
5680
+ .ProseMirror table th {
5681
+ background: var(--color-mono100);
5682
+ font-weight: 600;
5683
+ text-align: left;
5684
+ }
5685
+ .ProseMirror table p {
5686
+ margin: 0;
5687
+ }
5688
+ .ProseMirror .selectedCell::after {
5689
+ content: '';
5690
+ position: absolute;
5691
+ inset: 0;
5692
+ background: rgba(59, 130, 246, 0.15);
5693
+ pointer-events: none;
5694
+ z-index: 2;
5695
+ }
5696
+ .ProseMirror .column-resize-handle {
5697
+ position: absolute;
5698
+ top: 0;
5699
+ right: -2px;
5700
+ bottom: -2px;
5701
+ width: 4px;
5702
+ background: #3b82f6;
5703
+ pointer-events: none;
5704
+ }
5705
+ .ProseMirror.resize-cursor {
5706
+ cursor: col-resize;
5707
+ }
5614
5708
  @layer components {
5615
5709
  .select-2xs {
5616
5710
  height: var(--control-height-2xs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loword/loword-design-system",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "description": "로워드 디자인 시스템 컴포넌트 패키지(Tailwind v4)",
5
5
  "keywords": [
6
6
  "react",
@@ -63,6 +63,7 @@
63
63
  "@tiptap/extension-highlight": "^3.26.0",
64
64
  "@tiptap/extension-image": "^3.26.0",
65
65
  "@tiptap/extension-link": "^3.26.0",
66
+ "@tiptap/extension-table": "^3.26.0",
66
67
  "@tiptap/extension-text-align": "^3.26.0",
67
68
  "@tiptap/extension-text-style": "^3.26.0",
68
69
  "@tiptap/extension-underline": "^3.26.0",
@@ -131,6 +132,9 @@
131
132
  "@tiptap/extension-link": {
132
133
  "optional": true
133
134
  },
135
+ "@tiptap/extension-table": {
136
+ "optional": true
137
+ },
134
138
  "@tiptap/extension-text-align": {
135
139
  "optional": true
136
140
  },
@@ -209,6 +213,7 @@
209
213
  "@tiptap/extension-highlight": "^3.26.0",
210
214
  "@tiptap/extension-image": "^3.26.0",
211
215
  "@tiptap/extension-link": "^3.26.0",
216
+ "@tiptap/extension-table": "^3.26.0",
212
217
  "@tiptap/extension-text-align": "^3.26.0",
213
218
  "@tiptap/extension-text-style": "^3.26.0",
214
219
  "@tiptap/extension-underline": "^3.26.0",
@@ -47,9 +47,13 @@
47
47
  }
48
48
 
49
49
  /* 이미지 정렬 스타일 */
50
+ /* height만 !important로 잠근다. 리사이즈 노드뷰가 width/height를 함께 인라인 px로
51
+ 쓰는데, 높이가 고정되면 컨테이너가 좁아질 때 max-width로 폭만 줄어 이미지가
52
+ 찌그러진다. 높이를 auto로 두면 항상 폭을 따라가므로 비율이 유지되고,
53
+ width는 인라인이 그대로 먹으므로 드래그 리사이즈도 동작한다. */
50
54
  .ProseMirror img {
51
55
  max-width: 100%;
52
- height: auto;
56
+ height: auto !important;
53
57
  display: block;
54
58
  margin: 1rem auto;
55
59
  }
@@ -72,7 +76,6 @@
72
76
  /* 이미지 선택 스타일 */
73
77
  .ProseMirror img {
74
78
  cursor: pointer;
75
- border: 2px solid transparent;
76
79
  transition: border-color 0.2s;
77
80
  }
78
81
 
@@ -165,3 +168,72 @@
165
168
  .ProseMirror [data-resize-wrapper] img {
166
169
  margin: 0 !important;
167
170
  }
171
+
172
+ /* 리사이즈 핸들은 래퍼를 기준으로 배치된다. 래퍼가 이미지보다 넓으면 핸들이
173
+ 이미지 모서리에서 떨어져 보이므로, 래퍼는 항상 이미지 크기에 맞춘다.
174
+ (래퍼는 부모가 block이면 기본값이 100%라 가만두면 벌어진다.) */
175
+ .ProseMirror [data-resize-wrapper] {
176
+ width: fit-content;
177
+ }
178
+
179
+ /* 표
180
+ prose 기본 표는 가로줄만 그어 에디터에서 셀 경계가 보이지 않는다. 격자 테두리로 덮는다.
181
+ @layer 밖(=무레이어)이라 utilities 레이어의 prose보다 우선한다. */
182
+ .ProseMirror .tableWrapper {
183
+ overflow-x: auto;
184
+ margin: 1rem 0;
185
+ }
186
+
187
+ .ProseMirror table {
188
+ width: 100%;
189
+ margin: 0;
190
+ /* 열 너비 리사이즈(colgroup width)가 반영되려면 fixed여야 한다. */
191
+ table-layout: fixed;
192
+ border-collapse: collapse;
193
+ }
194
+
195
+ .ProseMirror table td,
196
+ .ProseMirror table th {
197
+ /* 열 리사이즈 핸들의 위치 기준 */
198
+ position: relative;
199
+ min-width: 1em;
200
+ padding: 0.5rem 0.75rem;
201
+ border: 1px solid var(--color-neutral200);
202
+ vertical-align: top;
203
+ }
204
+
205
+ .ProseMirror table th {
206
+ background: var(--color-mono100);
207
+ font-weight: 600;
208
+ text-align: left;
209
+ }
210
+
211
+ /* 셀 안 문단은 prose의 블록 여백을 쓰지 않는다 — 셀 높이가 과하게 늘어난다. */
212
+ .ProseMirror table p {
213
+ margin: 0;
214
+ }
215
+
216
+ /* 드래그로 여러 셀을 선택했을 때 */
217
+ .ProseMirror .selectedCell::after {
218
+ content: '';
219
+ position: absolute;
220
+ inset: 0;
221
+ background: rgba(59, 130, 246, 0.15);
222
+ pointer-events: none;
223
+ z-index: 2;
224
+ }
225
+
226
+ /* 열 너비 리사이즈 핸들 (셀 오른쪽 경계) */
227
+ .ProseMirror .column-resize-handle {
228
+ position: absolute;
229
+ top: 0;
230
+ right: -2px;
231
+ bottom: -2px;
232
+ width: 4px;
233
+ background: #3b82f6;
234
+ pointer-events: none;
235
+ }
236
+
237
+ .ProseMirror.resize-cursor {
238
+ cursor: col-resize;
239
+ }