wini-web-components 8.4.97 → 8.4.99
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 +887 -63
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,73 +1,897 @@
|
|
|
1
1
|
# wini-web-components
|
|
2
2
|
|
|
3
|
-
A modern, lightweight
|
|
3
|
+
A modern, lightweight React TypeScript UI component library with 35+ ready-to-use components, responsive layout utilities, design token theming, and optional Wini backend integration for dynamic form/table/page rendering.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/wini-web-components)
|
|
6
|
+
[](LICENSE)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- **Responsive Design**: Built-in CSS classes for seamless responsiveness across devices, from mobile to extra-large screens.
|
|
9
|
-
- **Customizable**: Easily style and configure components to match your project's design.
|
|
10
|
-
- **Lightweight**: Minimal overhead to keep your app fast and efficient.
|
|
11
|
-
- **TypeScript Support**: Fully typed with TSX for a better developer experience.
|
|
8
|
+
---
|
|
12
9
|
|
|
13
|
-
##
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Setup: Add Global Styles](#setup-add-global-styles)
|
|
14
|
+
- [Setup: Wrap Your App with WiniProvider](#setup-wrap-your-app-with-winiprovider)
|
|
15
|
+
- [Layout System](#layout-system)
|
|
16
|
+
- [Components](#components)
|
|
17
|
+
- [Button](#button)
|
|
18
|
+
- [Winicon](#winicon)
|
|
19
|
+
- [TextField](#textfield)
|
|
20
|
+
- [TextArea](#textarea)
|
|
21
|
+
- [Select1](#select1)
|
|
22
|
+
- [Checkbox](#checkbox)
|
|
23
|
+
- [Switch](#switch)
|
|
24
|
+
- [RadioButton](#radiobutton)
|
|
25
|
+
- [DateTimePicker](#datetimepicker)
|
|
26
|
+
- [NumberPicker](#numberpicker)
|
|
27
|
+
- [Slider](#slider)
|
|
28
|
+
- [Rating](#rating)
|
|
29
|
+
- [InputOtp](#inputotp)
|
|
30
|
+
- [ColorPicker](#colorpicker)
|
|
31
|
+
- [SelectMultiple](#selectmultiple)
|
|
32
|
+
- [Tag](#tag)
|
|
33
|
+
- [Pagination](#pagination)
|
|
34
|
+
- [InfiniteScroll](#infinitescroll)
|
|
35
|
+
- [Dialog](#dialog)
|
|
36
|
+
- [Popup](#popup)
|
|
37
|
+
- [ToastMessage](#toastmessage)
|
|
38
|
+
- [ProgressBar](#progressbar)
|
|
39
|
+
- [ProgressCircle](#progresscircle)
|
|
40
|
+
- [Calendar](#calendar)
|
|
41
|
+
- [Carousel](#carousel)
|
|
42
|
+
- [VideoPlayer / AudioPlayer / IframePlayer](#videoplayer--audioplayer--iframeplayer)
|
|
43
|
+
- [ImportFile / UploadFiles](#importfile--uploadfiles)
|
|
44
|
+
- [CustomCkEditor5](#customckeditor5)
|
|
45
|
+
- [WiniEditor](#winieditor)
|
|
46
|
+
- [IconPicker](#iconpicker)
|
|
47
|
+
- [Backend-Driven Modules](#backend-driven-modules)
|
|
48
|
+
- [PageById](#pagebyid)
|
|
49
|
+
- [PageByUrl](#pagebyurl)
|
|
50
|
+
- [FormById](#formbyid)
|
|
51
|
+
- [CardById](#cardbyid)
|
|
52
|
+
- [ViewById](#viewbyid)
|
|
53
|
+
- [Responsive Grid Classes](#responsive-grid-classes)
|
|
54
|
+
- [Design Tokens & Theming](#design-tokens--theming)
|
|
14
55
|
|
|
15
|
-
|
|
56
|
+
---
|
|
16
57
|
|
|
58
|
+
## Installation
|
|
17
59
|
|
|
60
|
+
```bash
|
|
18
61
|
npm install wini-web-components
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
These provide:
|
|
67
|
+
- **`root.css`** — CSS design token variables (colors, borders, shadows) through https://cdn.jsdelivr.net/gh/WiniGit/web-component@latest/src/skin/root.css
|
|
68
|
+
- **`typography.css`** — text utility classes (`heading-1` → `heading-8`, `body-1` → `body-3`, etc.) through https://cdn.jsdelivr.net/gh/WiniGit/web-component@latest/src/skin/typography.css
|
|
69
|
+
- **`layout.css`** — `row`, `col`, and responsive grid classes through https://cdn.jsdelivr.net/gh/WiniGit/web-component@latest/src/skin/layout.css
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Setup: Wrap Your App with WiniProvider
|
|
74
|
+
|
|
75
|
+
`WiniProvider` is the root provider. It sets up routing, toasts, dialogs, auth token handling, and optionally loads design tokens and i18n from a Wini backend.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// main.tsx
|
|
79
|
+
import WiniProvider from 'wini-web-components'
|
|
80
|
+
|
|
81
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
82
|
+
<WiniProvider
|
|
83
|
+
pid="your-project-id"
|
|
84
|
+
url="https://your-wini-api.com/"
|
|
85
|
+
fileUrl="https://your-file-server.com/"
|
|
86
|
+
imgUrlId="https://your-cdn.com/"
|
|
87
|
+
theme="light" // "light" | "dark"
|
|
88
|
+
loadResources={true} // set false to skip backend token/i18n loading
|
|
89
|
+
>
|
|
90
|
+
<Route path="/" element={<HomePage />} />
|
|
91
|
+
<Route path="/about" element={<AboutPage />} />
|
|
92
|
+
</WiniProvider>
|
|
93
|
+
)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
> **Note:** `WiniProvider` wraps `BrowserRouter` internally — do **not** add another `BrowserRouter` in your app.
|
|
97
|
+
|
|
98
|
+
### Access Global Context
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { useWiniContext } from 'wini-web-components'
|
|
102
|
+
|
|
103
|
+
function MyComponent() {
|
|
104
|
+
const { theme, setTheme, userData, setUserData, globalData, setGlobalData, i18n } = useWiniContext()
|
|
105
|
+
return <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Toggle theme</button>
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Layout System
|
|
112
|
+
|
|
113
|
+
Use `row` and `col` classes for flex layouts. These are available globally after importing the skin CSS.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
// Horizontal layout (flex-direction: row, align-items: center)
|
|
117
|
+
<div className="row" style={{ gap: 12 }}>
|
|
118
|
+
<span>Left</span>
|
|
119
|
+
<span className="remain">This stretches to fill remaining space</span>
|
|
120
|
+
<span>Right</span>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
// Vertical layout (flex-direction: column)
|
|
124
|
+
<div className="col" style={{ gap: 8 }}>
|
|
125
|
+
<span>Top</span>
|
|
126
|
+
<span>Bottom</span>
|
|
127
|
+
</div>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> `remain` inside a `row` or `col` expands to fill available space (`flex: 1`).
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Components
|
|
135
|
+
|
|
136
|
+
### Button
|
|
137
|
+
|
|
138
|
+
A versatile button supporting sizes, color variants, icons, links, tooltips, and keyboard `Enter` on submit type.
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
import { Button, Winicon } from 'wini-web-components'
|
|
142
|
+
|
|
143
|
+
// Basic
|
|
144
|
+
<Button label="Click me" onClick={() => alert('clicked!')} />
|
|
145
|
+
|
|
146
|
+
// Size variants (default: size32)
|
|
147
|
+
<Button label="Large" className="size48 button-primary" onClick={...} />
|
|
148
|
+
|
|
149
|
+
// As a link
|
|
150
|
+
<Button label="Go to docs" linkTo="https://example.com" target="_blank" className="size40 button-neutral" />
|
|
151
|
+
|
|
152
|
+
// With prefix icon
|
|
153
|
+
<Button
|
|
154
|
+
label="Save"
|
|
155
|
+
prefix={<Winicon src="outline/files/save-2" size={16} />}
|
|
156
|
+
className="size40 button-primary"
|
|
157
|
+
onClick={...}
|
|
158
|
+
/>
|
|
159
|
+
|
|
160
|
+
// With tooltip
|
|
161
|
+
<Button label="Info" tooltip={{ message: 'More details', position: 'top' }} />
|
|
162
|
+
|
|
163
|
+
// Submit type — also triggers on Enter key
|
|
164
|
+
<Button label="Submit" type="submit" className="size40 button-primary" onClick={...} />
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Size classes:** `size24` `size32`*(default)* `size40` `size48` `size56` `size64`
|
|
168
|
+
|
|
169
|
+
**Color classes:** `button-primary` `button-grey` `button-neutral` `button-black` `button-white` `button-infor` `button-warning` `button-error` `button-success` `button-infor-main` `button-warning-main` `button-error-main` `button-success-main`
|
|
170
|
+
|
|
171
|
+
> `SimpleButton` is a variant that auto-disables itself during the async `onClick` to prevent double-clicks.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### Winicon
|
|
176
|
+
|
|
177
|
+
SVG icon component loaded from the [WiniGit icon library CDN](https://github.com/WiniGit/icon-library). Icons are cached in the browser after first load.
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { Winicon } from 'wini-web-components'
|
|
181
|
+
|
|
182
|
+
<Winicon src="outline/user/user" size={24} color="#287CF0" />
|
|
183
|
+
<Winicon src="fill/actions/trash" size={20} onClick={() => handleDelete()} className="icon-button" />
|
|
184
|
+
|
|
185
|
+
// With tooltip
|
|
186
|
+
<Winicon src="outline/essential/info-circle" size={20} tooltip={{ message: 'Help', position: 'bottom' }} />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Size classes:** `size24` `size32` `size40` `size48` `size56` `size64`
|
|
190
|
+
**Style classes:** `icon-button` (adds hover/click interactivity styles), `light`
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### TextField
|
|
195
|
+
|
|
196
|
+
Styled text input with optional prefix/suffix slots, helper text, and `react-hook-form` support.
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
import { TextField } from 'wini-web-components'
|
|
200
|
+
|
|
201
|
+
// Basic
|
|
202
|
+
<TextField placeholder="Enter name" onChange={(e) => setName(e.target.value)} />
|
|
203
|
+
|
|
204
|
+
// With prefix icon and helper text
|
|
205
|
+
<TextField
|
|
206
|
+
prefix={<Winicon src="outline/user/user" size={16} />}
|
|
207
|
+
placeholder="Email"
|
|
208
|
+
type="email"
|
|
209
|
+
helperText="Invalid email" // shown below the field in red
|
|
210
|
+
className="size40 body-3"
|
|
211
|
+
/>
|
|
212
|
+
|
|
213
|
+
// With react-hook-form
|
|
214
|
+
const { register } = useForm()
|
|
215
|
+
<TextField placeholder="Username" register={register('username', { required: true })} />
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Size classes:** `size24` `size32` `size40`*(default)* `size48`
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### TextArea
|
|
223
|
+
|
|
224
|
+
Multi-line text input.
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
import { TextArea } from 'wini-web-components'
|
|
228
|
+
|
|
229
|
+
<TextArea placeholder="Write something..." onChange={(e) => setText(e.target.value)} />
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### Select1
|
|
235
|
+
|
|
236
|
+
Single-value dropdown. Supports static options, async lazy-loading, hierarchical (parent/child) options, and custom render.
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
import { Select1 } from 'wini-web-components'
|
|
240
|
+
|
|
241
|
+
const options = [
|
|
242
|
+
{ id: '1', name: 'Option A' },
|
|
243
|
+
{ id: '2', name: 'Option B' },
|
|
244
|
+
{ id: '3', name: 'Option C', disabled: true },
|
|
245
|
+
]
|
|
246
|
+
|
|
247
|
+
// Static options
|
|
248
|
+
<Select1
|
|
249
|
+
value={selected}
|
|
250
|
+
options={options}
|
|
251
|
+
placeholder="Choose one"
|
|
252
|
+
onChange={(item) => setSelected(item?.id)}
|
|
253
|
+
/>
|
|
254
|
+
|
|
255
|
+
// Async options (loaded on open / search)
|
|
256
|
+
<Select1
|
|
257
|
+
options={[]}
|
|
258
|
+
getOptions={async ({ length, search }) => {
|
|
259
|
+
const res = await fetchItems({ page: Math.floor(length / 10) + 1, search })
|
|
260
|
+
return { data: res.items, totalCount: res.total }
|
|
261
|
+
}}
|
|
262
|
+
onChange={(item) => setSelected(item?.id)}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
### Checkbox
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
import { Checkbox } from 'wini-web-components'
|
|
272
|
+
|
|
273
|
+
<Checkbox value={isChecked} onChange={(val) => setIsChecked(val)} />
|
|
274
|
+
<Checkbox value={null} /> {/* null = indeterminate state */}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### Switch
|
|
280
|
+
|
|
281
|
+
Toggle switch with customizable colors and size.
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
import { Switch } from 'wini-web-components'
|
|
285
|
+
|
|
286
|
+
<Switch value={isOn} onChange={(val) => setIsOn(val)} />
|
|
287
|
+
<Switch value={isOn} size="2.4rem" onBackground="#287CF0" offBackground="#D7D7DB" onChange={...} />
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
### RadioButton
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
import { RadioButton } from 'wini-web-components'
|
|
296
|
+
|
|
297
|
+
<RadioButton value={selected === 'a'} onChange={() => setSelected('a')} label="Option A" />
|
|
298
|
+
<RadioButton value={selected === 'b'} onChange={() => setSelected('b')} label="Option B" />
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
### DateTimePicker
|
|
304
|
+
|
|
305
|
+
Date and/or time picker.
|
|
306
|
+
|
|
307
|
+
```tsx
|
|
308
|
+
import { DateTimePicker } from 'wini-web-components'
|
|
309
|
+
|
|
310
|
+
<DateTimePicker value={date} onChange={(val) => setDate(val)} placeholder="Pick a date" />
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### NumberPicker
|
|
316
|
+
|
|
317
|
+
Numeric input with increment/decrement controls.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
import { NumberPicker } from 'wini-web-components'
|
|
321
|
+
|
|
322
|
+
<NumberPicker value={count} onChange={(val) => setCount(val)} min={0} max={100} />
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
### Slider
|
|
328
|
+
|
|
329
|
+
Range slider input.
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
import { Slider } from 'wini-web-components'
|
|
333
|
+
|
|
334
|
+
<Slider value={volume} min={0} max={100} onChange={(val) => setVolume(val)} />
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
### Rating
|
|
340
|
+
|
|
341
|
+
Star rating input.
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
import { Rating } from 'wini-web-components'
|
|
345
|
+
|
|
346
|
+
<Rating value={3} onChange={(val) => setRating(val)} />
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
### InputOtp
|
|
352
|
+
|
|
353
|
+
OTP / PIN code input with configurable digit count.
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
import { InputOtp } from 'wini-web-components'
|
|
357
|
+
|
|
358
|
+
<InputOtp length={6} onComplete={(code) => verifyOtp(code)} />
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
### ColorPicker
|
|
364
|
+
|
|
365
|
+
Hex/RGBA color picker input.
|
|
366
|
+
|
|
367
|
+
```tsx
|
|
368
|
+
import { ColorPicker } from 'wini-web-components'
|
|
369
|
+
|
|
370
|
+
<ColorPicker value={color} onChange={(hex) => setColor(hex)} />
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
### SelectMultiple
|
|
376
|
+
|
|
377
|
+
Multi-value dropdown with tag display.
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
import { SelectMultiple } from 'wini-web-components'
|
|
381
|
+
|
|
382
|
+
<SelectMultiple
|
|
383
|
+
value={['1', '2']}
|
|
384
|
+
options={[{ id: '1', name: 'React' }, { id: '2', name: 'TypeScript' }]}
|
|
385
|
+
onChange={(items) => setSelected(items.map(i => i.id))}
|
|
386
|
+
/>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
### Tag
|
|
392
|
+
|
|
393
|
+
Small label/badge component with color support.
|
|
394
|
+
|
|
395
|
+
```tsx
|
|
396
|
+
import { Tag } from 'wini-web-components'
|
|
397
|
+
|
|
398
|
+
<Tag>Active</Tag>
|
|
399
|
+
<Tag style={{ backgroundColor: '#B7D3FA', color: '#287CF0' }}>Info</Tag>
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
### Pagination
|
|
405
|
+
|
|
406
|
+
Page navigation component.
|
|
407
|
+
|
|
408
|
+
```tsx
|
|
409
|
+
import { Pagination } from 'wini-web-components'
|
|
410
|
+
|
|
411
|
+
<Pagination
|
|
412
|
+
currentPage={page}
|
|
413
|
+
total={totalItems}
|
|
414
|
+
pageSize={20}
|
|
415
|
+
onChange={(newPage) => setPage(newPage)}
|
|
416
|
+
/>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
### InfiniteScroll
|
|
422
|
+
|
|
423
|
+
Trigger a callback when the user scrolls to the bottom of a container.
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
import { InfiniteScroll } from 'wini-web-components'
|
|
427
|
+
|
|
428
|
+
<InfiniteScroll onLoadMore={() => fetchNextPage()} isLoading={loading} hasMore={hasMore}>
|
|
429
|
+
{items.map(item => <div key={item.id}>{item.name}</div>)}
|
|
430
|
+
</InfiniteScroll>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### Dialog
|
|
436
|
+
|
|
437
|
+
A global imperative dialog (confirm/alert modal). Rendered by `WiniProvider` — no extra setup needed.
|
|
438
|
+
|
|
439
|
+
```tsx
|
|
440
|
+
import { showDialog, DialogAlignment, ComponentStatus } from 'wini-web-components'
|
|
441
|
+
|
|
442
|
+
showDialog({
|
|
443
|
+
title: 'Delete item?',
|
|
444
|
+
content: 'This action cannot be undone.',
|
|
445
|
+
status: ComponentStatus.ERROR,
|
|
446
|
+
alignment: DialogAlignment.center,
|
|
447
|
+
onSubmit: () => handleDelete(),
|
|
448
|
+
submitTitle: 'Delete',
|
|
449
|
+
cancelTitle: 'Cancel',
|
|
450
|
+
})
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Status options:** `ComponentStatus.INFOR` `ComponentStatus.WARNING` `ComponentStatus.ERROR` `ComponentStatus.SUCCESS`
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
### Popup
|
|
458
|
+
|
|
459
|
+
A flexible fullscreen/overlay modal managed via ref.
|
|
460
|
+
|
|
461
|
+
```tsx
|
|
462
|
+
import { Popup, showPopup, closePopup } from 'wini-web-components'
|
|
463
|
+
import { useRef } from 'react'
|
|
464
|
+
|
|
465
|
+
const popupRef = useRef<Popup>()
|
|
466
|
+
|
|
467
|
+
// Trigger open
|
|
468
|
+
showPopup({
|
|
469
|
+
ref: popupRef,
|
|
470
|
+
heading: <h3>My Popup</h3>,
|
|
471
|
+
body: <p>Custom content here</p>,
|
|
472
|
+
footer: <Button label="Close" onClick={() => closePopup(popupRef)} />,
|
|
473
|
+
clickOverlayClosePopup: true,
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
// Place once in your JSX
|
|
477
|
+
<Popup ref={popupRef} />
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
### ToastMessage
|
|
483
|
+
|
|
484
|
+
Imperative toast notifications. Rendered by `WiniProvider` — no extra setup needed.
|
|
485
|
+
|
|
486
|
+
```tsx
|
|
487
|
+
import { ToastMessage } from 'wini-web-components'
|
|
488
|
+
|
|
489
|
+
ToastMessage.success('Saved successfully!')
|
|
490
|
+
ToastMessage.errors('Something went wrong.')
|
|
491
|
+
ToastMessage.warn('Check your input.')
|
|
492
|
+
ToastMessage.infor('New update available.')
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
### ProgressBar
|
|
498
|
+
|
|
499
|
+
```tsx
|
|
500
|
+
import { ProgressBar } from 'wini-web-components'
|
|
501
|
+
|
|
502
|
+
<ProgressBar value={72} max={100} />
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
### ProgressCircle
|
|
508
|
+
|
|
509
|
+
```tsx
|
|
510
|
+
import { ProgressCircle } from 'wini-web-components'
|
|
511
|
+
|
|
512
|
+
<ProgressCircle value={72} max={100} />
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
### Calendar
|
|
518
|
+
|
|
519
|
+
Standalone date calendar view.
|
|
520
|
+
|
|
521
|
+
```tsx
|
|
522
|
+
import { Calendar } from 'wini-web-components'
|
|
523
|
+
|
|
524
|
+
<Calendar value={date} onChange={(val) => setDate(val)} />
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
### Carousel
|
|
530
|
+
|
|
531
|
+
Image/content slideshow powered by `react-awesome-slider`.
|
|
532
|
+
|
|
533
|
+
```tsx
|
|
534
|
+
import { Carousel } from 'wini-web-components'
|
|
535
|
+
|
|
536
|
+
<Carousel>
|
|
537
|
+
<div data-src="/image1.jpg" />
|
|
538
|
+
<div data-src="/image2.jpg" />
|
|
539
|
+
</Carousel>
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
### VideoPlayer / AudioPlayer / IframePlayer
|
|
545
|
+
|
|
546
|
+
Media player components for video, audio, and embedded iframes.
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
import { VideoPlayer, AudioPlayer, IframePlayer } from 'wini-web-components'
|
|
550
|
+
|
|
551
|
+
<VideoPlayer src="https://example.com/video.mp4" />
|
|
552
|
+
<AudioPlayer src="https://example.com/audio.mp3" />
|
|
553
|
+
<IframePlayer src="https://www.youtube.com/embed/dQw4w9WgXcQ" />
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
### ImportFile / UploadFiles
|
|
559
|
+
|
|
560
|
+
File import input and multi-file uploader.
|
|
561
|
+
|
|
562
|
+
```tsx
|
|
563
|
+
import { ImportFile, UploadFiles } from 'wini-web-components'
|
|
564
|
+
|
|
565
|
+
// Single file pick (no upload)
|
|
566
|
+
<ImportFile onChange={(file) => setFile(file)} accept=".pdf,.docx" />
|
|
567
|
+
|
|
568
|
+
// Upload to server
|
|
569
|
+
<UploadFiles
|
|
570
|
+
onComplete={(urls) => setAttachments(urls)}
|
|
571
|
+
maxFiles={5}
|
|
572
|
+
/>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
### CustomCkEditor5
|
|
578
|
+
|
|
579
|
+
Rich text editor wrapper for CKEditor 5. Requires `ckeditor5` and `@ckeditor/ckeditor5-react` as peer dependencies.
|
|
580
|
+
|
|
581
|
+
```tsx
|
|
582
|
+
import { CustomCkEditor5 } from 'wini-web-components'
|
|
583
|
+
|
|
584
|
+
<CustomCkEditor5 value={html} onChange={(html) => setHtml(html)} />
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
### WiniEditor
|
|
590
|
+
|
|
591
|
+
Lightweight built-in rich text editor (no peer dependency required).
|
|
592
|
+
|
|
593
|
+
```tsx
|
|
594
|
+
import { WiniEditor } from 'wini-web-components'
|
|
595
|
+
|
|
596
|
+
<WiniEditor value={content} onChange={(val) => setContent(val)} />
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
### IconPicker
|
|
602
|
+
|
|
603
|
+
Searchable icon selector from the Wini icon library.
|
|
604
|
+
|
|
605
|
+
```tsx
|
|
606
|
+
import { IconPicker } from 'wini-web-components'
|
|
607
|
+
|
|
608
|
+
<IconPicker value={icon} onChange={(iconName) => setIcon(iconName)} />
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
613
|
+
---
|
|
614
|
+
|
|
615
|
+
## Backend-Driven Modules
|
|
616
|
+
|
|
617
|
+
These components connect to the **Wini backend** and render entire UIs from server-side configuration (layouts, forms, cards, views). They require `WiniProvider` to be set up with a valid `pid` and `url`.
|
|
618
|
+
|
|
619
|
+
> All five components share a common customization API: `propsData`, `childrenData`, and `itemData` — which let you override specific elements by their **layer ID** (the `id` field set in the Wini editor for that element).
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
### PageById
|
|
624
|
+
|
|
625
|
+
Renders a full page (layout shell + body content) fetched from the backend by page ID. Typically used inside a `<Route>`.
|
|
626
|
+
|
|
627
|
+
```tsx
|
|
628
|
+
import { PageById } from 'wini-web-components'
|
|
629
|
+
|
|
630
|
+
// Basic — renders the full page with its layout
|
|
631
|
+
<Route path="/dashboard" element={<PageById id="PAGE_ID" />} />
|
|
632
|
+
|
|
633
|
+
// Override props of a specific layer by its element ID
|
|
634
|
+
<PageById
|
|
635
|
+
id="PAGE_ID"
|
|
636
|
+
propsData={{
|
|
637
|
+
"element-gid": { style: { backgroundColor: 'red' }, className: 'my-class' }
|
|
638
|
+
}}
|
|
639
|
+
/>
|
|
640
|
+
|
|
641
|
+
// Replace children of a layer entirely
|
|
642
|
+
<PageById
|
|
643
|
+
id="PAGE_ID"
|
|
644
|
+
childrenData={{
|
|
645
|
+
"element-gid": <MyCustomComponent />
|
|
646
|
+
}}
|
|
647
|
+
/>
|
|
648
|
+
|
|
649
|
+
// Replace a layer entirely
|
|
650
|
+
<PageById
|
|
651
|
+
id="PAGE_ID"
|
|
652
|
+
itemData={{
|
|
653
|
+
"element-gid": <MyCustomComponent />
|
|
654
|
+
}}
|
|
655
|
+
/>
|
|
656
|
+
|
|
657
|
+
// Render only the layout shell (without body content)
|
|
658
|
+
<PageById id="PAGE_ID" onlyLayout />
|
|
659
|
+
|
|
660
|
+
// Render only the body content (without layout shell)
|
|
661
|
+
<PageById id="PAGE_ID" onlyBody />
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
### PageByUrl
|
|
667
|
+
|
|
668
|
+
Same as `PageById` but looks up the page by its **URL path** configured in the Wini backend. Useful for dynamic routing where page IDs are not known at build time.
|
|
669
|
+
|
|
670
|
+
```tsx
|
|
671
|
+
import { PageByUrl } from 'wini-web-components'
|
|
672
|
+
|
|
673
|
+
// Renders the page registered under "/dashboard" in the Wini backend
|
|
674
|
+
<PageByUrl url="/dashboard" />
|
|
675
|
+
|
|
676
|
+
// Inject custom children into the layout body slot
|
|
677
|
+
<PageByUrl url="/dashboard" onlyLayout>
|
|
678
|
+
<MyBodyContent />
|
|
679
|
+
</PageByUrl>
|
|
680
|
+
|
|
681
|
+
// Same customization API as PageById
|
|
682
|
+
<PageByUrl
|
|
683
|
+
url="/dashboard"
|
|
684
|
+
propsData={{ "element-gid": { style: { color: 'blue' } } }}
|
|
685
|
+
childrenData={{ "element-gid": <CustomWidget /> }}
|
|
686
|
+
/>
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
### FormById
|
|
692
|
+
|
|
693
|
+
Renders a data-entry form from backend configuration by form ID. Manages its own `react-hook-form` state internally. Exposes an imperative ref for programmatic submit.
|
|
694
|
+
|
|
695
|
+
```tsx
|
|
696
|
+
import { FormById } from 'wini-web-components'
|
|
697
|
+
import { useRef } from 'react'
|
|
698
|
+
|
|
699
|
+
const formRef = useRef(null)
|
|
700
|
+
|
|
701
|
+
// Basic — form submits and calls onSubmit with field values
|
|
702
|
+
<FormById
|
|
703
|
+
id="FORM_ID"
|
|
704
|
+
onSubmit={(data) => console.log('submitted:', data)}
|
|
705
|
+
onError={(errors) => console.error('validation failed:', errors)}
|
|
706
|
+
/>
|
|
707
|
+
|
|
708
|
+
// Pre-populate with existing data (e.g. edit mode)
|
|
709
|
+
<FormById
|
|
710
|
+
id="FORM_ID"
|
|
711
|
+
data={{ Name: 'Alice', Age: 30 }}
|
|
712
|
+
onSubmit={(data) => updateRecord(data)}
|
|
713
|
+
/>
|
|
714
|
+
|
|
715
|
+
// Load data from backend by query
|
|
716
|
+
<FormById
|
|
717
|
+
id="FORM_ID"
|
|
718
|
+
controller={{ searchRaw: '@Id:{some-id}' }}
|
|
719
|
+
onSubmit={(data) => updateRecord(data)}
|
|
720
|
+
/>
|
|
721
|
+
|
|
722
|
+
// Load data from backend by IDs
|
|
723
|
+
<FormById
|
|
724
|
+
id="FORM_ID"
|
|
725
|
+
controller={{ ids: 'id1,id2', maxLength: 1 }}
|
|
726
|
+
onSubmit={(data) => updateRecord(data)}
|
|
727
|
+
/>
|
|
728
|
+
|
|
729
|
+
// Trigger submit programmatically via ref
|
|
730
|
+
<FormById ref={formRef} id="FORM_ID" onSubmit={handleSubmit} />
|
|
731
|
+
<Button label="Save" onClick={() => formRef.current?.onSubmit()} />
|
|
732
|
+
|
|
733
|
+
// Supply custom dropdown options for a relation field
|
|
734
|
+
<FormById
|
|
735
|
+
id="FORM_ID"
|
|
736
|
+
customOptions={{ categoryId: [{ id: '1', name: 'Tech' }, { id: '2', name: 'Art' }] }}
|
|
737
|
+
onSubmit={handleSubmit}
|
|
738
|
+
/>
|
|
739
|
+
|
|
740
|
+
// Customize a specific field's wrapper props or replace it entirely
|
|
741
|
+
<FormById
|
|
742
|
+
id="FORM_ID"
|
|
743
|
+
propsData={{ "field-element-gid": { style: { display: 'none' } } }}
|
|
744
|
+
itemData={{ "field-element-gid": <MyCustomField /> }}
|
|
745
|
+
onSubmit={handleSubmit}
|
|
746
|
+
/>
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
**Ref handle:**
|
|
750
|
+
```ts
|
|
751
|
+
formRef.current.onSubmit() // trigger submit programmatically
|
|
752
|
+
formRef.current.methods // UseFormReturn — full react-hook-form instance
|
|
753
|
+
formRef.current.cols // resolved column definitions from backend
|
|
754
|
+
formRef.current.rels // resolved relation definitions from backend
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
### CardById
|
|
760
|
+
|
|
761
|
+
Renders a **repeating list** of items using a card template configured in the backend. Fetches its own data, supports pagination, filtering, sorting, and exposes a ref for imperative data refresh.
|
|
762
|
+
|
|
763
|
+
```tsx
|
|
764
|
+
import { CardById } from 'wini-web-components'
|
|
765
|
+
import { useRef } from 'react'
|
|
766
|
+
|
|
767
|
+
const cardRef = useRef(null)
|
|
768
|
+
|
|
769
|
+
// Basic — fetches and renders all items
|
|
770
|
+
<CardById id="CARD_ID" />
|
|
771
|
+
|
|
772
|
+
// With query controller (search + pagination)
|
|
773
|
+
<CardById
|
|
774
|
+
id="CARD_ID"
|
|
775
|
+
controller={{ page: 1, size: 10, searchRaw: '@Status:[0 1]', sortby: [{ prop: 'Name', direction: 'ASC' }] }}
|
|
776
|
+
onLoaded={({ data, totalCount }) => setTotal(totalCount)}
|
|
777
|
+
/>
|
|
778
|
+
|
|
779
|
+
// Provide data directly (skip backend fetch)
|
|
780
|
+
<CardById
|
|
781
|
+
id="CARD_ID"
|
|
782
|
+
cardData={[{ Id: '1', Name: 'Item A' }, { Id: '2', Name: 'Item B' }]}
|
|
783
|
+
/>
|
|
784
|
+
|
|
785
|
+
// Fetch all records
|
|
786
|
+
<CardById id="CARD_ID" controller="all" />
|
|
787
|
+
|
|
788
|
+
// Custom render per item — functions receive (itemData, index, methods)
|
|
789
|
+
<CardById
|
|
790
|
+
id="CARD_ID"
|
|
791
|
+
propsData={{
|
|
792
|
+
"element-gid": (item, index) => ({ style: { color: item.IsActive ? 'green' : 'red' } })
|
|
793
|
+
}}
|
|
794
|
+
childrenData={{
|
|
795
|
+
"element-gid": (item, index) => <span>{item.Name}</span>
|
|
796
|
+
}}
|
|
797
|
+
itemData={{
|
|
798
|
+
"element-gid": (item, index) => <MyCustomRow data={item} />
|
|
799
|
+
}}
|
|
800
|
+
/>
|
|
801
|
+
|
|
802
|
+
// Empty state
|
|
803
|
+
<CardById id="CARD_ID" emptyMessage="No items found" emptyLink="/create" />
|
|
804
|
+
|
|
805
|
+
// Imperative refresh
|
|
806
|
+
<CardById ref={cardRef} id="CARD_ID" controller={{ page: 1, size: 10, searchRaw: '*' }} />
|
|
807
|
+
<Button label="Refresh" onClick={() => cardRef.current?.getData(1)} />
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
**Ref handle:**
|
|
811
|
+
```ts
|
|
812
|
+
cardRef.current.getData(page?) // re-fetch data (optionally set page)
|
|
813
|
+
cardRef.current.data // { data: Array<{...}>, totalCount?: number }
|
|
814
|
+
cardRef.current.setData(newData) // manually update rendered data
|
|
815
|
+
cardRef.current.controller // current active query controller
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
---
|
|
819
|
+
|
|
820
|
+
### ViewById
|
|
821
|
+
|
|
822
|
+
Renders a **single item detail view** from backend configuration. Similar to `CardById` but for one record instead of a list.
|
|
823
|
+
|
|
824
|
+
```tsx
|
|
825
|
+
import { ViewById } from 'wini-web-components'
|
|
826
|
+
|
|
827
|
+
// Pass data directly (e.g. from a parent list)
|
|
828
|
+
<ViewById
|
|
829
|
+
id="VIEW_ID"
|
|
830
|
+
data={{ Id: 'abc', Name: 'Alice', Email: 'alice@example.com' }}
|
|
831
|
+
/>
|
|
832
|
+
|
|
833
|
+
// Or let it fetch by query
|
|
834
|
+
<ViewById
|
|
835
|
+
id="VIEW_ID"
|
|
836
|
+
controller={{ searchRaw: `@Id:{${recordId}}` }}
|
|
837
|
+
onLoaded={({ data }) => setRecord(data)}
|
|
838
|
+
/>
|
|
839
|
+
|
|
840
|
+
// Override specific elements — same API as PageById/CardById
|
|
841
|
+
<ViewById
|
|
842
|
+
id="VIEW_ID"
|
|
843
|
+
data={record}
|
|
844
|
+
propsData={{ "label-gid": { style: { fontWeight: 'bold' } } }}
|
|
845
|
+
childrenData={{ "value-gid": <strong>{record.Name}</strong> }}
|
|
846
|
+
/>
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
## Responsive Grid Classes
|
|
852
|
+
|
|
853
|
+
The layout system uses a **24-column grid**. Add these classes to children inside a `row`.
|
|
854
|
+
|
|
855
|
+
| Class | Columns | Notes |
|
|
856
|
+
|---|---|---|
|
|
857
|
+
| `col1` – `col24` | 1/24 – 24/24 | Always applied |
|
|
858
|
+
| `remain` | fills rest | `flex: 1` |
|
|
859
|
+
| `col1-min` – `col24-min` | at **< 576px** | phones |
|
|
860
|
+
| `col1-sm` – `col24-sm` | at **≥ 576px** | small devices |
|
|
861
|
+
| `col1-md` – `col24-md` | at **≥ 768px** | tablets |
|
|
862
|
+
| `col1-lg` – `col24-lg` | at **≥ 992px** | laptops |
|
|
863
|
+
| `col1-xl` – `col24-xl` | at **≥ 1200px** | desktops |
|
|
864
|
+
| `col1-xxl` – `col24-xxl` | at **> 1200px** | wide screens |
|
|
865
|
+
|
|
866
|
+
```tsx
|
|
867
|
+
// 2-column on desktop, stacks on mobile
|
|
868
|
+
<div className="row" style={{ gap: 16 }}>
|
|
869
|
+
<div className="col24 col12-lg" style={{ "--gutter": "16px" }}>Left panel</div>
|
|
870
|
+
<div className="col24 col12-lg" style={{ "--gutter": "16px" }}>Right panel</div>
|
|
871
|
+
</div>
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
---
|
|
875
|
+
|
|
876
|
+
## Design Tokens & Theming
|
|
877
|
+
|
|
878
|
+
Colors are defined as CSS variables in `root.css` and can be overridden by WiniProvider at runtime.
|
|
879
|
+
|
|
880
|
+
```css
|
|
881
|
+
/* Default token examples */
|
|
882
|
+
--primary-main-color: #287CF0;
|
|
883
|
+
--primary-bolder-color: #0F62D7;
|
|
884
|
+
--neutral-bolder-border: 1px solid #D7D7DB;
|
|
885
|
+
/* semantic */
|
|
886
|
+
--success-main-color: ...;
|
|
887
|
+
--error-main-color: ...;
|
|
888
|
+
--warning-main-color: ...;
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
Dark mode is toggled by adding the `.dark` class to `<html>`. Use `setTheme` from `useWiniContext`:
|
|
19
892
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
\
|
|
26
|
-
row: for horizontal layout. \
|
|
27
|
-
col: for vertical layout.
|
|
28
|
-
|
|
29
|
-
## Responsive Design:
|
|
30
|
-
wini-web-components comes with built-in CSS classes to ensure your UI looks great on all devices. The library supports responsive layouts for:\
|
|
31
|
-
Min Devices (Small phones): < 576px. \
|
|
32
|
-
Small Devices (Phones): Up to 576px. \
|
|
33
|
-
Medium Devices (Tablets): 576px to 768px. \
|
|
34
|
-
Large Devices (Laptops): 768px to 992px. \
|
|
35
|
-
Extra Large Devices (Desktops): 992px to 1200px. \
|
|
36
|
-
Extra Extra Large Devices: > 1200px. \
|
|
37
|
-
Each component is designed to adapt seamlessly to different screen sizes, with CSS classes: \
|
|
38
|
-
Ex: remain, col0, col1, col2, col3, col4, col6, col8, col10, col12, col16, col18, col20, col24, col1-min, col2-min, col3-sm, col6-sm, col8-md, col10-lg, col12-lg, col16-xl, col18-xl, col20-xxl, col24-xxl
|
|
39
|
-
|
|
40
|
-
## Using code features:
|
|
41
|
-
Components
|
|
42
|
-
wini-web-components includes the following UI components, ready to drop into your React project:
|
|
43
|
-
### Button: A versatile button component with multiple styles.
|
|
44
|
-
support className: \
|
|
45
|
-
Ex: size64, size56, size48, size40, size24, default is size32. button-grey, button-primary, button-neutral, button-black, button-white, button-infor, button-warning, button-error, button-success, button-infor-main, button-warning-main, button-error-main, button-success-main
|
|
46
|
-
### WiniIcon: A custom icon component for your app.
|
|
47
|
-
support className: \
|
|
48
|
-
Ex: icon-button, light, size64, size56, size48, size40, size32, size24.
|
|
49
|
-
|
|
50
|
-
### Calendar: A date selection component for scheduling and events.
|
|
51
|
-
### Carousel: A slideshow component for displaying images or content.
|
|
52
|
-
### Checkbox: A customizable checkbox for forms.
|
|
53
|
-
### CK-Editor: A rich text editor integration for content creation.
|
|
54
|
-
### Date-Time-Picker: A component for selecting dates and times.
|
|
55
|
-
### Dialog: A modal dialog for alerts, forms, or custom content.
|
|
56
|
-
### Input-File: A file upload input with a clean UI.
|
|
57
|
-
### Input-Multi-Select: A multi-select dropdown for forms.
|
|
58
|
-
### Input-Text: A styled text input field.
|
|
59
|
-
### Input-Textarea: A textarea for longer text input.
|
|
60
|
-
### Number-Picker: A component for selecting numerical values.
|
|
61
|
-
### Pagination: A pagination component for navigating large datasets.
|
|
62
|
-
### Popup: A popup component for notifications or overlays.
|
|
63
|
-
### Progress-Bar: A progress bar to show task completion.
|
|
64
|
-
### Progress-Circle: A circular progress indicator.
|
|
65
|
-
### Radio-Button: A radio button for single-choice selections.
|
|
66
|
-
### Rating: A star rating component for reviews or feedback.
|
|
67
|
-
### Select: A dropdown select component for forms.
|
|
68
|
-
### Slider: A slider for selecting a range of values.
|
|
69
|
-
### Switch: A toggle switch for on/off states.
|
|
70
|
-
### Table: A responsive table for displaying tabular data.
|
|
71
|
-
### Tag: A tag component for categorization or labeling.
|
|
72
|
-
### Text-Area: A textarea with additional styling options.
|
|
73
|
-
### Text-Field: A general-purpose text input field.
|
|
893
|
+
```tsx
|
|
894
|
+
const { setTheme } = useWiniContext()
|
|
895
|
+
setTheme('dark') // adds .dark to <html>
|
|
896
|
+
setTheme('light') // removes .dark from <html>
|
|
897
|
+
```
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "wini-web-components",
|
|
3
3
|
"private": false,
|
|
4
4
|
"description": "A simple ui library for React",
|
|
5
|
-
"version": "8.4.
|
|
5
|
+
"version": "8.4.99",
|
|
6
6
|
"main": "dist/index.umd.js",
|
|
7
7
|
"module": "dist/index.es.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
@@ -70,7 +70,11 @@
|
|
|
70
70
|
"url": "git+https://github.com/WiniGit/web-component.git"
|
|
71
71
|
},
|
|
72
72
|
"keywords": [
|
|
73
|
-
"wini"
|
|
73
|
+
"wini",
|
|
74
|
+
"web",
|
|
75
|
+
"components",
|
|
76
|
+
"react",
|
|
77
|
+
"ui"
|
|
74
78
|
],
|
|
75
79
|
"author": "thunt",
|
|
76
80
|
"license": "MIT",
|