@bunnix/components 0.9.3 → 0.9.4
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/@types/index.d.ts +59 -2
- package/README.md +73 -109
- package/package.json +1 -1
- package/src/components/ComboBox.mjs +8 -2
- package/src/components/DatePicker.mjs +234 -57
- package/src/components/InputField.mjs +55 -6
- package/src/components/TimePicker.mjs +255 -65
- package/src/index.mjs +3 -0
- package/src/styles/controls.css +37 -0
- package/src/utils/maskUtils.mjs +569 -0
package/@types/index.d.ts
CHANGED
|
@@ -218,6 +218,33 @@ export interface BadgeProps extends BaseProps {
|
|
|
218
218
|
shape?: "capsule" | "circle" | string;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
export type InputMaskType =
|
|
222
|
+
| "date" // DD/MM/YYYY
|
|
223
|
+
| "time" // HH:MM
|
|
224
|
+
| "email" // lowercase, no spaces
|
|
225
|
+
| "currency" // $ 1,234.56
|
|
226
|
+
| "decimal" // 123.45
|
|
227
|
+
| "integer" // 123
|
|
228
|
+
| "phone" // +1 (234) 567-8900
|
|
229
|
+
| "phone-br" // +55 11 99999-9999 or +55 11 9999-9999 (Brazilian phone)
|
|
230
|
+
| "credit-card" // 1234 5678 9012 3456
|
|
231
|
+
| "cpf" // 123.456.789-01 (Brazilian CPF)
|
|
232
|
+
| "cnpj" // 12.345.678/0001-90 (Brazilian CNPJ)
|
|
233
|
+
| "cep" // 12345-678 (Brazilian ZIP code)
|
|
234
|
+
| string; // Custom pattern using 9 (digit), A (letter), * (alphanumeric)
|
|
235
|
+
|
|
236
|
+
export interface InputMaskConfig {
|
|
237
|
+
type?: InputMaskType;
|
|
238
|
+
pattern?: string; // Custom pattern: 9=digit, A=letter, *=alphanumeric
|
|
239
|
+
options?: {
|
|
240
|
+
prefix?: string;
|
|
241
|
+
thousandsSeparator?: string;
|
|
242
|
+
decimalSeparator?: string;
|
|
243
|
+
decimalPlaces?: number;
|
|
244
|
+
allowNegative?: boolean;
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
221
248
|
export interface InputFieldProps extends BaseProps {
|
|
222
249
|
type?: string;
|
|
223
250
|
variant?: "regular" | "rounded" | string;
|
|
@@ -226,6 +253,8 @@ export interface InputFieldProps extends BaseProps {
|
|
|
226
253
|
placeholder?: string;
|
|
227
254
|
label?: string;
|
|
228
255
|
disabled?: boolean;
|
|
256
|
+
autocomplete?: string;
|
|
257
|
+
mask?: InputMaskType | InputMaskConfig;
|
|
229
258
|
suggestions?: string[];
|
|
230
259
|
onInput?: (event?: any) => void;
|
|
231
260
|
onChange?: (event?: any) => void;
|
|
@@ -255,6 +284,7 @@ export interface ComboBoxProps extends BaseProps {
|
|
|
255
284
|
options?: Array<string | ComboBoxOption>;
|
|
256
285
|
selection?: any;
|
|
257
286
|
size?: SizeValue;
|
|
287
|
+
label?: string;
|
|
258
288
|
onChange?: (event?: any) => void;
|
|
259
289
|
change?: (event?: any) => void;
|
|
260
290
|
}
|
|
@@ -346,14 +376,36 @@ export interface DatePickerProps extends BaseProps {
|
|
|
346
376
|
placeholder?: string;
|
|
347
377
|
range?: boolean;
|
|
348
378
|
variant?: "regular" | "rounded" | string;
|
|
349
|
-
size?:
|
|
379
|
+
size?: SizeRegularUp;
|
|
380
|
+
label?: string;
|
|
381
|
+
disabled?: boolean;
|
|
382
|
+
value?: Date | null;
|
|
383
|
+
onInput?: (event?: any) => void;
|
|
384
|
+
onChange?: (event?: { target: { value: string }; date: Date | null }) => void;
|
|
385
|
+
onFocus?: (event?: any) => void;
|
|
386
|
+
onBlur?: (event?: any) => void;
|
|
387
|
+
input?: (event?: any) => void;
|
|
388
|
+
change?: (event?: { target: { value: string }; date: Date | null }) => void;
|
|
389
|
+
focus?: (event?: any) => void;
|
|
390
|
+
blur?: (event?: any) => void;
|
|
350
391
|
}
|
|
351
392
|
|
|
352
393
|
export interface TimePickerProps extends BaseProps {
|
|
353
394
|
id?: string;
|
|
354
395
|
placeholder?: string;
|
|
355
396
|
variant?: "regular" | "rounded" | string;
|
|
356
|
-
size?:
|
|
397
|
+
size?: SizeRegularUp;
|
|
398
|
+
label?: string;
|
|
399
|
+
disabled?: boolean;
|
|
400
|
+
value?: { hours: number; minutes: number } | null;
|
|
401
|
+
onInput?: (event?: any) => void;
|
|
402
|
+
onChange?: (event?: { target: { value: string }; time: { hours: number; minutes: number } | null }) => void;
|
|
403
|
+
onFocus?: (event?: any) => void;
|
|
404
|
+
onBlur?: (event?: any) => void;
|
|
405
|
+
input?: (event?: any) => void;
|
|
406
|
+
change?: (event?: { target: { value: string }; time: { hours: number; minutes: number } | null }) => void;
|
|
407
|
+
focus?: (event?: any) => void;
|
|
408
|
+
blur?: (event?: any) => void;
|
|
357
409
|
}
|
|
358
410
|
|
|
359
411
|
export interface DropdownMenuItem {
|
|
@@ -503,6 +555,11 @@ export const toastState: any;
|
|
|
503
555
|
export function showToast(options?: ToastOptions): void;
|
|
504
556
|
export function hideToast(): void;
|
|
505
557
|
|
|
558
|
+
// Mask utilities
|
|
559
|
+
export function applyMask(value: string, mask: InputMaskType | InputMaskConfig): string;
|
|
560
|
+
export function validateMask(value: string, mask: InputMaskType | InputMaskConfig): boolean;
|
|
561
|
+
export function getMaskMaxLength(mask: InputMaskType | InputMaskConfig): number | null;
|
|
562
|
+
|
|
506
563
|
declare module "@bunnix/components/styles.css" {
|
|
507
564
|
const content: string;
|
|
508
565
|
export default content;
|
package/README.md
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
# @bunnix/components
|
|
2
2
|
|
|
3
|
-
Design system + UI components for Bunnix projects.
|
|
3
|
+
Design system + UI components for Bunnix projects. Ships ESM source with CSS and icon assets for modern bundlers.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- This project is currently in **alpha release candidate**. APIs and components may change until the first stable release.
|
|
7
|
-
- Icon usage & attribution:
|
|
8
|
-
- COLLECTION: Framework7 Line Icons — LICENSE: MIT License — AUTHOR: framework7io
|
|
9
|
-
- COLLECTION: Iconcino Interface Icons — LICENSE: CC0 1.0 — AUTHOR: Gabriele Malaspina
|
|
10
|
-
- Sources (copy/paste): `https://framework7.io/icons/` and `https://iconcino.com/`
|
|
5
|
+
**Status**: Alpha release candidate - APIs may change before v1.0
|
|
11
6
|
|
|
12
7
|
## Install
|
|
13
8
|
|
|
@@ -15,71 +10,78 @@ Disclaimer:
|
|
|
15
10
|
npm install @bunnix/components @bunnix/core
|
|
16
11
|
```
|
|
17
12
|
|
|
18
|
-
`@bunnix/core` is a peer dependency
|
|
13
|
+
`@bunnix/core` is a peer dependency.
|
|
19
14
|
|
|
20
|
-
##
|
|
15
|
+
## Quick Start
|
|
21
16
|
|
|
22
|
-
Import
|
|
17
|
+
Import CSS once at your app entry:
|
|
23
18
|
|
|
24
19
|
```js
|
|
25
20
|
import "@bunnix/components/styles.css";
|
|
26
21
|
```
|
|
27
22
|
|
|
28
|
-
|
|
23
|
+
Use components:
|
|
29
24
|
|
|
30
25
|
```js
|
|
31
|
-
import { Button, Icon,
|
|
32
|
-
|
|
33
|
-
export default function Example() {
|
|
34
|
-
return Button({ variant: "regular" }, [
|
|
35
|
-
Icon({ name: "star", fill: "white" }),
|
|
36
|
-
Text({ type: "text" }, "Star")
|
|
37
|
-
]);
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Component examples
|
|
42
|
-
|
|
43
|
-
Button with icon:
|
|
44
|
-
|
|
45
|
-
```js
|
|
46
|
-
import { Button, Icon } from "@bunnix/components";
|
|
26
|
+
import { Button, Icon, InputField, DatePicker } from "@bunnix/components";
|
|
47
27
|
|
|
28
|
+
// Button with icon
|
|
48
29
|
Button({ variant: "regular" }, [
|
|
49
30
|
Icon({ name: "star", fill: "white" }),
|
|
50
31
|
"Star"
|
|
51
32
|
]);
|
|
33
|
+
|
|
34
|
+
// Input with mask
|
|
35
|
+
InputField({ label: "Phone", mask: "phone-br" });
|
|
36
|
+
|
|
37
|
+
// Date picker
|
|
38
|
+
DatePicker({ label: "Birth Date", change: (e) => console.log(e.date) });
|
|
52
39
|
```
|
|
53
40
|
|
|
54
|
-
|
|
41
|
+
## Key Features
|
|
55
42
|
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
### Input Masks
|
|
44
|
+
InputField supports 12+ built-in masks plus custom patterns:
|
|
45
|
+
- `date`, `time`, `email`, `currency`, `decimal`, `integer`
|
|
46
|
+
- `phone`, `phone-br`, `credit-card`
|
|
47
|
+
- `cpf`, `cnpj`, `cep` (Brazilian documents)
|
|
48
|
+
- Custom patterns: `{ pattern: "999.999.999-99" }` (9=digit, A=letter, *=alphanumeric)
|
|
58
49
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]
|
|
50
|
+
```js
|
|
51
|
+
InputField({
|
|
52
|
+
label: "Price",
|
|
53
|
+
mask: { type: "currency", options: { prefix: "R$", decimalPlaces: 2 }}
|
|
64
54
|
});
|
|
65
55
|
```
|
|
66
56
|
|
|
67
|
-
|
|
57
|
+
Mask utilities available for custom use:
|
|
58
|
+
```js
|
|
59
|
+
import { applyMask, validateMask, getMaskMaxLength } from "@bunnix/components";
|
|
60
|
+
```
|
|
68
61
|
|
|
62
|
+
### Date & Time Pickers
|
|
63
|
+
Text inputs with masks that show popover calendars/selectors on focus:
|
|
69
64
|
```js
|
|
70
|
-
|
|
65
|
+
DatePicker({ label: "Date", change: (e) => console.log(e.date) });
|
|
66
|
+
TimePicker({ label: "Time", change: (e) => console.log(e.time) });
|
|
67
|
+
```
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
### Dialog & Toast
|
|
70
|
+
```js
|
|
71
|
+
import { showDialog, showToast } from "@bunnix/components";
|
|
72
|
+
|
|
73
|
+
showDialog({ title: "Welcome", message: "Ready to go!" });
|
|
74
|
+
showToast({ message: "Saved", icon: "success-circle" });
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
### 30+ Components
|
|
78
|
+
Button, Icon, Text, InputField, ComboBox, DatePicker, TimePicker, SearchBox, Checkbox, ToggleSwitch, Badge, Card, Table, Sidebar, NavigationBar, Dialog, Toast, and more.
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
See `/playgrounds` for live examples of all components.
|
|
79
81
|
|
|
80
82
|
## Theming
|
|
81
83
|
|
|
82
|
-
Override CSS variables
|
|
84
|
+
Override CSS variables:
|
|
83
85
|
|
|
84
86
|
```css
|
|
85
87
|
:root {
|
|
@@ -87,104 +89,66 @@ Override CSS variables after importing the stylesheet:
|
|
|
87
89
|
--background-color: #ffffff;
|
|
88
90
|
--border-color: #e5e7eb;
|
|
89
91
|
--base-padding: 0.75rem;
|
|
90
|
-
--base-gap: 0.6rem;
|
|
91
92
|
--font-family: "Inter", system-ui, sans-serif;
|
|
92
93
|
}
|
|
93
94
|
```
|
|
94
95
|
|
|
95
|
-
## CSS
|
|
96
|
+
## CSS Utilities
|
|
96
97
|
|
|
97
|
-
|
|
98
|
+
Use the same utilities that power the components:
|
|
98
99
|
|
|
99
|
-
- Layout
|
|
100
|
-
- Surfaces
|
|
101
|
-
- Typography
|
|
102
|
-
- Buttons
|
|
103
|
-
-
|
|
104
|
-
- Icons: `icon`, `icon-<name>`, `icon-xs|sm|lg|xl`, `icon-default|base|white|secondary|tertiary|quaternary|destructive`
|
|
105
|
-
|
|
106
|
-
Example:
|
|
100
|
+
- **Layout**: `row-container`, `column-container`, `grid-flow`, `gap-xs|sm|md|lg`
|
|
101
|
+
- **Surfaces**: `box`, `card`, `shadow`, `rounded`
|
|
102
|
+
- **Typography**: `text-primary|secondary|tertiary`, `text-sm|base|lg|xl`
|
|
103
|
+
- **Buttons**: `btn`, `btn-flat`, `btn-outline`, `btn-destructive`
|
|
104
|
+
- **Icons**: `icon`, `icon-<name>`, `icon-xs|sm|lg|xl`
|
|
107
105
|
|
|
108
106
|
```js
|
|
109
107
|
import Bunnix from "@bunnix/core";
|
|
110
108
|
const { div, span } = Bunnix;
|
|
111
109
|
|
|
112
|
-
div({ class: "card row-container gap-sm
|
|
113
|
-
span({ class: "icon icon-star icon-base
|
|
114
|
-
span({ class: "text-primary
|
|
110
|
+
div({ class: "card row-container gap-sm" }, [
|
|
111
|
+
span({ class: "icon icon-star icon-base" }),
|
|
112
|
+
span({ class: "text-primary" }, "Custom card")
|
|
115
113
|
]);
|
|
116
114
|
```
|
|
117
115
|
|
|
118
|
-
##
|
|
119
|
-
|
|
120
|
-
- `name`: icon slug (e.g. `star`) or a full class (e.g. `icon-star`). IDEs should autocomplete shipped icon names.
|
|
121
|
-
- `fill`: `default | base | white | secondary | tertiary | quaternary | destructive` or any `icon-*` utility.
|
|
122
|
-
- `size`: `xsmall | small | regular | large | xlarge` or `icon-xs | icon-sm | icon-lg | icon-xl`.
|
|
116
|
+
## Bundler Setup
|
|
123
117
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
Works with webpack, vite, rollup, or any modern ESM bundler. Ensure your bundler:
|
|
119
|
+
- Processes CSS imports
|
|
120
|
+
- Handles CSS `url(...)` for SVG assets
|
|
121
|
+
- Supports `.mjs` extensions
|
|
127
122
|
|
|
123
|
+
Minimal webpack example:
|
|
128
124
|
```js
|
|
129
|
-
import path from "path";
|
|
130
|
-
import { fileURLToPath } from "url";
|
|
131
|
-
import HtmlWebpackPlugin from "html-webpack-plugin";
|
|
132
|
-
|
|
133
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
134
|
-
const __dirname = path.dirname(__filename);
|
|
135
|
-
|
|
136
125
|
export default {
|
|
137
|
-
entry: "./src/index.mjs",
|
|
138
|
-
output: {
|
|
139
|
-
filename: "main.js",
|
|
140
|
-
path: path.resolve(__dirname, "dist"),
|
|
141
|
-
clean: true,
|
|
142
|
-
assetModuleFilename: "images/[hash][ext][query]"
|
|
143
|
-
},
|
|
144
|
-
mode: "development",
|
|
145
126
|
module: {
|
|
146
127
|
rules: [
|
|
147
|
-
{ test:
|
|
148
|
-
{ test:
|
|
128
|
+
{ test: /\.css$/i, use: ["style-loader", "css-loader"] },
|
|
129
|
+
{ test: /\.(png|svg|jpg|jpeg|gif)$/i, type: "asset/resource" }
|
|
149
130
|
]
|
|
150
|
-
},
|
|
151
|
-
resolve: {
|
|
152
|
-
extensions: [".mjs", ".js", ".json"]
|
|
153
|
-
},
|
|
154
|
-
plugins: [
|
|
155
|
-
new HtmlWebpackPlugin({ template: "./public/index.html" })
|
|
156
|
-
],
|
|
157
|
-
devServer: {
|
|
158
|
-
static: { directory: path.join(__dirname, "public") },
|
|
159
|
-
compress: true,
|
|
160
|
-
port: 3000,
|
|
161
|
-
open: true
|
|
162
131
|
}
|
|
163
132
|
};
|
|
164
133
|
```
|
|
165
134
|
|
|
166
|
-
##
|
|
135
|
+
## Icon Attribution
|
|
136
|
+
|
|
137
|
+
- Framework7 Line Icons (MIT) - framework7io
|
|
138
|
+
- Iconcino Interface Icons (CC0 1.0) - Gabriele Malaspina
|
|
139
|
+
|
|
140
|
+
## Project Structure
|
|
167
141
|
|
|
168
142
|
```
|
|
169
143
|
src/
|
|
170
|
-
components/ #
|
|
171
|
-
styles/ #
|
|
144
|
+
components/ # Component library
|
|
145
|
+
styles/ # Design system CSS
|
|
172
146
|
icons/ # SVG assets
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
playgrounds/ #
|
|
147
|
+
utils/ # Utilities (masks, etc.)
|
|
148
|
+
index.mjs # Package exports
|
|
149
|
+
playgrounds/ # Component showcase
|
|
176
150
|
```
|
|
177
151
|
|
|
178
|
-
## Playground
|
|
179
|
-
|
|
180
|
-
The playground consumes `@bunnix/components` directly. Start it with your preferred dev server (whatever you use today), and ensure the CSS import stays at `playgrounds/src/index.mjs`.
|
|
181
|
-
|
|
182
|
-
## Publishing notes
|
|
183
|
-
|
|
184
|
-
- This package targets ESM consumers and ships source files (no dist build).
|
|
185
|
-
- Ensure `files` and `exports` in `package.json` include `src/` and CSS entries.
|
|
186
|
-
- GitHub CI should run with Node that supports ESM (Node 16+ recommended).
|
|
187
|
-
|
|
188
152
|
## License
|
|
189
153
|
|
|
190
154
|
ISC
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import Bunnix from "@bunnix/core";
|
|
2
2
|
import { clampSize, toSizeToken } from "../utils/sizeUtils.mjs";
|
|
3
|
-
const { select, option, div, span } = Bunnix;
|
|
3
|
+
const { select, option, div, label, span } = Bunnix;
|
|
4
4
|
|
|
5
5
|
export default function ComboBox({
|
|
6
6
|
options = [],
|
|
7
7
|
selection,
|
|
8
8
|
size,
|
|
9
|
+
label: labelText,
|
|
9
10
|
class: className = "",
|
|
10
11
|
onChange,
|
|
11
12
|
change,
|
|
@@ -40,7 +41,7 @@ export default function ComboBox({
|
|
|
40
41
|
return option({ value: opt.value }, opt.label ?? opt.value);
|
|
41
42
|
});
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
const selectElement = div({ class: "combobox" }, [
|
|
44
45
|
select({
|
|
45
46
|
class: `combobox-select ${sizeClass} ${className}`.trim(),
|
|
46
47
|
value: selection ?? "",
|
|
@@ -49,4 +50,9 @@ export default function ComboBox({
|
|
|
49
50
|
}, resolvedChildren),
|
|
50
51
|
span({ class: `combobox-chevron icon icon-chevron-down icon-base ${iconSizeClass}`.trim() })
|
|
51
52
|
]);
|
|
53
|
+
|
|
54
|
+
return div({ class: "column-container no-margin shrink-0 gap-0" }, [
|
|
55
|
+
labelText && label({ class: "label select-none" }, labelText),
|
|
56
|
+
selectElement
|
|
57
|
+
]);
|
|
52
58
|
}
|