@idds/react 1.4.4 → 1.4.6
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 +467 -329
- package/dist/index.cjs.js +1 -1
- package/dist/index.css +1 -1
- package/dist/index.es.js +8 -4
- package/dist/index.umd.js +1 -1
- package/dist/types/components/FileUpload.d.ts +4 -3
- package/dist/types/components/FileUpload.d.ts.map +1 -1
- package/dist/types/components/SingleFileUpload.d.ts +2 -2
- package/dist/types/components/SingleFileUpload.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,429 +1,567 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @idds/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React UI component library for INA Digital Design System.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package provides a comprehensive set of React components built with TypeScript. All styles are managed centrally in `@idds/styles` package and are **not dependent on Tailwind CSS classes**. Components use pure CSS with BEM-like naming conventions.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- [B. React Project`](#b-react-project)
|
|
9
|
+
```bash
|
|
10
|
+
npm install @idds/react
|
|
11
|
+
```
|
|
13
12
|
|
|
14
|
-
##
|
|
13
|
+
## Peer Dependencies
|
|
15
14
|
|
|
16
15
|
```bash
|
|
17
|
-
|
|
18
|
-
npm install @idds/react tailwindcss@4.1.6 @tailwindcss/vite@4.1.6 @tabler/icons-react
|
|
19
|
-
# atau menggunakan Yarn
|
|
20
|
-
yarn add @idds/react tailwindcss@4.1.6 @tailwindcss/vite@4.1.6 @tabler/icons-react
|
|
16
|
+
npm install react@>=18.0.0 react-dom@>=18.0.0
|
|
21
17
|
```
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
1. Pastikan anda telah menginstall `@astrojs/react^4.2.7`, `react^18.0.0`, dan `react-dom^18.0.0`
|
|
26
|
-
2. Buat file **tailwind.config**, lalu import createPreset serta input nama brand yang hendak Anda pilih. Misal : BGN
|
|
27
|
-
```ts
|
|
28
|
-
import createPreset from '@idds/react/tailwind.preset.js';
|
|
29
|
-
export default {
|
|
30
|
-
darkMode: 'class',
|
|
31
|
-
presets: [createPreset({ brand: 'BGN' })],
|
|
32
|
-
theme: {
|
|
33
|
-
// anda tetap diperbolehkan untuk melakukan customization variable yang belum tercover di design-system
|
|
34
|
-
extend: {
|
|
35
|
-
spacing: {
|
|
36
|
-
'0.5': '2px',
|
|
37
|
-
'1.5': '6px',
|
|
38
|
-
'2.5': '10px',
|
|
39
|
-
'3.5': '14px',
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
plugins: [],
|
|
44
|
-
};
|
|
45
|
-
```
|
|
46
|
-
3. Di file global CSS anda, misal di `src/styles/global.css`, import plugin Tailwind agar utilitas tailwind bisa di gunakan sertakan juga `@config` dari **tailwind.config** nya agar custom theme & preset design system yang telah kita definisikan bisa terpakai.
|
|
47
|
-
```ts
|
|
48
|
-
@import "tailwindcss";
|
|
49
|
-
@config '../../tailwind.config.ts';
|
|
50
|
-
```
|
|
51
|
-
4. Import file CSS dari design system pada root file `.astro` Anda (yang terdapat tag `<html></html>` nya). Misal di src/layout/BaseLayout.astro. Pastikan Anda mengimport nya sebelum global CSS
|
|
19
|
+
## Quick Start
|
|
52
20
|
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
import { SITE_TITLE, SITE_DESCRIPTION } from '../constants';
|
|
56
|
-
import '@idds/react/style.css';
|
|
57
|
-
import '../styles/global.css';
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
<!doctype html>
|
|
61
|
-
<html lang="en">
|
|
62
|
-
<head>
|
|
63
|
-
<meta charset="UTF-8" />
|
|
64
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
65
|
-
<title>{SITE_TITLE}</title>
|
|
66
|
-
|
|
67
|
-
<meta name="generator" content={Astro.generator} />
|
|
68
|
-
<meta name="description" content={SITE_DESCRIPTION} />
|
|
69
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
70
|
-
<link rel="sitemap" type="application/xml" href="/sitemap-index.xml" />
|
|
71
|
-
</head>
|
|
72
|
-
<body
|
|
73
|
-
class:list={[
|
|
74
|
-
'pb-10',
|
|
75
|
-
'bg-gray-50 dark:bg-gray-800',
|
|
76
|
-
'scrollbar scrollbar-w-3 scrollbar-thumb-rounded-[0.25rem]',
|
|
77
|
-
'scrollbar-track-slate-200 scrollbar-thumb-gray-400',
|
|
78
|
-
'dark:scrollbar-track-gray-900 dark:scrollbar-thumb-gray-700',
|
|
79
|
-
]}
|
|
80
|
-
>
|
|
81
|
-
<slot />
|
|
82
|
-
</body>
|
|
83
|
-
</html>
|
|
84
|
-
|
|
85
|
-
<script></script>
|
|
86
|
-
|
|
87
|
-
<style is:global>
|
|
88
|
-
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Urbanist:ital,wght@0,100..900;1,100..900&display=swap');
|
|
89
|
-
</style>
|
|
90
|
-
```
|
|
21
|
+
### 1. Import CSS
|
|
91
22
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
1. Pastikan anda telah menginstall `react^18.0.0`, dan `react-dom^18.0.0`
|
|
95
|
-
2. Buat file **tailwind.config**, lalu import createPreset serta input nama brand yang hendak Anda pilih. Misal : BGN
|
|
96
|
-
|
|
97
|
-
```ts
|
|
98
|
-
// tailwind.config.js
|
|
99
|
-
import createPreset from '@idds/react/tailwind.preset.js';
|
|
100
|
-
|
|
101
|
-
/** @type {import('tailwindcss').Config} */
|
|
102
|
-
export default {
|
|
103
|
-
presets: [createPreset({ brand: 'BGN' })],
|
|
104
|
-
content: [
|
|
105
|
-
'./index.html',
|
|
106
|
-
'./src/**/*.{js,ts,jsx,tsx}',
|
|
107
|
-
'./*.{js,ts,jsx,tsx}',
|
|
108
|
-
],
|
|
109
|
-
theme: {
|
|
110
|
-
extend: {
|
|
111
|
-
backgroundImage: {},
|
|
112
|
-
colors: {},
|
|
113
|
-
fontSize: {},
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
plugins: [],
|
|
117
|
-
};
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
3. Di file global CSS anda, misal di `src/index.css`, import plugin Tailwind agar utilitas tailwind bisa di gunakan sertakan juga `@config` dari **tailwind.config** nya agar custom theme & preset design system yang telah kita definisikan bisa terpakai.
|
|
121
|
-
```ts
|
|
122
|
-
@import "tailwindcss";
|
|
123
|
-
@config '../../tailwind.config.ts';
|
|
124
|
-
```
|
|
125
|
-
4. Import file CSS dari design system pada root file `.jsx/.tsx` dari project React Anda. Misal menggunakan vite, maka ada di `src/main.jsx` seperti contoh dibawah ini :
|
|
23
|
+
Import the styles in your application entry point:
|
|
126
24
|
|
|
127
25
|
```jsx
|
|
128
|
-
|
|
129
|
-
import { createRoot } from 'react-dom/client';
|
|
26
|
+
// src/main.jsx or src/index.jsx
|
|
130
27
|
import '@idds/react/style.css';
|
|
131
|
-
import './index.css';
|
|
132
|
-
import App from './App.jsx';
|
|
133
|
-
|
|
134
|
-
createRoot(document.getElementById('root')).render(
|
|
135
|
-
<StrictMode>
|
|
136
|
-
<App />
|
|
137
|
-
</StrictMode>
|
|
138
|
-
);
|
|
139
28
|
```
|
|
140
29
|
|
|
141
|
-
|
|
30
|
+
### 2. Import and Use Components
|
|
142
31
|
|
|
143
|
-
|
|
32
|
+
```jsx
|
|
33
|
+
import { Button, TextField } from '@idds/react';
|
|
34
|
+
|
|
35
|
+
function App() {
|
|
36
|
+
return (
|
|
37
|
+
<div>
|
|
38
|
+
<Button variant="primary" size="md">
|
|
39
|
+
Click me
|
|
40
|
+
</Button>
|
|
41
|
+
<TextField
|
|
42
|
+
label="Email"
|
|
43
|
+
placeholder="Enter your email"
|
|
44
|
+
value={value}
|
|
45
|
+
onChange={setValue}
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
144
51
|
|
|
145
|
-
|
|
52
|
+
## Usage
|
|
146
53
|
|
|
147
|
-
|
|
148
|
-
2. [Instalasi](#instalasi)
|
|
149
|
-
3. [Konfigurasi Vite & Tailwind](#konfigurasi-vite--tailwind)
|
|
54
|
+
### Import Individual Components
|
|
150
55
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
56
|
+
```jsx
|
|
57
|
+
import { Button, TextField, SelectDropdown, Modal } from '@idds/react';
|
|
58
|
+
```
|
|
154
59
|
|
|
155
|
-
|
|
60
|
+
### Import All Components
|
|
156
61
|
|
|
157
|
-
|
|
62
|
+
```jsx
|
|
63
|
+
import * as IDDS from '@idds/react';
|
|
158
64
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
8. [Publikasi ke NPM](#publikasi-ke-npm)
|
|
163
|
-
9. [License](#license)
|
|
65
|
+
// Use components
|
|
66
|
+
const { Button, TextField, SelectDropdown } = IDDS;
|
|
67
|
+
```
|
|
164
68
|
|
|
165
|
-
|
|
69
|
+
### Import Color Tokens (Optional - for Tailwind CSS integration)
|
|
166
70
|
|
|
167
|
-
|
|
71
|
+
If you want to use INA Digital color tokens with Tailwind CSS in your project:
|
|
168
72
|
|
|
169
|
-
|
|
170
|
-
- NPM / Yarn
|
|
171
|
-
- React & ReactDOM
|
|
73
|
+
#### Tailwind CSS v3
|
|
172
74
|
|
|
173
|
-
|
|
75
|
+
For Tailwind CSS v3, import the TypeScript token files:
|
|
174
76
|
|
|
175
|
-
|
|
77
|
+
```jsx
|
|
78
|
+
// tailwind.config.js
|
|
79
|
+
import iddsColorTokens from '@idds/react';
|
|
80
|
+
import bgnColorTokens from '@idds/react'; // Brand-specific tokens
|
|
176
81
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
82
|
+
export default {
|
|
83
|
+
theme: {
|
|
84
|
+
extend: {
|
|
85
|
+
colors: {
|
|
86
|
+
...iddsColorTokens,
|
|
87
|
+
...bgnColorTokens,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
182
92
|
```
|
|
183
93
|
|
|
184
|
-
|
|
94
|
+
#### Tailwind CSS v4
|
|
185
95
|
|
|
186
|
-
|
|
96
|
+
For Tailwind CSS v4, import the CSS theme files directly in your main CSS file:
|
|
187
97
|
|
|
188
|
-
|
|
98
|
+
```css
|
|
99
|
+
/* src/index.css or your main CSS file */
|
|
189
100
|
|
|
190
|
-
|
|
191
|
-
|
|
101
|
+
/* Tailwind CSS v4 */
|
|
102
|
+
@import 'tailwindcss';
|
|
192
103
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
104
|
+
/* INA Digital color tokens */
|
|
105
|
+
@import '@idds/styles/tailwind/css/idds.css';
|
|
106
|
+
@import '@idds/styles/tailwind/css/bgn.css'; /* Optional: brand theme */
|
|
107
|
+
```
|
|
196
108
|
|
|
197
|
-
|
|
109
|
+
Or use minified versions for production:
|
|
198
110
|
|
|
199
|
-
|
|
111
|
+
```css
|
|
112
|
+
@import 'tailwindcss';
|
|
113
|
+
@import '@idds/styles/tailwind/css/idds.min.css';
|
|
114
|
+
@import '@idds/styles/tailwind/css/bgn.min.css';
|
|
115
|
+
```
|
|
200
116
|
|
|
201
|
-
|
|
117
|
+
Then you can use Tailwind utility classes with INA Digital colors:
|
|
202
118
|
|
|
203
|
-
|
|
204
|
-
|
|
119
|
+
```jsx
|
|
120
|
+
<div className="bg-blue-500 text-white p-4">
|
|
121
|
+
<p className="text-guide-500">This text uses guide-500 color</p>
|
|
122
|
+
<p className="text-neutral-500">This text uses neutral-500 color</p>
|
|
123
|
+
</div>
|
|
124
|
+
```
|
|
205
125
|
|
|
206
|
-
|
|
207
|
-
|
|
126
|
+
**Available brand theme files:**
|
|
127
|
+
|
|
128
|
+
- `@idds/styles/tailwind/css/idds.css` - Default theme
|
|
129
|
+
- `@idds/styles/tailwind/css/inagov.css` - INAGov brand
|
|
130
|
+
- `@idds/styles/tailwind/css/inaku.css` - INAKu brand
|
|
131
|
+
- `@idds/styles/tailwind/css/inapas.css` - INAPas brand
|
|
132
|
+
- `@idds/styles/tailwind/css/bgn.css` - BGN brand
|
|
133
|
+
- `@idds/styles/tailwind/css/bkn.css` - BKN brand
|
|
134
|
+
- `@idds/styles/tailwind/css/lan.css` - LAN brand
|
|
135
|
+
- `@idds/styles/tailwind/css/panrb.css` - panrb brand
|
|
136
|
+
|
|
137
|
+
## Available Components
|
|
138
|
+
|
|
139
|
+
### Form Components
|
|
140
|
+
|
|
141
|
+
- **TextField** - Text input with validation, clear button, and character count
|
|
142
|
+
- **TextArea** - Multi-line text input with autosize
|
|
143
|
+
- **PasswordInput** - Password input with show/hide toggle
|
|
144
|
+
- **SelectDropdown** - Dropdown select with search and multi-select support
|
|
145
|
+
- **Checkbox** - Checkbox input
|
|
146
|
+
- **RadioInput** - Radio button input
|
|
147
|
+
- **DatePicker** - Date picker with single, range, and multiple modes
|
|
148
|
+
- **TimePicker** - Time picker
|
|
149
|
+
- **YearPicker** - Year picker
|
|
150
|
+
- **MonthPicker** - Month picker
|
|
151
|
+
- **PhoneInput** - Phone number input with country selector
|
|
152
|
+
- **OneTimePassword** - OTP input component
|
|
153
|
+
- **FileUpload** - File upload with drag & drop and validation
|
|
154
|
+
- **SingleFileUpload** - Single file upload component
|
|
155
|
+
- **Toggle** - Toggle switch component
|
|
156
|
+
|
|
157
|
+
### Layout Components
|
|
158
|
+
|
|
159
|
+
- **Card** - Card container component
|
|
160
|
+
- **Accordion** - Collapsible accordion component
|
|
161
|
+
- **AccordionCard** - Accordion with card styling
|
|
162
|
+
- **AccordionGroup** - Group of accordions
|
|
163
|
+
- **Divider** - Horizontal or vertical divider
|
|
164
|
+
- **Stepper** - Step indicator component
|
|
165
|
+
- **Breadcrumb** - Breadcrumb navigation
|
|
166
|
+
- **TabHorizontal** - Horizontal tabs
|
|
167
|
+
- **TabVertical** - Vertical tabs
|
|
168
|
+
|
|
169
|
+
### Feedback Components
|
|
170
|
+
|
|
171
|
+
- **Alert** - Alert message component
|
|
172
|
+
- **Toast** - Toast notification (use with ToastProvider)
|
|
173
|
+
- **ToastProvider** - Provider for toast notifications
|
|
174
|
+
- **Modal** - Modal dialog component
|
|
175
|
+
- **Drawer** - Side drawer component
|
|
176
|
+
- **BottomSheet** - Bottom sheet component
|
|
177
|
+
- **Tooltip** - Tooltip component
|
|
178
|
+
- **Skeleton** - Loading skeleton component
|
|
179
|
+
- **Spinner** - Loading spinner component
|
|
180
|
+
- **ProgressBar** - Progress bar component
|
|
181
|
+
- **LinearProgressIndicator** - Linear progress indicator
|
|
182
|
+
- **TableProgressBar** - Progress bar for tables
|
|
183
|
+
|
|
184
|
+
### Data Display Components
|
|
185
|
+
|
|
186
|
+
- **Table** - Advanced table with sorting, pagination, and editing
|
|
187
|
+
- **FieldInputTable** - Table with inline input fields
|
|
188
|
+
- **MultipleChoiceGrid** - Grid for multiple choice questions
|
|
189
|
+
- **Avatar** - Avatar component
|
|
190
|
+
- **Badge** - Badge component
|
|
191
|
+
- **Chip** - Chip component
|
|
192
|
+
- **List** - List component with variants
|
|
193
|
+
- **ListItem** - List item component
|
|
194
|
+
- **ListItemAvatar** - List item with avatar
|
|
195
|
+
- **ListItemButton** - List item as button
|
|
196
|
+
- **ListItemIcon** - List item with icon
|
|
197
|
+
- **ListItemText** - List item text
|
|
198
|
+
- **ListSubheader** - List subheader
|
|
199
|
+
|
|
200
|
+
### Navigation Components
|
|
201
|
+
|
|
202
|
+
- **Button** - Button component with multiple variants
|
|
203
|
+
- **ButtonGroup** - Group of buttons
|
|
204
|
+
- **ActionDropdown** - Dropdown menu for actions
|
|
205
|
+
- **Dropdown** - General dropdown component
|
|
206
|
+
- **Pagination** - Pagination component
|
|
207
|
+
- **InputSearch** - Search input component
|
|
208
|
+
|
|
209
|
+
### Other Components
|
|
210
|
+
|
|
211
|
+
- **ThemeToggle** - Dark/light theme toggle
|
|
212
|
+
- **Collapse** - Collapsible content component
|
|
213
|
+
|
|
214
|
+
## Theme System
|
|
215
|
+
|
|
216
|
+
### Setting Brand Theme
|
|
217
|
+
|
|
218
|
+
The design system supports multiple brand themes. You can switch between them programmatically:
|
|
208
219
|
|
|
209
|
-
|
|
210
|
-
|
|
220
|
+
```jsx
|
|
221
|
+
import { setBrandTheme } from '@idds/react';
|
|
211
222
|
|
|
212
|
-
|
|
223
|
+
// Set brand theme
|
|
224
|
+
setBrandTheme('bgn'); // or 'inagov', 'inaku', 'inapas', 'bkn', 'lan', 'panrb'
|
|
213
225
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
import react from '@vitejs/plugin-react';
|
|
217
|
-
import tailwindcss from '@tailwindcss/vite';
|
|
226
|
+
// Use default theme
|
|
227
|
+
setBrandTheme('default');
|
|
218
228
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
229
|
+
// Remove brand theme (use default)
|
|
230
|
+
setBrandTheme(null);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Available Brand Themes
|
|
234
|
+
|
|
235
|
+
- `'default'` - Default INA Digital theme
|
|
236
|
+
- `'inagov'` - INAGov brand theme
|
|
237
|
+
- `'inaku'` - INAKu brand theme
|
|
238
|
+
- `'inapas'` - INAPas brand theme
|
|
239
|
+
- `'bgn'` - BGN brand theme
|
|
240
|
+
- `'bkn'` - BKN brand theme
|
|
241
|
+
- `'lan'` - LAN brand theme
|
|
242
|
+
- `'panrb'` - panrb brand theme
|
|
243
|
+
|
|
244
|
+
### Custom Theme
|
|
245
|
+
|
|
246
|
+
You can also set a custom theme:
|
|
247
|
+
|
|
248
|
+
```jsx
|
|
249
|
+
import { setCustomTheme } from '@idds/react';
|
|
250
|
+
|
|
251
|
+
setCustomTheme({
|
|
252
|
+
name: 'custom',
|
|
253
|
+
colors: {
|
|
254
|
+
primary500: '#0968f6',
|
|
255
|
+
primary600: '#0754c4',
|
|
256
|
+
// ... other color tokens
|
|
245
257
|
},
|
|
246
258
|
});
|
|
247
259
|
```
|
|
248
260
|
|
|
249
|
-
###
|
|
261
|
+
### Theme Utilities
|
|
250
262
|
|
|
251
|
-
|
|
252
|
-
|
|
263
|
+
```jsx
|
|
264
|
+
import {
|
|
265
|
+
getCurrentTheme,
|
|
266
|
+
getAvailableBrands,
|
|
267
|
+
resetTheme,
|
|
268
|
+
isValidBrand,
|
|
269
|
+
} from '@idds/react';
|
|
253
270
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
"tailwindCSS.includeLanguages": {
|
|
257
|
-
"typescript": "javascript",
|
|
258
|
-
"typescriptreact": "javascriptreact"
|
|
259
|
-
},
|
|
260
|
-
"editor.formatOnSave": true,
|
|
261
|
-
"tailwindCSS.classAttributes": ["class", "class:list", "className"],
|
|
262
|
-
// Suruh Tailwind IntelliSense mem-parse file global.css sebagai config
|
|
263
|
-
"tailwindCSS.experimental.configFile": "src/index.css"
|
|
264
|
-
}
|
|
265
|
-
```
|
|
271
|
+
// Get current active theme
|
|
272
|
+
const currentTheme = getCurrentTheme();
|
|
266
273
|
|
|
267
|
-
|
|
274
|
+
// Get available brand names
|
|
275
|
+
const brands = getAvailableBrands();
|
|
268
276
|
|
|
269
|
-
|
|
277
|
+
// Reset to default theme
|
|
278
|
+
resetTheme();
|
|
270
279
|
|
|
271
|
-
|
|
280
|
+
// Validate brand name
|
|
281
|
+
if (isValidBrand('bgn')) {
|
|
282
|
+
setBrandTheme('bgn');
|
|
283
|
+
}
|
|
284
|
+
```
|
|
272
285
|
|
|
273
|
-
|
|
286
|
+
## Utilities
|
|
274
287
|
|
|
275
|
-
|
|
276
|
-
- Definisikan brand colors, font family, spacing, dll.
|
|
277
|
-
- File ini akan di-_export_ dan dikonsumsi oleh project lain.
|
|
288
|
+
### Form Utilities
|
|
278
289
|
|
|
279
|
-
|
|
290
|
+
```jsx
|
|
291
|
+
import { useForm, FormProvider, FormField } from '@idds/react';
|
|
280
292
|
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
// Form handling with validation
|
|
294
|
+
const { handleSubmit, register, errors } = useForm();
|
|
295
|
+
```
|
|
283
296
|
|
|
284
|
-
|
|
297
|
+
### Confirmation Dialog
|
|
285
298
|
|
|
286
|
-
```
|
|
287
|
-
import {
|
|
299
|
+
```jsx
|
|
300
|
+
import { ConfirmationProvider, useConfirmation } from '@idds/react';
|
|
288
301
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
302
|
+
// Wrap your app
|
|
303
|
+
<ConfirmationProvider>
|
|
304
|
+
<App />
|
|
305
|
+
</ConfirmationProvider>;
|
|
306
|
+
|
|
307
|
+
// Use in components
|
|
308
|
+
const confirm = useConfirmation();
|
|
309
|
+
|
|
310
|
+
const handleDelete = async () => {
|
|
311
|
+
const result = await confirm({
|
|
312
|
+
title: 'Delete Item',
|
|
313
|
+
message: 'Are you sure you want to delete this item?',
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
if (result) {
|
|
317
|
+
// User confirmed
|
|
318
|
+
}
|
|
300
319
|
};
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Toast Notifications
|
|
323
|
+
|
|
324
|
+
```jsx
|
|
325
|
+
import { ToastProvider, useToast } from '@idds/react';
|
|
301
326
|
|
|
302
|
-
|
|
327
|
+
// Wrap your app
|
|
328
|
+
<ToastProvider>
|
|
329
|
+
<App />
|
|
330
|
+
</ToastProvider>;
|
|
331
|
+
|
|
332
|
+
// Use in components
|
|
333
|
+
const toast = useToast();
|
|
334
|
+
|
|
335
|
+
toast.success('Operation completed successfully!');
|
|
336
|
+
toast.error('An error occurred');
|
|
337
|
+
toast.info('Information message');
|
|
338
|
+
toast.warning('Warning message');
|
|
303
339
|
```
|
|
304
340
|
|
|
305
|
-
|
|
341
|
+
### Security Utilities
|
|
306
342
|
|
|
307
|
-
```
|
|
308
|
-
import
|
|
343
|
+
```jsx
|
|
344
|
+
import {
|
|
345
|
+
sanitizeInput,
|
|
346
|
+
validateInput,
|
|
347
|
+
encodeHtmlEntities,
|
|
348
|
+
decodeHtmlEntities,
|
|
349
|
+
} from '@idds/react';
|
|
350
|
+
|
|
351
|
+
// Sanitize user input
|
|
352
|
+
const sanitized = sanitizeInput(userInput);
|
|
353
|
+
|
|
354
|
+
// Validate input for XSS
|
|
355
|
+
const validation = validateInput(userInput);
|
|
356
|
+
if (!validation.isValid) {
|
|
357
|
+
console.warn('Security threat detected:', validation.threats);
|
|
358
|
+
}
|
|
359
|
+
```
|
|
309
360
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
};
|
|
361
|
+
### File Validation
|
|
362
|
+
|
|
363
|
+
```jsx
|
|
364
|
+
import { validateFile, validateMagicNumber, formatFileSize } from '@idds/react';
|
|
365
|
+
|
|
366
|
+
// Validate file
|
|
367
|
+
const result = validateFile(file, {
|
|
368
|
+
allowedTypes: 'image/*',
|
|
369
|
+
maxSize: 5 * 1024 * 1024, // 5MB
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// Validate magic number (file signature)
|
|
373
|
+
const magicResult = await validateMagicNumber(file, 'image/png');
|
|
374
|
+
|
|
375
|
+
// Format file size
|
|
376
|
+
const formatted = formatFileSize(1024 * 1024); // "1 MB"
|
|
314
377
|
```
|
|
315
378
|
|
|
316
|
-
|
|
379
|
+
### Formatting Utilities
|
|
317
380
|
|
|
318
|
-
|
|
381
|
+
```jsx
|
|
382
|
+
import {
|
|
383
|
+
formattingThousand,
|
|
384
|
+
onlyAlphanumeric,
|
|
385
|
+
onlyNumericValue,
|
|
386
|
+
onlyDecimalNumber,
|
|
387
|
+
} from '@idds/react';
|
|
388
|
+
|
|
389
|
+
formattingThousand(1000000); // "1,000,000"
|
|
390
|
+
onlyAlphanumeric('abc123!@#'); // "abc123"
|
|
391
|
+
onlyNumericValue('123abc'); // "123"
|
|
392
|
+
onlyDecimalNumber('123.45'); // "123.45"
|
|
393
|
+
```
|
|
319
394
|
|
|
320
|
-
|
|
395
|
+
## Component Examples
|
|
321
396
|
|
|
322
|
-
|
|
323
|
-
Untuk build aplikasi React (pastikan `module` & `moduleResolution` = `nodenext`).
|
|
397
|
+
### TextField
|
|
324
398
|
|
|
325
|
-
|
|
326
|
-
|
|
399
|
+
```jsx
|
|
400
|
+
import { TextField } from '@idds/react';
|
|
401
|
+
|
|
402
|
+
<TextField
|
|
403
|
+
label="Email"
|
|
404
|
+
placeholder="Enter your email"
|
|
405
|
+
value={email}
|
|
406
|
+
onChange={setEmail}
|
|
407
|
+
type="email"
|
|
408
|
+
required
|
|
409
|
+
showClearButton
|
|
410
|
+
maxLength={100}
|
|
411
|
+
showCharCount
|
|
412
|
+
/>;
|
|
413
|
+
```
|
|
327
414
|
|
|
328
|
-
|
|
415
|
+
### Button
|
|
329
416
|
|
|
330
|
-
|
|
417
|
+
```jsx
|
|
418
|
+
import { Button } from '@idds/react';
|
|
331
419
|
|
|
332
|
-
|
|
420
|
+
<Button variant="primary" size="md" onClick={handleClick}>
|
|
421
|
+
Submit
|
|
422
|
+
</Button>;
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### SelectDropdown
|
|
333
426
|
|
|
427
|
+
```jsx
|
|
428
|
+
import { SelectDropdown } from '@idds/react';
|
|
429
|
+
|
|
430
|
+
const options = [
|
|
431
|
+
{ value: '1', label: 'Option 1' },
|
|
432
|
+
{ value: '2', label: 'Option 2' },
|
|
433
|
+
];
|
|
434
|
+
|
|
435
|
+
<SelectDropdown
|
|
436
|
+
label="Select Option"
|
|
437
|
+
options={options}
|
|
438
|
+
value={selected}
|
|
439
|
+
onChange={setSelected}
|
|
440
|
+
searchable
|
|
441
|
+
clearable
|
|
442
|
+
/>;
|
|
334
443
|
```
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
444
|
+
|
|
445
|
+
### DatePicker
|
|
446
|
+
|
|
447
|
+
```jsx
|
|
448
|
+
import { DatePicker } from '@idds/react';
|
|
449
|
+
|
|
450
|
+
<DatePicker
|
|
451
|
+
label="Select Date"
|
|
452
|
+
value={date}
|
|
453
|
+
onChange={setDate}
|
|
454
|
+
mode="single"
|
|
455
|
+
dateFormat="DD/MM/YYYY"
|
|
456
|
+
showIcon
|
|
457
|
+
showClearButton
|
|
458
|
+
/>;
|
|
342
459
|
```
|
|
343
460
|
|
|
344
|
-
|
|
461
|
+
### Table
|
|
345
462
|
|
|
346
|
-
|
|
463
|
+
```jsx
|
|
464
|
+
import { Table } from '@idds/react';
|
|
347
465
|
|
|
348
|
-
|
|
466
|
+
const columns = [
|
|
467
|
+
{ key: 'name', label: 'Name' },
|
|
468
|
+
{ key: 'email', label: 'Email' },
|
|
469
|
+
];
|
|
349
470
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
font-weight: 400;
|
|
355
|
-
font-style: normal;
|
|
356
|
-
}
|
|
357
|
-
/* … weight lainnya */
|
|
358
|
-
```
|
|
471
|
+
const data = [
|
|
472
|
+
{ id: 1, name: 'John', email: 'john@example.com' },
|
|
473
|
+
{ id: 2, name: 'Jane', email: 'jane@example.com' },
|
|
474
|
+
];
|
|
359
475
|
|
|
360
|
-
|
|
476
|
+
<Table columns={columns} data={data} />;
|
|
477
|
+
```
|
|
361
478
|
|
|
362
|
-
|
|
363
|
-
@import 'tailwindcss/base';
|
|
364
|
-
@import 'tailwindcss/components';
|
|
365
|
-
@import 'tailwindcss/utilities';
|
|
479
|
+
## Styling
|
|
366
480
|
|
|
367
|
-
|
|
481
|
+
### CSS Classes
|
|
368
482
|
|
|
369
|
-
|
|
370
|
-
@config './tailwind.config.ts';
|
|
371
|
-
```
|
|
483
|
+
Components use BEM-like naming conventions:
|
|
372
484
|
|
|
373
|
-
|
|
485
|
+
- `ina-button` - Base button class
|
|
486
|
+
- `ina-button--primary` - Primary variant
|
|
487
|
+
- `ina-button--disabled` - Disabled state
|
|
488
|
+
- `ina-text-field` - Text field component
|
|
489
|
+
- `ina-text-field__input` - Input element
|
|
490
|
+
- `ina-text-field__label` - Label element
|
|
374
491
|
|
|
375
|
-
|
|
492
|
+
### Custom Styling
|
|
376
493
|
|
|
377
|
-
|
|
494
|
+
You can override component styles using CSS:
|
|
378
495
|
|
|
379
|
-
```
|
|
380
|
-
{
|
|
381
|
-
|
|
382
|
-
"version": "0.6.21",
|
|
383
|
-
"type": "module",
|
|
384
|
-
"main": "dist/@idds/react.umd.js",
|
|
385
|
-
"module": "dist/@idds/react.es.js",
|
|
386
|
-
"types": "dist/types/index.d.ts",
|
|
387
|
-
"files": ["dist", "dist/tailwind.preset.js"],
|
|
388
|
-
"scripts": {
|
|
389
|
-
"build:css": "npx @tailwindcss/cli -i src/index.css -o dist/style.css --minify",
|
|
390
|
-
"build:preset": "tsc --project tsconfig.preset.json",
|
|
391
|
-
"build": "tsc --project tsconfig.app.json && vite build && npm run build:preset && npm run build:css"
|
|
392
|
-
},
|
|
393
|
-
"peerDependencies": {
|
|
394
|
-
"react": ">=18.0.0", // gunakan >= untuk meminimalisir error missmatch react version antara design-system and consumer project
|
|
395
|
-
"react-dom": ">=18.0.0"
|
|
396
|
-
},
|
|
397
|
-
"style": "dist/style.css", // agar saat consumer import "@idds/react/style.css" maka akan di arahkan ke file yang ada didalam folder dist/style.css
|
|
398
|
-
"exports": {
|
|
399
|
-
".": {
|
|
400
|
-
"import": "./dist/@idds/react.es.js",
|
|
401
|
-
"require": "./dist/@idds/react.umd.js",
|
|
402
|
-
"types": "./dist/types/index.d.ts"
|
|
403
|
-
},
|
|
404
|
-
"./tailwind.preset.js": {
|
|
405
|
-
"import": "./dist/tailwind.preset.js",
|
|
406
|
-
"require": "./dist/tailwind.preset.js"
|
|
407
|
-
},
|
|
408
|
-
"./style.css": {
|
|
409
|
-
"import": "./dist/style.css",
|
|
410
|
-
"require": "./dist/style.css"
|
|
411
|
-
},
|
|
412
|
-
"./*": "./dist/*"
|
|
413
|
-
}
|
|
496
|
+
```css
|
|
497
|
+
.ina-button--primary {
|
|
498
|
+
background-color: your-custom-color;
|
|
414
499
|
}
|
|
415
500
|
```
|
|
416
501
|
|
|
417
|
-
|
|
502
|
+
### Using with Tailwind CSS (Optional)
|
|
503
|
+
|
|
504
|
+
If you want to use Tailwind CSS utility classes alongside the design system:
|
|
505
|
+
|
|
506
|
+
1. Install Tailwind CSS in your project
|
|
507
|
+
2. Import color tokens:
|
|
508
|
+
|
|
509
|
+
```js
|
|
510
|
+
// tailwind.config.js
|
|
511
|
+
import iddsColorTokens from '@idds/react';
|
|
512
|
+
|
|
513
|
+
export default {
|
|
514
|
+
theme: {
|
|
515
|
+
extend: {
|
|
516
|
+
colors: iddsColorTokens,
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
};
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
3. Use Tailwind classes for custom styling:
|
|
523
|
+
|
|
524
|
+
```jsx
|
|
525
|
+
<div className="bg-blue-500 text-white p-4">
|
|
526
|
+
<Button>Click me</Button>
|
|
527
|
+
</div>
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
> **Note:** Tailwind CSS is **optional**. The design system works perfectly without it. Components are fully styled and functional using only the included CSS.
|
|
531
|
+
|
|
532
|
+
## TypeScript Support
|
|
533
|
+
|
|
534
|
+
All components are fully typed with TypeScript:
|
|
535
|
+
|
|
536
|
+
```tsx
|
|
537
|
+
import { TextField, type TextFieldProps } from '@idds/react';
|
|
538
|
+
|
|
539
|
+
const props: TextFieldProps = {
|
|
540
|
+
label: 'Email',
|
|
541
|
+
value: email,
|
|
542
|
+
onChange: setEmail,
|
|
543
|
+
};
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Development
|
|
418
547
|
|
|
419
548
|
```bash
|
|
549
|
+
# Install dependencies
|
|
550
|
+
npm install
|
|
551
|
+
|
|
552
|
+
# Start development server
|
|
553
|
+
npm run dev
|
|
554
|
+
|
|
555
|
+
# Build for production
|
|
420
556
|
npm run build
|
|
421
|
-
npm version patch
|
|
422
|
-
npm publish --access public
|
|
423
|
-
```
|
|
424
557
|
|
|
425
|
-
|
|
558
|
+
# Type checking
|
|
559
|
+
npm run type-check
|
|
560
|
+
|
|
561
|
+
# Linting
|
|
562
|
+
npm run lint
|
|
563
|
+
```
|
|
426
564
|
|
|
427
565
|
## License
|
|
428
566
|
|
|
429
|
-
INA Digital ©
|
|
567
|
+
INA Digital © [Umar Faruq]
|