react-component-by-vite 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/README.md +759 -0
- package/dist/index.es.js +168 -0
- package/dist/index.umd.js +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,759 @@
|
|
|
1
|
+
# First React Component Test
|
|
2
|
+
|
|
3
|
+
Panduan lengkap membuat library React dari nol hingga publish ke npm.
|
|
4
|
+
|
|
5
|
+
## 📋 Daftar Isi
|
|
6
|
+
|
|
7
|
+
- [Pendahuluan](#pendahuluan)
|
|
8
|
+
- [Prasyarat](#prasyarat)
|
|
9
|
+
- [1. Setup Proyek Awal](#1-setup-proyek-awal)
|
|
10
|
+
- [2. Membuat Struktur Folder](#2-membuat-struktur-folder)
|
|
11
|
+
- [3. Konfigurasi Vite](#3-konfigurasi-vite)
|
|
12
|
+
- [4. Membuat Komponen React](#4-membuat-komponen-react)
|
|
13
|
+
- [5. Setup Storybook](#5-setup-storybook)
|
|
14
|
+
- [6. Build Library](#6-build-library)
|
|
15
|
+
- [7. Testing (Opsional)](#7-testing-opsional)
|
|
16
|
+
- [8. Publish ke NPM](#8-publish-ke-npm)
|
|
17
|
+
- [Troubleshooting](#troubleshooting)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📖 Pendahuluan
|
|
22
|
+
|
|
23
|
+
Library ini adalah template untuk membuat **React Component Library** yang dapat dipublikasikan di npm. Library ini dirancang untuk:
|
|
24
|
+
|
|
25
|
+
- ✅ Mendukung CommonJS (UMD) dan ES Modules
|
|
26
|
+
- ✅ Menggunakan Storybook untuk dokumentasi komponen
|
|
27
|
+
- ✅ Optimasi bundle dengan Vite
|
|
28
|
+
- ✅ Support React 18+ dan React 19+
|
|
29
|
+
- ✅ TypeScript & JavaScript support
|
|
30
|
+
- ✅ Testing dengan Vitest
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🔧 Prasyarat
|
|
35
|
+
|
|
36
|
+
Sebelum memulai, pastikan Anda sudah menginstall:
|
|
37
|
+
|
|
38
|
+
- **Node.js** (v18+): [Download di nodejs.org](https://nodejs.org/)
|
|
39
|
+
- **npm** (v9+) atau **yarn** (v3+)
|
|
40
|
+
- **Git**: Untuk version control
|
|
41
|
+
- **npm account**: Untuk publish ke npm ([https://www.npmjs.com/](https://www.npmjs.com/))
|
|
42
|
+
|
|
43
|
+
Verifikasi instalasi:
|
|
44
|
+
```bash
|
|
45
|
+
node --version
|
|
46
|
+
npm --version
|
|
47
|
+
git --version
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 1. Setup Proyek Awal
|
|
53
|
+
|
|
54
|
+
### 1.1 Buat Folder Proyek
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
mkdir first-react-component-test
|
|
58
|
+
cd first-react-component-test
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 1.2 Inisialisasi Git
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git init
|
|
65
|
+
git config user.name "Nama Anda"
|
|
66
|
+
git config user.email "email@example.com"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 1.3 Inisialisasi npm
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm init -y
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Ini akan membuat `package.json` dengan konfigurasi default.
|
|
76
|
+
|
|
77
|
+
### 1.4 Update package.json
|
|
78
|
+
|
|
79
|
+
Edit `package.json` dan sesuaikan dengan informasi library Anda:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"name": "first-react-component-test",
|
|
84
|
+
"version": "1.0.0",
|
|
85
|
+
"description": "Komponen React kustom pertamaku",
|
|
86
|
+
"type": "module",
|
|
87
|
+
"main": "./dist/index.umd.js",
|
|
88
|
+
"module": "./dist/index.es.js",
|
|
89
|
+
"exports": {
|
|
90
|
+
".": {
|
|
91
|
+
"import": "./dist/index.es.js",
|
|
92
|
+
"require": "./dist/index.umd.js"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"files": [
|
|
96
|
+
"dist"
|
|
97
|
+
],
|
|
98
|
+
"scripts": {
|
|
99
|
+
"dev": "vite",
|
|
100
|
+
"build": "vite build",
|
|
101
|
+
"storybook": "storybook dev -p 6006",
|
|
102
|
+
"build-storybook": "storybook build"
|
|
103
|
+
},
|
|
104
|
+
"peerDependencies": {
|
|
105
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
106
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
107
|
+
},
|
|
108
|
+
"keywords": [
|
|
109
|
+
"react",
|
|
110
|
+
"component"
|
|
111
|
+
],
|
|
112
|
+
"author": "Nama Anda",
|
|
113
|
+
"license": "MIT",
|
|
114
|
+
"repository": {
|
|
115
|
+
"type": "git",
|
|
116
|
+
"url": "https://github.com/username/first-react-component-test"
|
|
117
|
+
},
|
|
118
|
+
"bugs": {
|
|
119
|
+
"url": "https://github.com/username/first-react-component-test/issues"
|
|
120
|
+
},
|
|
121
|
+
"homepage": "https://github.com/username/first-react-component-test#readme"
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Penjelasan field penting:**
|
|
126
|
+
- `name`: Nama package di npm (harus unik)
|
|
127
|
+
- `main`: Entry point untuk CommonJS
|
|
128
|
+
- `module`: Entry point untuk ES Modules
|
|
129
|
+
- `exports`: Mendefinisikan multiple entry points
|
|
130
|
+
- `files`: File yang akan dipublikasikan ke npm
|
|
131
|
+
- `peerDependencies`: Dependency yang harus diinstall oleh user
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 2. Membuat Struktur Folder
|
|
136
|
+
|
|
137
|
+
Buat struktur folder proyek:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
mkdir -p src/stories
|
|
141
|
+
touch src/index.js
|
|
142
|
+
touch .gitignore
|
|
143
|
+
touch .npmrc
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Struktur folder akhir:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
first-react-component-test/
|
|
150
|
+
├── node_modules/
|
|
151
|
+
├── src/
|
|
152
|
+
│ ├── components/
|
|
153
|
+
│ │ ├── ChatTrigger.tsx
|
|
154
|
+
│ │ ├── ChatWindow.tsx
|
|
155
|
+
│ │ └── MyComponent.jsx
|
|
156
|
+
│ ├── stories/
|
|
157
|
+
│ │ ├── ChatTrigger.stories.jsx
|
|
158
|
+
│ │ ├── ChatWindow.stories.jsx
|
|
159
|
+
│ │ └── MyComponent.stories.jsx
|
|
160
|
+
│ └── index.js
|
|
161
|
+
├── dist/ (generated saat build)
|
|
162
|
+
├── .gitignore
|
|
163
|
+
├── .npmrc
|
|
164
|
+
├── vite.config.js
|
|
165
|
+
├── package.json
|
|
166
|
+
└── README.md
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 2.1 Buat .gitignore
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
cat > .gitignore << 'EOF'
|
|
173
|
+
# Dependencies
|
|
174
|
+
node_modules/
|
|
175
|
+
package-lock.json
|
|
176
|
+
yarn.lock
|
|
177
|
+
pnpm-lock.yaml
|
|
178
|
+
|
|
179
|
+
# Build output
|
|
180
|
+
dist/
|
|
181
|
+
build/
|
|
182
|
+
|
|
183
|
+
# Logs
|
|
184
|
+
npm-debug.log*
|
|
185
|
+
yarn-debug.log*
|
|
186
|
+
yarn-error.log*
|
|
187
|
+
|
|
188
|
+
# IDE
|
|
189
|
+
.vscode/
|
|
190
|
+
.idea/
|
|
191
|
+
*.swp
|
|
192
|
+
*.swo
|
|
193
|
+
.DS_Store
|
|
194
|
+
|
|
195
|
+
# Storybook
|
|
196
|
+
storybook-static/
|
|
197
|
+
|
|
198
|
+
# Environment variables
|
|
199
|
+
.env
|
|
200
|
+
.env.local
|
|
201
|
+
EOF
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 2.2 Buat .npmrc
|
|
205
|
+
|
|
206
|
+
File ini mengonfigurasi npm publishing:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
cat > .npmrc << 'EOF'
|
|
210
|
+
# Publish public packages
|
|
211
|
+
access=public
|
|
212
|
+
|
|
213
|
+
# Optional: set registry (gunakan jika menggunakan private registry)
|
|
214
|
+
# registry=https://registry.npmjs.org/
|
|
215
|
+
EOF
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 3. Konfigurasi Vite
|
|
221
|
+
|
|
222
|
+
### 3.1 Install Dependencies
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm install --save-dev vite @vitejs/plugin-react
|
|
226
|
+
npm install --save-dev @storybook/react-vite storybook
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 3.2 Buat vite.config.js
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
/// <reference types="vitest/config" />
|
|
233
|
+
import { defineConfig } from 'vite';
|
|
234
|
+
import react from '@vitejs/plugin-react';
|
|
235
|
+
import { resolve } from 'path';
|
|
236
|
+
|
|
237
|
+
export default defineConfig({
|
|
238
|
+
plugins: [react()],
|
|
239
|
+
build: {
|
|
240
|
+
lib: {
|
|
241
|
+
// Entry point ke index.js di folder src
|
|
242
|
+
entry: resolve(__dirname, 'src/index.js'),
|
|
243
|
+
name: 'FirstReactComponentTest',
|
|
244
|
+
// Format output: ES module dan UMD
|
|
245
|
+
formats: ['es', 'umd'],
|
|
246
|
+
fileName: (format) => `index.${format}.js`,
|
|
247
|
+
},
|
|
248
|
+
rollupOptions: {
|
|
249
|
+
// Jangan masukkan react ke dalam bundle
|
|
250
|
+
external: ['react', 'react-dom', 'react/jsx-runtime'],
|
|
251
|
+
output: {
|
|
252
|
+
// Konfigurasi global variables untuk UMD
|
|
253
|
+
globals: {
|
|
254
|
+
react: 'React',
|
|
255
|
+
'react-dom': 'ReactDOM',
|
|
256
|
+
'react/jsx-runtime': 'jsxRuntime'
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 4. Membuat Komponen React
|
|
267
|
+
|
|
268
|
+
### 4.1 Buat File Komponen
|
|
269
|
+
|
|
270
|
+
Contoh `src/components/MyComponent.jsx`:
|
|
271
|
+
|
|
272
|
+
```jsx
|
|
273
|
+
import React from 'react';
|
|
274
|
+
import PropTypes from 'prop-types';
|
|
275
|
+
|
|
276
|
+
export const MyComponent = ({ title, description, onClick }) => {
|
|
277
|
+
return (
|
|
278
|
+
<div style={{
|
|
279
|
+
padding: '20px',
|
|
280
|
+
border: '1px solid #ccc',
|
|
281
|
+
borderRadius: '8px',
|
|
282
|
+
backgroundColor: '#f9f9f9'
|
|
283
|
+
}}>
|
|
284
|
+
<h2>{title}</h2>
|
|
285
|
+
<p>{description}</p>
|
|
286
|
+
<button onClick={onClick}>Click Me</button>
|
|
287
|
+
</div>
|
|
288
|
+
);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
MyComponent.propTypes = {
|
|
292
|
+
title: PropTypes.string.isRequired,
|
|
293
|
+
description: PropTypes.string,
|
|
294
|
+
onClick: PropTypes.func
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
MyComponent.defaultProps = {
|
|
298
|
+
description: 'Deskripsi komponen',
|
|
299
|
+
onClick: () => console.log('Button clicked')
|
|
300
|
+
};
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### 4.2 Buat File TypeScript (Opsional)
|
|
304
|
+
|
|
305
|
+
Contoh `src/components/ChatTrigger.tsx`:
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import React, { FC, ReactNode } from 'react';
|
|
309
|
+
|
|
310
|
+
interface ChatTriggerProps {
|
|
311
|
+
children?: ReactNode;
|
|
312
|
+
onOpen?: () => void;
|
|
313
|
+
variant?: 'primary' | 'secondary';
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export const ChatTrigger: FC<ChatTriggerProps> = ({
|
|
317
|
+
children = 'Open Chat',
|
|
318
|
+
onOpen,
|
|
319
|
+
variant = 'primary'
|
|
320
|
+
}) => {
|
|
321
|
+
return (
|
|
322
|
+
<button
|
|
323
|
+
onClick={onOpen}
|
|
324
|
+
style={{
|
|
325
|
+
padding: '10px 20px',
|
|
326
|
+
backgroundColor: variant === 'primary' ? '#007bff' : '#6c757d',
|
|
327
|
+
color: '#fff',
|
|
328
|
+
border: 'none',
|
|
329
|
+
borderRadius: '4px',
|
|
330
|
+
cursor: 'pointer'
|
|
331
|
+
}}
|
|
332
|
+
>
|
|
333
|
+
{children}
|
|
334
|
+
</button>
|
|
335
|
+
);
|
|
336
|
+
};
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### 4.3 Buat File Index (Entry Point)
|
|
340
|
+
|
|
341
|
+
`src/index.js`:
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
// Export semua komponen
|
|
345
|
+
export { MyComponent } from './components/MyComponent.jsx';
|
|
346
|
+
export { ChatTrigger } from './components/ChatTrigger.tsx';
|
|
347
|
+
export { ChatWindow } from './components/ChatWindow.tsx';
|
|
348
|
+
|
|
349
|
+
// Atau dengan named exports
|
|
350
|
+
// export * from './components/MyComponent.jsx';
|
|
351
|
+
// export * from './components/ChatTrigger.tsx';
|
|
352
|
+
// export * from './components/ChatWindow.tsx';
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## 5. Setup Storybook
|
|
358
|
+
|
|
359
|
+
Storybook membantu Anda mendokumentasikan dan menguji komponen secara visual.
|
|
360
|
+
|
|
361
|
+
### 5.1 Install Storybook
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
npx storybook@latest init --type react
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Atau manual:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
npm install --save-dev storybook @storybook/react @storybook/react-vite
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### 5.2 Buat .storybook/main.js
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
export default {
|
|
377
|
+
stories: ['../src/**/*.stories.{js,jsx,ts,tsx}'],
|
|
378
|
+
addons: [
|
|
379
|
+
'@storybook/addon-links',
|
|
380
|
+
'@storybook/addon-essentials',
|
|
381
|
+
'@storybook/addon-onboarding'
|
|
382
|
+
],
|
|
383
|
+
framework: '@storybook/react-vite',
|
|
384
|
+
core: {
|
|
385
|
+
builder: '@storybook/builder-vite'
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### 5.3 Buat File Story
|
|
391
|
+
|
|
392
|
+
`src/components/MyComponent.stories.jsx`:
|
|
393
|
+
|
|
394
|
+
```jsx
|
|
395
|
+
import { MyComponent } from './MyComponent';
|
|
396
|
+
|
|
397
|
+
export default {
|
|
398
|
+
title: 'Components/MyComponent',
|
|
399
|
+
component: MyComponent,
|
|
400
|
+
tags: ['autodocs'],
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
export const Primary = {
|
|
404
|
+
args: {
|
|
405
|
+
title: 'Hello Component',
|
|
406
|
+
description: 'Ini adalah contoh komponen'
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
export const Secondary = {
|
|
411
|
+
args: {
|
|
412
|
+
title: 'Secondary Variant',
|
|
413
|
+
description: 'Variant kedua dari komponen',
|
|
414
|
+
onClick: () => alert('Tombol diklik!')
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### 5.4 Jalankan Storybook
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
npm run storybook
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Storybook akan berjalan di `http://localhost:6006`
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## 6. Build Library
|
|
430
|
+
|
|
431
|
+
### 6.1 Build untuk NPM
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
npm run build
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Ini akan menghasilkan folder `dist/` dengan:
|
|
438
|
+
- `dist/index.es.js` - ES Module format
|
|
439
|
+
- `dist/index.umd.js` - UMD format (untuk browser dan Node.js)
|
|
440
|
+
|
|
441
|
+
### 6.2 Verifikasi Build
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
ls -la dist/
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Seharusnya Anda melihat dua file yang dihasilkan.
|
|
448
|
+
|
|
449
|
+
### 6.3 Test Build Lokal (Opsional)
|
|
450
|
+
|
|
451
|
+
Untuk test apakah package bisa diinstall:
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
# Di folder proyek lain
|
|
455
|
+
npm install /path/to/first-react-component-test
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## 7. Testing (Opsional)
|
|
461
|
+
|
|
462
|
+
### 7.1 Install Vitest
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### 7.2 Setup vitest.config.js
|
|
469
|
+
|
|
470
|
+
```javascript
|
|
471
|
+
import { defineConfig } from 'vitest/config';
|
|
472
|
+
import react from '@vitejs/plugin-react';
|
|
473
|
+
|
|
474
|
+
export default defineConfig({
|
|
475
|
+
plugins: [react()],
|
|
476
|
+
test: {
|
|
477
|
+
globals: true,
|
|
478
|
+
environment: 'jsdom',
|
|
479
|
+
setupFiles: './src/test/setup.js'
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### 7.3 Buat Test File
|
|
485
|
+
|
|
486
|
+
`src/components/MyComponent.test.jsx`:
|
|
487
|
+
|
|
488
|
+
```jsx
|
|
489
|
+
import { describe, it, expect } from 'vitest';
|
|
490
|
+
import { render, screen } from '@testing-library/react';
|
|
491
|
+
import { MyComponent } from './MyComponent';
|
|
492
|
+
|
|
493
|
+
describe('MyComponent', () => {
|
|
494
|
+
it('renders with title', () => {
|
|
495
|
+
render(<MyComponent title="Test Title" />);
|
|
496
|
+
expect(screen.getByText('Test Title')).toBeInTheDocument();
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it('displays description', () => {
|
|
500
|
+
render(<MyComponent title="Test" description="Test Description" />);
|
|
501
|
+
expect(screen.getByText('Test Description')).toBeInTheDocument();
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### 7.4 Update package.json
|
|
507
|
+
|
|
508
|
+
```json
|
|
509
|
+
{
|
|
510
|
+
"scripts": {
|
|
511
|
+
"test": "vitest",
|
|
512
|
+
"test:ui": "vitest --ui"
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### 7.5 Jalankan Test
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
npm run test
|
|
521
|
+
npm run test:ui
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## 8. Publish ke NPM
|
|
527
|
+
|
|
528
|
+
### 8.1 Persiapan Pre-Publish
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
# 1. Pastikan build sudah terbuat
|
|
532
|
+
npm run build
|
|
533
|
+
|
|
534
|
+
# 2. Verifikasi package.json
|
|
535
|
+
cat package.json | grep -E '"name"|"version"|"main"|"module"'
|
|
536
|
+
|
|
537
|
+
# 3. Commit semua perubahan
|
|
538
|
+
git add .
|
|
539
|
+
git commit -m "Initial commit"
|
|
540
|
+
|
|
541
|
+
# 4. Create tag version
|
|
542
|
+
git tag v1.0.0
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### 8.2 Login ke NPM
|
|
546
|
+
|
|
547
|
+
```bash
|
|
548
|
+
npm login
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Masukkan:
|
|
552
|
+
- Username npm Anda
|
|
553
|
+
- Password
|
|
554
|
+
- Email
|
|
555
|
+
- OTP (One-Time Password) jika enabled
|
|
556
|
+
|
|
557
|
+
**Verifikasi login:**
|
|
558
|
+
```bash
|
|
559
|
+
npm whoami
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### 8.3 Test Publish (Opsional)
|
|
563
|
+
|
|
564
|
+
Sebelum publish ke npm public, Anda bisa test dengan npm dry-run:
|
|
565
|
+
|
|
566
|
+
```bash
|
|
567
|
+
npm publish --dry-run
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
Ini akan menampilkan file apa saja yang akan dipublikasikan tanpa benar-benar publish.
|
|
571
|
+
|
|
572
|
+
### 8.4 Publish ke NPM
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
npm publish
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
**Output yang diharapkan:**
|
|
579
|
+
```
|
|
580
|
+
npm notice
|
|
581
|
+
npm notice 📦 first-react-component-test@1.0.0
|
|
582
|
+
npm notice === Tarball Contents ===
|
|
583
|
+
npm notice 258B dist/index.es.js
|
|
584
|
+
npm notice 312B dist/index.umd.js
|
|
585
|
+
npm notice 456B package.json
|
|
586
|
+
npm notice === Tarball Details ===
|
|
587
|
+
npm notice name: first-react-component-test
|
|
588
|
+
npm notice version: 1.0.0
|
|
589
|
+
npm notice ...
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### 8.5 Verifikasi Publish
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
# Cek di npm registry
|
|
596
|
+
npm view first-react-component-test
|
|
597
|
+
|
|
598
|
+
# Atau kunjungi: https://www.npmjs.com/package/first-react-component-test
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## 9. Update dan Re-publish
|
|
604
|
+
|
|
605
|
+
### 9.1 Semantic Versioning
|
|
606
|
+
|
|
607
|
+
Gunakan format `MAJOR.MINOR.PATCH`:
|
|
608
|
+
|
|
609
|
+
```
|
|
610
|
+
1.2.3
|
|
611
|
+
│ │ └─ PATCH (bug fixes)
|
|
612
|
+
│ └─── MINOR (new features, backward compatible)
|
|
613
|
+
└───── MAJOR (breaking changes)
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### 9.2 Update Version
|
|
617
|
+
|
|
618
|
+
```bash
|
|
619
|
+
# Patch version (1.0.0 → 1.0.1)
|
|
620
|
+
npm version patch
|
|
621
|
+
|
|
622
|
+
# Minor version (1.0.0 → 1.1.0)
|
|
623
|
+
npm version minor
|
|
624
|
+
|
|
625
|
+
# Major version (1.0.0 → 2.0.0)
|
|
626
|
+
npm version major
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Ini akan:
|
|
630
|
+
- Update `package.json`
|
|
631
|
+
- Create git tag otomatis
|
|
632
|
+
- Commit changes
|
|
633
|
+
|
|
634
|
+
### 9.3 Re-publish
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
npm publish
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
## 🚀 Cara Menggunakan Library
|
|
643
|
+
|
|
644
|
+
Setelah publish, user bisa install library Anda:
|
|
645
|
+
|
|
646
|
+
```bash
|
|
647
|
+
npm install first-react-component-test
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Import dan Gunakan
|
|
651
|
+
|
|
652
|
+
**Di React App:**
|
|
653
|
+
|
|
654
|
+
```jsx
|
|
655
|
+
import React from 'react';
|
|
656
|
+
import { MyComponent, ChatTrigger } from 'first-react-component-test';
|
|
657
|
+
|
|
658
|
+
function App() {
|
|
659
|
+
return (
|
|
660
|
+
<div>
|
|
661
|
+
<MyComponent title="Hello" description="Welcome" />
|
|
662
|
+
<ChatTrigger onOpen={() => console.log('opened')} />
|
|
663
|
+
</div>
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
export default App;
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## 🐛 Troubleshooting
|
|
673
|
+
|
|
674
|
+
### Masalah: "Cannot find module 'react'"
|
|
675
|
+
|
|
676
|
+
**Penyebab:** React tidak diinstall di project yang menggunakan library.
|
|
677
|
+
|
|
678
|
+
**Solusi:**
|
|
679
|
+
```bash
|
|
680
|
+
npm install react react-dom
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Masalah: "Module is not defined"
|
|
684
|
+
|
|
685
|
+
**Penyebab:** Konfigurasi Vite tidak benar.
|
|
686
|
+
|
|
687
|
+
**Solusi:** Pastikan `vite.config.js` memiliki:
|
|
688
|
+
```javascript
|
|
689
|
+
plugins: [react()],
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### Masalah: Build tidak menghasilkan file di dist
|
|
693
|
+
|
|
694
|
+
**Penyebab:** Entry point tidak benar atau index.js kosong.
|
|
695
|
+
|
|
696
|
+
**Solusi:** Verifikasi `src/index.js` export komponen dengan benar:
|
|
697
|
+
```javascript
|
|
698
|
+
export { MyComponent } from './components/MyComponent.jsx';
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
### Masalah: Publish gagal "Package name already exists"
|
|
702
|
+
|
|
703
|
+
**Penyebab:** Nama package sudah terdaftar di npm.
|
|
704
|
+
|
|
705
|
+
**Solusi:** Gunakan nama unik dengan scope:
|
|
706
|
+
```json
|
|
707
|
+
{
|
|
708
|
+
"name": "@username/first-react-component-test"
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Masalah: Storybook tidak bisa jalankan komponen
|
|
713
|
+
|
|
714
|
+
**Penyebab:** Dependencies TypeScript tidak terinstall.
|
|
715
|
+
|
|
716
|
+
**Solusi:**
|
|
717
|
+
```bash
|
|
718
|
+
npm install --save-dev typescript
|
|
719
|
+
npm install --save-dev @types/react @types/react-dom
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
## 📚 Resources Tambahan
|
|
725
|
+
|
|
726
|
+
- [Vite Documentation](https://vitejs.dev/)
|
|
727
|
+
- [Storybook Documentation](https://storybook.js.org/)
|
|
728
|
+
- [NPM Publishing Guide](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry)
|
|
729
|
+
- [React Documentation](https://react.dev/)
|
|
730
|
+
- [Semantic Versioning](https://semver.org/)
|
|
731
|
+
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
## 📝 Checklist Pre-Publish
|
|
735
|
+
|
|
736
|
+
Sebelum publish, pastikan:
|
|
737
|
+
|
|
738
|
+
- [ ] `package.json` sudah dikonfigurasi dengan benar
|
|
739
|
+
- [ ] `name` unik dan belum terdaftar di npm
|
|
740
|
+
- [ ] `version` sudah diupdate sesuai semantic versioning
|
|
741
|
+
- [ ] `main` dan `module` menunjuk ke file yang benar
|
|
742
|
+
- [ ] `files` include folder `dist`
|
|
743
|
+
- [ ] Build berhasil tanpa error: `npm run build`
|
|
744
|
+
- [ ] Semua file dikompilasi di folder `dist`
|
|
745
|
+
- [ ] Git sudah diinit dan commit pertama sudah dibuat
|
|
746
|
+
- [ ] `.npmrc` sudah dibuat
|
|
747
|
+
- [ ] Sudah login ke npm: `npm whoami`
|
|
748
|
+
- [ ] Storybook running dengan baik
|
|
749
|
+
- [ ] README.md lengkap dengan dokumentasi
|
|
750
|
+
|
|
751
|
+
---
|
|
752
|
+
|
|
753
|
+
## 📄 License
|
|
754
|
+
|
|
755
|
+
MIT License - Gratis untuk digunakan secara komersial dan pribadi.
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
**Happy Publishing! 🎉**
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { useEffect as e, useRef as t, useState as n } from "react";
|
|
2
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
3
|
+
//#region src/MyComponent.jsx
|
|
4
|
+
var a = ({ text: e = "Halo dari NPM!", color: t = "blue" }) => /* @__PURE__ */ r("button", {
|
|
5
|
+
style: {
|
|
6
|
+
padding: "10px 20px",
|
|
7
|
+
backgroundColor: t,
|
|
8
|
+
color: "#fff",
|
|
9
|
+
border: "none",
|
|
10
|
+
borderRadius: "5px",
|
|
11
|
+
cursor: "pointer"
|
|
12
|
+
},
|
|
13
|
+
children: e
|
|
14
|
+
}), o = ({ open: a }) => {
|
|
15
|
+
let [o, s] = n(!1), [c, l] = n([{
|
|
16
|
+
id: 0,
|
|
17
|
+
role: "bot",
|
|
18
|
+
text: "Halo! Saya bisa dibuka pakai tombol maupun langsung lewat props!"
|
|
19
|
+
}]), [u, d] = n(""), [f, p] = n(!1), m = t(null), h = a !== void 0, g = h ? a === "true" || a === !0 : o;
|
|
20
|
+
e(() => {
|
|
21
|
+
if (!h) {
|
|
22
|
+
let e = () => s((e) => !e);
|
|
23
|
+
return window.addEventListener("TOGGLE_CHAT_BOT", e), () => window.removeEventListener("TOGGLE_CHAT_BOT", e);
|
|
24
|
+
}
|
|
25
|
+
}, [h]);
|
|
26
|
+
let _ = async () => {
|
|
27
|
+
let e = u.trim();
|
|
28
|
+
if (!(!e || f)) {
|
|
29
|
+
p(!0), l((t) => [...t, {
|
|
30
|
+
id: Date.now(),
|
|
31
|
+
role: "user",
|
|
32
|
+
text: e
|
|
33
|
+
}]), d("");
|
|
34
|
+
try {
|
|
35
|
+
let t = `Pesan diterima (id: ${(await (await fetch("https://jsonplaceholder.typicode.com/posts", {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "Content-Type": "application/json" },
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
title: "chat-message",
|
|
40
|
+
body: e,
|
|
41
|
+
userId: 1
|
|
42
|
+
})
|
|
43
|
+
})).json())?.id ?? "-"}). Isi: ${e}`;
|
|
44
|
+
l((e) => [...e, {
|
|
45
|
+
id: Date.now() + 1,
|
|
46
|
+
role: "bot",
|
|
47
|
+
text: t
|
|
48
|
+
}]);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
console.error("Gagal mengirim ke API:", e), l((e) => [...e, {
|
|
51
|
+
id: Date.now() + 2,
|
|
52
|
+
role: "bot",
|
|
53
|
+
text: "Maaf, gagal mengirim pesan. Coba lagi."
|
|
54
|
+
}]);
|
|
55
|
+
} finally {
|
|
56
|
+
p(!1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return e(() => {
|
|
61
|
+
m.current?.scrollTo({
|
|
62
|
+
top: m.current.scrollHeight,
|
|
63
|
+
behavior: "smooth"
|
|
64
|
+
});
|
|
65
|
+
}, [c.length]), g ? /* @__PURE__ */ i("div", {
|
|
66
|
+
style: {
|
|
67
|
+
position: "fixed",
|
|
68
|
+
bottom: "100px",
|
|
69
|
+
right: "30px",
|
|
70
|
+
width: "350px",
|
|
71
|
+
height: "450px",
|
|
72
|
+
background: "white",
|
|
73
|
+
borderRadius: "10px",
|
|
74
|
+
boxShadow: "0 5px 20px rgba(0,0,0,0.2)",
|
|
75
|
+
display: "flex",
|
|
76
|
+
flexDirection: "column",
|
|
77
|
+
zIndex: 9999,
|
|
78
|
+
fontFamily: "sans-serif"
|
|
79
|
+
},
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ r("div", {
|
|
82
|
+
style: {
|
|
83
|
+
background: "#007bff",
|
|
84
|
+
color: "white",
|
|
85
|
+
padding: "15px",
|
|
86
|
+
borderRadius: "10px 10px 0 0"
|
|
87
|
+
},
|
|
88
|
+
children: /* @__PURE__ */ r("strong", { children: "AI Chat Bot" })
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ r("div", {
|
|
91
|
+
ref: m,
|
|
92
|
+
style: {
|
|
93
|
+
flex: 1,
|
|
94
|
+
padding: "15px",
|
|
95
|
+
overflowY: "auto",
|
|
96
|
+
display: "flex",
|
|
97
|
+
flexDirection: "column",
|
|
98
|
+
gap: "8px"
|
|
99
|
+
},
|
|
100
|
+
children: c.map((e) => /* @__PURE__ */ r("div", {
|
|
101
|
+
style: {
|
|
102
|
+
maxWidth: "80%",
|
|
103
|
+
alignSelf: e.role === "user" ? "flex-end" : "flex-start",
|
|
104
|
+
background: e.role === "user" ? "#e6f0ff" : "#f1f1f1",
|
|
105
|
+
padding: "8px 10px",
|
|
106
|
+
borderRadius: "8px",
|
|
107
|
+
wordBreak: "break-word"
|
|
108
|
+
},
|
|
109
|
+
children: e.text
|
|
110
|
+
}, e.id))
|
|
111
|
+
}),
|
|
112
|
+
/* @__PURE__ */ i("div", {
|
|
113
|
+
style: {
|
|
114
|
+
padding: "10px",
|
|
115
|
+
borderTop: "1px solid #eee",
|
|
116
|
+
display: "flex",
|
|
117
|
+
gap: "8px"
|
|
118
|
+
},
|
|
119
|
+
children: [/* @__PURE__ */ r("input", {
|
|
120
|
+
type: "text",
|
|
121
|
+
value: u,
|
|
122
|
+
onChange: (e) => d(e.target.value),
|
|
123
|
+
onKeyDown: (e) => {
|
|
124
|
+
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), _());
|
|
125
|
+
},
|
|
126
|
+
placeholder: "Ketik pesan...",
|
|
127
|
+
style: {
|
|
128
|
+
flex: 1,
|
|
129
|
+
padding: "10px",
|
|
130
|
+
border: "1px solid #ccc",
|
|
131
|
+
borderRadius: "6px",
|
|
132
|
+
outline: "none"
|
|
133
|
+
},
|
|
134
|
+
disabled: f
|
|
135
|
+
}), /* @__PURE__ */ r("button", {
|
|
136
|
+
onClick: _,
|
|
137
|
+
disabled: f || !u.trim(),
|
|
138
|
+
style: {
|
|
139
|
+
background: "#007bff",
|
|
140
|
+
color: "white",
|
|
141
|
+
border: "none",
|
|
142
|
+
padding: "10px 14px",
|
|
143
|
+
borderRadius: "6px",
|
|
144
|
+
cursor: f || !u.trim() ? "not-allowed" : "pointer"
|
|
145
|
+
},
|
|
146
|
+
children: f ? "Mengirim..." : "Kirim"
|
|
147
|
+
})]
|
|
148
|
+
})
|
|
149
|
+
]
|
|
150
|
+
}) : null;
|
|
151
|
+
}, s = ({ text: e = "💬 Chat" }) => /* @__PURE__ */ r("button", {
|
|
152
|
+
onClick: () => {
|
|
153
|
+
let e = new CustomEvent("TOGGLE_CHAT_BOT");
|
|
154
|
+
window.dispatchEvent(e);
|
|
155
|
+
},
|
|
156
|
+
style: {
|
|
157
|
+
padding: "12px 24px",
|
|
158
|
+
background: "#007bff",
|
|
159
|
+
color: "white",
|
|
160
|
+
border: "none",
|
|
161
|
+
borderRadius: "50px",
|
|
162
|
+
cursor: "pointer",
|
|
163
|
+
boxShadow: "0 4px 10px rgba(0,0,0,0.15)"
|
|
164
|
+
},
|
|
165
|
+
children: e
|
|
166
|
+
});
|
|
167
|
+
//#endregion
|
|
168
|
+
export { s as ChatTrigger, o as ChatWindow, a as MyComponent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("react/jsx-runtime")):typeof define==`function`&&define.amd?define([`exports`,`react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.FirstReactComponentTest={},e.React,e.jsxRuntime))})(this,function(e,t,n){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var r=Object.create,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,l=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var s=o(t),l=0,u=s.length,d;l<u;l++)d=s[l],!c.call(e,d)&&d!==n&&i(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=a(t,d))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:r(s(e)),l(t||!e||!e.__esModule?i(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1),e.ChatTrigger=({text:e=`💬 Chat`})=>(0,n.jsx)(`button`,{onClick:()=>{let e=new CustomEvent(`TOGGLE_CHAT_BOT`);window.dispatchEvent(e)},style:{padding:`12px 24px`,background:`#007bff`,color:`white`,border:`none`,borderRadius:`50px`,cursor:`pointer`,boxShadow:`0 4px 10px rgba(0,0,0,0.15)`},children:e}),e.ChatWindow=({open:e})=>{let[r,i]=(0,t.useState)(!1),[a,o]=(0,t.useState)([{id:0,role:`bot`,text:`Halo! Saya bisa dibuka pakai tombol maupun langsung lewat props!`}]),[s,c]=(0,t.useState)(``),[l,u]=(0,t.useState)(!1),d=(0,t.useRef)(null),f=e!==void 0,p=f?e===`true`||e===!0:r;(0,t.useEffect)(()=>{if(!f){let e=()=>i(e=>!e);return window.addEventListener(`TOGGLE_CHAT_BOT`,e),()=>window.removeEventListener(`TOGGLE_CHAT_BOT`,e)}},[f]);let m=async()=>{let e=s.trim();if(!(!e||l)){u(!0),o(t=>[...t,{id:Date.now(),role:`user`,text:e}]),c(``);try{let t=`Pesan diterima (id: ${(await(await fetch(`https://jsonplaceholder.typicode.com/posts`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:`chat-message`,body:e,userId:1})})).json())?.id??`-`}). Isi: ${e}`;o(e=>[...e,{id:Date.now()+1,role:`bot`,text:t}])}catch(e){console.error(`Gagal mengirim ke API:`,e),o(e=>[...e,{id:Date.now()+2,role:`bot`,text:`Maaf, gagal mengirim pesan. Coba lagi.`}])}finally{u(!1)}}};return(0,t.useEffect)(()=>{d.current?.scrollTo({top:d.current.scrollHeight,behavior:`smooth`})},[a.length]),p?(0,n.jsxs)(`div`,{style:{position:`fixed`,bottom:`100px`,right:`30px`,width:`350px`,height:`450px`,background:`white`,borderRadius:`10px`,boxShadow:`0 5px 20px rgba(0,0,0,0.2)`,display:`flex`,flexDirection:`column`,zIndex:9999,fontFamily:`sans-serif`},children:[(0,n.jsx)(`div`,{style:{background:`#007bff`,color:`white`,padding:`15px`,borderRadius:`10px 10px 0 0`},children:(0,n.jsx)(`strong`,{children:`AI Chat Bot`})}),(0,n.jsx)(`div`,{ref:d,style:{flex:1,padding:`15px`,overflowY:`auto`,display:`flex`,flexDirection:`column`,gap:`8px`},children:a.map(e=>(0,n.jsx)(`div`,{style:{maxWidth:`80%`,alignSelf:e.role===`user`?`flex-end`:`flex-start`,background:e.role===`user`?`#e6f0ff`:`#f1f1f1`,padding:`8px 10px`,borderRadius:`8px`,wordBreak:`break-word`},children:e.text},e.id))}),(0,n.jsxs)(`div`,{style:{padding:`10px`,borderTop:`1px solid #eee`,display:`flex`,gap:`8px`},children:[(0,n.jsx)(`input`,{type:`text`,value:s,onChange:e=>c(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),m())},placeholder:`Ketik pesan...`,style:{flex:1,padding:`10px`,border:`1px solid #ccc`,borderRadius:`6px`,outline:`none`},disabled:l}),(0,n.jsx)(`button`,{onClick:m,disabled:l||!s.trim(),style:{background:`#007bff`,color:`white`,border:`none`,padding:`10px 14px`,borderRadius:`6px`,cursor:l||!s.trim()?`not-allowed`:`pointer`},children:l?`Mengirim...`:`Kirim`})]})]}):null},e.MyComponent=({text:e=`Halo dari NPM!`,color:t=`blue`})=>(0,n.jsx)(`button`,{style:{padding:`10px 20px`,backgroundColor:t,color:`#fff`,border:`none`,borderRadius:`5px`,cursor:`pointer`},children:e})});
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-component-by-vite",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Komponen React kustom pertamaku",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.umd.js",
|
|
7
|
+
"module": "./dist/index.es.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.es.js",
|
|
11
|
+
"require": "./dist/index.umd.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "vite build",
|
|
19
|
+
"storybook": "storybook dev -p 6006",
|
|
20
|
+
"build-storybook": "storybook build"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
24
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"react",
|
|
28
|
+
"component"
|
|
29
|
+
],
|
|
30
|
+
"author": "Nama Anda",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@chromatic-com/storybook": "^5.2.1",
|
|
34
|
+
"@storybook/addon-a11y": "^10.4.1",
|
|
35
|
+
"@storybook/addon-docs": "^10.4.1",
|
|
36
|
+
"@storybook/addon-mcp": "^0.6.0",
|
|
37
|
+
"@storybook/addon-vitest": "^10.4.1",
|
|
38
|
+
"@storybook/react-vite": "^10.4.1",
|
|
39
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
40
|
+
"@vitest/browser-playwright": "^4.1.8",
|
|
41
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
42
|
+
"playwright": "^1.60.0",
|
|
43
|
+
"prop-types": "^15.8.1",
|
|
44
|
+
"storybook": "^10.4.1",
|
|
45
|
+
"vitest": "^4.1.8"
|
|
46
|
+
}
|
|
47
|
+
}
|