@nexus-cross/design-system 1.1.1 → 2.0.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/claude-rules/nexus/CLAUDE.md +102 -6
- package/cursor-rules/CLAUDE.md +38 -9
- package/cursor-rules/nexus-project-setup.mdc +80 -19
- package/cursor-rules/nexus-ui-api.mdc +8 -2
- package/dist/chunks/{chunk-NZHK76R3.js → chunk-LYPBQI3Y.js} +31 -6
- package/dist/chunks/{chunk-6BWOKTVQ.mjs → chunk-WZFKTTVX.mjs} +31 -6
- package/dist/components/NxImage.d.ts.map +1 -1
- package/dist/index.js +22 -23
- package/dist/index.mjs +4 -5
- package/dist/modal/index.js +11 -11
- package/dist/modal/index.mjs +2 -2
- package/dist/nx-image.js +2 -2
- package/dist/nx-image.mjs +1 -1
- package/dist/tailwind-v4.css +19 -0
- package/dist/tokens/TOKENS.md +426 -0
- package/dist/tokens/company.css +410 -0
- package/dist/tokens/css.css +405 -0
- package/dist/tokens/data/borderWidth.json +38 -0
- package/dist/tokens/data/breakpoint.json +23 -0
- package/dist/tokens/data/color.json +973 -0
- package/dist/tokens/data/index.ts +63 -0
- package/dist/tokens/data/motion.json +64 -0
- package/dist/tokens/data/opacity.json +65 -0
- package/dist/tokens/data/radius.json +25 -0
- package/dist/tokens/data/shadow.json +76 -0
- package/dist/tokens/data/size.json +46 -0
- package/dist/tokens/data/space.json +86 -0
- package/dist/tokens/data/typography.json +626 -0
- package/dist/tokens/data/zIndex.json +22 -0
- package/dist/tokens/index.d.ts +11 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +12 -0
- package/dist/tokens/index.mjs +1 -0
- package/dist/tokens/tailwind.js +260 -0
- package/dist/tokens-domains/data/index.ts +16 -0
- package/dist/tokens-domains/data/prediction/domain.json +324 -0
- package/dist/tokens-domains/index.d.ts +12 -0
- package/dist/tokens-domains/index.d.ts.map +1 -0
- package/dist/tokens-domains/index.js +12 -0
- package/dist/tokens-domains/index.mjs +1 -0
- package/dist/tokens-domains/prediction-vars.css +154 -0
- package/dist/tokens-domains/prediction.css +153 -0
- package/dist/tokens-domains/prediction.md +70 -0
- package/dist/tokens-domains/tailwind.js +59 -0
- package/package.json +27 -6
- package/dist/chunks/{chunk-5ZVPTIL3.mjs → chunk-3VFBPFZF.mjs} +1 -1
- package/dist/chunks/{chunk-7F4SOLAC.js → chunk-U53UA76K.js} +1 -1
|
@@ -34,7 +34,13 @@
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
-
## Quick
|
|
37
|
+
## Quick Install (단일 패키지)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install @nexus-cross/design-system # 토큰/도메인 토큰까지 자동 transitive install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Component / Token Import
|
|
38
44
|
|
|
39
45
|
```tsx
|
|
40
46
|
import {
|
|
@@ -47,25 +53,115 @@ import {
|
|
|
47
53
|
} from '@nexus-cross/design-system';
|
|
48
54
|
|
|
49
55
|
import { modal, useModal, ModalTemplate, ModalContainer } from '@nexus-cross/design-system/modal';
|
|
56
|
+
|
|
57
|
+
// 토큰 JS API (sub-path)
|
|
58
|
+
import { getTheme } from '@nexus-cross/design-system/tokens';
|
|
59
|
+
import { getPredictionTheme } from '@nexus-cross/design-system/tokens-domains';
|
|
50
60
|
```
|
|
51
61
|
|
|
52
62
|
---
|
|
53
63
|
|
|
54
64
|
## CSS Setup (한 번만)
|
|
55
65
|
|
|
56
|
-
### Tailwind v4
|
|
66
|
+
### Tailwind v4 (Next + Turbopack / Vite 등 모든 환경) — **2줄 셋업**
|
|
67
|
+
|
|
68
|
+
**design-system + 토큰을 함께 쓸 때 (대부분의 경우):**
|
|
57
69
|
```css
|
|
70
|
+
/* globals.css */
|
|
58
71
|
@import 'tailwindcss';
|
|
59
|
-
@import '@nexus-cross/
|
|
60
|
-
/*
|
|
72
|
+
@import '@nexus-cross/design-system/tailwind-v4.css';
|
|
73
|
+
/* 도메인 토큰 사용 시 한 줄 추가 */
|
|
74
|
+
/* @import '@nexus-cross/design-system/tokens-domains/prediction.css'; */
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`tailwind-v4.css` 안에서 회사 공통 토큰이 sub-path를 통해 자동 로드되므로 **토큰 import를 따로 쓸 필요 없습니다.** 컴포넌트 CSS는 Tailwind의 `components` 레이어에 주입되어 `className="bg-red-500"` 오버라이드가 항상 utility에 우선합니다.
|
|
78
|
+
|
|
79
|
+
**디자인 토큰만 쓸 때 (design-system 없이):** `@nexus-cross/tokens`를 별도 설치하고 `@import '@nexus-cross/tokens/company.css';` 사용.
|
|
80
|
+
|
|
81
|
+
**`@layer base, nexus, components, utilities;` statement를 직접 쓰지 마세요.** Tailwind v4 프로세서가 자동 정리/제거하기 때문에 의도와 다르게 동작합니다.
|
|
82
|
+
|
|
83
|
+
### Tailwind v3 / 순수 CSS
|
|
84
|
+
```css
|
|
85
|
+
/* globals.css */
|
|
86
|
+
@import '@nexus-cross/design-system/tokens/css';
|
|
61
87
|
@import '@nexus-cross/design-system/styles.css';
|
|
88
|
+
@tailwind base; @tailwind components; @tailwind utilities;
|
|
62
89
|
```
|
|
90
|
+
또는 entry에서 `import '@nexus-cross/design-system/styles'`.
|
|
63
91
|
|
|
64
|
-
### Next.js
|
|
92
|
+
### Next.js (모든 버전)
|
|
65
93
|
```js
|
|
66
94
|
// next.config.mjs
|
|
67
95
|
const nextConfig = {
|
|
68
|
-
transpilePackages: ['@nexus-cross/design-system'
|
|
96
|
+
transpilePackages: ['@nexus-cross/design-system'],
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Global Setup — `<Toaster />` / `<ModalContainer />`
|
|
103
|
+
|
|
104
|
+
`Toaster` / `ModalContainer`는 내부적으로 `useState`를 사용하는 **클라이언트 컴포넌트**입니다.
|
|
105
|
+
|
|
106
|
+
| 환경 | 패턴 |
|
|
107
|
+
|---|---|
|
|
108
|
+
| Next.js App Router (root layout이 server component) | **반드시 `"use client"` wrapper로 분리** |
|
|
109
|
+
| Vite, CRA, Pages Router 등 root가 이미 client | 직접 import 가능 |
|
|
110
|
+
|
|
111
|
+
### Pattern A — Next.js App Router (권장)
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
// app/providers.tsx
|
|
115
|
+
"use client";
|
|
116
|
+
|
|
117
|
+
import { Toaster } from '@nexus-cross/design-system';
|
|
118
|
+
import { ModalContainer } from '@nexus-cross/design-system/modal';
|
|
119
|
+
|
|
120
|
+
export function NexusProviders() {
|
|
121
|
+
return (
|
|
122
|
+
<>
|
|
123
|
+
<ModalContainer />
|
|
124
|
+
<Toaster position="top-right" />
|
|
125
|
+
</>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
// app/layout.tsx (server component — "use client" 추가 금지)
|
|
132
|
+
import { NexusProviders } from './providers';
|
|
133
|
+
import './globals.css';
|
|
134
|
+
|
|
135
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
136
|
+
return (
|
|
137
|
+
<html lang="ko">
|
|
138
|
+
<body>
|
|
139
|
+
{children}
|
|
140
|
+
<NexusProviders />
|
|
141
|
+
</body>
|
|
142
|
+
</html>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
> ❌ server `layout.tsx`에서 `Toaster` / `ModalContainer`를 직접 import하면
|
|
148
|
+
> `TypeError: useState only works in Client Components.` 에러 발생.
|
|
149
|
+
|
|
150
|
+
### Pattern B — Vite / CRA / 이미 client인 root
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
// App.tsx
|
|
154
|
+
import { Toaster } from '@nexus-cross/design-system';
|
|
155
|
+
import { ModalContainer } from '@nexus-cross/design-system/modal';
|
|
156
|
+
|
|
157
|
+
export default function App() {
|
|
158
|
+
return (
|
|
159
|
+
<>
|
|
160
|
+
{/* routes / pages */}
|
|
161
|
+
<ModalContainer />
|
|
162
|
+
<Toaster position="top-right" />
|
|
163
|
+
</>
|
|
164
|
+
);
|
|
69
165
|
}
|
|
70
166
|
```
|
|
71
167
|
|
package/cursor-rules/CLAUDE.md
CHANGED
|
@@ -25,33 +25,62 @@
|
|
|
25
25
|
|
|
26
26
|
4. **`className` 오버라이드 시 `!important` 금지.** `cn()` 유틸이 프리픽스 충돌 자동 해소.
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## 설치 (단일 패키지)
|
|
29
|
+
|
|
30
|
+
v2.0부터 `@nexus-cross/design-system` 1개 install로 토큰까지 모두 사용 가능합니다.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @nexus-cross/design-system
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Component / Token Import
|
|
29
37
|
|
|
30
38
|
```tsx
|
|
39
|
+
// UI 컴포넌트
|
|
31
40
|
import { Button, TextInput, TextArea, Select, Switch, Chip, Spinner, Divider } from '@nexus-cross/design-system';
|
|
32
41
|
import { Tooltip, Popover, Drawer, Accordion } from '@nexus-cross/design-system';
|
|
33
42
|
import { toast, Toaster } from '@nexus-cross/design-system';
|
|
34
43
|
import { modal, useModal, ModalTemplate, ModalContainer } from '@nexus-cross/design-system/modal';
|
|
35
|
-
import { NumberInput, numberInputBind } from '@nexus-cross/design-system';
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
import { NumberInput, numberInputBind, Avatar, Tab, ToggleGroup, cn } from '@nexus-cross/design-system';
|
|
45
|
+
|
|
46
|
+
// 토큰 JS API (sub-path)
|
|
47
|
+
import { getTheme } from '@nexus-cross/design-system/tokens';
|
|
48
|
+
import { getPredictionTheme } from '@nexus-cross/design-system/tokens-domains';
|
|
38
49
|
```
|
|
39
50
|
|
|
40
51
|
## CSS Setup
|
|
41
52
|
|
|
42
|
-
### Tailwind v4
|
|
53
|
+
### Tailwind v4 (Next + Turbopack / Vite 등 모든 환경) — **2줄 셋업**
|
|
54
|
+
|
|
55
|
+
**design-system + 토큰을 함께 쓸 때 (대부분의 경우):**
|
|
43
56
|
```css
|
|
57
|
+
/* globals.css */
|
|
44
58
|
@import 'tailwindcss';
|
|
45
|
-
@import '@nexus-cross/
|
|
46
|
-
/*
|
|
59
|
+
@import '@nexus-cross/design-system/tailwind-v4.css';
|
|
60
|
+
/* 도메인 토큰 사용 시 한 줄 추가 */
|
|
61
|
+
/* @import '@nexus-cross/design-system/tokens-domains/prediction.css'; */
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`tailwind-v4.css` 안에서 회사 공통 토큰이 자동 로드되므로 **토큰 import를 따로 쓸 필요 없습니다.** 컴포넌트 CSS는 Tailwind의 `components` 레이어에 주입되어 `className="bg-red-500"` 오버라이드가 항상 utility에 우선합니다.
|
|
65
|
+
|
|
66
|
+
**디자인 토큰만 쓸 때 (design-system 없이):** `@nexus-cross/tokens`를 별도 설치하고 `@import '@nexus-cross/tokens/company.css';` 사용.
|
|
67
|
+
|
|
68
|
+
**절대 직접 `@layer base, nexus, components, utilities;` 같은 statement를 globals.css에 쓰지 말 것.** Tailwind v4 프로세서가 자동 정리해버려 의도와 다르게 동작합니다.
|
|
69
|
+
|
|
70
|
+
### Tailwind v3 / 순수 CSS
|
|
71
|
+
```css
|
|
72
|
+
/* globals.css */
|
|
73
|
+
@import '@nexus-cross/design-system/tokens/css';
|
|
47
74
|
@import '@nexus-cross/design-system/styles.css';
|
|
75
|
+
@tailwind base; @tailwind components; @tailwind utilities;
|
|
48
76
|
```
|
|
77
|
+
또는 entry에서 `import '@nexus-cross/design-system/styles'`.
|
|
49
78
|
|
|
50
|
-
### Next.js
|
|
79
|
+
### Next.js (모든 버전)
|
|
51
80
|
```js
|
|
52
81
|
// next.config.mjs
|
|
53
82
|
const nextConfig = {
|
|
54
|
-
transpilePackages: ['@nexus-cross/design-system'
|
|
83
|
+
transpilePackages: ['@nexus-cross/design-system'],
|
|
55
84
|
}
|
|
56
85
|
```
|
|
57
86
|
|
|
@@ -13,28 +13,41 @@ This project uses NEXUS Design System. All generated code MUST follow the rules
|
|
|
13
13
|
- **UI Components**: `@nexus-cross/design-system` (React, CVA + Plain CSS)
|
|
14
14
|
- **Styling**: Tailwind CSS v4 + NEXUS semantic tokens
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Install (단일 패키지)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
v2.0부터 design-system 1개 install로 토큰까지 모두 가능합니다.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| Tailwind v4 | `@nexus-cross/design-system/styles/layer` | wrapped in `@layer nexus` |
|
|
20
|
+
```bash
|
|
21
|
+
npm install @nexus-cross/design-system # @nexus-cross/tokens, tokens-domains 자동 transitive install
|
|
22
|
+
```
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
// Tailwind v3, Plain CSS, CSS Modules
|
|
27
|
-
import '@nexus-cross/design-system/styles'
|
|
24
|
+
토큰만 단독으로 쓰는 경우엔 `npm install @nexus-cross/tokens` (또는 `tokens-domains`) 가능.
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
import '@nexus-cross/design-system/styles/layer'
|
|
31
|
-
```
|
|
26
|
+
## Design System CSS Setup
|
|
32
27
|
|
|
33
|
-
|
|
28
|
+
| Environment | Setup |
|
|
29
|
+
|---|---|
|
|
30
|
+
| **Tailwind v4** (Next + Turbopack / Vite 등) | `globals.css`에서 2줄: `@import 'tailwindcss';` + `@import '@nexus-cross/design-system/tailwind-v4.css';` |
|
|
31
|
+
| Tailwind v3 | `globals.css`에 `@import '@nexus-cross/design-system/tokens/css';` + `@import '@nexus-cross/design-system/styles.css';` |
|
|
32
|
+
| Plain CSS / CSS Modules | `@import '@nexus-cross/design-system/tokens/css';` + entry에서 `import '@nexus-cross/design-system/styles'` |
|
|
33
|
+
|
|
34
|
+
### Tailwind v4 — **2줄 셋업** (권장)
|
|
35
|
+
|
|
36
|
+
**design-system + 토큰을 함께 쓸 때 (대부분의 경우):**
|
|
34
37
|
```css
|
|
35
|
-
|
|
38
|
+
/* globals.css */
|
|
39
|
+
@import 'tailwindcss';
|
|
40
|
+
@import '@nexus-cross/design-system/tailwind-v4.css';
|
|
41
|
+
/* 도메인 토큰 사용 시 */
|
|
42
|
+
/* @import '@nexus-cross/design-system/tokens-domains/prediction.css'; */
|
|
36
43
|
```
|
|
37
44
|
|
|
45
|
+
`tailwind-v4.css` 안에서 회사 공통 토큰이 sub-path를 통해 자동 로드되므로 **토큰 import를 따로 쓸 필요 없습니다.** 컴포넌트 CSS는 Tailwind의 `components` 레이어에 주입되어 `className="bg-red-500"` 오버라이드가 항상 utility에 우선합니다.
|
|
46
|
+
|
|
47
|
+
**디자인 토큰만 쓸 때 (design-system 없이):** `@nexus-cross/tokens`를 별도 설치하고 `@import '@nexus-cross/tokens/company.css';` 사용.
|
|
48
|
+
|
|
49
|
+
**`@layer base, nexus, components, utilities;` 같은 statement를 직접 쓰지 마세요.** Tailwind v4 프로세서가 자동으로 정리/제거하기 때문에 의도와 다르게 동작합니다.
|
|
50
|
+
|
|
38
51
|
## Absolute Rules
|
|
39
52
|
|
|
40
53
|
1. **Always use NEXUS tokens for colors.** Hardcoding is prohibited.
|
|
@@ -190,15 +203,62 @@ The following components MUST be placed at the app root (layout.tsx or App.tsx).
|
|
|
190
203
|
| `<ModalContainer />` | `@nexus-cross/design-system/modal` | Using `modal()` or `useModal()` | Modal rendering container |
|
|
191
204
|
| `<Toaster />` | `@nexus-cross/design-system` | Using `toast()` | Toast notification renderer |
|
|
192
205
|
|
|
206
|
+
> Both components use `useState` internally → they are **client components**.
|
|
207
|
+
> In environments where the root layout is a **server component** (e.g. Next.js App Router), import them through a `"use client"` wrapper as shown in **Pattern A**.
|
|
208
|
+
> If the root layout is already a client component (e.g. Vite, CRA, Pages Router with `"use client"` already declared), you can use them directly as in **Pattern B**.
|
|
209
|
+
|
|
210
|
+
### Pattern A — Next.js App Router / RSC (Recommended)
|
|
211
|
+
|
|
212
|
+
Server components cannot directly render client components that use hooks. Wrap providers in a single client file:
|
|
213
|
+
|
|
193
214
|
```tsx
|
|
194
|
-
//
|
|
215
|
+
// app/providers.tsx
|
|
216
|
+
"use client";
|
|
217
|
+
|
|
218
|
+
import { Toaster } from '@nexus-cross/design-system';
|
|
195
219
|
import { ModalContainer } from '@nexus-cross/design-system/modal';
|
|
220
|
+
|
|
221
|
+
export function NexusProviders() {
|
|
222
|
+
return (
|
|
223
|
+
<>
|
|
224
|
+
<ModalContainer />
|
|
225
|
+
<Toaster position="top-right" />
|
|
226
|
+
</>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
// app/layout.tsx (server component — DO NOT add "use client" here)
|
|
233
|
+
import { NexusProviders } from './providers';
|
|
234
|
+
import './globals.css';
|
|
235
|
+
|
|
236
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
237
|
+
return (
|
|
238
|
+
<html lang="en">
|
|
239
|
+
<body>
|
|
240
|
+
{children}
|
|
241
|
+
<NexusProviders />
|
|
242
|
+
</body>
|
|
243
|
+
</html>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
> ❌ Importing `Toaster` / `ModalContainer` directly inside a server `layout.tsx` throws:
|
|
249
|
+
> `TypeError: useState only works in Client Components.`
|
|
250
|
+
|
|
251
|
+
### Pattern B — Vite / CRA / Already-client roots
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
// App.tsx (already a client component)
|
|
196
255
|
import { Toaster } from '@nexus-cross/design-system';
|
|
256
|
+
import { ModalContainer } from '@nexus-cross/design-system/modal';
|
|
197
257
|
|
|
198
|
-
export default function
|
|
258
|
+
export default function App() {
|
|
199
259
|
return (
|
|
200
260
|
<>
|
|
201
|
-
{
|
|
261
|
+
{/* ... your routes/pages ... */}
|
|
202
262
|
<ModalContainer />
|
|
203
263
|
<Toaster position="top-right" />
|
|
204
264
|
</>
|
|
@@ -225,8 +285,9 @@ import { toast, Toaster } from '@nexus-cross/design-system';
|
|
|
225
285
|
// Modal system (separate subpath)
|
|
226
286
|
import { modal, useModal, ModalTemplate, ModalContainer } from '@nexus-cross/design-system/modal';
|
|
227
287
|
|
|
228
|
-
// Tokens (
|
|
229
|
-
import { getTheme } from '@nexus-cross/tokens';
|
|
288
|
+
// Tokens (sub-path — design-system 1개 install로 사용 가능)
|
|
289
|
+
import { getTheme } from '@nexus-cross/design-system/tokens';
|
|
290
|
+
import { getPredictionTheme } from '@nexus-cross/design-system/tokens-domains';
|
|
230
291
|
```
|
|
231
292
|
|
|
232
293
|
## Modal Writing Rules
|
|
@@ -1023,7 +1023,10 @@ function MyModal({ close, resolve }: { close: () => void; resolve: (value: any)
|
|
|
1023
1023
|
```tsx
|
|
1024
1024
|
import { modal, useModal, ModalContainer } from '@nexus-cross/design-system/modal';
|
|
1025
1025
|
|
|
1026
|
-
// ModalContainer MUST be placed at the app root
|
|
1026
|
+
// ModalContainer MUST be placed at the app root.
|
|
1027
|
+
// It uses useState internally → it's a client component.
|
|
1028
|
+
// In Next.js App Router, wrap it in a "use client" file (e.g. providers.tsx)
|
|
1029
|
+
// and render that wrapper from the (server) layout. NEVER add "use client" to layout.tsx itself.
|
|
1027
1030
|
<ModalContainer />
|
|
1028
1031
|
|
|
1029
1032
|
// Method 1: modal() function
|
|
@@ -2164,7 +2167,10 @@ Toast notifications. Sonner-based.
|
|
|
2164
2167
|
```tsx
|
|
2165
2168
|
import { toast, Toaster } from '@nexus-cross/design-system';
|
|
2166
2169
|
|
|
2167
|
-
// Place Toaster at app root
|
|
2170
|
+
// Place Toaster at the app root.
|
|
2171
|
+
// It uses useState internally → it's a client component.
|
|
2172
|
+
// In Next.js App Router, wrap it in a "use client" file (e.g. providers.tsx)
|
|
2173
|
+
// and render that wrapper from the (server) layout. NEVER add "use client" to layout.tsx itself.
|
|
2168
2174
|
<Toaster position="top-right" />
|
|
2169
2175
|
|
|
2170
2176
|
// Usage
|
|
@@ -48,9 +48,34 @@ var NxImage = React__namespace.forwardRef(
|
|
|
48
48
|
const [status, setStatus] = React__namespace.useState(
|
|
49
49
|
"loading"
|
|
50
50
|
);
|
|
51
|
+
const [currentSrc, setCurrentSrc] = React__namespace.useState(src);
|
|
52
|
+
const innerRef = React__namespace.useRef(null);
|
|
53
|
+
const setRefs = React__namespace.useCallback(
|
|
54
|
+
(node) => {
|
|
55
|
+
innerRef.current = node;
|
|
56
|
+
if (typeof ref === "function") {
|
|
57
|
+
ref(node);
|
|
58
|
+
} else if (ref) {
|
|
59
|
+
ref.current = node;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
[ref]
|
|
63
|
+
);
|
|
51
64
|
React__namespace.useEffect(() => {
|
|
52
|
-
|
|
65
|
+
setCurrentSrc(src);
|
|
53
66
|
}, [src]);
|
|
67
|
+
React__namespace.useEffect(() => {
|
|
68
|
+
setStatus("loading");
|
|
69
|
+
const img = innerRef.current;
|
|
70
|
+
if (!img || !currentSrc) return;
|
|
71
|
+
if (img.complete) {
|
|
72
|
+
if (img.naturalHeight > 0) {
|
|
73
|
+
setStatus("loaded");
|
|
74
|
+
} else if (img.src) {
|
|
75
|
+
setStatus("error");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, [currentSrc]);
|
|
54
79
|
const handleLoad = React__namespace.useCallback(
|
|
55
80
|
(e) => {
|
|
56
81
|
setStatus("loaded");
|
|
@@ -60,14 +85,14 @@ var NxImage = React__namespace.forwardRef(
|
|
|
60
85
|
);
|
|
61
86
|
const handleError = React__namespace.useCallback(
|
|
62
87
|
(e) => {
|
|
63
|
-
if (fallbackSrc &&
|
|
64
|
-
|
|
88
|
+
if (fallbackSrc && currentSrc !== fallbackSrc) {
|
|
89
|
+
setCurrentSrc(fallbackSrc);
|
|
65
90
|
return;
|
|
66
91
|
}
|
|
67
92
|
setStatus("error");
|
|
68
93
|
onError?.(e);
|
|
69
94
|
},
|
|
70
|
-
[fallbackSrc, onError]
|
|
95
|
+
[fallbackSrc, currentSrc, onError]
|
|
71
96
|
);
|
|
72
97
|
const wrapperStyle = {
|
|
73
98
|
...style,
|
|
@@ -84,8 +109,8 @@ var NxImage = React__namespace.forwardRef(
|
|
|
84
109
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85
110
|
"img",
|
|
86
111
|
{
|
|
87
|
-
ref,
|
|
88
|
-
src,
|
|
112
|
+
ref: setRefs,
|
|
113
|
+
src: currentSrc,
|
|
89
114
|
alt: alt ?? "",
|
|
90
115
|
loading: lazy ? "lazy" : "eager",
|
|
91
116
|
className: chunkCZC76ZD5_js.cn(
|
|
@@ -26,9 +26,34 @@ var NxImage = React.forwardRef(
|
|
|
26
26
|
const [status, setStatus] = React.useState(
|
|
27
27
|
"loading"
|
|
28
28
|
);
|
|
29
|
+
const [currentSrc, setCurrentSrc] = React.useState(src);
|
|
30
|
+
const innerRef = React.useRef(null);
|
|
31
|
+
const setRefs = React.useCallback(
|
|
32
|
+
(node) => {
|
|
33
|
+
innerRef.current = node;
|
|
34
|
+
if (typeof ref === "function") {
|
|
35
|
+
ref(node);
|
|
36
|
+
} else if (ref) {
|
|
37
|
+
ref.current = node;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
[ref]
|
|
41
|
+
);
|
|
29
42
|
React.useEffect(() => {
|
|
30
|
-
|
|
43
|
+
setCurrentSrc(src);
|
|
31
44
|
}, [src]);
|
|
45
|
+
React.useEffect(() => {
|
|
46
|
+
setStatus("loading");
|
|
47
|
+
const img = innerRef.current;
|
|
48
|
+
if (!img || !currentSrc) return;
|
|
49
|
+
if (img.complete) {
|
|
50
|
+
if (img.naturalHeight > 0) {
|
|
51
|
+
setStatus("loaded");
|
|
52
|
+
} else if (img.src) {
|
|
53
|
+
setStatus("error");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, [currentSrc]);
|
|
32
57
|
const handleLoad = React.useCallback(
|
|
33
58
|
(e) => {
|
|
34
59
|
setStatus("loaded");
|
|
@@ -38,14 +63,14 @@ var NxImage = React.forwardRef(
|
|
|
38
63
|
);
|
|
39
64
|
const handleError = React.useCallback(
|
|
40
65
|
(e) => {
|
|
41
|
-
if (fallbackSrc &&
|
|
42
|
-
|
|
66
|
+
if (fallbackSrc && currentSrc !== fallbackSrc) {
|
|
67
|
+
setCurrentSrc(fallbackSrc);
|
|
43
68
|
return;
|
|
44
69
|
}
|
|
45
70
|
setStatus("error");
|
|
46
71
|
onError?.(e);
|
|
47
72
|
},
|
|
48
|
-
[fallbackSrc, onError]
|
|
73
|
+
[fallbackSrc, currentSrc, onError]
|
|
49
74
|
);
|
|
50
75
|
const wrapperStyle = {
|
|
51
76
|
...style,
|
|
@@ -62,8 +87,8 @@ var NxImage = React.forwardRef(
|
|
|
62
87
|
/* @__PURE__ */ jsx(
|
|
63
88
|
"img",
|
|
64
89
|
{
|
|
65
|
-
ref,
|
|
66
|
-
src,
|
|
90
|
+
ref: setRefs,
|
|
91
|
+
src: currentSrc,
|
|
67
92
|
alt: alt ?? "",
|
|
68
93
|
loading: lazy ? "lazy" : "eager",
|
|
69
94
|
className: cn(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NxImage.d.ts","sourceRoot":"","sources":["../../src/components/NxImage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,UAAU,YAAa,SAAQ,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;IACtE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAClD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"NxImage.d.ts","sourceRoot":"","sources":["../../src/components/NxImage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,UAAU,YAAa,SAAQ,KAAK,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;IACtE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAClD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,uFA8IZ,CAAC;AAIF,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
require('./styles.css');
|
|
2
1
|
'use strict';
|
|
3
2
|
|
|
3
|
+
var chunkAZ2URLDD_js = require('./chunks/chunk-AZ2URLDD.js');
|
|
4
4
|
var chunkYB5ZKHVB_js = require('./chunks/chunk-YB5ZKHVB.js');
|
|
5
5
|
var chunk3RK3UT2O_js = require('./chunks/chunk-3RK3UT2O.js');
|
|
6
|
-
var chunkAZ2URLDD_js = require('./chunks/chunk-AZ2URLDD.js');
|
|
7
6
|
var chunkC2DSAJTL_js = require('./chunks/chunk-C2DSAJTL.js');
|
|
8
7
|
var chunkK3CK7NTP_js = require('./chunks/chunk-K3CK7NTP.js');
|
|
9
8
|
var chunkDICN6GKE_js = require('./chunks/chunk-DICN6GKE.js');
|
|
10
9
|
var chunkDYPPVXQF_js = require('./chunks/chunk-DYPPVXQF.js');
|
|
11
|
-
var
|
|
10
|
+
var chunkLYPBQI3Y_js = require('./chunks/chunk-LYPBQI3Y.js');
|
|
12
11
|
var chunkLTS674LF_js = require('./chunks/chunk-LTS674LF.js');
|
|
13
12
|
var chunkLAGQ7J5A_js = require('./chunks/chunk-LAGQ7J5A.js');
|
|
14
13
|
var chunkQK6NCII4_js = require('./chunks/chunk-QK6NCII4.js');
|
|
@@ -45,13 +44,13 @@ var chunkXGIJZ3NZ_js = require('./chunks/chunk-XGIJZ3NZ.js');
|
|
|
45
44
|
var chunk2T7RUYEK_js = require('./chunks/chunk-2T7RUYEK.js');
|
|
46
45
|
var chunk4ENXP7WH_js = require('./chunks/chunk-4ENXP7WH.js');
|
|
47
46
|
var chunkMA2VCCIY_js = require('./chunks/chunk-MA2VCCIY.js');
|
|
48
|
-
var
|
|
47
|
+
var chunkU53UA76K_js = require('./chunks/chunk-U53UA76K.js');
|
|
48
|
+
var chunkHHXDOKXY_js = require('./chunks/chunk-HHXDOKXY.js');
|
|
49
49
|
var chunkNHDGKOAM_js = require('./chunks/chunk-NHDGKOAM.js');
|
|
50
50
|
var chunkT2IY2TSR_js = require('./chunks/chunk-T2IY2TSR.js');
|
|
51
51
|
var chunkXEHFB62A_js = require('./chunks/chunk-XEHFB62A.js');
|
|
52
52
|
var chunkINP2AH3B_js = require('./chunks/chunk-INP2AH3B.js');
|
|
53
53
|
var chunkHUPAHDJ7_js = require('./chunks/chunk-HUPAHDJ7.js');
|
|
54
|
-
var chunkHHXDOKXY_js = require('./chunks/chunk-HHXDOKXY.js');
|
|
55
54
|
var chunkP3DZKXG4_js = require('./chunks/chunk-P3DZKXG4.js');
|
|
56
55
|
var chunkWKCXACMZ_js = require('./chunks/chunk-WKCXACMZ.js');
|
|
57
56
|
var chunkS2GMEC43_js = require('./chunks/chunk-S2GMEC43.js');
|
|
@@ -341,6 +340,10 @@ var buttonTokenSchema = {
|
|
|
341
340
|
}
|
|
342
341
|
};
|
|
343
342
|
|
|
343
|
+
Object.defineProperty(exports, "useInView", {
|
|
344
|
+
enumerable: true,
|
|
345
|
+
get: function () { return chunkAZ2URLDD_js.useInView; }
|
|
346
|
+
});
|
|
344
347
|
Object.defineProperty(exports, "Toaster", {
|
|
345
348
|
enumerable: true,
|
|
346
349
|
get: function () { return chunkYB5ZKHVB_js.Toaster; }
|
|
@@ -377,10 +380,6 @@ Object.defineProperty(exports, "useTableHighlight", {
|
|
|
377
380
|
enumerable: true,
|
|
378
381
|
get: function () { return chunk3RK3UT2O_js.useTableHighlight; }
|
|
379
382
|
});
|
|
380
|
-
Object.defineProperty(exports, "useInView", {
|
|
381
|
-
enumerable: true,
|
|
382
|
-
get: function () { return chunkAZ2URLDD_js.useInView; }
|
|
383
|
-
});
|
|
384
383
|
Object.defineProperty(exports, "DropdownMenu", {
|
|
385
384
|
enumerable: true,
|
|
386
385
|
get: function () { return chunkC2DSAJTL_js.DropdownMenu; }
|
|
@@ -431,7 +430,7 @@ Object.defineProperty(exports, "tagInputVariants", {
|
|
|
431
430
|
});
|
|
432
431
|
Object.defineProperty(exports, "NxImage", {
|
|
433
432
|
enumerable: true,
|
|
434
|
-
get: function () { return
|
|
433
|
+
get: function () { return chunkLYPBQI3Y_js.NxImage; }
|
|
435
434
|
});
|
|
436
435
|
Object.defineProperty(exports, "DatePicker", {
|
|
437
436
|
enumerable: true,
|
|
@@ -795,39 +794,43 @@ Object.defineProperty(exports, "avatarVariants", {
|
|
|
795
794
|
});
|
|
796
795
|
Object.defineProperty(exports, "ModalContainer", {
|
|
797
796
|
enumerable: true,
|
|
798
|
-
get: function () { return
|
|
797
|
+
get: function () { return chunkU53UA76K_js.ModalContainer_default; }
|
|
799
798
|
});
|
|
800
799
|
Object.defineProperty(exports, "ModalPortalTarget", {
|
|
801
800
|
enumerable: true,
|
|
802
|
-
get: function () { return
|
|
801
|
+
get: function () { return chunkU53UA76K_js.ModalPortalTarget_default; }
|
|
803
802
|
});
|
|
804
803
|
Object.defineProperty(exports, "ModalTemplate", {
|
|
805
804
|
enumerable: true,
|
|
806
|
-
get: function () { return
|
|
805
|
+
get: function () { return chunkU53UA76K_js.ModalTemplate_default; }
|
|
807
806
|
});
|
|
808
807
|
Object.defineProperty(exports, "checkModal", {
|
|
809
808
|
enumerable: true,
|
|
810
|
-
get: function () { return
|
|
809
|
+
get: function () { return chunkU53UA76K_js.checkModal; }
|
|
811
810
|
});
|
|
812
811
|
Object.defineProperty(exports, "closeModal", {
|
|
813
812
|
enumerable: true,
|
|
814
|
-
get: function () { return
|
|
813
|
+
get: function () { return chunkU53UA76K_js.closeModal; }
|
|
815
814
|
});
|
|
816
815
|
Object.defineProperty(exports, "getModalDefaultOption", {
|
|
817
816
|
enumerable: true,
|
|
818
|
-
get: function () { return
|
|
817
|
+
get: function () { return chunkU53UA76K_js.getModalDefaultOption; }
|
|
819
818
|
});
|
|
820
819
|
Object.defineProperty(exports, "modal", {
|
|
821
820
|
enumerable: true,
|
|
822
|
-
get: function () { return
|
|
821
|
+
get: function () { return chunkU53UA76K_js.openModal; }
|
|
823
822
|
});
|
|
824
823
|
Object.defineProperty(exports, "openModal", {
|
|
825
824
|
enumerable: true,
|
|
826
|
-
get: function () { return
|
|
825
|
+
get: function () { return chunkU53UA76K_js.openModal; }
|
|
827
826
|
});
|
|
828
827
|
Object.defineProperty(exports, "resetModal", {
|
|
829
828
|
enumerable: true,
|
|
830
|
-
get: function () { return
|
|
829
|
+
get: function () { return chunkU53UA76K_js.resetModal; }
|
|
830
|
+
});
|
|
831
|
+
Object.defineProperty(exports, "useDraggableBottomSheet", {
|
|
832
|
+
enumerable: true,
|
|
833
|
+
get: function () { return chunkHHXDOKXY_js.useDraggableBottomSheet; }
|
|
831
834
|
});
|
|
832
835
|
Object.defineProperty(exports, "useDraggableWindow", {
|
|
833
836
|
enumerable: true,
|
|
@@ -853,10 +856,6 @@ Object.defineProperty(exports, "useModal", {
|
|
|
853
856
|
enumerable: true,
|
|
854
857
|
get: function () { return chunkHUPAHDJ7_js.useModal; }
|
|
855
858
|
});
|
|
856
|
-
Object.defineProperty(exports, "useDraggableBottomSheet", {
|
|
857
|
-
enumerable: true,
|
|
858
|
-
get: function () { return chunkHHXDOKXY_js.useDraggableBottomSheet; }
|
|
859
|
-
});
|
|
860
859
|
Object.defineProperty(exports, "Button", {
|
|
861
860
|
enumerable: true,
|
|
862
861
|
get: function () { return chunkP3DZKXG4_js.Button; }
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
export { useInView } from './chunks/chunk-2JTPRBHZ.mjs';
|
|
2
2
|
export { Toaster, toast, useToast } from './chunks/chunk-ZWSIIGA3.mjs';
|
|
3
3
|
export { Table, TableHighlightProvider, TableRow, TdColumn, tableRowVariants, useTableHighlight } from './chunks/chunk-AAITRHED.mjs';
|
|
4
|
-
export { useInView } from './chunks/chunk-2JTPRBHZ.mjs';
|
|
5
4
|
export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuRoot, DropdownMenuSeparator, DropdownMenuTrigger } from './chunks/chunk-6DBRL6NA.mjs';
|
|
6
5
|
export { ToggleGroup, toggleGroupVariants } from './chunks/chunk-PIGHBDK5.mjs';
|
|
7
6
|
export { Slider, sliderVariants } from './chunks/chunk-H2G5FMRN.mjs';
|
|
8
7
|
export { TagInput, tagInputVariants } from './chunks/chunk-H2V7RHYV.mjs';
|
|
9
|
-
export { NxImage } from './chunks/chunk-
|
|
8
|
+
export { NxImage } from './chunks/chunk-WZFKTTVX.mjs';
|
|
10
9
|
export { DatePicker } from './chunks/chunk-FBC53TOS.mjs';
|
|
11
10
|
export { ImageUpload, imageUploadVariants } from './chunks/chunk-5J63FUAS.mjs';
|
|
12
11
|
export { ClientOnly } from './chunks/chunk-AOXXE5UQ.mjs';
|
|
@@ -43,13 +42,13 @@ export { TextArea, textAreaVariants } from './chunks/chunk-ZU4AWAFT.mjs';
|
|
|
43
42
|
export { NumberInput, numberInputBind, numberInputVariants } from './chunks/chunk-BJM3NDT2.mjs';
|
|
44
43
|
export { PriceInput, priceInputVariants } from './chunks/chunk-WGGBE4ZD.mjs';
|
|
45
44
|
export { Avatar, avatarVariants } from './chunks/chunk-YLO4UKSC.mjs';
|
|
46
|
-
export { ModalContainer_default as ModalContainer, ModalPortalTarget_default as ModalPortalTarget, ModalTemplate_default as ModalTemplate, checkModal, closeModal, getModalDefaultOption, openModal as modal, openModal, resetModal } from './chunks/chunk-
|
|
45
|
+
export { ModalContainer_default as ModalContainer, ModalPortalTarget_default as ModalPortalTarget, ModalTemplate_default as ModalTemplate, checkModal, closeModal, getModalDefaultOption, openModal as modal, openModal, resetModal } from './chunks/chunk-3VFBPFZF.mjs';
|
|
46
|
+
export { useDraggableBottomSheet } from './chunks/chunk-U56AGSLE.mjs';
|
|
47
47
|
export { useDraggableWindow } from './chunks/chunk-4J3GCZ7W.mjs';
|
|
48
48
|
export { scrollFreeze, scrollRelease } from './chunks/chunk-54IA2P2Z.mjs';
|
|
49
49
|
export { useCheckDevice_default as useCheckDevice } from './chunks/chunk-YEWKPWK3.mjs';
|
|
50
50
|
export { useClickOutside_default as useClickOutside } from './chunks/chunk-OTGS6BDQ.mjs';
|
|
51
51
|
export { useModal } from './chunks/chunk-6H7V2I3X.mjs';
|
|
52
|
-
export { useDraggableBottomSheet } from './chunks/chunk-U56AGSLE.mjs';
|
|
53
52
|
export { Button, buttonVariants } from './chunks/chunk-VVXQZ4XH.mjs';
|
|
54
53
|
export { Chip, chipVariants } from './chunks/chunk-RX5UKRYK.mjs';
|
|
55
54
|
export { Badge, badgeVariants } from './chunks/chunk-CUTMLBC3.mjs';
|