@waysnx/ui-core 0.1.1
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 +475 -0
- package/dist/components/Alert/Alert.css +1 -0
- package/dist/components/Autocomplete/Autocomplete.css +76 -0
- package/dist/components/Button/Button.css +12 -0
- package/dist/components/Checkbox/Checkbox.css +1 -0
- package/dist/components/DatePicker/DatePicker.css +66 -0
- package/dist/components/DateRangePicker/DateRangePicker.css +68 -0
- package/dist/components/DateTimePicker/DateTimePicker.css +68 -0
- package/dist/components/Divider/Divider.css +1 -0
- package/dist/components/FileUpload/FileUpload.css +164 -0
- package/dist/components/HtmlContent/HtmlContent.css +115 -0
- package/dist/components/HtmlEditor/HtmlEditor.css +133 -0
- package/dist/components/Input/Input.css +33 -0
- package/dist/components/Link/Link.css +30 -0
- package/dist/components/Radio/Radio.css +1 -0
- package/dist/components/Select/Select.css +31 -0
- package/dist/components/Slider/Slider.css +10 -0
- package/dist/components/Spinner/Spinner.css +1 -0
- package/dist/components/Switch/Switch.css +1 -0
- package/dist/components/Textarea/Textarea.css +1 -0
- package/dist/components/TimePicker/TimePicker.css +68 -0
- package/dist/components/Tree/Tree.css +70 -0
- package/dist/index.cjs +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.cts +291 -0
- package/dist/index.d.ts +291 -0
- package/dist/index.js +1 -0
- package/dist/styles/base.css +1 -0
- package/dist/styles/index.css +22 -0
- package/dist/styles/tokens.css +9 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
# @waysnx/ui-core
|
|
2
|
+
|
|
3
|
+
Core UI components for WaysNX - A comprehensive React component library with form controls, inputs, buttons, date pickers, and more.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 Modern, accessible UI components
|
|
8
|
+
- 📝 Complete form controls (Input, Select, Checkbox, Radio, etc.)
|
|
9
|
+
- 📅 Date and date range pickers
|
|
10
|
+
- 🔒 Built-in XSS protection with DOMPurify
|
|
11
|
+
- 🎯 TypeScript support
|
|
12
|
+
- 🌙 Dark mode ready
|
|
13
|
+
- 📦 Tree-shakeable
|
|
14
|
+
- 🎨 CSS variables for easy theming
|
|
15
|
+
- 📋 JSON Schema to Form converter
|
|
16
|
+
- ⚡ Optimized and minified for production
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
### Prerequisites
|
|
21
|
+
|
|
22
|
+
This package requires React 18+ and react-datepicker as peer dependencies.
|
|
23
|
+
|
|
24
|
+
### Install via npm
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @waysnx/ui-core react-datepicker
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Authentication Setup
|
|
31
|
+
|
|
32
|
+
Since this package is hosted on GitHub Packages, you need to authenticate:
|
|
33
|
+
|
|
34
|
+
1. Create a `.npmrc` file in your project root:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
@waysnx:registry=https://npm.pkg.github.com/
|
|
38
|
+
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. Generate a GitHub Personal Access Token:
|
|
42
|
+
- Go to: https://github.com/settings/tokens
|
|
43
|
+
- Click "Generate new token (classic)"
|
|
44
|
+
- Select scope: `read:packages`
|
|
45
|
+
- Copy the token and replace `YOUR_GITHUB_TOKEN` in `.npmrc`
|
|
46
|
+
|
|
47
|
+
3. Add `.npmrc` to `.gitignore`:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
echo ".npmrc" >> .gitignore
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Import CSS
|
|
54
|
+
|
|
55
|
+
Import the required CSS files in your main entry file (e.g., `main.tsx` or `App.tsx`):
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import '@waysnx/ui-core/dist/index.css';
|
|
59
|
+
import 'react-datepicker/dist/react-datepicker.css';
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
### Basic Components
|
|
65
|
+
|
|
66
|
+
```jsx
|
|
67
|
+
import { Button, Input, Select, Checkbox } from '@waysnx/ui-core';
|
|
68
|
+
import { useState } from 'react';
|
|
69
|
+
|
|
70
|
+
function MyForm() {
|
|
71
|
+
const [name, setName] = useState('');
|
|
72
|
+
const [country, setCountry] = useState('');
|
|
73
|
+
const [agreed, setAgreed] = useState(false);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<div>
|
|
77
|
+
<Input
|
|
78
|
+
label="Name"
|
|
79
|
+
value={name}
|
|
80
|
+
onChange={(e) => setName(e.target.value)}
|
|
81
|
+
placeholder="Enter your name"
|
|
82
|
+
required
|
|
83
|
+
/>
|
|
84
|
+
|
|
85
|
+
<Select
|
|
86
|
+
label="Country"
|
|
87
|
+
value={country}
|
|
88
|
+
onChange={(e) => setCountry(e.target.value)}
|
|
89
|
+
options={[
|
|
90
|
+
{ value: 'us', label: 'United States' },
|
|
91
|
+
{ value: 'uk', label: 'United Kingdom' },
|
|
92
|
+
{ value: 'ca', label: 'Canada' }
|
|
93
|
+
]}
|
|
94
|
+
/>
|
|
95
|
+
|
|
96
|
+
<Checkbox
|
|
97
|
+
label="I agree to terms and conditions"
|
|
98
|
+
checked={agreed}
|
|
99
|
+
onChange={(e) => setAgreed(e.target.checked)}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
<Button variant="primary" type="submit">
|
|
103
|
+
Submit
|
|
104
|
+
</Button>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Switch Component
|
|
111
|
+
|
|
112
|
+
```jsx
|
|
113
|
+
import { Switch } from '@waysnx/ui-core';
|
|
114
|
+
import { useState } from 'react';
|
|
115
|
+
|
|
116
|
+
function MyComponent() {
|
|
117
|
+
const [enabled, setEnabled] = useState(false);
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<Switch
|
|
121
|
+
label="Enable notifications"
|
|
122
|
+
checked={enabled}
|
|
123
|
+
onChange={(e) => setEnabled(e.target.checked)}
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Date Picker
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
import { DatePicker } from '@waysnx/ui-core';
|
|
133
|
+
import { useState } from 'react';
|
|
134
|
+
|
|
135
|
+
function MyComponent() {
|
|
136
|
+
const [date, setDate] = useState(null);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<DatePicker
|
|
140
|
+
label="Select Date"
|
|
141
|
+
selected={date}
|
|
142
|
+
onChange={setDate}
|
|
143
|
+
placeholder="Choose a date"
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Multi-Select with Select All
|
|
150
|
+
|
|
151
|
+
```jsx
|
|
152
|
+
import { Select } from '@waysnx/ui-core';
|
|
153
|
+
import { useState } from 'react';
|
|
154
|
+
|
|
155
|
+
function MyComponent() {
|
|
156
|
+
const [selected, setSelected] = useState([]);
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<Select
|
|
160
|
+
label="Select Skills"
|
|
161
|
+
value={selected}
|
|
162
|
+
onChange={(e) => {
|
|
163
|
+
const options = Array.from(e.target.selectedOptions, option => option.value);
|
|
164
|
+
setSelected(options);
|
|
165
|
+
}}
|
|
166
|
+
options={[
|
|
167
|
+
{ value: 'js', label: 'JavaScript' },
|
|
168
|
+
{ value: 'ts', label: 'TypeScript' },
|
|
169
|
+
{ value: 'react', label: 'React' }
|
|
170
|
+
]}
|
|
171
|
+
multiple
|
|
172
|
+
showSelectAll
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### JSON Schema to Form
|
|
179
|
+
|
|
180
|
+
Convert JSON Schema to form fields automatically:
|
|
181
|
+
|
|
182
|
+
```jsx
|
|
183
|
+
import { schemaToFormFields, type JSONSchema } from '@waysnx/ui-core';
|
|
184
|
+
import { useState } from 'react';
|
|
185
|
+
|
|
186
|
+
const formSchema: JSONSchema = {
|
|
187
|
+
type: 'object',
|
|
188
|
+
properties: {
|
|
189
|
+
firstName: {
|
|
190
|
+
type: 'string',
|
|
191
|
+
title: 'First Name',
|
|
192
|
+
'x-placeholder': 'John'
|
|
193
|
+
},
|
|
194
|
+
email: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
format: 'email',
|
|
197
|
+
title: 'Email Address'
|
|
198
|
+
},
|
|
199
|
+
country: {
|
|
200
|
+
type: 'string',
|
|
201
|
+
title: 'Country',
|
|
202
|
+
enum: ['United States', 'United Kingdom', 'Canada']
|
|
203
|
+
},
|
|
204
|
+
birthdate: {
|
|
205
|
+
type: 'string',
|
|
206
|
+
format: 'date',
|
|
207
|
+
title: 'Date of Birth'
|
|
208
|
+
},
|
|
209
|
+
interests: {
|
|
210
|
+
type: 'array',
|
|
211
|
+
title: 'Interests',
|
|
212
|
+
items: {
|
|
213
|
+
type: 'string',
|
|
214
|
+
enum: ['Technology', 'Sports', 'Music', 'Travel']
|
|
215
|
+
},
|
|
216
|
+
'x-component': 'checkbox-group'
|
|
217
|
+
},
|
|
218
|
+
newsletter: {
|
|
219
|
+
type: 'boolean',
|
|
220
|
+
title: 'Subscribe to newsletter',
|
|
221
|
+
'x-component': 'checkbox'
|
|
222
|
+
},
|
|
223
|
+
status: {
|
|
224
|
+
type: 'boolean',
|
|
225
|
+
title: 'Active Status'
|
|
226
|
+
// Will render as Switch by default
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
required: ['firstName', 'email']
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
function DynamicForm() {
|
|
233
|
+
const [formData, setFormData] = useState({});
|
|
234
|
+
|
|
235
|
+
const handleChange = (name: string, value: any) => {
|
|
236
|
+
setFormData(prev => ({ ...prev, [name]: value }));
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const fields = schemaToFormFields(formSchema, formData, handleChange);
|
|
240
|
+
|
|
241
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
242
|
+
e.preventDefault();
|
|
243
|
+
console.log('Form data:', formData);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<form onSubmit={handleSubmit}>
|
|
248
|
+
{fields.map(field => (
|
|
249
|
+
<div key={field.name}>
|
|
250
|
+
{field.component}
|
|
251
|
+
</div>
|
|
252
|
+
))}
|
|
253
|
+
</form>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Available Components
|
|
259
|
+
|
|
260
|
+
### Form Controls
|
|
261
|
+
- `Input` - Text, email, password, number inputs with optional password toggle
|
|
262
|
+
- `Select` - Single and multi-select dropdowns with optional select-all
|
|
263
|
+
- `Checkbox` - Single checkbox or checkbox group
|
|
264
|
+
- `Radio` - Radio button group
|
|
265
|
+
- `Textarea` - Multi-line text input
|
|
266
|
+
- `Switch` - Toggle switch
|
|
267
|
+
- `Slider` - Range slider
|
|
268
|
+
- `Autocomplete` - Searchable dropdown with filtering
|
|
269
|
+
- `FileUpload` - File upload with drag & drop
|
|
270
|
+
|
|
271
|
+
### Date & Time Components
|
|
272
|
+
- `DatePicker` - Single date picker
|
|
273
|
+
- `DateRangePicker` - Date range picker
|
|
274
|
+
- `DateTimePicker` - Date and time picker
|
|
275
|
+
- `TimePicker` - Time picker
|
|
276
|
+
|
|
277
|
+
### Buttons & Navigation
|
|
278
|
+
- `Button` - Button with variants (primary, secondary, destructive, outline, ghost)
|
|
279
|
+
- `Link` - Styled link component
|
|
280
|
+
|
|
281
|
+
### Content & Display
|
|
282
|
+
- `HtmlEditor` - Rich text editor (sanitized with DOMPurify)
|
|
283
|
+
- `HtmlContent` - Display HTML content (sanitized with DOMPurify)
|
|
284
|
+
- `Alert` - Alert/notification component
|
|
285
|
+
- `Spinner` - Loading spinner
|
|
286
|
+
- `Divider` - Horizontal divider line
|
|
287
|
+
|
|
288
|
+
### Layout & Structure
|
|
289
|
+
- `Stack` - Vertical or horizontal stack layout
|
|
290
|
+
- `Hidden` - Conditionally hide content
|
|
291
|
+
- `Tree` - Tree view component
|
|
292
|
+
|
|
293
|
+
### Utilities
|
|
294
|
+
- `schemaToFormFields` - Convert JSON Schema to form components
|
|
295
|
+
- `useDebounce` - Debounce hook for performance
|
|
296
|
+
|
|
297
|
+
## Button Variants
|
|
298
|
+
|
|
299
|
+
```jsx
|
|
300
|
+
<Button variant="primary">Primary</Button>
|
|
301
|
+
<Button variant="secondary">Secondary</Button>
|
|
302
|
+
<Button variant="destructive">Delete</Button>
|
|
303
|
+
<Button variant="outline">Outline</Button>
|
|
304
|
+
<Button variant="ghost">Ghost</Button>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Theming
|
|
308
|
+
|
|
309
|
+
The library uses CSS variables for easy theming. Override these in your CSS to match your app's design system.
|
|
310
|
+
|
|
311
|
+
### Available CSS Variables
|
|
312
|
+
|
|
313
|
+
#### Color Variables
|
|
314
|
+
|
|
315
|
+
```css
|
|
316
|
+
:root {
|
|
317
|
+
/* Primary Colors */
|
|
318
|
+
--wx-color-primary: #f19924;
|
|
319
|
+
--wx-color-primary-hover: #d88420;
|
|
320
|
+
--wx-color-primary-light: #fef3e6;
|
|
321
|
+
|
|
322
|
+
/* Secondary Colors */
|
|
323
|
+
--wx-color-secondary: #6b7280;
|
|
324
|
+
--wx-color-secondary-hover: #4b5563;
|
|
325
|
+
|
|
326
|
+
/* Status Colors */
|
|
327
|
+
--wx-color-success: #10b981;
|
|
328
|
+
--wx-color-danger: #ef4444;
|
|
329
|
+
--wx-color-warning: #f59e0b;
|
|
330
|
+
--wx-color-info: #3b82f6;
|
|
331
|
+
|
|
332
|
+
/* Text Colors */
|
|
333
|
+
--wx-text-primary: #111827;
|
|
334
|
+
--wx-text-secondary: #6b7280;
|
|
335
|
+
--wx-text-disabled: #9ca3af;
|
|
336
|
+
|
|
337
|
+
/* Background Colors */
|
|
338
|
+
--wx-bg-primary: #ffffff;
|
|
339
|
+
--wx-bg-secondary: #f9fafb;
|
|
340
|
+
--wx-bg-hover: #f3f4f6;
|
|
341
|
+
|
|
342
|
+
/* Border Colors */
|
|
343
|
+
--wx-border-color: #d1d5db;
|
|
344
|
+
--wx-border-focus: #f19924;
|
|
345
|
+
|
|
346
|
+
/* Accent Colors */
|
|
347
|
+
--wx-accent-orange: #f97316;
|
|
348
|
+
--wx-accent-orange-dark: #ea580c;
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
#### Dark Mode Support
|
|
353
|
+
|
|
354
|
+
```css
|
|
355
|
+
.dark {
|
|
356
|
+
--wx-color-primary: #fbbf24;
|
|
357
|
+
--wx-color-primary-hover: #f59e0b;
|
|
358
|
+
|
|
359
|
+
--wx-text-primary: #f3f4f6;
|
|
360
|
+
--wx-text-secondary: #9ca3af;
|
|
361
|
+
--wx-text-disabled: #6b7280;
|
|
362
|
+
|
|
363
|
+
--wx-bg-primary: #111827;
|
|
364
|
+
--wx-bg-secondary: #1f2937;
|
|
365
|
+
--wx-bg-hover: #374151;
|
|
366
|
+
|
|
367
|
+
--wx-border-color: #374151;
|
|
368
|
+
--wx-border-focus: #fbbf24;
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Dynamic Theme Integration
|
|
373
|
+
|
|
374
|
+
To integrate with your existing design system, create a theme override file:
|
|
375
|
+
|
|
376
|
+
```css
|
|
377
|
+
/* theme-override.css */
|
|
378
|
+
:root {
|
|
379
|
+
/* Map your app's variables to library variables */
|
|
380
|
+
--wx-color-primary: var(--your-brand-color, #f19924);
|
|
381
|
+
--wx-color-secondary: var(--your-gray-600, #6b7280);
|
|
382
|
+
--wx-text-primary: var(--your-text-color, #111827);
|
|
383
|
+
--wx-bg-primary: var(--your-bg-color, #ffffff);
|
|
384
|
+
/* ... map other variables */
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Import this file after the library CSS:
|
|
389
|
+
|
|
390
|
+
```javascript
|
|
391
|
+
import '@waysnx/ui-core/dist/index.css';
|
|
392
|
+
import './theme-override.css'; // Your overrides
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
This ensures library components automatically match your app's theme, including dark mode support.
|
|
396
|
+
|
|
397
|
+
## JSON Schema Extensions
|
|
398
|
+
|
|
399
|
+
The library supports custom JSON Schema extensions using the `x-` prefix:
|
|
400
|
+
|
|
401
|
+
- `x-placeholder` - Placeholder text for inputs
|
|
402
|
+
- `x-component` - Force specific component:
|
|
403
|
+
- `'checkbox'` - Single checkbox for boolean
|
|
404
|
+
- `'checkbox-group'` - Multiple checkboxes for array
|
|
405
|
+
- `'toggle'` or `'switch'` - Toggle switch for boolean
|
|
406
|
+
- `'button'` - Render as button
|
|
407
|
+
- `x-button-type` - Button type ('submit', 'button', 'reset')
|
|
408
|
+
- `x-button-variant` - Button variant ('primary', 'secondary', 'destructive', 'outline', 'ghost')
|
|
409
|
+
|
|
410
|
+
### JSON Schema Type Mappings
|
|
411
|
+
|
|
412
|
+
The library automatically maps JSON Schema types to components:
|
|
413
|
+
|
|
414
|
+
| Schema Type | Format | Component |
|
|
415
|
+
|------------|--------|-----------|
|
|
416
|
+
| `string` | - | Input (text) |
|
|
417
|
+
| `string` | `email` | Input (email) |
|
|
418
|
+
| `string` | `password` | Input (password) with toggle |
|
|
419
|
+
| `string` | `date` | DatePicker |
|
|
420
|
+
| `string` | `date-time` | DateTimePicker |
|
|
421
|
+
| `string` | `time` | TimePicker |
|
|
422
|
+
| `string` | `binary` | FileUpload |
|
|
423
|
+
| `string` | `uri` | Input (url) |
|
|
424
|
+
| `string` | `textarea` | Textarea |
|
|
425
|
+
| `string` | `html` | HtmlEditor |
|
|
426
|
+
| `string` | `enum` | Select (single) |
|
|
427
|
+
| `integer` / `number` | - | Input (number) |
|
|
428
|
+
| `integer` / `number` | with min/max | Slider |
|
|
429
|
+
| `boolean` | - | Switch (default) |
|
|
430
|
+
| `boolean` | `x-component: 'checkbox'` | Checkbox |
|
|
431
|
+
| `array` | `enum` items | Select (multi) or Checkbox group |
|
|
432
|
+
|
|
433
|
+
## TypeScript Support
|
|
434
|
+
|
|
435
|
+
Full TypeScript support with type definitions included:
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import type { JSONSchema, FormField } from '@waysnx/ui-core';
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Security
|
|
442
|
+
|
|
443
|
+
This package includes built-in XSS protection:
|
|
444
|
+
- HTML content is sanitized using DOMPurify
|
|
445
|
+
- Safe to render user-generated content
|
|
446
|
+
- Code is minified and optimized for production
|
|
447
|
+
|
|
448
|
+
## Browser Support
|
|
449
|
+
|
|
450
|
+
- Chrome (latest)
|
|
451
|
+
- Firefox (latest)
|
|
452
|
+
- Safari (latest)
|
|
453
|
+
- Edge (latest)
|
|
454
|
+
|
|
455
|
+
## Peer Dependencies
|
|
456
|
+
|
|
457
|
+
- `react` >= 18
|
|
458
|
+
- `react-dom` >= 18
|
|
459
|
+
- `react-datepicker` ^8.0.0
|
|
460
|
+
|
|
461
|
+
## License
|
|
462
|
+
|
|
463
|
+
MIT
|
|
464
|
+
|
|
465
|
+
## Repository
|
|
466
|
+
|
|
467
|
+
https://github.com/waysnx/waysnx-ui-kit
|
|
468
|
+
|
|
469
|
+
## Issues
|
|
470
|
+
|
|
471
|
+
https://github.com/waysnx/waysnx-ui-kit/issues
|
|
472
|
+
|
|
473
|
+
## Author
|
|
474
|
+
|
|
475
|
+
WaysNX Technologies
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.wx-alert{padding:12px 16px;border-radius:6px;font-size:14px}.wx-alert-info{background:#eff6ff;color:#1d4ed8}.wx-alert-success{background:#ecfdf5;color:#047857}.wx-alert-warning{background:#fffbeb;color:#b45309}.wx-alert-error{background:#fef2f2;color:#b91c1c}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
.wx-autocomplete-wrapper {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 4px;
|
|
5
|
+
position: relative;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.wx-autocomplete-label {
|
|
9
|
+
font-size: 14px;
|
|
10
|
+
font-weight: 500;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.wx-autocomplete-input {
|
|
14
|
+
width: 100%;
|
|
15
|
+
padding: 10px;
|
|
16
|
+
border: 1px solid #ccc;
|
|
17
|
+
border-radius: 6px;
|
|
18
|
+
outline: none;
|
|
19
|
+
height: 40px;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
font-size: 14px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.wx-autocomplete-input:focus {
|
|
25
|
+
border-color: var(--wx-color-primary, #f19924);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.wx-autocomplete-input-error {
|
|
29
|
+
border-color: var(--wx-color-error, #dc2626);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.wx-autocomplete-dropdown {
|
|
33
|
+
position: absolute;
|
|
34
|
+
top: 100%;
|
|
35
|
+
left: 0;
|
|
36
|
+
right: 0;
|
|
37
|
+
margin: 4px 0 0 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
max-width: 350px;
|
|
40
|
+
max-height: 240px;
|
|
41
|
+
overflow-y: auto;
|
|
42
|
+
background: #fff;
|
|
43
|
+
border: 1px solid #ccc;
|
|
44
|
+
border-radius: 6px;
|
|
45
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
46
|
+
z-index: 1000;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.wx-autocomplete-option {
|
|
50
|
+
padding: 10px 12px;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
display: block;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.wx-autocomplete-option:hover,
|
|
56
|
+
.wx-autocomplete-option-highlighted {
|
|
57
|
+
background: #f2f2f2;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.wx-autocomplete-no-options {
|
|
61
|
+
padding: 10px 12px;
|
|
62
|
+
color: #6b6b6d;
|
|
63
|
+
font-size: 14px;
|
|
64
|
+
text-align: center;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.wx-autocomplete-hint {
|
|
68
|
+
font-size: 12px;
|
|
69
|
+
color: #6b7280;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.wx-autocomplete-error-text {
|
|
73
|
+
font-size: 12px;
|
|
74
|
+
color: #dc2626;
|
|
75
|
+
}
|
|
76
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.wx-button{font-weight:500;border-radius:6px;padding:10px 16px;cursor:pointer;transition:background 0.15s ease,color 0.15s ease;outline:none}
|
|
2
|
+
.wx-button--primary{background:var(--wx-color-primary,#f19924);color:#fff;border:none}
|
|
3
|
+
.wx-button--primary:hover{background:var(--wx-color-primary-hover,#e08916)}
|
|
4
|
+
.wx-button--secondary{background:transparent;color:var(--wx-color-primary,#f19924);border:1px solid var(--wx-color-primary,#f19924)}
|
|
5
|
+
.wx-button--secondary:hover{background:var(--wx-color-primary,#f19924);color:#fff}
|
|
6
|
+
.wx-button--destructive{background:var(--wx-color-destructive,#dc2626);color:#fff;border:none}
|
|
7
|
+
.wx-button--destructive:hover{background:var(--wx-color-destructive-hover,#b91c1c)}
|
|
8
|
+
.wx-button--outline{background:transparent;color:var(--wx-color-text,#333);border:1px solid var(--wx-color-border,#ddd)}
|
|
9
|
+
.wx-button--outline:hover{background:var(--wx-color-bg-subtle,#f5f5f5)}
|
|
10
|
+
.wx-button--ghost{background:transparent;color:var(--wx-color-text,#333);border:none}
|
|
11
|
+
.wx-button--ghost:hover{background:var(--wx-color-bg-subtle,#f5f5f5)}
|
|
12
|
+
.wx-button:disabled{opacity:0.6;cursor:not-allowed}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.wx-checkbox-wrapper{display:flex;gap:8px;align-items:center}.wx-checkbox{width:16px;height:16px}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
.wx-datepicker-wrapper {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 4px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.wx-datepicker-label {
|
|
8
|
+
font-size: 14px;
|
|
9
|
+
font-weight: 500;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.wx-datepicker-input-wrapper {
|
|
13
|
+
position: relative;
|
|
14
|
+
display: block;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.wx-datepicker-react-wrapper {
|
|
18
|
+
display: block;
|
|
19
|
+
width: 100%;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.wx-datepicker-input {
|
|
23
|
+
width: 100%;
|
|
24
|
+
padding: 10px 36px 10px 10px !important;
|
|
25
|
+
border: 1px solid #ccc;
|
|
26
|
+
border-radius: 6px;
|
|
27
|
+
outline: none;
|
|
28
|
+
height: 40px;
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
font-size: 14px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.wx-datepicker-icon {
|
|
34
|
+
position: absolute;
|
|
35
|
+
right: 10px;
|
|
36
|
+
top: 10px;
|
|
37
|
+
width: 18px;
|
|
38
|
+
height: 18px;
|
|
39
|
+
color: #6b7280;
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
z-index: 10;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.wx-datepicker-input:focus {
|
|
45
|
+
border-color: var(--wx-color-primary, #f19924);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.wx-datepicker-input:disabled {
|
|
49
|
+
opacity: 0.6;
|
|
50
|
+
cursor: not-allowed;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.wx-datepicker-input-error {
|
|
54
|
+
border-color: var(--wx-color-error, #dc2626);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.wx-datepicker-hint {
|
|
58
|
+
font-size: 12px;
|
|
59
|
+
color: #6b7280;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.wx-datepicker-error-text {
|
|
63
|
+
font-size: 12px;
|
|
64
|
+
color: #dc2626;
|
|
65
|
+
}
|
|
66
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
.wx-daterangepicker-wrapper {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 4px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.wx-daterangepicker-label {
|
|
8
|
+
font-size: 14px;
|
|
9
|
+
font-weight: 500;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.wx-daterangepicker-input-wrapper {
|
|
13
|
+
position: relative;
|
|
14
|
+
display: inline-block;
|
|
15
|
+
width: 100%;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.wx-daterangepicker-react-wrapper {
|
|
19
|
+
display: block;
|
|
20
|
+
width: 100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.wx-daterangepicker-input {
|
|
24
|
+
width: 100%;
|
|
25
|
+
padding: 10px 36px 10px 10px;
|
|
26
|
+
border: 1px solid #ccc;
|
|
27
|
+
border-radius: 6px;
|
|
28
|
+
outline: none;
|
|
29
|
+
height: 40px;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
font-size: 14px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.wx-daterangepicker-icon {
|
|
35
|
+
position: absolute;
|
|
36
|
+
right: 10px;
|
|
37
|
+
top: 50%;
|
|
38
|
+
transform: translateY(-50%);
|
|
39
|
+
width: 18px;
|
|
40
|
+
height: 18px;
|
|
41
|
+
color: #6b7280;
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
z-index: 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.wx-daterangepicker-input:focus {
|
|
47
|
+
border-color: var(--wx-color-primary, #f19924);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.wx-daterangepicker-input:disabled {
|
|
51
|
+
opacity: 0.6;
|
|
52
|
+
cursor: not-allowed;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.wx-daterangepicker-input-error {
|
|
56
|
+
border-color: var(--wx-color-error, #dc2626);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.wx-daterangepicker-hint {
|
|
60
|
+
font-size: 12px;
|
|
61
|
+
color: #6b7280;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.wx-daterangepicker-error-text {
|
|
65
|
+
font-size: 12px;
|
|
66
|
+
color: #dc2626;
|
|
67
|
+
}
|
|
68
|
+
|