motile-ui 1.1.3 → 1.2.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.
Files changed (45) hide show
  1. package/README.md +6 -2
  2. package/dist/components/Accordion/index.d.ts +1 -1
  3. package/dist/components/Badge/Badge.css +1 -1
  4. package/dist/components/Badge/index.d.ts +1 -1
  5. package/dist/components/Button/index.d.ts +1 -1
  6. package/dist/components/Checkbox/index.d.ts +1 -1
  7. package/dist/components/Dock/index.d.ts +2 -2
  8. package/dist/components/Drawer/Drawer.js +6 -6
  9. package/dist/components/Drawer/index.d.ts +1 -1
  10. package/dist/components/Input/index.d.ts +1 -1
  11. package/dist/components/Modal/Modal.d.ts +1 -1
  12. package/dist/components/Modal/Modal.js +8 -8
  13. package/dist/components/Modal/index.d.ts +1 -1
  14. package/dist/components/NumberFlow/NumberFlow.css +1 -0
  15. package/dist/components/NumberFlow/NumberFlow.d.ts +31 -0
  16. package/dist/components/NumberFlow/NumberFlow.js +128 -0
  17. package/dist/components/NumberFlow/NumberFlow.test.d.ts +1 -0
  18. package/dist/components/NumberFlow/index.d.ts +2 -0
  19. package/dist/components/Popover/Popover.d.ts +1 -1
  20. package/dist/components/Popover/Popover.js +8 -8
  21. package/dist/components/Popover/index.d.ts +1 -1
  22. package/dist/components/Sheet/Sheet.d.ts +1 -1
  23. package/dist/components/Sheet/Sheet.js +6 -6
  24. package/dist/components/Sheet/index.d.ts +1 -1
  25. package/dist/components/Skeleton/index.d.ts +1 -1
  26. package/dist/components/SpeedDial/SpeedDial.js +1 -1
  27. package/dist/components/SpeedDial/index.d.ts +2 -2
  28. package/dist/components/Switch/index.d.ts +1 -1
  29. package/dist/components/Textarea/index.d.ts +1 -1
  30. package/dist/components/TimePicker/TimePicker.css +1 -0
  31. package/dist/components/TimePicker/TimePicker.d.ts +32 -0
  32. package/dist/components/TimePicker/TimePicker.js +280 -0
  33. package/dist/components/TimePicker/TimePicker.test.d.ts +1 -0
  34. package/dist/components/TimePicker/index.d.ts +2 -0
  35. package/dist/components/Toast/index.d.ts +2 -2
  36. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  37. package/dist/components/Tooltip/Tooltip.js +4 -4
  38. package/dist/components/Tooltip/index.d.ts +1 -1
  39. package/dist/hooks/index.d.ts +3 -3
  40. package/dist/hooks/index.js +6 -6
  41. package/dist/index.d.ts +31 -27
  42. package/dist/index.js +34 -30
  43. package/dist/test/utils.d.ts +1 -1
  44. package/dist/utils/Slot.js +7 -7
  45. package/package.json +21 -1
package/README.md CHANGED
@@ -37,7 +37,7 @@
37
37
 
38
38
  ## ✨ 주요 기능
39
39
 
40
- - 🎨 **16개의 고품질 컴포넌트** - 웹뷰 애플리케이션을 위해 세심하게 제작
40
+ - 🎨 **18개의 고품질 컴포넌트** - 웹뷰 애플리케이션을 위해 세심하게 제작
41
41
  - 💪 **TypeScript 우선** - 포괄적인 타입 정의 완벽 지원
42
42
  - 🎭 **커스터마이징 가능** - CSS 변수로 쉬운 테마 설정
43
43
  - 📱 **모바일 최적화** - 터치 친화적 인터랙션과 반응형 디자인
@@ -187,6 +187,8 @@ color props > --motile-ui-btn > --motile-theme > #3b82f6 (기본값)
187
187
  - **Tooltip** - 툴팁
188
188
  - **Accordion** - 접을 수 있는 패널
189
189
  - **Dock** - 독 스타일 네비게이션 바
190
+ - **NumberFlow** - 숫자 애니메이션 컴포넌트
191
+ - **TimePicker** - 휠 스크롤 방식 타임피커
190
192
 
191
193
  ---
192
194
 
@@ -217,7 +219,7 @@ MIT © [Innopers](https://github.com/Innopers)
217
219
 
218
220
  ## ✨ Features
219
221
 
220
- - 🎨 **16 High-Quality Components** - Carefully crafted for webview applications
222
+ - 🎨 **18 High-Quality Components** - Carefully crafted for webview applications
221
223
  - 💪 **TypeScript First** - Full TypeScript support with comprehensive type definitions
222
224
  - 🎭 **Customizable** - Easy theming with CSS variables
223
225
  - 📱 **Mobile Optimized** - Touch-friendly interactions and responsive design
@@ -367,6 +369,8 @@ color props > --motile-ui-btn > --motile-theme > #3b82f6 (default)
367
369
  - **Tooltip** - Tooltip
368
370
  - **Accordion** - Collapsible panel
369
371
  - **Dock** - Dock-style navigation bar
372
+ - **NumberFlow** - Animated number transition component
373
+ - **TimePicker** - Wheel scroll style time picker
370
374
 
371
375
  ---
372
376
 
@@ -1,2 +1,2 @@
1
+ export type { AccordionContentProps, AccordionHeaderProps, AccordionProps, } from './Accordion';
1
2
  export { Accordion } from './Accordion';
2
- export type { AccordionProps, AccordionHeaderProps, AccordionContentProps, } from './Accordion';
@@ -1 +1 @@
1
- .motile-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.2;border-radius:9999px;white-space:nowrap;vertical-align:middle;background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );color:#fff}.motile-badge--large{padding:6px 16px;font-size:1rem;min-height:32px}.motile-badge--medium{padding:5px 12px;font-size:.875rem;min-height:26px}.motile-badge--small{padding:4px 8px;font-size:.75rem;min-height:24px}.motile-badge--primary{background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );color:#fff}.motile-badge--secondary{background:color-mix(in srgb,var(--motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6))) 10%,transparent);color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );border:1px solid var(--motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)))}.motile-badge--secondary.motile-badge--large{padding:5px 15px;min-height:30px}.motile-badge--secondary.motile-badge--medium{padding:4px 11px;min-height:24px}.motile-badge--secondary.motile-badge--small{padding:3px 7px;min-height:22px}.motile-badge--outlined{background-color:#fff;color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );border:1px solid var(--motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)))}.motile-badge--outlined.motile-badge--large{padding:5px 15px;min-height:30px}.motile-badge--outlined.motile-badge--medium{padding:4px 11px;min-height:24px}.motile-badge--outlined.motile-badge--small{padding:3px 7px;min-height:22px}.motile-badge--dot{background-color:transparent;padding:0;gap:6px;color:inherit}.motile-badge__dot{display:inline-block;border-radius:50%;background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) )}.motile-badge__text{line-height:1.2}.motile-badge--dot.motile-badge--large .motile-badge__dot{width:12px;height:12px}.motile-badge--dot.motile-badge--medium .motile-badge__dot{width:10px;height:10px}.motile-badge--dot.motile-badge--small .motile-badge__dot{width:8px;height:8px}.motile-badge--shimmer{background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );color:#fff;position:relative;overflow:hidden}.motile-badge--shimmer:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.3) 50%,transparent 100%);animation:shimmer 2s infinite}@keyframes shimmer{0%{transform:translate(0)}to{transform:translate(200%)}}@media (prefers-reduced-motion: reduce){.motile-badge--shimmer:before{animation:none}}@media (max-width: 768px){.motile-badge:active{filter:brightness(.92)}}@supports (-webkit-touch-callout: none){.motile-badge{-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}}
1
+ .motile-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.2;border-radius:9999px;white-space:nowrap;vertical-align:middle;background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );color:#fff}.motile-badge--large{padding:6px 16px;font-size:1rem;min-height:32px}.motile-badge--medium{padding:5px 12px;font-size:.875rem;min-height:26px}.motile-badge--small{padding:4px 8px;font-size:.75rem;min-height:24px}.motile-badge--primary{background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );color:#fff}.motile-badge--secondary{background:color-mix(in srgb,var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) ) 10%,transparent);color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );border:1px solid var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) )}.motile-badge--secondary.motile-badge--large{padding:5px 15px;min-height:30px}.motile-badge--secondary.motile-badge--medium{padding:4px 11px;min-height:24px}.motile-badge--secondary.motile-badge--small{padding:3px 7px;min-height:22px}.motile-badge--outlined{background-color:#fff;color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );border:1px solid var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) )}.motile-badge--outlined.motile-badge--large{padding:5px 15px;min-height:30px}.motile-badge--outlined.motile-badge--medium{padding:4px 11px;min-height:24px}.motile-badge--outlined.motile-badge--small{padding:3px 7px;min-height:22px}.motile-badge--dot{background-color:transparent;padding:0;gap:6px;color:inherit}.motile-badge__dot{display:inline-block;border-radius:50%;background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) )}.motile-badge__text{line-height:1.2}.motile-badge--dot.motile-badge--large .motile-badge__dot{width:12px;height:12px}.motile-badge--dot.motile-badge--medium .motile-badge__dot{width:10px;height:10px}.motile-badge--dot.motile-badge--small .motile-badge__dot{width:8px;height:8px}.motile-badge--shimmer{background-color:var( --motile-badge-color, var(--motile-ui-badge, var(--motile-theme, #3b82f6)) );color:#fff;position:relative;overflow:hidden}.motile-badge--shimmer:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.3) 50%,transparent 100%);animation:shimmer 2s infinite}@keyframes shimmer{0%{transform:translate(0)}to{transform:translate(200%)}}@media (prefers-reduced-motion: reduce){.motile-badge--shimmer:before{animation:none}}@media (max-width: 768px){.motile-badge:active{filter:brightness(.92)}}@supports (-webkit-touch-callout: none){.motile-badge{-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}}
@@ -1,2 +1,2 @@
1
- export { Badge } from './Badge';
2
1
  export type { BadgeProps } from './Badge';
2
+ export { Badge } from './Badge';
@@ -1,2 +1,2 @@
1
- export { Button } from './Button';
2
1
  export type { ButtonProps } from './Button';
2
+ export { Button } from './Button';
@@ -1,2 +1,2 @@
1
- export { Checkbox } from './Checkbox';
2
1
  export type { CheckboxProps } from './Checkbox';
2
+ export { Checkbox } from './Checkbox';
@@ -1,2 +1,2 @@
1
- export { Dock, DockRoot, DockItem, DockSeparator } from './Dock';
2
- export type { DockRootProps, DockItemProps, DockSeparatorProps, DockPosition, } from './Dock';
1
+ export type { DockItemProps, DockPosition, DockRootProps, DockSeparatorProps, } from './Dock';
2
+ export { Dock, DockItem, DockRoot, DockSeparator } from './Dock';
@@ -1,10 +1,10 @@
1
1
  import { jsx as u } from "react/jsx-runtime";
2
2
  import W, { forwardRef as w, useState as g, useEffect as Y, useRef as _, createContext as G, useContext as J } from "react";
3
3
  import { createPortal as Q } from "react-dom";
4
+ import { useClickOutside as X } from "../../hooks/useClickOutside.js";
5
+ import { useEscapeKey as Z } from "../../hooks/useEscapeKey.js";
6
+ import { useScrollLock as k } from "../../hooks/useScrollLock.js";
4
7
  import { Slot as M } from "../../utils/Slot.js";
5
- import { useScrollLock as X } from "../../hooks/useScrollLock.js";
6
- import { useClickOutside as Z } from "../../hooks/useClickOutside.js";
7
- import { useEscapeKey as k } from "../../hooks/useEscapeKey.js";
8
8
  import './Drawer.css';/* empty css */
9
9
  const $ = G(null), f = () => {
10
10
  const r = J($);
@@ -29,7 +29,7 @@ const $ = G(null), f = () => {
29
29
  escapeKey: (e == null ? void 0 : e.escapeKey) ?? !1,
30
30
  clickOutside: (e == null ? void 0 : e.clickOutside) ?? !1
31
31
  };
32
- X({
32
+ k({
33
33
  enabled: D,
34
34
  allowedSelectors: ["[data-scroll-allowed]", ".motile-drawer__body"]
35
35
  });
@@ -54,11 +54,11 @@ const $ = G(null), f = () => {
54
54
  i.style.transition = "transform 0.3s ease", i.style.transform = "translateY(0)", N(!0);
55
55
  });
56
56
  });
57
- }, [x]), Z({
57
+ }, [x]), X({
58
58
  refs: [a],
59
59
  handler: p,
60
60
  enabled: D && S.clickOutside
61
- }), k({
61
+ }), Z({
62
62
  handler: p,
63
63
  enabled: D && S.escapeKey
64
64
  });
@@ -1,2 +1,2 @@
1
+ export type { CloseOnBackdropOptions, DrawerBodyProps, DrawerCloseProps, DrawerContentProps, DrawerHandleProps, DrawerOverlayProps, DrawerPortalProps, DrawerRootProps, DrawerTitleProps, DrawerTriggerProps, } from './Drawer';
1
2
  export { Drawer } from './Drawer';
2
- export type { CloseOnBackdropOptions, DrawerRootProps, DrawerTriggerProps, DrawerPortalProps, DrawerOverlayProps, DrawerContentProps, DrawerHandleProps, DrawerTitleProps, DrawerBodyProps, DrawerCloseProps, } from './Drawer';
@@ -1,2 +1,2 @@
1
- export { Input } from './Input';
2
1
  export type { InputProps } from './Input';
2
+ export { Input } from './Input';
@@ -148,4 +148,4 @@ export declare const Modal: {
148
148
  Footer: React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLDivElement>>;
149
149
  Header: React.ForwardRefExoticComponent<ModalHeaderProps & React.RefAttributes<HTMLDivElement>>;
150
150
  };
151
- export type { ModalVariant, ModalRootProps, ModalOverlayProps, ModalContentProps, ModalCloseProps, ModalTitleProps, ModalBodyProps, ModalHeaderProps, ModalFooterProps, };
151
+ export type { ModalBodyProps, ModalCloseProps, ModalContentProps, ModalFooterProps, ModalHeaderProps, ModalOverlayProps, ModalRootProps, ModalTitleProps, ModalVariant, };
@@ -1,10 +1,10 @@
1
1
  import { jsx as l, jsxs as L } from "react/jsx-runtime";
2
2
  import n, { useRef as k, useState as O, useEffect as P, useId as h, createContext as V, useContext as q } from "react";
3
3
  import { createPortal as z } from "react-dom";
4
- import { Slot as A } from "../../utils/Slot.js";
5
- import { useClickOutside as D } from "../../hooks/useClickOutside.js";
6
- import { useEscapeKey as G } from "../../hooks/useEscapeKey.js";
7
- import { useScrollLock as J } from "../../hooks/useScrollLock.js";
4
+ import { useClickOutside as A } from "../../hooks/useClickOutside.js";
5
+ import { useEscapeKey as D } from "../../hooks/useEscapeKey.js";
6
+ import { useScrollLock as G } from "../../hooks/useScrollLock.js";
7
+ import { Slot as J } from "../../utils/Slot.js";
8
8
  import './Modal.css';/* empty css */
9
9
  const v = V(null), m = () => {
10
10
  const o = q(v);
@@ -45,16 +45,16 @@ const v = V(null), m = () => {
45
45
  E(!0);
46
46
  }, []);
47
47
  const b = typeof e == "boolean" ? e : e.clickOutside ?? !1, T = typeof e == "boolean" ? e : e.escapeKey ?? !1;
48
- J({
48
+ G({
49
49
  enabled: c && !a,
50
50
  allowedSelectors: [".motile-modal__content"]
51
- }), D({
51
+ }), A({
52
52
  refs: [M],
53
53
  handler: () => {
54
54
  b && f(!1);
55
55
  },
56
56
  enabled: c
57
- }), G({
57
+ }), D({
58
58
  handler: () => {
59
59
  T && f(!1);
60
60
  },
@@ -152,7 +152,7 @@ const R = n.forwardRef(
152
152
  e == null || e(i), s(!1);
153
153
  };
154
154
  return o ? /* @__PURE__ */ l(
155
- A,
155
+ J,
156
156
  {
157
157
  ...d,
158
158
  onClick: u,
@@ -1,2 +1,2 @@
1
+ export type { CloseOnBackdropOptions, ModalBodyProps, ModalCloseProps, ModalContentProps, ModalFooterProps, ModalHeaderProps, ModalOverlayProps, ModalRootProps, ModalTitleProps, ModalVariant, } from './Modal';
1
2
  export { Modal } from './Modal';
2
- export type { ModalVariant, CloseOnBackdropOptions, ModalRootProps, ModalOverlayProps, ModalContentProps, ModalCloseProps, ModalTitleProps, ModalBodyProps, ModalHeaderProps, ModalFooterProps, } from './Modal';
@@ -0,0 +1 @@
1
+ .motile-number-flow{display:inline-flex;align-items:center;font-variant-numeric:tabular-nums;line-height:1}.motile-number-flow__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.motile-number-flow__value{display:inline-flex;align-items:center}.motile-number-flow__digit{display:inline-block;height:1em;overflow:hidden;line-height:1;vertical-align:top}.motile-number-flow__digit-column{display:flex;flex-direction:column;will-change:transform;transform:translateZ(0);backface-visibility:hidden}.motile-number-flow__digit-value{display:flex;align-items:center;justify-content:center;height:1em;line-height:1}.motile-number-flow__separator{display:inline-block;line-height:1}@media (prefers-reduced-motion: reduce){.motile-number-flow__digit-column{transition:none!important}}
@@ -0,0 +1,31 @@
1
+ import { default as React } from 'react';
2
+ export interface NumberFlowProps {
3
+ /**
4
+ * 표시할 숫자 값
5
+ */
6
+ value: number;
7
+ /**
8
+ * 로케일 (기본값: 'ko-KR')
9
+ * @example 'en-US', 'ko-KR', 'ja-JP'
10
+ */
11
+ locale?: string;
12
+ /**
13
+ * 애니메이션 지속 시간 (ms)
14
+ * @default 600
15
+ */
16
+ duration?: number;
17
+ /**
18
+ * 컨테이너 className
19
+ */
20
+ className?: string;
21
+ /**
22
+ * 인라인 스타일
23
+ */
24
+ style?: React.CSSProperties;
25
+ /**
26
+ * 마운트 시 애니메이션 적용 여부
27
+ * @default true
28
+ */
29
+ animateOnMount?: boolean;
30
+ }
31
+ export declare const NumberFlow: React.ForwardRefExoticComponent<NumberFlowProps & React.RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,128 @@
1
+ import { jsx as l, jsxs as M } from "react/jsx-runtime";
2
+ import g, { useRef as y, useMemo as _, useEffect as R, useState as C } from "react";
3
+ import './NumberFlow.css';/* empty css */
4
+ function O(t, a) {
5
+ return new Intl.NumberFormat(a).format(t);
6
+ }
7
+ function x(t) {
8
+ return /^\d$/.test(t);
9
+ }
10
+ const T = [
11
+ "0",
12
+ "1",
13
+ "2",
14
+ "3",
15
+ "4",
16
+ "5",
17
+ "6",
18
+ "7",
19
+ "8",
20
+ "9",
21
+ "0",
22
+ "1",
23
+ "2",
24
+ "3",
25
+ "4",
26
+ "5",
27
+ "6",
28
+ "7",
29
+ "8",
30
+ "9",
31
+ "0",
32
+ "1",
33
+ "2",
34
+ "3",
35
+ "4",
36
+ "5",
37
+ "6",
38
+ "7",
39
+ "8",
40
+ "9"
41
+ ], S = g.memo(
42
+ ({ value: t, prevValue: a, direction: i, duration: N, index: b, animateOnMount: p }) => {
43
+ const r = parseInt(t, 10), e = a === null ? p ? 0 : r : parseInt(a, 10), [s, u] = C(e), c = b * 50;
44
+ R(() => {
45
+ if (e === r)
46
+ return;
47
+ let n;
48
+ i === "up" ? n = r >= e ? r - e : 10 - e + r : n = e >= r ? e - r : e + 10 - r;
49
+ const o = setTimeout(() => {
50
+ u(
51
+ (f) => i === "up" ? f + n : f - n
52
+ );
53
+ }, c + 10);
54
+ return () => clearTimeout(o);
55
+ }, [t, e, r, i, c]);
56
+ const w = {
57
+ transform: `translateY(${-((s % 30 + 30) % 30) * (100 / 30)}%)`,
58
+ transition: `transform ${N}ms ease-out`
59
+ };
60
+ return /* @__PURE__ */ l("span", { className: "motile-number-flow__digit", children: /* @__PURE__ */ l("span", { className: "motile-number-flow__digit-column", style: w, children: T.map((n, o) => /* @__PURE__ */ l("span", { className: "motile-number-flow__digit-value", children: n }, o)) }) });
61
+ }
62
+ );
63
+ S.displayName = "NumberFlow.Digit";
64
+ const $ = g.memo(({ value: t }) => /* @__PURE__ */ l("span", { className: "motile-number-flow__separator", children: t }));
65
+ $.displayName = "NumberFlow.Separator";
66
+ const Y = g.forwardRef(
67
+ ({
68
+ value: t,
69
+ locale: a = "ko-KR",
70
+ duration: i = 600,
71
+ className: N,
72
+ style: b,
73
+ animateOnMount: p = !0
74
+ }, r) => {
75
+ const d = y(null), e = y(null), s = _(
76
+ () => O(t, a),
77
+ [t, a]
78
+ ), u = e.current, c = _(() => {
79
+ if (d.current === null) return "up";
80
+ const m = d.current;
81
+ return m < 0 && t < 0 ? Math.abs(t) >= Math.abs(m) ? "up" : "down" : t >= m ? "up" : "down";
82
+ }, [t]);
83
+ R(() => {
84
+ d.current = t, e.current = s;
85
+ }, [t, s]);
86
+ const h = _(() => {
87
+ const m = s.split(""), w = (u == null ? void 0 : u.split("")) || [];
88
+ let n = 0;
89
+ return m.map((o, f) => {
90
+ const I = `${f}-${o}`, D = w[f] || null;
91
+ if (x(o)) {
92
+ const F = n;
93
+ return n++, /* @__PURE__ */ l(
94
+ S,
95
+ {
96
+ value: o,
97
+ prevValue: x(D || "") ? D : null,
98
+ direction: c,
99
+ duration: i,
100
+ index: F,
101
+ animateOnMount: p
102
+ },
103
+ I
104
+ );
105
+ }
106
+ return /* @__PURE__ */ l($, { value: o }, I);
107
+ });
108
+ }, [s, u, c, i, p]);
109
+ return /* @__PURE__ */ M(
110
+ "span",
111
+ {
112
+ ref: r,
113
+ className: `motile-number-flow ${N || ""}`,
114
+ style: b,
115
+ "aria-label": s,
116
+ role: "text",
117
+ children: [
118
+ /* @__PURE__ */ l("span", { className: "motile-number-flow__sr-only", children: s }),
119
+ /* @__PURE__ */ l("span", { className: "motile-number-flow__value", "aria-hidden": "true", children: h })
120
+ ]
121
+ }
122
+ );
123
+ }
124
+ );
125
+ Y.displayName = "NumberFlow";
126
+ export {
127
+ Y as NumberFlow
128
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export type { NumberFlowProps } from './NumberFlow';
2
+ export { NumberFlow } from './NumberFlow';
@@ -68,4 +68,4 @@ export declare const Popover: {
68
68
  Trigger: typeof PopoverTrigger;
69
69
  Content: typeof PopoverContent;
70
70
  };
71
- export type { PopoverRootProps, PopoverTriggerProps, PopoverContentProps, Placement, Align, PopoverVariant, };
71
+ export type { Align, Placement, PopoverContentProps, PopoverRootProps, PopoverTriggerProps, PopoverVariant, };
@@ -1,10 +1,10 @@
1
1
  import { jsxs as $, jsx as g } from "react/jsx-runtime";
2
2
  import h, { useCallback as R, useId as k, useRef as I, useMemo as N, createContext as j, useContext as E } from "react";
3
+ import { useClickOutside as T } from "../../hooks/useClickOutside.js";
4
+ import { useEscapeKey as A } from "../../hooks/useEscapeKey.js";
5
+ import { FloatingArrow as B } from "../../utils/FloatingArrow.js";
6
+ import { Slot as F } from "../../utils/Slot.js";
3
7
  import './Popover.css';/* empty css */
4
- import { Slot as T } from "../../utils/Slot.js";
5
- import { useClickOutside as A } from "../../hooks/useClickOutside.js";
6
- import { useEscapeKey as B } from "../../hooks/useEscapeKey.js";
7
- import { FloatingArrow as F } from "../../utils/FloatingArrow.js";
8
8
  const S = j(null);
9
9
  function C() {
10
10
  const t = E(S);
@@ -91,7 +91,7 @@ function V({ children: t, asChild: s = !1 }) {
91
91
  e((c) => !c);
92
92
  }, [e]);
93
93
  return s ? /* @__PURE__ */ g(
94
- T,
94
+ F,
95
95
  {
96
96
  ref: (c) => {
97
97
  l.current = c;
@@ -137,7 +137,7 @@ function q({
137
137
  contentRef: w,
138
138
  wrapperRef: b
139
139
  } = C();
140
- if (B({
140
+ if (A({
141
141
  handler: R(
142
142
  (p) => {
143
143
  u && (n == null || n(p), p.defaultPrevented || r(!1));
@@ -145,7 +145,7 @@ function q({
145
145
  [u, n, r]
146
146
  ),
147
147
  enabled: e
148
- }), A({
148
+ }), T({
149
149
  refs: [b],
150
150
  handler: R(
151
151
  (p) => {
@@ -175,7 +175,7 @@ function q({
175
175
  },
176
176
  children: [
177
177
  c && /* @__PURE__ */ g(
178
- F,
178
+ B,
179
179
  {
180
180
  className: "motile-popover-arrow",
181
181
  variant: a,
@@ -1,2 +1,2 @@
1
+ export type { Align, Placement, PopoverContentProps, PopoverRootProps, PopoverTriggerProps, PopoverVariant, } from './Popover';
1
2
  export { Popover } from './Popover';
2
- export type { PopoverRootProps, PopoverTriggerProps, PopoverContentProps, Placement, Align, PopoverVariant, } from './Popover';
@@ -96,4 +96,4 @@ export declare const Sheet: {
96
96
  Body: typeof SheetBody;
97
97
  Close: typeof SheetClose;
98
98
  };
99
- export type { SheetRootProps, SheetTriggerProps, SheetPortalProps, SheetOverlayProps, SheetContentProps, SheetHeaderProps, SheetTitleProps, SheetBodyProps, SheetCloseProps, };
99
+ export type { SheetBodyProps, SheetCloseProps, SheetContentProps, SheetHeaderProps, SheetOverlayProps, SheetPortalProps, SheetRootProps, SheetTitleProps, SheetTriggerProps, };
@@ -1,10 +1,10 @@
1
1
  import { jsx as d, jsxs as $ } from "react/jsx-runtime";
2
2
  import { useCallback as k, useState as S, useEffect as b, useId as A, useRef as g, useMemo as F, createContext as N, useContext as T } from "react";
3
3
  import { createPortal as w } from "react-dom";
4
+ import { useEscapeKey as K } from "../../hooks/useEscapeKey.js";
5
+ import { useHistoryClose as H } from "../../hooks/useHistoryClose.js";
6
+ import { useScrollLock as P } from "../../hooks/useScrollLock.js";
4
7
  import { Slot as O } from "../../utils/Slot.js";
5
- import { useScrollLock as K } from "../../hooks/useScrollLock.js";
6
- import { useEscapeKey as H } from "../../hooks/useEscapeKey.js";
7
- import { useHistoryClose as P } from "../../hooks/useHistoryClose.js";
8
8
  import './Sheet.css';/* empty css */
9
9
  const I = N(null);
10
10
  function v() {
@@ -42,7 +42,7 @@ function q({
42
42
  value: l,
43
43
  defaultValue: s,
44
44
  onChange: r
45
- }), { isClosingFromHistory: y, navigateAndClose: u } = P({
45
+ }), { isClosingFromHistory: y, navigateAndClose: u } = H({
46
46
  isOpen: c,
47
47
  onClose: () => p(!1),
48
48
  enabled: a
@@ -173,10 +173,10 @@ function E({ children: e, className: n = "", style: o }) {
173
173
  escapeKey: s.escapeKey ?? !1,
174
174
  clickOutside: s.clickOutside ?? !1
175
175
  };
176
- if (K({
176
+ if (P({
177
177
  enabled: t,
178
178
  allowedSelectors: [".motile-sheet__body"]
179
- }), H({
179
+ }), K({
180
180
  handler: () => i(!1),
181
181
  enabled: t && _.escapeKey
182
182
  }), b(() => {
@@ -1,2 +1,2 @@
1
+ export type { CloseOnBackdropOptions, SheetBodyProps, SheetCloseProps, SheetContentProps, SheetHeaderProps, SheetOverlayProps, SheetPortalProps, SheetPosition, SheetRootProps, SheetTitleProps, SheetTriggerProps, } from './Sheet';
1
2
  export { Sheet } from './Sheet';
2
- export type { SheetPosition, CloseOnBackdropOptions, SheetRootProps, SheetTriggerProps, SheetPortalProps, SheetOverlayProps, SheetContentProps, SheetHeaderProps, SheetTitleProps, SheetBodyProps, SheetCloseProps, } from './Sheet';
@@ -1,2 +1,2 @@
1
- export { Skeleton } from './Skeleton';
2
1
  export type { SkeletonProps } from './Skeleton';
2
+ export { Skeleton } from './Skeleton';
@@ -1,8 +1,8 @@
1
1
  import { jsx as s } from "react/jsx-runtime";
2
2
  import m, { forwardRef as c, useRef as y, useId as b, createContext as R, useContext as h } from "react";
3
- import { Slot as f } from "../../utils/Slot.js";
4
3
  import { useClickOutside as v } from "../../hooks/useClickOutside.js";
5
4
  import { useEscapeKey as A } from "../../hooks/useEscapeKey.js";
5
+ import { Slot as f } from "../../utils/Slot.js";
6
6
  import './SpeedDial.css';/* empty css */
7
7
  const _ = R(null), g = () => {
8
8
  const e = h(_);
@@ -1,2 +1,2 @@
1
- export { SpeedDial, SpeedDialRoot, SpeedDialTrigger, SpeedDialActions, SpeedDialAction, } from './SpeedDial';
2
- export type { SpeedDialDirection, SpeedDialRootProps, SpeedDialTriggerProps, SpeedDialActionsProps, SpeedDialActionProps, } from './SpeedDial';
1
+ export type { SpeedDialActionProps, SpeedDialActionsProps, SpeedDialDirection, SpeedDialRootProps, SpeedDialTriggerProps, } from './SpeedDial';
2
+ export { SpeedDial, SpeedDialAction, SpeedDialActions, SpeedDialRoot, SpeedDialTrigger, } from './SpeedDial';
@@ -1,2 +1,2 @@
1
- export { Switch } from './Switch';
2
1
  export type { SwitchProps } from './Switch';
2
+ export { Switch } from './Switch';
@@ -1,2 +1,2 @@
1
+ export type { AutoSizeConfig, TextareaProps } from './Textarea';
1
2
  export { Textarea } from './Textarea';
2
- export type { TextareaProps, AutoSizeConfig } from './Textarea';
@@ -0,0 +1 @@
1
+ .motile-timepicker{display:flex;position:relative;user-select:none;-webkit-user-select:none;overflow:hidden;width:200px;height:120px}.motile-timepicker--disabled{pointer-events:none}.motile-timepicker__column{flex:1;overflow-y:scroll;overflow-x:hidden;scroll-snap-type:none;scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;touch-action:pan-y;cursor:grab}@media (hover: none) and (pointer: coarse){.motile-timepicker__column{scroll-snap-type:y mandatory;cursor:default}}.motile-timepicker__column::-webkit-scrollbar{display:none}.motile-timepicker__item{display:flex;align-items:center;justify-content:center;scroll-snap-align:center;font-variant-numeric:tabular-nums;color:#d1d5db}.motile-timepicker__item--selected{color:inherit}.motile-timepicker__spacer{flex-shrink:0;pointer-events:none}.motile-timepicker__highlight{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);pointer-events:none;background-color:#0000000d;border-radius:8px;z-index:0}.motile-timepicker__column{position:relative;z-index:1}@media (prefers-reduced-motion: reduce){.motile-timepicker__column{scroll-behavior:auto}}
@@ -0,0 +1,32 @@
1
+ import { default as React } from 'react';
2
+ export type TimeFormat = "12" | "24";
3
+ export type TimePeriod = "AM" | "PM";
4
+ export type MinuteStep = 1 | 5 | 10 | 15 | 30;
5
+ export interface TimeValue {
6
+ hour: number;
7
+ minute: number;
8
+ period?: TimePeriod;
9
+ }
10
+ export interface TimePickerRootProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
11
+ value?: TimeValue;
12
+ defaultValue?: TimeValue;
13
+ onChange?: (time: TimeValue) => void;
14
+ format?: TimeFormat;
15
+ minuteStep?: MinuteStep;
16
+ disabled?: boolean;
17
+ itemHeight?: number;
18
+ children: React.ReactNode;
19
+ }
20
+ export declare const TimePickerRoot: React.ForwardRefExoticComponent<TimePickerRootProps & React.RefAttributes<HTMLDivElement>>;
21
+ export interface TimePickerColumnProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
22
+ type: "hour" | "minute" | "period";
23
+ }
24
+ export declare const TimePickerColumn: React.ForwardRefExoticComponent<TimePickerColumnProps & React.RefAttributes<HTMLDivElement>>;
25
+ export interface TimePickerHighlightProps extends React.HTMLAttributes<HTMLDivElement> {
26
+ }
27
+ export declare const TimePickerHighlight: React.ForwardRefExoticComponent<TimePickerHighlightProps & React.RefAttributes<HTMLDivElement>>;
28
+ export declare const TimePicker: {
29
+ Root: React.ForwardRefExoticComponent<TimePickerRootProps & React.RefAttributes<HTMLDivElement>>;
30
+ Column: React.ForwardRefExoticComponent<TimePickerColumnProps & React.RefAttributes<HTMLDivElement>>;
31
+ Highlight: React.ForwardRefExoticComponent<TimePickerHighlightProps & React.RefAttributes<HTMLDivElement>>;
32
+ };
@@ -0,0 +1,280 @@
1
+ import { jsx as S, jsxs as X } from "react/jsx-runtime";
2
+ import { forwardRef as U, useRef as f, useMemo as O, useCallback as T, useEffect as N, useState as Z, createContext as ee, useContext as te } from "react";
3
+ import './TimePicker.css';/* empty css */
4
+ const W = ee(null), q = () => {
5
+ const t = te(W);
6
+ if (!t)
7
+ throw new Error(
8
+ "TimePicker components must be used within TimePicker.Root"
9
+ );
10
+ return t;
11
+ }, z = U(
12
+ ({
13
+ value: t,
14
+ defaultValue: R,
15
+ onChange: v,
16
+ format: s = "12",
17
+ minuteStep: l = 5,
18
+ disabled: p = !1,
19
+ itemHeight: o = 40,
20
+ children: g,
21
+ className: D,
22
+ style: I,
23
+ ...$
24
+ }, a) => {
25
+ const [x, w] = Z(() => t || R || {
26
+ hour: s === "12" ? 12 : 0,
27
+ minute: 0,
28
+ period: s === "12" ? "AM" : void 0
29
+ }), M = t !== void 0, k = M ? t : x, E = O(() => s === "12" ? Array.from({ length: 12 }, (n, h) => h + 1) : Array.from({ length: 24 }, (n, h) => h), [s]), L = O(() => {
30
+ const n = 60 / l;
31
+ return Array.from({ length: n }, (h, u) => u * l);
32
+ }, [l]), b = O(() => ["AM", "PM"], []), V = T(
33
+ (n, h) => {
34
+ const u = { ...k };
35
+ n === "hour" ? u.hour = h : n === "minute" ? u.minute = h : u.period = h, M || w(u), v == null || v(u);
36
+ },
37
+ [k, M, v]
38
+ ), A = {
39
+ value: k,
40
+ format: s,
41
+ minuteStep: l,
42
+ disabled: p,
43
+ itemHeight: o,
44
+ updateValue: V,
45
+ hourOptions: E,
46
+ minuteOptions: L,
47
+ periodOptions: b
48
+ }, i = {
49
+ "--timepicker-item-height": `${o}px`,
50
+ ...I
51
+ };
52
+ return /* @__PURE__ */ S(W.Provider, { value: A, children: /* @__PURE__ */ S(
53
+ "div",
54
+ {
55
+ ref: a,
56
+ className: `motile-timepicker ${p ? "motile-timepicker--disabled" : ""} ${D || ""}`,
57
+ style: i,
58
+ "aria-disabled": p,
59
+ role: "group",
60
+ "aria-label": "시간 선택",
61
+ ...$,
62
+ children: g
63
+ }
64
+ ) });
65
+ }
66
+ );
67
+ z.displayName = "TimePicker.Root";
68
+ const B = U(({ type: t, className: R, ...v }, s) => {
69
+ const {
70
+ value: l,
71
+ disabled: p,
72
+ itemHeight: o,
73
+ updateValue: g,
74
+ hourOptions: D,
75
+ minuteOptions: I,
76
+ periodOptions: $
77
+ } = q(), a = f(null), x = f(null), w = f(!1), M = f(!1), k = f(0), E = f(null), L = f(!0), b = f(!1), V = f(0), A = f(0), i = O(() => {
78
+ switch (t) {
79
+ case "hour":
80
+ return D;
81
+ case "minute":
82
+ return I;
83
+ case "period":
84
+ return $;
85
+ default:
86
+ return [];
87
+ }
88
+ }, [t, D, I, $]), n = O(() => {
89
+ switch (t) {
90
+ case "hour":
91
+ return l.hour;
92
+ case "minute":
93
+ return l.minute;
94
+ case "period":
95
+ return l.period;
96
+ default:
97
+ return;
98
+ }
99
+ }, [t, l]), h = T(
100
+ (e) => t === "period" ? e : e.toString().padStart(2, "0"),
101
+ [t]
102
+ ), u = T(
103
+ (e, r = !0) => {
104
+ const c = a.current;
105
+ if (!c || e === void 0) return;
106
+ const m = i.indexOf(e);
107
+ if (m === -1) return;
108
+ const _ = m * o;
109
+ c.scrollTo({
110
+ top: _,
111
+ behavior: r ? "smooth" : "auto"
112
+ });
113
+ },
114
+ [i, o]
115
+ ), P = T(() => typeof window < "u" && window.matchMedia("(hover: none) and (pointer: coarse)").matches, []), Y = T(
116
+ (e) => {
117
+ if (P()) return;
118
+ e.preventDefault();
119
+ const r = a.current;
120
+ r && (k.current += e.deltaY, E.current && clearTimeout(E.current), M.current = !0, E.current = setTimeout(() => {
121
+ const c = k.current, m = 20, _ = 80;
122
+ let d = 0;
123
+ if (Math.abs(c) >= m && (d = Math.sign(c) * Math.max(1, Math.round(Math.abs(c) / _))), d !== 0) {
124
+ const H = i.indexOf(n), j = Math.max(
125
+ 0,
126
+ Math.min(H + d, i.length - 1)
127
+ );
128
+ if (j !== H) {
129
+ const K = i[j], Q = j * o;
130
+ r.scrollTo({ top: Q, behavior: "smooth" }), g(t, K);
131
+ }
132
+ }
133
+ k.current = 0, setTimeout(() => {
134
+ M.current = !1;
135
+ }, 150);
136
+ }, 50));
137
+ },
138
+ [i, o, n, g, t, P]
139
+ ), G = T(
140
+ (e) => {
141
+ if (P() || p) return;
142
+ const r = a.current;
143
+ r && (b.current = !0, V.current = e.clientY, A.current = r.scrollTop, r.style.cursor = "grabbing", e.preventDefault());
144
+ },
145
+ [P, p]
146
+ ), y = T((e) => {
147
+ if (!b.current) return;
148
+ const r = a.current;
149
+ if (!r) return;
150
+ const c = V.current - e.clientY;
151
+ r.scrollTop = A.current + c;
152
+ }, []), C = T(() => {
153
+ if (!b.current) return;
154
+ b.current = !1;
155
+ const e = a.current;
156
+ if (!e) return;
157
+ e.style.cursor = "grab";
158
+ const r = e.scrollTop, c = Math.round(r / o), m = Math.max(0, Math.min(c, i.length - 1)), _ = m * o;
159
+ e.scrollTo({ top: _, behavior: "smooth" });
160
+ const d = i[m];
161
+ d !== void 0 && d !== n && g(t, d);
162
+ }, [i, o, n, g, t]), J = T(() => {
163
+ if (M.current || b.current) return;
164
+ x.current && clearTimeout(x.current);
165
+ const e = P() ? 50 : 100;
166
+ x.current = setTimeout(() => {
167
+ const r = a.current;
168
+ if (!r) return;
169
+ if (w.current) {
170
+ w.current = !1;
171
+ return;
172
+ }
173
+ const c = r.scrollTop, m = Math.round(c / o), _ = Math.max(0, Math.min(m, i.length - 1)), d = i[_];
174
+ d !== void 0 && d !== n && g(t, d);
175
+ }, e);
176
+ }, [i, o, n, g, t, P]);
177
+ return N(() => {
178
+ if (!L.current) return;
179
+ L.current = !1;
180
+ const e = setTimeout(() => {
181
+ u(n, !1);
182
+ }, 0);
183
+ return () => clearTimeout(e);
184
+ }, [u, n]), N(() => {
185
+ const e = a.current;
186
+ if (!e || n === void 0) return;
187
+ const r = i.indexOf(n);
188
+ if (r === -1) return;
189
+ const c = r * o, m = e.scrollTop;
190
+ Math.abs(m - c) > 1 && (w.current = !0, u(n, !0), setTimeout(() => {
191
+ w.current = !1;
192
+ }, 200));
193
+ }, [n, u, i, o]), N(() => {
194
+ const e = a.current;
195
+ if (e)
196
+ return e.addEventListener("wheel", Y, { passive: !1 }), () => {
197
+ e.removeEventListener("wheel", Y);
198
+ };
199
+ }, [Y]), N(() => (document.addEventListener("mousemove", y), document.addEventListener("mouseup", C), () => {
200
+ document.removeEventListener("mousemove", y), document.removeEventListener("mouseup", C);
201
+ }), [y, C]), N(() => () => {
202
+ x.current !== null && clearTimeout(x.current);
203
+ }, []), /* @__PURE__ */ X(
204
+ "div",
205
+ {
206
+ ref: (e) => {
207
+ typeof s == "function" ? s(e) : s && (s.current = e), a.current = e;
208
+ },
209
+ className: `motile-timepicker__column ${R || ""}`,
210
+ onScroll: J,
211
+ onMouseDown: G,
212
+ role: "listbox",
213
+ "aria-label": `${t} selector`,
214
+ "aria-orientation": "vertical",
215
+ ...v,
216
+ children: [
217
+ /* @__PURE__ */ S(
218
+ "div",
219
+ {
220
+ className: "motile-timepicker__spacer",
221
+ style: { height: o },
222
+ "aria-hidden": "true"
223
+ }
224
+ ),
225
+ i.map((e, r) => {
226
+ const c = e === n;
227
+ return /* @__PURE__ */ S(
228
+ "div",
229
+ {
230
+ className: `motile-timepicker__item ${c ? "motile-timepicker__item--selected" : ""} ${p ? "motile-timepicker__item--disabled" : ""}`,
231
+ style: { height: o },
232
+ role: "option",
233
+ "aria-selected": c,
234
+ "data-value": e,
235
+ children: h(e)
236
+ },
237
+ r
238
+ );
239
+ }),
240
+ /* @__PURE__ */ S(
241
+ "div",
242
+ {
243
+ className: "motile-timepicker__spacer",
244
+ style: { height: o },
245
+ "aria-hidden": "true"
246
+ }
247
+ )
248
+ ]
249
+ }
250
+ );
251
+ });
252
+ B.displayName = "TimePicker.Column";
253
+ const F = U(({ className: t, style: R, ...v }, s) => {
254
+ const { itemHeight: l } = q(), p = {
255
+ height: l,
256
+ ...R
257
+ };
258
+ return /* @__PURE__ */ S(
259
+ "div",
260
+ {
261
+ ref: s,
262
+ className: `motile-timepicker__highlight ${t || ""}`,
263
+ style: p,
264
+ "aria-hidden": "true",
265
+ ...v
266
+ }
267
+ );
268
+ });
269
+ F.displayName = "TimePicker.Highlight";
270
+ const ie = {
271
+ Root: z,
272
+ Column: B,
273
+ Highlight: F
274
+ };
275
+ export {
276
+ ie as TimePicker,
277
+ B as TimePickerColumn,
278
+ F as TimePickerHighlight,
279
+ z as TimePickerRoot
280
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export type { MinuteStep, TimeFormat, TimePeriod, TimePickerColumnProps, TimePickerHighlightProps, TimePickerRootProps, TimeValue, } from './TimePicker';
2
+ export { TimePicker } from './TimePicker';
@@ -1,4 +1,4 @@
1
+ export type { Toast, ToastOptions, ToastProviderProps, ToastVariant, } from './Toast';
1
2
  export { ToastProvider, useToastContext } from './Toast';
2
- export type { ToastVariant, Toast, ToastOptions, ToastProviderProps, } from './Toast';
3
- export { useToast } from './useToast';
4
3
  export type { UseToastReturn } from './useToast';
4
+ export { useToast } from './useToast';
@@ -88,4 +88,4 @@ export declare const Tooltip: {
88
88
  Trigger: typeof TooltipTrigger;
89
89
  Content: typeof TooltipContent;
90
90
  };
91
- export type { TooltipRootProps, TooltipTriggerProps, TooltipContentProps, TooltipVariant, TooltipPosition, TooltipAlign, };
91
+ export type { TooltipAlign, TooltipContentProps, TooltipPosition, TooltipRootProps, TooltipTriggerProps, TooltipVariant, };
@@ -1,8 +1,8 @@
1
1
  import { jsxs as tt, jsx as V } from "react/jsx-runtime";
2
2
  import et, { useState as A, useEffect as B, useCallback as C, useId as ot, useRef as y, useLayoutEffect as nt, createContext as rt, useContext as st } from "react";
3
3
  import { createPortal as it } from "react-dom";
4
- import { Slot as at } from "../../utils/Slot.js";
5
- import { FloatingArrow as lt } from "../../utils/FloatingArrow.js";
4
+ import { FloatingArrow as at } from "../../utils/FloatingArrow.js";
5
+ import { Slot as lt } from "../../utils/Slot.js";
6
6
  import './Tooltip.css';/* empty css */
7
7
  const Z = rt(null);
8
8
  function J() {
@@ -225,7 +225,7 @@ function mt({ children: t, asChild: e = !1 }) {
225
225
  }, [s, r]);
226
226
  if (e)
227
227
  return /* @__PURE__ */ V(
228
- at,
228
+ lt,
229
229
  {
230
230
  ref: (c) => {
231
231
  m.current = c;
@@ -311,7 +311,7 @@ function bt({ children: t }) {
311
311
  children: [
312
312
  t,
313
313
  p && /* @__PURE__ */ V(
314
- lt,
314
+ at,
315
315
  {
316
316
  className: "motile-tooltip-arrow",
317
317
  variant: m,
@@ -1,2 +1,2 @@
1
+ export type { TooltipAlign, TooltipContentProps, TooltipPosition, TooltipRootProps, TooltipTriggerProps, TooltipVariant, } from './Tooltip';
1
2
  export { Tooltip } from './Tooltip';
2
- export type { TooltipRootProps, TooltipTriggerProps, TooltipContentProps, TooltipVariant, TooltipPosition, TooltipAlign, } from './Tooltip';
@@ -1,5 +1,5 @@
1
- export { useScrollLock } from './useScrollLock';
2
- export { useClickOutside } from './useClickOutside';
3
1
  export type { UseClickOutsideOptions } from './useClickOutside';
4
- export { useEscapeKey } from './useEscapeKey';
2
+ export { useClickOutside } from './useClickOutside';
5
3
  export type { UseEscapeKeyOptions } from './useEscapeKey';
4
+ export { useEscapeKey } from './useEscapeKey';
5
+ export { useScrollLock } from './useScrollLock';
@@ -1,8 +1,8 @@
1
- import { useScrollLock as r } from "./useScrollLock.js";
2
- import { useClickOutside as c } from "./useClickOutside.js";
3
- import { useEscapeKey as t } from "./useEscapeKey.js";
1
+ import { useClickOutside as r } from "./useClickOutside.js";
2
+ import { useEscapeKey as c } from "./useEscapeKey.js";
3
+ import { useScrollLock as t } from "./useScrollLock.js";
4
4
  export {
5
- c as useClickOutside,
6
- t as useEscapeKey,
7
- r as useScrollLock
5
+ r as useClickOutside,
6
+ c as useEscapeKey,
7
+ t as useScrollLock
8
8
  };
package/dist/index.d.ts CHANGED
@@ -1,32 +1,36 @@
1
- export { Button } from './components/Button';
2
- export type { ButtonProps } from './components/Button';
3
- export { Input } from './components/Input';
4
- export type { InputProps } from './components/Input';
5
- export { Textarea } from './components/Textarea';
6
- export type { TextareaProps, AutoSizeConfig } from './components/Textarea';
7
- export { Checkbox } from './components/Checkbox';
8
- export type { CheckboxProps } from './components/Checkbox';
9
- export { Switch } from './components/Switch';
10
- export type { SwitchProps } from './components/Switch';
1
+ export type { AccordionContentProps, AccordionHeaderProps, AccordionProps, } from './components/Accordion';
11
2
  export { Accordion } from './components/Accordion';
12
- export type { AccordionProps, AccordionHeaderProps, AccordionContentProps, } from './components/Accordion';
13
- export { Skeleton } from './components/Skeleton';
14
- export type { SkeletonProps } from './components/Skeleton';
15
- export { Badge } from './components/Badge';
16
3
  export type { BadgeProps } from './components/Badge';
17
- export { Tooltip } from './components/Tooltip';
18
- export type { TooltipRootProps, TooltipTriggerProps, TooltipContentProps, TooltipPosition, TooltipAlign, TooltipVariant, } from './components/Tooltip';
19
- export { Popover } from './components/Popover';
20
- export type { PopoverRootProps, PopoverTriggerProps, PopoverContentProps, } from './components/Popover';
4
+ export { Badge } from './components/Badge';
5
+ export type { ButtonProps } from './components/Button';
6
+ export { Button } from './components/Button';
7
+ export type { CheckboxProps } from './components/Checkbox';
8
+ export { Checkbox } from './components/Checkbox';
9
+ export type { DockItemProps, DockPosition, DockRootProps, DockSeparatorProps, } from './components/Dock';
10
+ export { Dock } from './components/Dock';
11
+ export type { CloseOnBackdropOptions, DrawerBodyProps, DrawerCloseProps, DrawerContentProps, DrawerHandleProps, DrawerOverlayProps, DrawerPortalProps, DrawerRootProps, DrawerTitleProps, DrawerTriggerProps, } from './components/Drawer';
21
12
  export { Drawer } from './components/Drawer';
22
- export type { CloseOnBackdropOptions, DrawerRootProps, DrawerTriggerProps, DrawerPortalProps, DrawerOverlayProps, DrawerContentProps, DrawerHandleProps, DrawerTitleProps, DrawerBodyProps, DrawerCloseProps, } from './components/Drawer';
23
- export { Sheet } from './components/Sheet';
24
- export type { SheetPosition, SheetRootProps, SheetTriggerProps, SheetPortalProps, SheetOverlayProps, SheetContentProps, SheetHeaderProps, SheetTitleProps, SheetBodyProps, SheetCloseProps, } from './components/Sheet';
13
+ export type { InputProps } from './components/Input';
14
+ export { Input } from './components/Input';
15
+ export type { ModalBodyProps, ModalCloseProps, ModalContentProps, ModalFooterProps, ModalHeaderProps, ModalOverlayProps, ModalRootProps, ModalTitleProps, ModalVariant, } from './components/Modal';
25
16
  export { Modal } from './components/Modal';
26
- export type { ModalVariant, ModalRootProps, ModalOverlayProps, ModalContentProps, ModalCloseProps, ModalTitleProps, ModalBodyProps, ModalHeaderProps, ModalFooterProps, } from './components/Modal';
27
- export { ToastProvider, useToast } from './components/Toast';
28
- export type { ToastVariant, Toast, ToastOptions, ToastProviderProps, UseToastReturn, } from './components/Toast';
29
- export { Dock } from './components/Dock';
30
- export type { DockRootProps, DockItemProps, DockSeparatorProps, DockPosition, } from './components/Dock';
17
+ export type { NumberFlowProps } from './components/NumberFlow';
18
+ export { NumberFlow } from './components/NumberFlow';
19
+ export type { PopoverContentProps, PopoverRootProps, PopoverTriggerProps, } from './components/Popover';
20
+ export { Popover } from './components/Popover';
21
+ export type { SheetBodyProps, SheetCloseProps, SheetContentProps, SheetHeaderProps, SheetOverlayProps, SheetPortalProps, SheetPosition, SheetRootProps, SheetTitleProps, SheetTriggerProps, } from './components/Sheet';
22
+ export { Sheet } from './components/Sheet';
23
+ export type { SkeletonProps } from './components/Skeleton';
24
+ export { Skeleton } from './components/Skeleton';
25
+ export type { SpeedDialActionProps, SpeedDialActionsProps, SpeedDialDirection, SpeedDialRootProps, SpeedDialTriggerProps, } from './components/SpeedDial';
31
26
  export { SpeedDial } from './components/SpeedDial';
32
- export type { SpeedDialDirection, SpeedDialRootProps, SpeedDialTriggerProps, SpeedDialActionsProps, SpeedDialActionProps, } from './components/SpeedDial';
27
+ export type { SwitchProps } from './components/Switch';
28
+ export { Switch } from './components/Switch';
29
+ export type { AutoSizeConfig, TextareaProps } from './components/Textarea';
30
+ export { Textarea } from './components/Textarea';
31
+ export type { MinuteStep, TimeFormat, TimePeriod, TimePickerColumnProps, TimePickerHighlightProps, TimePickerRootProps, TimeValue, } from './components/TimePicker';
32
+ export { TimePicker } from './components/TimePicker';
33
+ export type { Toast, ToastOptions, ToastProviderProps, ToastVariant, UseToastReturn, } from './components/Toast';
34
+ export { ToastProvider, useToast } from './components/Toast';
35
+ export type { TooltipAlign, TooltipContentProps, TooltipPosition, TooltipRootProps, TooltipTriggerProps, TooltipVariant, } from './components/Tooltip';
36
+ export { Tooltip } from './components/Tooltip';
package/dist/index.js CHANGED
@@ -1,36 +1,40 @@
1
- import { Button as e } from "./components/Button/Button.js";
2
- import { Input as p } from "./components/Input/Input.js";
3
- import { Textarea as f } from "./components/Textarea/Textarea.js";
1
+ import { Accordion as e } from "./components/Accordion/Accordion.js";
2
+ import { Badge as p } from "./components/Badge/Badge.js";
3
+ import { Button as x } from "./components/Button/Button.js";
4
4
  import { Checkbox as a } from "./components/Checkbox/Checkbox.js";
5
- import { Switch as d } from "./components/Switch/Switch.js";
6
- import { Accordion as l } from "./components/Accordion/Accordion.js";
7
- import { Skeleton as S } from "./components/Skeleton/Skeleton.js";
8
- import { Badge as h } from "./components/Badge/Badge.js";
9
- import { Tooltip as s } from "./components/Tooltip/Tooltip.js";
10
- import { Popover as D } from "./components/Popover/Popover.js";
11
- import { Drawer as w } from "./components/Drawer/Drawer.js";
5
+ import { Dock as c } from "./components/Dock/Dock.js";
6
+ import { Drawer as l } from "./components/Drawer/Drawer.js";
7
+ import { Input as k } from "./components/Input/Input.js";
8
+ import { Modal as u } from "./components/Modal/Modal.js";
9
+ import { NumberFlow as h } from "./components/NumberFlow/NumberFlow.js";
10
+ import { Popover as w } from "./components/Popover/Popover.js";
12
11
  import { Sheet as P } from "./components/Sheet/Sheet.js";
13
- import { Modal as g } from "./components/Modal/Modal.js";
14
- import { ToastProvider as C } from "./components/Toast/Toast.js";
15
- import { useToast as M } from "./components/Toast/useToast.js";
16
- import { Dock as q } from "./components/Dock/Dock.js";
17
- import { SpeedDial as z } from "./components/SpeedDial/SpeedDial.js";
12
+ import { Skeleton as v } from "./components/Skeleton/Skeleton.js";
13
+ import { SpeedDial as g } from "./components/SpeedDial/SpeedDial.js";
14
+ import { Switch as C } from "./components/Switch/Switch.js";
15
+ import { Textarea as I } from "./components/Textarea/Textarea.js";
16
+ import { TimePicker as N } from "./components/TimePicker/TimePicker.js";
17
+ import { ToastProvider as q } from "./components/Toast/Toast.js";
18
+ import { useToast as z } from "./components/Toast/useToast.js";
19
+ import { Tooltip as G } from "./components/Tooltip/Tooltip.js";
18
20
  export {
19
- l as Accordion,
20
- h as Badge,
21
- e as Button,
21
+ e as Accordion,
22
+ p as Badge,
23
+ x as Button,
22
24
  a as Checkbox,
23
- q as Dock,
24
- w as Drawer,
25
- p as Input,
26
- g as Modal,
27
- D as Popover,
25
+ c as Dock,
26
+ l as Drawer,
27
+ k as Input,
28
+ u as Modal,
29
+ h as NumberFlow,
30
+ w as Popover,
28
31
  P as Sheet,
29
- S as Skeleton,
30
- z as SpeedDial,
31
- d as Switch,
32
- f as Textarea,
33
- C as ToastProvider,
34
- s as Tooltip,
35
- M as useToast
32
+ v as Skeleton,
33
+ g as SpeedDial,
34
+ C as Switch,
35
+ I as Textarea,
36
+ N as TimePicker,
37
+ q as ToastProvider,
38
+ G as Tooltip,
39
+ z as useToast
36
40
  };
@@ -1,5 +1,5 @@
1
- import { RenderOptions } from '@testing-library/react';
2
1
  import { ReactElement } from 'react';
2
+ import { RenderOptions } from '@testing-library/react';
3
3
  /**
4
4
  * Custom render function with common providers
5
5
  * 필요시 ThemeProvider, ToastProvider 등 추가 가능
@@ -1,10 +1,10 @@
1
- import i from "react";
2
- const r = i.forwardRef(
1
+ import c from "react";
2
+ const r = c.forwardRef(
3
3
  ({ children: e, ...a }, t) => {
4
- if (!i.isValidElement(e))
4
+ if (!c.isValidElement(e))
5
5
  return null;
6
6
  const n = o(e);
7
- return i.cloneElement(e, {
7
+ return c.cloneElement(e, {
8
8
  ...l(a, e.props),
9
9
  ref: t ? m(t, n) : n
10
10
  });
@@ -13,7 +13,7 @@ const r = i.forwardRef(
13
13
  r.displayName = "Slot";
14
14
  function o(e) {
15
15
  var n;
16
- let a = (n = Object.getOwnPropertyDescriptor(e.props, "ref")) == null ? void 0 : n.get;
16
+ const a = (n = Object.getOwnPropertyDescriptor(e.props, "ref")) == null ? void 0 : n.get;
17
17
  return a && "isReactWarning" in a && a.isReactWarning ? e.ref : e.props.ref || e.ref;
18
18
  }
19
19
  function l(e, a) {
@@ -24,8 +24,8 @@ function l(e, a) {
24
24
  });
25
25
  for (const n in a) {
26
26
  const f = e[n], s = a[n];
27
- /^on[A-Z]/.test(n) ? typeof f == "function" && typeof s == "function" ? t[n] = (...c) => {
28
- s(...c), f(...c);
27
+ /^on[A-Z]/.test(n) ? typeof f == "function" && typeof s == "function" ? t[n] = (...i) => {
28
+ s(...i), f(...i);
29
29
  } : typeof f == "function" && (t[n] = f) : n !== "className" && n !== "style" && (t[n] = f ?? s);
30
30
  }
31
31
  for (const n in e)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motile-ui",
3
- "version": "1.1.3",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "description": "A modern React component library for webview applications",
6
6
  "main": "./dist/index.js",
@@ -43,6 +43,10 @@
43
43
  "types": "./dist/components/Modal/Modal.d.ts",
44
44
  "import": "./dist/components/Modal/Modal.js"
45
45
  },
46
+ "./NumberFlow": {
47
+ "types": "./dist/components/NumberFlow/NumberFlow.d.ts",
48
+ "import": "./dist/components/NumberFlow/NumberFlow.js"
49
+ },
46
50
  "./Popover": {
47
51
  "types": "./dist/components/Popover/Popover.d.ts",
48
52
  "import": "./dist/components/Popover/Popover.js"
@@ -67,6 +71,10 @@
67
71
  "types": "./dist/components/Textarea/Textarea.d.ts",
68
72
  "import": "./dist/components/Textarea/Textarea.js"
69
73
  },
74
+ "./TimePicker": {
75
+ "types": "./dist/components/TimePicker/TimePicker.d.ts",
76
+ "import": "./dist/components/TimePicker/TimePicker.js"
77
+ },
70
78
  "./Toast": {
71
79
  "types": "./dist/components/Toast/Toast.d.ts",
72
80
  "import": "./dist/components/Toast/Toast.js"
@@ -100,6 +108,10 @@
100
108
  "test": "vitest",
101
109
  "test:ui": "vitest --ui",
102
110
  "test:coverage": "vitest --coverage",
111
+ "lint": "eslint src",
112
+ "lint:fix": "eslint src --fix",
113
+ "format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
114
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\"",
103
115
  "storybook": "storybook dev -p 6006",
104
116
  "build-storybook": "storybook build",
105
117
  "prepublishOnly": "npm run build"
@@ -109,6 +121,7 @@
109
121
  "react-dom": ">=18.0.0"
110
122
  },
111
123
  "devDependencies": {
124
+ "@eslint/js": "^9.39.1",
112
125
  "@storybook/addon-essentials": "^8.4.7",
113
126
  "@storybook/addon-interactions": "^8.4.7",
114
127
  "@storybook/addon-links": "^8.4.7",
@@ -126,12 +139,19 @@
126
139
  "@vitest/coverage-v8": "^2.1.8",
127
140
  "@vitest/ui": "^2.1.8",
128
141
  "chromatic": "^13.3.3",
142
+ "eslint": "^9.39.1",
143
+ "eslint-config-prettier": "^10.1.8",
144
+ "eslint-plugin-react": "^7.37.5",
145
+ "eslint-plugin-react-hooks": "^7.0.1",
146
+ "eslint-plugin-simple-import-sort": "^12.1.1",
129
147
  "happy-dom": "^20.0.10",
130
148
  "jsdom": "^27.0.1",
149
+ "prettier": "^3.7.4",
131
150
  "react": "^18.3.1",
132
151
  "react-dom": "^18.3.1",
133
152
  "storybook": "^8.4.7",
134
153
  "typescript": "^5.6.3",
154
+ "typescript-eslint": "^8.48.1",
135
155
  "vite": "^5.4.11",
136
156
  "vite-plugin-dts": "^4.3.0",
137
157
  "vite-plugin-lib-inject-css": "^2.2.2",