motile-ui 1.2.2 → 1.3.0
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/README.md +6 -2
- package/dist/components/Select/Select.css +1 -0
- package/dist/components/Select/Select.d.ts +220 -0
- package/dist/components/Select/Select.js +323 -0
- package/dist/components/Select/Select.test.d.ts +1 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Tab/Tab.css +1 -0
- package/dist/components/Tab/Tab.d.ts +107 -0
- package/dist/components/Tab/Tab.js +314 -0
- package/dist/components/Tab/Tab.test.d.ts +1 -0
- package/dist/components/Tab/index.d.ts +2 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +6 -4
- package/dist/hooks/useMediaQuery.d.ts +11 -0
- package/dist/hooks/useMediaQuery.js +17 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +34 -30
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
## ✨ 주요 기능
|
|
39
39
|
|
|
40
|
-
- 🎨 **
|
|
40
|
+
- 🎨 **20개의 고품질 컴포넌트** - 웹뷰 애플리케이션을 위해 세심하게 제작
|
|
41
41
|
- 💪 **TypeScript 우선** - 포괄적인 타입 정의 완벽 지원
|
|
42
42
|
- 🎭 **커스터마이징 가능** - CSS 변수로 쉬운 테마 설정
|
|
43
43
|
- 📱 **모바일 최적화** - 터치 친화적 인터랙션과 반응형 디자인
|
|
@@ -176,6 +176,7 @@ color props > --motile-ui-btn > --motile-theme > #3b82f6 (기본값)
|
|
|
176
176
|
- **Textarea** - 여러 줄 텍스트 입력 필드
|
|
177
177
|
- **Checkbox** - 체크박스 입력
|
|
178
178
|
- **Switch** - 토글 스위치
|
|
179
|
+
- **Select** - 드롭다운 선택 메뉴
|
|
179
180
|
- **Badge** - 상태 표시 배지
|
|
180
181
|
- **Toast** - 알림 메시지
|
|
181
182
|
- **Skeleton** - 로딩 상태 플레이스홀더
|
|
@@ -185,6 +186,7 @@ color props > --motile-ui-btn > --motile-theme > #3b82f6 (기본값)
|
|
|
185
186
|
- **Sheet** - 좌우에서 슬라이드되는 사이드 패널
|
|
186
187
|
- **Popover** - 팝오버 메뉴
|
|
187
188
|
- **Tooltip** - 툴팁
|
|
189
|
+
- **Tab** - 콘텐츠 전환 탭
|
|
188
190
|
- **Accordion** - 접을 수 있는 패널
|
|
189
191
|
- **Dock** - 독 스타일 네비게이션 바
|
|
190
192
|
- **NumberFlow** - 숫자 애니메이션 컴포넌트
|
|
@@ -219,7 +221,7 @@ MIT © [Innopers](https://github.com/Innopers)
|
|
|
219
221
|
|
|
220
222
|
## ✨ Features
|
|
221
223
|
|
|
222
|
-
- 🎨 **
|
|
224
|
+
- 🎨 **20 High-Quality Components** - Carefully crafted for webview applications
|
|
223
225
|
- 💪 **TypeScript First** - Full TypeScript support with comprehensive type definitions
|
|
224
226
|
- 🎭 **Customizable** - Easy theming with CSS variables
|
|
225
227
|
- 📱 **Mobile Optimized** - Touch-friendly interactions and responsive design
|
|
@@ -358,6 +360,7 @@ color props > --motile-ui-btn > --motile-theme > #3b82f6 (default)
|
|
|
358
360
|
- **Textarea** - Multi-line text input field
|
|
359
361
|
- **Checkbox** - Checkbox input
|
|
360
362
|
- **Switch** - Toggle switch
|
|
363
|
+
- **Select** - Dropdown selection menu
|
|
361
364
|
- **Badge** - Status badge indicator
|
|
362
365
|
- **Toast** - Notification message
|
|
363
366
|
- **Skeleton** - Loading state placeholder
|
|
@@ -367,6 +370,7 @@ color props > --motile-ui-btn > --motile-theme > #3b82f6 (default)
|
|
|
367
370
|
- **Sheet** - Side panel that slides from left or right
|
|
368
371
|
- **Popover** - Popover menu
|
|
369
372
|
- **Tooltip** - Tooltip
|
|
373
|
+
- **Tab** - Content switching tabs
|
|
370
374
|
- **Accordion** - Collapsible panel
|
|
371
375
|
- **Dock** - Dock-style navigation bar
|
|
372
376
|
- **NumberFlow** - Animated number transition component
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.motile-select__trigger{position:relative;box-sizing:border-box;width:100%;min-height:48px;padding:12px 40px 12px 16px;display:flex;align-items:center;background-color:#fff;border:1px solid #d1d5db;border-radius:8px;font-size:16px;color:#1f2937;text-align:left;cursor:pointer;transition:border-color .2s ease}.motile-select__trigger[aria-expanded=true]{border-color:color-mix(in srgb,var( --motile-select-color, var(--motile-ui-select, var(--motile-theme, #3b82f6)) ) 60%,transparent);background-color:#e5e7eb80;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);filter:blur(1.5px);color:#1f293780}.motile-select__trigger:disabled,.motile-select__trigger[disabled]{background-color:#f9fafb;color:#9ca3af;border-color:#e5e7eb;cursor:not-allowed}.motile-select__icon{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;transition:transform .2s}.motile-select__trigger[aria-expanded=true] .motile-select__icon{transform:translateY(-50%) rotate(180deg)}.motile-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.motile-select__content{position:absolute;top:calc(100% + 4px);left:0;width:100%;box-sizing:border-box;max-height:300px;overflow-y:auto;background-color:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;transform-origin:top center;visibility:hidden;opacity:0;transform:translateY(-12px) scaleY(.85);pointer-events:none;transition:opacity .45s cubic-bezier(.34,1.56,.64,1),transform .45s cubic-bezier(.34,1.56,.64,1),visibility 0s linear .45s}.motile-select__content--open{visibility:visible;opacity:1;transform:translateY(0) scaleY(1);pointer-events:auto;transition:opacity .45s cubic-bezier(.34,1.56,.64,1),transform .45s cubic-bezier(.34,1.56,.64,1),visibility 0s linear 0s}.motile-select__content::-webkit-scrollbar{width:8px}.motile-select__content::-webkit-scrollbar-track{background:transparent}.motile-select__content::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:4px}.motile-select__content::-webkit-scrollbar-thumb:hover{background-color:#9ca3af}.motile-select__item{position:relative;box-sizing:border-box;min-height:44px;padding:12px 40px 12px 16px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:16px;line-height:1.5;color:#1f2937;cursor:pointer;transition:background-color .15s;-webkit-tap-highlight-color:transparent}.motile-select__item:hover:not(.motile-select__item--disabled){background-color:#f9fafb}.motile-select__item--selected{font-weight:500}.motile-select__item--selected:not(.motile-select__item--disabled){background-color:color-mix(in srgb,var( --motile-select-color, var(--motile-ui-select, var(--motile-theme, #3b82f6)) ) 5%,transparent)}.motile-select__item--disabled{color:#d1d5db;cursor:not-allowed}.motile-select__check{position:absolute;right:12px;color:var( --motile-select-color, var(--motile-ui-select, var(--motile-theme, #3b82f6)) )}@media (prefers-color-scheme: dark){.motile-select__trigger:disabled,.motile-select__trigger[disabled]{background-color:#1f2937;color:#6b7280;border-color:#374151}.motile-select__content{background-color:#1f2937;border-color:#374151}.motile-select__item{color:#f9fafb}.motile-select__item:hover:not(.motile-select__item--disabled){background-color:#374151}.motile-select__item--selected:not(.motile-select__item--disabled){background-color:#3b82f626}.motile-select__item--disabled{color:#4b5563}}.motile-select__mobile-list{width:100%;box-sizing:border-box;padding-bottom:16px;padding-bottom:max(16px,env(safe-area-inset-bottom))}@media (prefers-reduced-motion: reduce){.motile-select__content,.motile-select__item{transition:none}}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Select Value Type
|
|
4
|
+
*/
|
|
5
|
+
export type SelectValue = string | number;
|
|
6
|
+
/**
|
|
7
|
+
* 백드롭 인터랙션으로 닫기 옵션
|
|
8
|
+
* - boolean: ESC 키와 외부 클릭 모두 제어
|
|
9
|
+
* - object: 각각 독립적으로 제어
|
|
10
|
+
*/
|
|
11
|
+
export type CloseOnBackdropOptions = boolean | {
|
|
12
|
+
/**
|
|
13
|
+
* ESC 키로 닫기 허용
|
|
14
|
+
* @default false (object 사용 시)
|
|
15
|
+
*/
|
|
16
|
+
escapeKey?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* 외부 클릭으로 닫기 허용
|
|
19
|
+
* @default false (object 사용 시)
|
|
20
|
+
*/
|
|
21
|
+
clickOutside?: boolean;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* SelectRoot Props
|
|
25
|
+
*/
|
|
26
|
+
export interface SelectRootProps {
|
|
27
|
+
/**
|
|
28
|
+
* 선택된 값 (Controlled)
|
|
29
|
+
* @remarks string | number를 지원합니다
|
|
30
|
+
*/
|
|
31
|
+
value?: SelectValue;
|
|
32
|
+
/**
|
|
33
|
+
* 초기 선택 값 (Uncontrolled)
|
|
34
|
+
*/
|
|
35
|
+
defaultValue?: SelectValue;
|
|
36
|
+
/**
|
|
37
|
+
* 값 변경 콜백
|
|
38
|
+
*/
|
|
39
|
+
onValueChange?: (value: SelectValue) => void;
|
|
40
|
+
/**
|
|
41
|
+
* 열림/닫힘 상태 (Controlled)
|
|
42
|
+
* @remarks open prop을 제공하면 외부에서 열림 상태를 제어할 수 있습니다
|
|
43
|
+
*/
|
|
44
|
+
open?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 열림/닫힘 상태 변경 콜백
|
|
47
|
+
*/
|
|
48
|
+
onOpenChange?: (open: boolean) => void;
|
|
49
|
+
/**
|
|
50
|
+
* 비활성화 여부
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
disabled?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* z-index 값
|
|
56
|
+
* @default 40
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // 다른 오버레이보다 위에 표시
|
|
60
|
+
* <Select.Root zIndex={60}>
|
|
61
|
+
*/
|
|
62
|
+
zIndex?: number;
|
|
63
|
+
/**
|
|
64
|
+
* 체크 아이콘 숨김 여부
|
|
65
|
+
* @default false
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // 커스텀 레이아웃 사용 시 체크 아이콘 숨기기
|
|
69
|
+
* <Select.Root hideCheckIcon>
|
|
70
|
+
*/
|
|
71
|
+
hideCheckIcon?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Select의 breakpoint (모바일/데스크톱 전환점)
|
|
74
|
+
* @default 768
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* // 600px 이하: Drawer, 초과: Floating dropdown
|
|
78
|
+
* <Select.Root maxWidth="600px">
|
|
79
|
+
*
|
|
80
|
+
* // 1024px 이하: Drawer, 초과: Floating dropdown
|
|
81
|
+
* <Select.Root maxWidth={1024}>
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* - maxWidth는 오직 mobile/desktop 전환 breakpoint로만 사용됩니다
|
|
85
|
+
* - viewport <= maxWidth: Drawer 사용 (전체 화면)
|
|
86
|
+
* - viewport > maxWidth: Floating dropdown 사용 (Trigger 너비와 동일)
|
|
87
|
+
* - Content 너비는 항상 Trigger 너비를 따라갑니다
|
|
88
|
+
* - 기본값: 768px breakpoint
|
|
89
|
+
*/
|
|
90
|
+
maxWidth?: string | number;
|
|
91
|
+
/**
|
|
92
|
+
* 백드롭 인터랙션으로 닫기 제어
|
|
93
|
+
*
|
|
94
|
+
* - `true`: 외부 클릭과 ESC 키 모두 허용
|
|
95
|
+
* - `false`: 외부 클릭과 ESC 키 모두 비활성화
|
|
96
|
+
* - `{ escapeKey: true }`: ESC 키만 허용
|
|
97
|
+
* - `{ clickOutside: true }`: 외부 클릭만 허용
|
|
98
|
+
* - `{ escapeKey: true, clickOutside: true }`: 모두 허용 (명시적)
|
|
99
|
+
*
|
|
100
|
+
* @default true
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* // 외부 클릭과 ESC 키 모두 허용
|
|
104
|
+
* <Select.Root closeOnBackdrop={true}>
|
|
105
|
+
*
|
|
106
|
+
* // ESC 키만 허용
|
|
107
|
+
* <Select.Root closeOnBackdrop={{ escapeKey: true }}>
|
|
108
|
+
*
|
|
109
|
+
* // 외부 클릭만 허용
|
|
110
|
+
* <Select.Root closeOnBackdrop={{ clickOutside: true }}>
|
|
111
|
+
*
|
|
112
|
+
* // 모두 비활성화
|
|
113
|
+
* <Select.Root closeOnBackdrop={false}>
|
|
114
|
+
*/
|
|
115
|
+
closeOnBackdrop?: CloseOnBackdropOptions;
|
|
116
|
+
/**
|
|
117
|
+
* 커스텀 색상
|
|
118
|
+
* @example '#10b981'
|
|
119
|
+
*
|
|
120
|
+
* @remarks
|
|
121
|
+
* Trigger, Content, Item 전체에 적용되는 테마 색상을 설정합니다.
|
|
122
|
+
* CSS 변수 `--motile-select-color`로 적용됩니다.
|
|
123
|
+
*/
|
|
124
|
+
color?: string;
|
|
125
|
+
/**
|
|
126
|
+
* 자식 컴포넌트
|
|
127
|
+
*/
|
|
128
|
+
children: React.ReactNode;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* SelectRoot - Context Provider
|
|
132
|
+
*/
|
|
133
|
+
export declare const SelectRoot: React.FC<SelectRootProps>;
|
|
134
|
+
/**
|
|
135
|
+
* SelectTrigger Props
|
|
136
|
+
*/
|
|
137
|
+
export interface SelectTriggerProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
138
|
+
/**
|
|
139
|
+
* 자식 컴포넌트
|
|
140
|
+
*/
|
|
141
|
+
children: React.ReactNode;
|
|
142
|
+
/**
|
|
143
|
+
* 자식 요소를 렌더링할지 여부 (Slot 패턴)
|
|
144
|
+
* @default false
|
|
145
|
+
*/
|
|
146
|
+
asChild?: boolean;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* SelectTrigger - 버튼
|
|
150
|
+
*/
|
|
151
|
+
export declare const SelectTrigger: React.ForwardRefExoticComponent<SelectTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
152
|
+
/**
|
|
153
|
+
* SelectValue Props
|
|
154
|
+
*/
|
|
155
|
+
export interface SelectValueProps {
|
|
156
|
+
/**
|
|
157
|
+
* 값이 없을 때 표시할 placeholder
|
|
158
|
+
*/
|
|
159
|
+
placeholder?: string;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* SelectValue - 선택된 값 표시
|
|
163
|
+
*/
|
|
164
|
+
export declare const SelectValue: React.FC<SelectValueProps>;
|
|
165
|
+
/**
|
|
166
|
+
* SelectContent Props
|
|
167
|
+
*/
|
|
168
|
+
export interface SelectContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
169
|
+
/**
|
|
170
|
+
* 자식 컴포넌트 (SelectItem들)
|
|
171
|
+
*/
|
|
172
|
+
children: React.ReactNode;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* SelectContent - 드롭다운 컨테이너 (Portal)
|
|
176
|
+
* 모바일에서는 Drawer로, 데스크톱에서는 floating dropdown으로 렌더링
|
|
177
|
+
*/
|
|
178
|
+
export declare const SelectContent: React.ForwardRefExoticComponent<SelectContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
179
|
+
/**
|
|
180
|
+
* SelectItem Props
|
|
181
|
+
*/
|
|
182
|
+
export interface SelectItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
183
|
+
/**
|
|
184
|
+
* 옵션 값 (선택적)
|
|
185
|
+
* @remarks
|
|
186
|
+
* - value prop을 제공하면 SelectValue가 자동으로 label을 표시합니다
|
|
187
|
+
* - value prop이 없으면 onClick으로 완전히 제어할 수 있습니다
|
|
188
|
+
*/
|
|
189
|
+
value?: SelectValue;
|
|
190
|
+
/**
|
|
191
|
+
* 선택 상태 (선택적)
|
|
192
|
+
* @remarks
|
|
193
|
+
* - selected prop을 제공하면 value 비교보다 우선합니다
|
|
194
|
+
* - 객체 데이터를 사용할 때 유용합니다
|
|
195
|
+
*/
|
|
196
|
+
selected?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* 비활성화 여부
|
|
199
|
+
* @default false
|
|
200
|
+
*/
|
|
201
|
+
disabled?: boolean;
|
|
202
|
+
/**
|
|
203
|
+
* 표시할 내용
|
|
204
|
+
*/
|
|
205
|
+
children: React.ReactNode;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* SelectItem - 개별 옵션
|
|
209
|
+
*/
|
|
210
|
+
export declare const SelectItem: React.ForwardRefExoticComponent<SelectItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
211
|
+
/**
|
|
212
|
+
* Select Namespace
|
|
213
|
+
*/
|
|
214
|
+
export declare const Select: {
|
|
215
|
+
Root: React.FC<SelectRootProps>;
|
|
216
|
+
Trigger: React.ForwardRefExoticComponent<SelectTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
217
|
+
Value: React.FC<SelectValueProps>;
|
|
218
|
+
Content: React.ForwardRefExoticComponent<SelectContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
219
|
+
Item: React.ForwardRefExoticComponent<SelectItemProps & React.RefAttributes<HTMLDivElement>>;
|
|
220
|
+
};
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { jsxs as L, jsx as n } from "react/jsx-runtime";
|
|
2
|
+
import M, { useEffect as j, useState as R, useRef as P, useId as ee, useCallback as $, createContext as te, useContext as oe } from "react";
|
|
3
|
+
import { Drawer as C } from "../Drawer/Drawer.js";
|
|
4
|
+
import { useClickOutside as se } from "../../hooks/useClickOutside.js";
|
|
5
|
+
import { useEscapeKey as ne } from "../../hooks/useEscapeKey.js";
|
|
6
|
+
import { useMediaQuery as le } from "../../hooks/useMediaQuery.js";
|
|
7
|
+
import { Slot as ie } from "../../utils/Slot.js";
|
|
8
|
+
import './Select.css';/* empty css */
|
|
9
|
+
const O = te(null), z = () => {
|
|
10
|
+
const e = oe(O);
|
|
11
|
+
if (!e)
|
|
12
|
+
throw new Error("Select components must be used within Select.Root");
|
|
13
|
+
return e;
|
|
14
|
+
}, Q = ({
|
|
15
|
+
value: e,
|
|
16
|
+
defaultValue: c,
|
|
17
|
+
onValueChange: l,
|
|
18
|
+
open: i,
|
|
19
|
+
onOpenChange: o,
|
|
20
|
+
disabled: a = !1,
|
|
21
|
+
zIndex: u = 40,
|
|
22
|
+
hideCheckIcon: g = !1,
|
|
23
|
+
maxWidth: r = 768,
|
|
24
|
+
closeOnBackdrop: s = !0,
|
|
25
|
+
color: S,
|
|
26
|
+
children: w
|
|
27
|
+
}) => {
|
|
28
|
+
const [d, _] = R(c), [y, p] = R(!1), f = P(null), v = P(null), m = e !== void 0, h = m ? e : d, E = i !== void 0, b = E ? i : y, K = P(b);
|
|
29
|
+
K.current = b;
|
|
30
|
+
const [D, T] = R(/* @__PURE__ */ new Map()), F = `select-content-${ee()}`, G = r ? `(max-width: ${typeof r == "number" ? `${r}px` : r})` : "(max-width: 768px)", k = le(G), J = typeof s == "boolean" ? s : s.clickOutside ?? !1, X = typeof s == "boolean" ? s : s.escapeKey ?? !1, x = $(
|
|
31
|
+
(t) => {
|
|
32
|
+
E || p(t), o == null || o(t);
|
|
33
|
+
},
|
|
34
|
+
[E, o]
|
|
35
|
+
), Y = (t) => {
|
|
36
|
+
var I;
|
|
37
|
+
m || _(t), l == null || l(t), x(!1), (I = f.current) == null || I.focus();
|
|
38
|
+
}, Z = $(
|
|
39
|
+
(t, I) => {
|
|
40
|
+
T((N) => {
|
|
41
|
+
const H = new Map(N);
|
|
42
|
+
return H.set(t, I), H;
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
[]
|
|
46
|
+
), V = $((t) => {
|
|
47
|
+
T((I) => {
|
|
48
|
+
const N = new Map(I);
|
|
49
|
+
return N.delete(t), N;
|
|
50
|
+
});
|
|
51
|
+
}, []);
|
|
52
|
+
se({
|
|
53
|
+
refs: [v, f],
|
|
54
|
+
handler: () => {
|
|
55
|
+
b && J && x(!1);
|
|
56
|
+
},
|
|
57
|
+
enabled: b && !k
|
|
58
|
+
}), ne({
|
|
59
|
+
handler: () => {
|
|
60
|
+
var t;
|
|
61
|
+
b && X && (x(!1), (t = f.current) == null || t.focus());
|
|
62
|
+
},
|
|
63
|
+
enabled: b && !k
|
|
64
|
+
}), j(() => {
|
|
65
|
+
if (!b) return;
|
|
66
|
+
const t = () => {
|
|
67
|
+
x(!1);
|
|
68
|
+
};
|
|
69
|
+
return window.addEventListener("resize", t), () => window.removeEventListener("resize", t);
|
|
70
|
+
}, [b, x]), j(() => {
|
|
71
|
+
K.current && x(!1);
|
|
72
|
+
}, [k, x]);
|
|
73
|
+
const W = {
|
|
74
|
+
open: b,
|
|
75
|
+
setOpen: x,
|
|
76
|
+
value: h,
|
|
77
|
+
onValueChange: Y,
|
|
78
|
+
disabled: a,
|
|
79
|
+
triggerRef: f,
|
|
80
|
+
contentRef: v,
|
|
81
|
+
contentId: F,
|
|
82
|
+
itemLabels: D,
|
|
83
|
+
registerItem: Z,
|
|
84
|
+
unregisterItem: V,
|
|
85
|
+
zIndex: u,
|
|
86
|
+
hideCheckIcon: g,
|
|
87
|
+
isMobile: k,
|
|
88
|
+
maxWidth: r,
|
|
89
|
+
closeOnBackdrop: s,
|
|
90
|
+
color: S
|
|
91
|
+
};
|
|
92
|
+
return /* @__PURE__ */ n(O.Provider, { value: W, children: /* @__PURE__ */ n("div", { style: { position: "relative" }, children: w }) });
|
|
93
|
+
};
|
|
94
|
+
Q.displayName = "Select.Root";
|
|
95
|
+
const B = M.forwardRef(({ children: e, className: c, style: l, asChild: i = !1, ...o }, a) => {
|
|
96
|
+
const { open: u, setOpen: g, disabled: r, triggerRef: s, contentId: S, zIndex: w, color: d } = z(), _ = () => {
|
|
97
|
+
r || g(!u);
|
|
98
|
+
}, y = M.useCallback(
|
|
99
|
+
(h) => {
|
|
100
|
+
s.current = h, typeof a == "function" ? a(h) : a && (a.current = h);
|
|
101
|
+
},
|
|
102
|
+
[a, s]
|
|
103
|
+
), p = ["motile-select__trigger", c].filter(Boolean).join(" "), f = {
|
|
104
|
+
zIndex: w,
|
|
105
|
+
...l,
|
|
106
|
+
...d && { "--motile-select-color": d }
|
|
107
|
+
}, v = {
|
|
108
|
+
ref: y,
|
|
109
|
+
type: "button",
|
|
110
|
+
role: "combobox",
|
|
111
|
+
"aria-controls": S,
|
|
112
|
+
"aria-expanded": u,
|
|
113
|
+
"aria-haspopup": "listbox",
|
|
114
|
+
disabled: r,
|
|
115
|
+
className: p,
|
|
116
|
+
style: f,
|
|
117
|
+
onClick: _,
|
|
118
|
+
...o
|
|
119
|
+
}, m = /* @__PURE__ */ n(
|
|
120
|
+
"svg",
|
|
121
|
+
{
|
|
122
|
+
className: "motile-select__icon",
|
|
123
|
+
width: "20",
|
|
124
|
+
height: "20",
|
|
125
|
+
viewBox: "0 0 20 20",
|
|
126
|
+
fill: "none",
|
|
127
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
128
|
+
children: /* @__PURE__ */ n(
|
|
129
|
+
"path",
|
|
130
|
+
{
|
|
131
|
+
d: "M5 7.5L10 12.5L15 7.5",
|
|
132
|
+
stroke: "currentColor",
|
|
133
|
+
strokeWidth: "1.5",
|
|
134
|
+
strokeLinecap: "round",
|
|
135
|
+
strokeLinejoin: "round"
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
return i ? /* @__PURE__ */ n(ie, { ...v, children: e }) : /* @__PURE__ */ L("button", { ...v, children: [
|
|
141
|
+
e,
|
|
142
|
+
m
|
|
143
|
+
] });
|
|
144
|
+
});
|
|
145
|
+
B.displayName = "Select.Trigger";
|
|
146
|
+
const U = ({
|
|
147
|
+
placeholder: e = "선택하세요"
|
|
148
|
+
}) => {
|
|
149
|
+
const { value: c, itemLabels: l } = z(), i = c ? l.get(c) : void 0;
|
|
150
|
+
return /* @__PURE__ */ n("span", { className: "motile-select__value", children: i || e });
|
|
151
|
+
};
|
|
152
|
+
U.displayName = "Select.Value";
|
|
153
|
+
const q = M.forwardRef(({ children: e, className: c, style: l, ...i }, o) => {
|
|
154
|
+
const {
|
|
155
|
+
open: a,
|
|
156
|
+
setOpen: u,
|
|
157
|
+
contentRef: g,
|
|
158
|
+
contentId: r,
|
|
159
|
+
zIndex: s,
|
|
160
|
+
isMobile: S,
|
|
161
|
+
closeOnBackdrop: w,
|
|
162
|
+
color: d
|
|
163
|
+
} = z(), [_, y] = R(!1);
|
|
164
|
+
j(() => {
|
|
165
|
+
y(!0);
|
|
166
|
+
}, []);
|
|
167
|
+
const p = M.useCallback(
|
|
168
|
+
(m) => {
|
|
169
|
+
g.current = m, typeof o == "function" ? o(m) : o && (o.current = m);
|
|
170
|
+
},
|
|
171
|
+
[o, g]
|
|
172
|
+
);
|
|
173
|
+
if (!_)
|
|
174
|
+
return null;
|
|
175
|
+
if (S)
|
|
176
|
+
return /* @__PURE__ */ L(
|
|
177
|
+
C.Root,
|
|
178
|
+
{
|
|
179
|
+
open: a,
|
|
180
|
+
onOpenChange: u,
|
|
181
|
+
closeOnBackdrop: w,
|
|
182
|
+
closeOnDrag: !0,
|
|
183
|
+
maxHeight: "70dvh",
|
|
184
|
+
zIndex: 9999,
|
|
185
|
+
children: [
|
|
186
|
+
/* @__PURE__ */ L(C.Portal, { children: [
|
|
187
|
+
/* @__PURE__ */ n(C.Overlay, {}),
|
|
188
|
+
/* @__PURE__ */ L(C.Content, { children: [
|
|
189
|
+
/* @__PURE__ */ n(C.Handle, {}),
|
|
190
|
+
/* @__PURE__ */ n(
|
|
191
|
+
C.Body,
|
|
192
|
+
{
|
|
193
|
+
style: { padding: 0 },
|
|
194
|
+
children: /* @__PURE__ */ n(
|
|
195
|
+
"div",
|
|
196
|
+
{
|
|
197
|
+
id: r,
|
|
198
|
+
role: "listbox",
|
|
199
|
+
className: `motile-select__mobile-list ${c || ""}`,
|
|
200
|
+
...i,
|
|
201
|
+
children: e
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
] })
|
|
207
|
+
] }),
|
|
208
|
+
/* @__PURE__ */ n("div", { style: { display: "none" }, "aria-hidden": "true", children: e })
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
const f = [
|
|
213
|
+
"motile-select__content",
|
|
214
|
+
a && "motile-select__content--open",
|
|
215
|
+
c
|
|
216
|
+
].filter(Boolean).join(" "), v = {
|
|
217
|
+
zIndex: s,
|
|
218
|
+
...l,
|
|
219
|
+
...d && { "--motile-select-color": d }
|
|
220
|
+
};
|
|
221
|
+
return /* @__PURE__ */ n(
|
|
222
|
+
"div",
|
|
223
|
+
{
|
|
224
|
+
ref: p,
|
|
225
|
+
id: r,
|
|
226
|
+
role: "listbox",
|
|
227
|
+
className: f,
|
|
228
|
+
style: v,
|
|
229
|
+
tabIndex: -1,
|
|
230
|
+
...i,
|
|
231
|
+
children: e
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
q.displayName = "Select.Content";
|
|
236
|
+
const A = M.forwardRef(
|
|
237
|
+
({
|
|
238
|
+
value: e,
|
|
239
|
+
selected: c,
|
|
240
|
+
disabled: l = !1,
|
|
241
|
+
children: i,
|
|
242
|
+
className: o,
|
|
243
|
+
style: a,
|
|
244
|
+
onClick: u,
|
|
245
|
+
...g
|
|
246
|
+
}, r) => {
|
|
247
|
+
const {
|
|
248
|
+
value: s,
|
|
249
|
+
onValueChange: S,
|
|
250
|
+
setOpen: w,
|
|
251
|
+
registerItem: d,
|
|
252
|
+
hideCheckIcon: _,
|
|
253
|
+
color: y
|
|
254
|
+
} = z(), p = c !== void 0 ? c : e !== void 0 && s === e;
|
|
255
|
+
j(() => {
|
|
256
|
+
e !== void 0 && d(e, i);
|
|
257
|
+
}, [e, i, d]);
|
|
258
|
+
const f = (h) => {
|
|
259
|
+
l || (u == null || u(h), !h.defaultPrevented && (e !== void 0 ? S(e) : w(!1)));
|
|
260
|
+
}, v = [
|
|
261
|
+
"motile-select__item",
|
|
262
|
+
p && "motile-select__item--selected",
|
|
263
|
+
l && "motile-select__item--disabled",
|
|
264
|
+
o
|
|
265
|
+
].filter(Boolean).join(" "), m = {
|
|
266
|
+
...a,
|
|
267
|
+
...y && { "--motile-select-color": y }
|
|
268
|
+
};
|
|
269
|
+
return /* @__PURE__ */ L(
|
|
270
|
+
"div",
|
|
271
|
+
{
|
|
272
|
+
ref: r,
|
|
273
|
+
role: "option",
|
|
274
|
+
"aria-selected": p,
|
|
275
|
+
"aria-disabled": l,
|
|
276
|
+
className: v,
|
|
277
|
+
style: m,
|
|
278
|
+
onClick: f,
|
|
279
|
+
...g,
|
|
280
|
+
children: [
|
|
281
|
+
i,
|
|
282
|
+
p && !_ && /* @__PURE__ */ n(
|
|
283
|
+
"svg",
|
|
284
|
+
{
|
|
285
|
+
className: "motile-select__check",
|
|
286
|
+
width: "16",
|
|
287
|
+
height: "16",
|
|
288
|
+
viewBox: "0 0 16 16",
|
|
289
|
+
fill: "none",
|
|
290
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
291
|
+
children: /* @__PURE__ */ n(
|
|
292
|
+
"path",
|
|
293
|
+
{
|
|
294
|
+
d: "M13.3334 4L6.00008 11.3333L2.66675 8",
|
|
295
|
+
stroke: "currentColor",
|
|
296
|
+
strokeWidth: "2",
|
|
297
|
+
strokeLinecap: "round",
|
|
298
|
+
strokeLinejoin: "round"
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
A.displayName = "Select.Item";
|
|
309
|
+
const be = {
|
|
310
|
+
Root: Q,
|
|
311
|
+
Trigger: B,
|
|
312
|
+
Value: U,
|
|
313
|
+
Content: q,
|
|
314
|
+
Item: A
|
|
315
|
+
};
|
|
316
|
+
export {
|
|
317
|
+
be as Select,
|
|
318
|
+
q as SelectContent,
|
|
319
|
+
A as SelectItem,
|
|
320
|
+
Q as SelectRoot,
|
|
321
|
+
B as SelectTrigger,
|
|
322
|
+
U as SelectValue
|
|
323
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.motile-tab{display:flex;gap:0}.motile-tab--horizontal{flex-direction:column}.motile-tab--vertical{flex-direction:row;align-items:flex-start}.motile-tab--disabled{pointer-events:none;opacity:.5}.motile-tab__list{display:flex;position:relative;border-bottom:1px solid #e5e7eb;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scroll-behavior:smooth;touch-action:pan-x;overscroll-behavior-x:contain;cursor:grab;scrollbar-width:none;-ms-overflow-style:none}.motile-tab__list:active{cursor:grabbing}.motile-tab__list::-webkit-scrollbar{display:none}.motile-tab__list--horizontal{flex-direction:row;gap:0}.motile-tab__list--vertical{flex-direction:column;overflow-x:hidden;overflow-y:auto;touch-action:pan-y;border-bottom:none;border-right:1px solid #e5e7eb;min-width:200px;max-height:600px}.motile-tab__list--underline{border-bottom:1px solid #e5e7eb}.motile-tab__list--vertical.motile-tab__list--underline{border-bottom:none;border-right:1px solid #e5e7eb}.motile-tab__list--pill{gap:8px;border:none}.motile-tab__list--vertical.motile-tab__list--pill{border:none}.motile-tab__trigger{border:none;background:none;margin:0;cursor:pointer;outline:none;-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center;position:relative;padding:12px 20px;min-width:fit-content;font-size:14px;font-weight:500;color:#6b7280;text-align:center;transition:all .2s cubic-bezier(.4,0,.2,1)}.motile-tab__trigger:focus-visible{outline:none;background-color:color-mix(in srgb,var(--motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #3b82f6))) 5%,transparent)}.motile-tab__trigger--disabled{cursor:not-allowed;opacity:.5}.motile-tab__trigger--underline{border-bottom:2px solid transparent;padding-bottom:10px}.motile-tab__trigger--underline:not(.motile-tab__trigger--disabled):hover{color:#374151}.motile-tab__trigger--underline.motile-tab__trigger--active,.motile-tab__trigger--underline.motile-tab__trigger--active:hover,.motile-tab__trigger--underline.motile-tab__trigger--active:focus,.motile-tab__trigger--underline.motile-tab__trigger--active:active{color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #3b82f6)) );border-bottom-color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #3b82f6)) )}.motile-tab__trigger--underline[data-orientation=vertical]{border-bottom:none;border-right:2px solid transparent;padding-bottom:12px;padding-right:18px;width:100%;justify-content:flex-start;align-items:flex-start}.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active,.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active:hover,.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active:focus,.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active:active{border-right-color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #3b82f6)) );border-bottom-color:transparent}.motile-tab__trigger--pill{border-radius:9999px;border:none;background-color:transparent;padding:10px 20px;color:#6b7280;font-weight:500}.motile-tab__trigger--pill:not(.motile-tab__trigger--disabled):hover{background-color:#0000000d;color:#374151}.motile-tab__trigger--pill.motile-tab__trigger--active,.motile-tab__trigger--pill.motile-tab__trigger--active:hover,.motile-tab__trigger--pill.motile-tab__trigger--active:focus,.motile-tab__trigger--pill.motile-tab__trigger--active:active{background-color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #3b82f6)) );color:#fff;font-weight:600}.motile-tab__trigger--pill[data-orientation=vertical]{width:100%;justify-content:flex-start;align-items:flex-start}.motile-tab__content{padding:20px 0;outline:none;animation:fadeIn .2s ease}.motile-tab--vertical .motile-tab__content{padding:0 0 0 20px}.motile-tab__content[hidden]{display:none}.motile-tab__content--active{animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@media (max-width: 768px){.motile-tab__trigger{padding:12px 24px;font-size:15px;transition:color .15s cubic-bezier(.4,0,.2,1),border-bottom-color .15s cubic-bezier(.4,0,.2,1),border-right-color .15s cubic-bezier(.4,0,.2,1),background-color .15s cubic-bezier(.4,0,.2,1),opacity .15s cubic-bezier(.4,0,.2,1)}.motile-tab__trigger--underline{padding-bottom:8px}.motile-tab__trigger--underline[data-orientation=vertical]{padding:10px 14px 10px 16px}.motile-tab__trigger--pill{padding:8px 16px}.motile-tab__list--vertical{min-width:160px}.motile-tab__content{padding:16px 0}.motile-tab--vertical .motile-tab__content{padding:0 0 0 16px}}@media print{.motile-tab__list{border:none}.motile-tab__trigger{display:none}.motile-tab__content[hidden]{display:block}}@media (prefers-color-scheme: dark){.motile-tab__list{border-color:#374151}.motile-tab__list--vertical,.motile-tab__list--vertical.motile-tab__list--underline{border-right-color:#374151;border-bottom-color:transparent}.motile-tab__trigger{color:#9ca3af}.motile-tab__trigger:not(.motile-tab__trigger--disabled):hover{color:#d1d5db}.motile-tab__trigger:focus-visible{background-color:color-mix(in srgb,var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #60a5fa)) ) 8%,transparent)}.motile-tab__trigger--underline.motile-tab__trigger--active,.motile-tab__trigger--underline.motile-tab__trigger--active:hover,.motile-tab__trigger--underline.motile-tab__trigger--active:focus,.motile-tab__trigger--underline.motile-tab__trigger--active:active{color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #60a5fa)) )}.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active,.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active:hover,.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active:focus,.motile-tab__trigger--underline[data-orientation=vertical].motile-tab__trigger--active:active{border-right-color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #60a5fa)) )}.motile-tab__trigger--pill{color:#9ca3af}.motile-tab__trigger--pill:not(.motile-tab__trigger--disabled):hover{background-color:#ffffff1a;color:#d1d5db}.motile-tab__trigger--pill.motile-tab__trigger--active,.motile-tab__trigger--pill.motile-tab__trigger--active:hover,.motile-tab__trigger--pill.motile-tab__trigger--active:focus,.motile-tab__trigger--pill.motile-tab__trigger--active:active{background-color:var( --motile-tab-color, var(--motile-ui-tab, var(--motile-theme, #60a5fa)) );color:#fff}}@media (prefers-reduced-motion: reduce){.motile-tab__trigger,.motile-tab__content{animation:none;transition:none}.motile-tab__content--active{animation:none}}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Tab 스타일 variant
|
|
4
|
+
* - `underline`: 하단 언더라인 (기본)
|
|
5
|
+
* - `pill`: 둥근 배경
|
|
6
|
+
*/
|
|
7
|
+
export type TabVariant = "underline" | "pill";
|
|
8
|
+
/**
|
|
9
|
+
* Tab 방향
|
|
10
|
+
* - `horizontal`: 좌우 배치 (기본)
|
|
11
|
+
* - `vertical`: 상하 배치
|
|
12
|
+
*/
|
|
13
|
+
export type TabOrientation = "horizontal" | "vertical";
|
|
14
|
+
/**
|
|
15
|
+
* Tab 활성화 모드
|
|
16
|
+
* - `automatic`: 포커스 시 즉시 활성화 (기본)
|
|
17
|
+
* - `manual`: Enter/Space로 활성화
|
|
18
|
+
*/
|
|
19
|
+
export type TabActivationMode = "automatic" | "manual";
|
|
20
|
+
export interface TabRootProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
21
|
+
/**
|
|
22
|
+
* 선택된 Tab value (controlled)
|
|
23
|
+
*/
|
|
24
|
+
value?: string;
|
|
25
|
+
/**
|
|
26
|
+
* 초기 선택 Tab value (uncontrolled)
|
|
27
|
+
*/
|
|
28
|
+
defaultValue?: string;
|
|
29
|
+
/**
|
|
30
|
+
* 값 변경 콜백
|
|
31
|
+
*/
|
|
32
|
+
onValueChange?: (value: string) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Tab 활성화 모드
|
|
35
|
+
* @default 'automatic'
|
|
36
|
+
*/
|
|
37
|
+
activationMode?: TabActivationMode;
|
|
38
|
+
/**
|
|
39
|
+
* Tab 방향
|
|
40
|
+
* @default 'horizontal'
|
|
41
|
+
*/
|
|
42
|
+
orientation?: TabOrientation;
|
|
43
|
+
/**
|
|
44
|
+
* Tab 스타일 variant
|
|
45
|
+
* @default 'underline'
|
|
46
|
+
*/
|
|
47
|
+
variant?: TabVariant;
|
|
48
|
+
/**
|
|
49
|
+
* 비활성화 여부
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* 커스텀 색상 (active tab, indicator)
|
|
55
|
+
* @example '#10b981'
|
|
56
|
+
*/
|
|
57
|
+
color?: string;
|
|
58
|
+
/**
|
|
59
|
+
* children을 wrapper 없이 직접 렌더링
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
asChild?: boolean;
|
|
63
|
+
children: React.ReactNode;
|
|
64
|
+
}
|
|
65
|
+
export interface TabListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
66
|
+
children: React.ReactNode;
|
|
67
|
+
/**
|
|
68
|
+
* children을 wrapper 없이 직접 렌더링
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
asChild?: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface TabTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
74
|
+
/**
|
|
75
|
+
* Tab의 고유 값 (필수)
|
|
76
|
+
*/
|
|
77
|
+
value: string;
|
|
78
|
+
/**
|
|
79
|
+
* children을 wrapper 없이 직접 렌더링
|
|
80
|
+
* @default false
|
|
81
|
+
*/
|
|
82
|
+
asChild?: boolean;
|
|
83
|
+
children: React.ReactNode;
|
|
84
|
+
}
|
|
85
|
+
export interface TabContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
86
|
+
/**
|
|
87
|
+
* 이 Content와 연결된 Tab의 value (필수)
|
|
88
|
+
*/
|
|
89
|
+
value: string;
|
|
90
|
+
/**
|
|
91
|
+
* 선택되지 않아도 항상 DOM에 마운트
|
|
92
|
+
* @default false
|
|
93
|
+
*/
|
|
94
|
+
forceMount?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* children을 wrapper 없이 직접 렌더링
|
|
97
|
+
* @default false
|
|
98
|
+
*/
|
|
99
|
+
asChild?: boolean;
|
|
100
|
+
children: React.ReactNode;
|
|
101
|
+
}
|
|
102
|
+
export declare const Tab: React.ForwardRefExoticComponent<TabRootProps & React.RefAttributes<HTMLDivElement>> & {
|
|
103
|
+
Root: React.ForwardRefExoticComponent<TabRootProps & React.RefAttributes<HTMLDivElement>>;
|
|
104
|
+
List: React.ForwardRefExoticComponent<TabListProps & React.RefAttributes<HTMLDivElement>>;
|
|
105
|
+
Trigger: React.ForwardRefExoticComponent<TabTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
106
|
+
Content: React.ForwardRefExoticComponent<TabContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
107
|
+
};
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { jsx as x } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as q, useState as et, useCallback as U, useRef as B, useEffect as K, useMemo as nt, createContext as st, useId as ot, useContext as rt } from "react";
|
|
3
|
+
import { Slot as W } from "../../utils/Slot.js";
|
|
4
|
+
import './Tab.css';/* empty css */
|
|
5
|
+
const g = "motile-tab", J = st(null), G = () => {
|
|
6
|
+
const e = rt(J);
|
|
7
|
+
if (!e)
|
|
8
|
+
throw new Error("Tab 컴포넌트는 Tab.Root 내에서 사용되어야 합니다");
|
|
9
|
+
return e;
|
|
10
|
+
}, Y = q(
|
|
11
|
+
({
|
|
12
|
+
value: e,
|
|
13
|
+
defaultValue: M,
|
|
14
|
+
onValueChange: p,
|
|
15
|
+
activationMode: y = "automatic",
|
|
16
|
+
orientation: i = "horizontal",
|
|
17
|
+
variant: l = "underline",
|
|
18
|
+
disabled: o = !1,
|
|
19
|
+
color: b,
|
|
20
|
+
className: h,
|
|
21
|
+
children: L,
|
|
22
|
+
asChild: w = !1,
|
|
23
|
+
style: P,
|
|
24
|
+
...n
|
|
25
|
+
}, T) => {
|
|
26
|
+
const [f, R] = et(M), k = e !== void 0, s = k ? e : f, E = U(
|
|
27
|
+
(t) => {
|
|
28
|
+
k || R(t), p == null || p(t);
|
|
29
|
+
},
|
|
30
|
+
[k, p]
|
|
31
|
+
), $ = B(/* @__PURE__ */ new Map()), A = B(/* @__PURE__ */ new Map()), _ = B(/* @__PURE__ */ new Map()), v = U(
|
|
32
|
+
(t, r, c, m) => {
|
|
33
|
+
$.current.set(t, r), A.current.set(t, c), _.current.set(t, m);
|
|
34
|
+
},
|
|
35
|
+
[]
|
|
36
|
+
), a = U((t) => {
|
|
37
|
+
$.current.delete(t), A.current.delete(t), _.current.delete(t);
|
|
38
|
+
}, []), d = B(!0);
|
|
39
|
+
K(() => {
|
|
40
|
+
if (!s || o) return;
|
|
41
|
+
const t = _.current.get(s);
|
|
42
|
+
if (!(t != null && t.current)) return;
|
|
43
|
+
const r = t.current, c = r.parentElement;
|
|
44
|
+
c && requestAnimationFrame(() => {
|
|
45
|
+
const m = i === "horizontal", u = m ? r.offsetLeft : r.offsetTop, O = m ? r.offsetWidth : r.offsetHeight, N = m ? c.clientWidth : c.clientHeight;
|
|
46
|
+
if (d.current) {
|
|
47
|
+
const D = u - N / 2 + O / 2;
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
const C = {
|
|
50
|
+
behavior: "smooth",
|
|
51
|
+
[m ? "left" : "top"]: Math.max(0, D)
|
|
52
|
+
};
|
|
53
|
+
c.scrollTo(C);
|
|
54
|
+
}, 100), d.current = !1;
|
|
55
|
+
} else {
|
|
56
|
+
const D = m ? c.scrollLeft : c.scrollTop, C = u + O, X = D + N;
|
|
57
|
+
if (u >= D && C <= X)
|
|
58
|
+
return;
|
|
59
|
+
let j;
|
|
60
|
+
u < D ? j = u : j = C - N;
|
|
61
|
+
const I = {
|
|
62
|
+
behavior: "smooth",
|
|
63
|
+
[m ? "left" : "top"]: Math.max(0, j)
|
|
64
|
+
};
|
|
65
|
+
c.scrollTo(I);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}, [s, o, i]);
|
|
69
|
+
const S = nt(
|
|
70
|
+
() => ({
|
|
71
|
+
value: s,
|
|
72
|
+
onValueChange: E,
|
|
73
|
+
orientation: i,
|
|
74
|
+
variant: l,
|
|
75
|
+
activationMode: y,
|
|
76
|
+
disabled: o,
|
|
77
|
+
color: b,
|
|
78
|
+
tabIds: $.current,
|
|
79
|
+
panelIds: A.current,
|
|
80
|
+
triggerRefs: _.current,
|
|
81
|
+
registerTab: v,
|
|
82
|
+
unregisterTab: a
|
|
83
|
+
}),
|
|
84
|
+
[
|
|
85
|
+
s,
|
|
86
|
+
E,
|
|
87
|
+
i,
|
|
88
|
+
l,
|
|
89
|
+
y,
|
|
90
|
+
o,
|
|
91
|
+
b,
|
|
92
|
+
v,
|
|
93
|
+
a
|
|
94
|
+
]
|
|
95
|
+
), z = [
|
|
96
|
+
g,
|
|
97
|
+
`${g}--${i}`,
|
|
98
|
+
o && `${g}--disabled`,
|
|
99
|
+
h
|
|
100
|
+
].filter(Boolean).join(" "), F = {
|
|
101
|
+
...P,
|
|
102
|
+
...b && { "--motile-tab-color": b }
|
|
103
|
+
}, H = {
|
|
104
|
+
...n,
|
|
105
|
+
"data-orientation": i,
|
|
106
|
+
"data-disabled": o ? "" : void 0
|
|
107
|
+
};
|
|
108
|
+
return /* @__PURE__ */ x(J.Provider, { value: S, children: w ? /* @__PURE__ */ x(
|
|
109
|
+
W,
|
|
110
|
+
{
|
|
111
|
+
ref: T,
|
|
112
|
+
...H,
|
|
113
|
+
className: z,
|
|
114
|
+
style: F,
|
|
115
|
+
children: L
|
|
116
|
+
}
|
|
117
|
+
) : /* @__PURE__ */ x("div", { ...H, ref: T, className: z, style: F, children: L }) });
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
Y.displayName = "Tab.Root";
|
|
121
|
+
const Q = q(
|
|
122
|
+
({ className: e, children: M, asChild: p = !1, ...y }, i) => {
|
|
123
|
+
const { orientation: l, variant: o } = G(), b = B(null), h = B(l);
|
|
124
|
+
K(() => {
|
|
125
|
+
h.current = l;
|
|
126
|
+
}, [l]);
|
|
127
|
+
const L = U(
|
|
128
|
+
(n) => {
|
|
129
|
+
b.current = n, typeof i == "function" ? i(n) : i && (i.current = n);
|
|
130
|
+
},
|
|
131
|
+
[i]
|
|
132
|
+
);
|
|
133
|
+
K(() => {
|
|
134
|
+
const n = b.current;
|
|
135
|
+
if (!n) return;
|
|
136
|
+
let T = !1, f = !1, R = 0, k = 0, s = null, E = 0;
|
|
137
|
+
const $ = (a) => {
|
|
138
|
+
if (a.button !== 0) return;
|
|
139
|
+
const d = h.current === "horizontal";
|
|
140
|
+
T = !0, f = !1, R = d ? a.clientX : a.clientY, k = d ? n.scrollLeft : n.scrollTop, n.style.scrollBehavior = "auto";
|
|
141
|
+
}, A = (a) => {
|
|
142
|
+
if (!T) return;
|
|
143
|
+
const d = h.current === "horizontal", z = (d ? a.clientX : a.clientY) - R;
|
|
144
|
+
!f && Math.abs(z) > 5 && (f = !0), f && (a.preventDefault(), E = k - z * 1.5, s || (s = requestAnimationFrame(() => {
|
|
145
|
+
d ? n.scrollLeft = E : n.scrollTop = E, s = null;
|
|
146
|
+
})));
|
|
147
|
+
}, _ = () => {
|
|
148
|
+
if (s && (cancelAnimationFrame(s), s = null), T = !1, n.style.scrollBehavior = "smooth", f) {
|
|
149
|
+
const a = (d) => {
|
|
150
|
+
d.preventDefault(), d.stopPropagation(), n.removeEventListener("click", a, !0);
|
|
151
|
+
};
|
|
152
|
+
n.addEventListener("click", a, !0);
|
|
153
|
+
}
|
|
154
|
+
}, v = () => {
|
|
155
|
+
s && (cancelAnimationFrame(s), s = null), T = !1, f = !1, n.style.scrollBehavior = "smooth";
|
|
156
|
+
};
|
|
157
|
+
return n.addEventListener("mousedown", $), document.addEventListener("mousemove", A), document.addEventListener("mouseup", _), n.addEventListener("mouseleave", v), () => {
|
|
158
|
+
s && cancelAnimationFrame(s), n.removeEventListener("mousedown", $), document.removeEventListener("mousemove", A), document.removeEventListener("mouseup", _), n.removeEventListener("mouseleave", v);
|
|
159
|
+
};
|
|
160
|
+
}, []);
|
|
161
|
+
const w = [
|
|
162
|
+
`${g}__list`,
|
|
163
|
+
`${g}__list--${l}`,
|
|
164
|
+
`${g}__list--${o}`,
|
|
165
|
+
e
|
|
166
|
+
].filter(Boolean).join(" "), P = {
|
|
167
|
+
...y,
|
|
168
|
+
role: "tablist",
|
|
169
|
+
"aria-orientation": l,
|
|
170
|
+
"data-orientation": l,
|
|
171
|
+
"data-variant": o
|
|
172
|
+
};
|
|
173
|
+
return p ? /* @__PURE__ */ x(W, { ref: L, ...P, className: e, children: M }) : /* @__PURE__ */ x("div", { ...P, ref: L, className: w, children: M });
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
Q.displayName = "Tab.List";
|
|
177
|
+
const Z = q(
|
|
178
|
+
({
|
|
179
|
+
value: e,
|
|
180
|
+
disabled: M,
|
|
181
|
+
className: p,
|
|
182
|
+
children: y,
|
|
183
|
+
asChild: i = !1,
|
|
184
|
+
...l
|
|
185
|
+
}, o) => {
|
|
186
|
+
const {
|
|
187
|
+
value: b,
|
|
188
|
+
onValueChange: h,
|
|
189
|
+
activationMode: L,
|
|
190
|
+
disabled: w,
|
|
191
|
+
orientation: P,
|
|
192
|
+
variant: n,
|
|
193
|
+
tabIds: T,
|
|
194
|
+
panelIds: f,
|
|
195
|
+
triggerRefs: R,
|
|
196
|
+
registerTab: k,
|
|
197
|
+
unregisterTab: s
|
|
198
|
+
} = G(), E = ot(), $ = `tab-trigger-${E}`, A = `tab-panel-${E}`, _ = B(null), v = w || M;
|
|
199
|
+
K(() => (k(e, $, A, _), () => {
|
|
200
|
+
s(e);
|
|
201
|
+
}), [e, $, A, k, s]);
|
|
202
|
+
const a = (t) => {
|
|
203
|
+
var O, N;
|
|
204
|
+
if (v) return;
|
|
205
|
+
const r = Array.from(R.keys()), c = r.indexOf(e), m = P === "horizontal";
|
|
206
|
+
let u = null;
|
|
207
|
+
switch (t.key) {
|
|
208
|
+
case "ArrowRight":
|
|
209
|
+
m && (t.preventDefault(), u = (c + 1) % r.length);
|
|
210
|
+
break;
|
|
211
|
+
case "ArrowLeft":
|
|
212
|
+
m && (t.preventDefault(), u = (c - 1 + r.length) % r.length);
|
|
213
|
+
break;
|
|
214
|
+
case "ArrowDown":
|
|
215
|
+
m || (t.preventDefault(), u = (c + 1) % r.length);
|
|
216
|
+
break;
|
|
217
|
+
case "ArrowUp":
|
|
218
|
+
m || (t.preventDefault(), u = (c - 1 + r.length) % r.length);
|
|
219
|
+
break;
|
|
220
|
+
case "Enter":
|
|
221
|
+
case " ":
|
|
222
|
+
L === "manual" && (t.preventDefault(), h(e));
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
if (u !== null) {
|
|
226
|
+
const D = r.length;
|
|
227
|
+
let C = 0;
|
|
228
|
+
const X = D;
|
|
229
|
+
for (; C < X; ) {
|
|
230
|
+
const j = r[u], I = R.get(j);
|
|
231
|
+
if (!((O = I == null ? void 0 : I.current) == null ? void 0 : O.disabled) && (I != null && I.current)) {
|
|
232
|
+
I.current.focus(), L === "automatic" && h(j);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
const tt = t.key === "ArrowLeft" || t.key === "ArrowUp" ? -1 : 1;
|
|
236
|
+
u = (u + tt + D) % D, C++;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
(N = l.onKeyDown) == null || N.call(l, t);
|
|
240
|
+
}, d = () => {
|
|
241
|
+
v || h(e);
|
|
242
|
+
}, S = b === e, z = {
|
|
243
|
+
id: T.get(e) || "",
|
|
244
|
+
role: "tab",
|
|
245
|
+
"aria-selected": S,
|
|
246
|
+
"aria-controls": f.get(e) || "",
|
|
247
|
+
"aria-disabled": v || void 0,
|
|
248
|
+
"data-state": S ? "active" : "inactive",
|
|
249
|
+
tabIndex: S ? 0 : -1
|
|
250
|
+
}, F = [
|
|
251
|
+
`${g}__trigger`,
|
|
252
|
+
`${g}__trigger--${n}`,
|
|
253
|
+
S && `${g}__trigger--active`,
|
|
254
|
+
v && `${g}__trigger--disabled`,
|
|
255
|
+
p
|
|
256
|
+
].filter(Boolean).join(" "), H = {
|
|
257
|
+
...l,
|
|
258
|
+
...z,
|
|
259
|
+
ref: (t) => {
|
|
260
|
+
_.current = t, typeof o == "function" ? o(t) : o && (o.current = t);
|
|
261
|
+
},
|
|
262
|
+
type: "button",
|
|
263
|
+
disabled: v,
|
|
264
|
+
onClick: d,
|
|
265
|
+
onKeyDown: a,
|
|
266
|
+
"data-value": e,
|
|
267
|
+
"data-orientation": P,
|
|
268
|
+
"data-disabled": v ? "" : void 0
|
|
269
|
+
};
|
|
270
|
+
return i ? /* @__PURE__ */ x(W, { ...H, className: F, children: y }) : /* @__PURE__ */ x("button", { ...H, className: F, children: y });
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
Z.displayName = "Tab.Trigger";
|
|
274
|
+
const V = q(
|
|
275
|
+
({
|
|
276
|
+
value: e,
|
|
277
|
+
forceMount: M = !1,
|
|
278
|
+
className: p,
|
|
279
|
+
children: y,
|
|
280
|
+
asChild: i = !1,
|
|
281
|
+
...l
|
|
282
|
+
}, o) => {
|
|
283
|
+
const { value: b, tabIds: h, panelIds: L } = G(), w = b === e;
|
|
284
|
+
if (!(M || w))
|
|
285
|
+
return null;
|
|
286
|
+
const n = {
|
|
287
|
+
id: L.get(e) || "",
|
|
288
|
+
role: "tabpanel",
|
|
289
|
+
"aria-labelledby": h.get(e) || "",
|
|
290
|
+
"data-state": w ? "active" : "inactive",
|
|
291
|
+
tabIndex: 0
|
|
292
|
+
}, T = [
|
|
293
|
+
`${g}__content`,
|
|
294
|
+
w && `${g}__content--active`,
|
|
295
|
+
p
|
|
296
|
+
].filter(Boolean).join(" "), f = {
|
|
297
|
+
...l,
|
|
298
|
+
...n,
|
|
299
|
+
hidden: !w,
|
|
300
|
+
"data-value": e
|
|
301
|
+
};
|
|
302
|
+
return i ? /* @__PURE__ */ x(W, { ref: o, ...f, className: p, children: y }) : /* @__PURE__ */ x("div", { ...f, ref: o, className: T, children: y });
|
|
303
|
+
}
|
|
304
|
+
);
|
|
305
|
+
V.displayName = "Tab.Content";
|
|
306
|
+
const ft = Object.assign(Y, {
|
|
307
|
+
Root: Y,
|
|
308
|
+
List: Q,
|
|
309
|
+
Trigger: Z,
|
|
310
|
+
Content: V
|
|
311
|
+
});
|
|
312
|
+
export {
|
|
313
|
+
ft as Tab
|
|
314
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ export type { UseClickOutsideOptions } from './useClickOutside';
|
|
|
2
2
|
export { useClickOutside } from './useClickOutside';
|
|
3
3
|
export type { UseEscapeKeyOptions } from './useEscapeKey';
|
|
4
4
|
export { useEscapeKey } from './useEscapeKey';
|
|
5
|
+
export { useMediaQuery } from './useMediaQuery';
|
|
5
6
|
export { useScrollLock } from './useScrollLock';
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { useClickOutside as r } from "./useClickOutside.js";
|
|
2
|
-
import { useEscapeKey as
|
|
3
|
-
import {
|
|
2
|
+
import { useEscapeKey as u } from "./useEscapeKey.js";
|
|
3
|
+
import { useMediaQuery as t } from "./useMediaQuery.js";
|
|
4
|
+
import { useScrollLock as f } from "./useScrollLock.js";
|
|
4
5
|
export {
|
|
5
6
|
r as useClickOutside,
|
|
6
|
-
|
|
7
|
-
t as
|
|
7
|
+
u as useEscapeKey,
|
|
8
|
+
t as useMediaQuery,
|
|
9
|
+
f as useScrollLock
|
|
8
10
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR-safe 미디어 쿼리 훅
|
|
3
|
+
*
|
|
4
|
+
* @param query - 미디어 쿼리 문자열 (예: "(max-width: 768px)")
|
|
5
|
+
* @returns 미디어 쿼리 매칭 여부
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const isMobile = useMediaQuery("(max-width: 768px)");
|
|
9
|
+
* const isDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
|
|
10
|
+
*/
|
|
11
|
+
export declare function useMediaQuery(query: string): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useState as i, useEffect as r } from "react";
|
|
2
|
+
function d(e) {
|
|
3
|
+
const [s, n] = i(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
|
|
4
|
+
return r(() => {
|
|
5
|
+
const t = window.matchMedia(e);
|
|
6
|
+
n(t.matches);
|
|
7
|
+
const a = (c) => {
|
|
8
|
+
n(c.matches);
|
|
9
|
+
};
|
|
10
|
+
return t.addEventListener("change", a), () => {
|
|
11
|
+
t.removeEventListener("change", a);
|
|
12
|
+
};
|
|
13
|
+
}, [e]), s;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
d as useMediaQuery
|
|
17
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export type { NumberFlowProps } from './components/NumberFlow';
|
|
|
18
18
|
export { NumberFlow } from './components/NumberFlow';
|
|
19
19
|
export type { PopoverContentProps, PopoverRootProps, PopoverTriggerProps, } from './components/Popover';
|
|
20
20
|
export { Popover } from './components/Popover';
|
|
21
|
+
export type { SelectContentProps, SelectItemProps, SelectRootProps, SelectTriggerProps, SelectValueProps, } from './components/Select';
|
|
22
|
+
export { Select } from './components/Select';
|
|
21
23
|
export type { SheetBodyProps, SheetCloseProps, SheetContentProps, SheetHeaderProps, SheetOverlayProps, SheetPortalProps, SheetPosition, SheetRootProps, SheetTitleProps, SheetTriggerProps, } from './components/Sheet';
|
|
22
24
|
export { Sheet } from './components/Sheet';
|
|
23
25
|
export type { SkeletonProps } from './components/Skeleton';
|
|
@@ -26,6 +28,8 @@ export type { SpeedDialActionProps, SpeedDialActionsProps, SpeedDialDirection, S
|
|
|
26
28
|
export { SpeedDial } from './components/SpeedDial';
|
|
27
29
|
export type { SwitchProps } from './components/Switch';
|
|
28
30
|
export { Switch } from './components/Switch';
|
|
31
|
+
export type { TabActivationMode, TabContentProps, TabListProps, TabOrientation, TabRootProps, TabTriggerProps, TabVariant, } from './components/Tab';
|
|
32
|
+
export { Tab } from './components/Tab';
|
|
29
33
|
export type { AutoSizeConfig, TextareaProps } from './components/Textarea';
|
|
30
34
|
export { Textarea } from './components/Textarea';
|
|
31
35
|
export type { MinuteStep, TimeFormat, TimePeriod, TimePickerColumnProps, TimePickerHighlightProps, TimePickerRootProps, TimeValue, } from './components/TimePicker';
|
package/dist/index.js
CHANGED
|
@@ -2,39 +2,43 @@ import { Accordion as e } from "./components/Accordion/Accordion.js";
|
|
|
2
2
|
import { Badge as p } from "./components/Badge/Badge.js";
|
|
3
3
|
import { Button as x } from "./components/Button/Button.js";
|
|
4
4
|
import { Checkbox as a } from "./components/Checkbox/Checkbox.js";
|
|
5
|
-
import { Dock as
|
|
6
|
-
import { Drawer as
|
|
7
|
-
import { Input as
|
|
8
|
-
import { Modal as
|
|
9
|
-
import { NumberFlow as
|
|
10
|
-
import { Popover as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
5
|
+
import { Dock as i } from "./components/Dock/Dock.js";
|
|
6
|
+
import { Drawer as T } from "./components/Drawer/Drawer.js";
|
|
7
|
+
import { Input as S } from "./components/Input/Input.js";
|
|
8
|
+
import { Modal as n } from "./components/Modal/Modal.js";
|
|
9
|
+
import { NumberFlow as b } from "./components/NumberFlow/NumberFlow.js";
|
|
10
|
+
import { Popover as s } from "./components/Popover/Popover.js";
|
|
11
|
+
import { Select as D } from "./components/Select/Select.js";
|
|
12
|
+
import { Sheet as v } from "./components/Sheet/Sheet.js";
|
|
13
|
+
import { Skeleton as g } from "./components/Skeleton/Skeleton.js";
|
|
14
|
+
import { SpeedDial as C } from "./components/SpeedDial/SpeedDial.js";
|
|
15
|
+
import { Switch as I } from "./components/Switch/Switch.js";
|
|
16
|
+
import { Tab as N } from "./components/Tab/Tab.js";
|
|
17
|
+
import { Textarea as q } from "./components/Textarea/Textarea.js";
|
|
18
|
+
import { TimePicker as z } from "./components/TimePicker/TimePicker.js";
|
|
19
|
+
import { ToastProvider as G } from "./components/Toast/Toast.js";
|
|
20
|
+
import { useToast as J } from "./components/Toast/useToast.js";
|
|
21
|
+
import { Tooltip as L } from "./components/Tooltip/Tooltip.js";
|
|
20
22
|
export {
|
|
21
23
|
e as Accordion,
|
|
22
24
|
p as Badge,
|
|
23
25
|
x as Button,
|
|
24
26
|
a as Checkbox,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
v as
|
|
33
|
-
g as
|
|
34
|
-
C as
|
|
35
|
-
I as
|
|
36
|
-
N as
|
|
37
|
-
q as
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
i as Dock,
|
|
28
|
+
T as Drawer,
|
|
29
|
+
S as Input,
|
|
30
|
+
n as Modal,
|
|
31
|
+
b as NumberFlow,
|
|
32
|
+
s as Popover,
|
|
33
|
+
D as Select,
|
|
34
|
+
v as Sheet,
|
|
35
|
+
g as Skeleton,
|
|
36
|
+
C as SpeedDial,
|
|
37
|
+
I as Switch,
|
|
38
|
+
N as Tab,
|
|
39
|
+
q as Textarea,
|
|
40
|
+
z as TimePicker,
|
|
41
|
+
G as ToastProvider,
|
|
42
|
+
L as Tooltip,
|
|
43
|
+
J as useToast
|
|
40
44
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "motile-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A modern React component library for webview applications",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -51,6 +51,10 @@
|
|
|
51
51
|
"types": "./dist/components/Popover/Popover.d.ts",
|
|
52
52
|
"import": "./dist/components/Popover/Popover.js"
|
|
53
53
|
},
|
|
54
|
+
"./Select": {
|
|
55
|
+
"types": "./dist/components/Select/Select.d.ts",
|
|
56
|
+
"import": "./dist/components/Select/Select.js"
|
|
57
|
+
},
|
|
54
58
|
"./Sheet": {
|
|
55
59
|
"types": "./dist/components/Sheet/useSheetNavigation.d.ts",
|
|
56
60
|
"import": "./dist/components/Sheet/useSheetNavigation.js"
|
|
@@ -67,6 +71,10 @@
|
|
|
67
71
|
"types": "./dist/components/Switch/Switch.d.ts",
|
|
68
72
|
"import": "./dist/components/Switch/Switch.js"
|
|
69
73
|
},
|
|
74
|
+
"./Tab": {
|
|
75
|
+
"types": "./dist/components/Tab/Tab.d.ts",
|
|
76
|
+
"import": "./dist/components/Tab/Tab.js"
|
|
77
|
+
},
|
|
70
78
|
"./Textarea": {
|
|
71
79
|
"types": "./dist/components/Textarea/Textarea.d.ts",
|
|
72
80
|
"import": "./dist/components/Textarea/Textarea.js"
|