@bunnix/components 0.10.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/index.d.ts +179 -15
- package/README.md +41 -4
- package/package.json +3 -8
- package/src/core/buttons.css +1 -0
- package/src/core/core.css +16 -2
- package/src/core/dialog.css +3 -1
- package/src/core/dialog.mjs +101 -16
- package/src/core/input.css +202 -0
- package/src/core/inputs.mjs +702 -23
- package/src/core/layout.mjs +1 -2
- package/src/core/media.css +36 -1
- package/src/core/media.mjs +13 -13
- package/src/core/menu.css +10 -29
- package/src/core/menu.mjs +159 -70
- package/src/core/outline.mjs +100 -0
- package/src/core/sidebar.mjs +189 -68
- package/src/core/sliderUtils.mjs +51 -0
- package/src/core/table.css +23 -0
- package/src/core/table.mjs +35 -20
- package/src/core/textareaUtils.mjs +31 -0
- package/src/core/utils.mjs +105 -0
- package/src/font-face/Framework7Icons-Regular.woff2 +0 -0
- package/src/index.mjs +3 -1
- package/src/icons/add-circle.svg +0 -1
- package/src/icons/add.svg +0 -1
- package/src/icons/alt.svg +0 -1
- package/src/icons/archive.svg +0 -1
- package/src/icons/arrow-down.svg +0 -1
- package/src/icons/arrow-left.svg +0 -1
- package/src/icons/arrow-right.svg +0 -1
- package/src/icons/arrow-up.svg +0 -1
- package/src/icons/at.svg +0 -1
- package/src/icons/attestation.svg +0 -1
- package/src/icons/battery-25.svg +0 -1
- package/src/icons/bell.svg +0 -3
- package/src/icons/bookmark.svg +0 -1
- package/src/icons/bot.svg +0 -1
- package/src/icons/bubble.svg +0 -1
- package/src/icons/building.svg +0 -3
- package/src/icons/button.svg +0 -1
- package/src/icons/calculate.svg +0 -1
- package/src/icons/calendar.svg +0 -1
- package/src/icons/captions-bubble.svg +0 -1
- package/src/icons/cart.svg +0 -1
- package/src/icons/chart.svg +0 -1
- package/src/icons/check.svg +0 -1
- package/src/icons/chevron-down.svg +0 -1
- package/src/icons/chevron-left.svg +0 -1
- package/src/icons/chevron-right.svg +0 -1
- package/src/icons/clip.svg +0 -1
- package/src/icons/clock.svg +0 -3
- package/src/icons/close-circle.svg +0 -3
- package/src/icons/close.svg +0 -1
- package/src/icons/cloud-download.svg +0 -1
- package/src/icons/cloud-upload.svg +0 -1
- package/src/icons/cloud.svg +0 -1
- package/src/icons/columns-layout.svg +0 -1
- package/src/icons/command.svg +0 -1
- package/src/icons/cube.svg +0 -1
- package/src/icons/delete.svg +0 -3
- package/src/icons/dollar.svg +0 -3
- package/src/icons/download.svg +0 -1
- package/src/icons/draw.svg +0 -1
- package/src/icons/duplicate.svg +0 -3
- package/src/icons/ear.svg +0 -1
- package/src/icons/edit.svg +0 -1
- package/src/icons/exclamation-mark.svg +0 -1
- package/src/icons/eye-open.svg +0 -1
- package/src/icons/eye.svg +0 -1
- package/src/icons/file-html.svg +0 -1
- package/src/icons/file.svg +0 -3
- package/src/icons/finger.svg +0 -1
- package/src/icons/flag.svg +0 -1
- package/src/icons/folder.svg +0 -1
- package/src/icons/function.svg +0 -1
- package/src/icons/gear.svg +0 -1
- package/src/icons/gift.svg +0 -1
- package/src/icons/globe.svg +0 -3
- package/src/icons/grid.svg +0 -1
- package/src/icons/hammer.svg +0 -1
- package/src/icons/hand.svg +0 -1
- package/src/icons/hare.svg +0 -1
- package/src/icons/heart.svg +0 -3
- package/src/icons/home.svg +0 -3
- package/src/icons/image.svg +0 -1
- package/src/icons/inbox.svg +0 -3
- package/src/icons/info.svg +0 -1
- package/src/icons/key.svg +0 -1
- package/src/icons/lamp.svg +0 -1
- package/src/icons/link.svg +0 -1
- package/src/icons/location.svg +0 -1
- package/src/icons/locker.svg +0 -1
- package/src/icons/login.svg +0 -1
- package/src/icons/logout.svg +0 -3
- package/src/icons/mail.svg +0 -3
- package/src/icons/map.svg +0 -3
- package/src/icons/markup.svg +0 -1
- package/src/icons/merge.svg +0 -1
- package/src/icons/more-horizontal.svg +0 -5
- package/src/icons/more-vertical.svg +0 -5
- package/src/icons/mouse.svg +0 -1
- package/src/icons/music-mic.svg +0 -1
- package/src/icons/paintbrush.svg +0 -1
- package/src/icons/palette.svg +0 -1
- package/src/icons/password.svg +0 -1
- package/src/icons/pencil.svg +0 -1
- package/src/icons/people.svg +0 -3
- package/src/icons/percent.svg +0 -1
- package/src/icons/person-add.svg +0 -1
- package/src/icons/person-remove.svg +0 -1
- package/src/icons/person.svg +0 -4
- package/src/icons/phone.svg +0 -1
- package/src/icons/pin.svg +0 -1
- package/src/icons/question-circle.svg +0 -3
- package/src/icons/remove-circle.svg +0 -1
- package/src/icons/return-arrow.svg +0 -1
- package/src/icons/save.svg +0 -1
- package/src/icons/search.svg +0 -1
- package/src/icons/sections.svg +0 -1
- package/src/icons/send.svg +0 -1
- package/src/icons/share.svg +0 -1
- package/src/icons/shine.svg +0 -1
- package/src/icons/sliders.svg +0 -1
- package/src/icons/star.svg +0 -3
- package/src/icons/staroflife.svg +0 -1
- package/src/icons/storage.svg +0 -1
- package/src/icons/success-circle.svg +0 -3
- package/src/icons/swap.svg +0 -1
- package/src/icons/switch.svg +0 -1
- package/src/icons/sync.svg +0 -3
- package/src/icons/table.svg +0 -3
- package/src/icons/tag.svg +0 -3
- package/src/icons/terminal.svg +0 -1
- package/src/icons/text.svg +0 -1
- package/src/icons/thumb-down.svg +0 -1
- package/src/icons/thumb-up.svg +0 -1
- package/src/icons/timer.svg +0 -3
- package/src/icons/toggle.svg +0 -1
- package/src/icons/trash.svg +0 -1
- package/src/icons/tv-music.svg +0 -1
- package/src/icons/update-page.svg +0 -1
- package/src/icons/upload.svg +0 -1
- package/src/icons/video.svg +0 -1
- package/src/icons/wallet.svg +0 -1
- package/src/icons/wand-stars.svg +0 -1
- package/src/icons/waveform.svg +0 -1
- package/src/icons/window.svg +0 -1
- package/src/utils/iconRegistry.generated.mjs +0 -187
- package/src/utils/iconRegistry.mjs +0 -34
package/@types/index.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ export type StateLike<T = any> = {
|
|
|
16
16
|
|
|
17
17
|
export interface LayoutProps extends BaseProps {
|
|
18
18
|
gap?: number | string;
|
|
19
|
+
fontSize?: number | string;
|
|
20
|
+
overflow?: string;
|
|
21
|
+
overflowX?: string;
|
|
22
|
+
overflowY?: string;
|
|
19
23
|
width?: number | string;
|
|
20
24
|
height?: number | string;
|
|
21
25
|
minWidth?: number | string;
|
|
@@ -24,8 +28,24 @@ export interface LayoutProps extends BaseProps {
|
|
|
24
28
|
maxHeight?: number | string;
|
|
25
29
|
fillWidth?: boolean;
|
|
26
30
|
fillHeight?: boolean;
|
|
31
|
+
zIndex?: number | string;
|
|
32
|
+
border?: "none" | "primary" | "secondary" | "tertiary" | "transparent";
|
|
33
|
+
bgColor?: "primary" | "primary-dimmed" | "secondary" | "success" | "success-dimmed" | "warning" | "warning-dimmed" | "danger" | string;
|
|
34
|
+
margin?: number | string;
|
|
27
35
|
marginX?: number | string;
|
|
28
36
|
marginY?: number | string;
|
|
37
|
+
marginTop?: number | string;
|
|
38
|
+
marginBottom?: number | string;
|
|
39
|
+
marginLeft?: number | string;
|
|
40
|
+
marginRight?: number | string;
|
|
41
|
+
padding?: number | string;
|
|
42
|
+
paddingX?: number | string;
|
|
43
|
+
paddingY?: number | string;
|
|
44
|
+
paddingTop?: number | string;
|
|
45
|
+
paddingBottom?: number | string;
|
|
46
|
+
paddingLeft?: number | string;
|
|
47
|
+
paddingRight?: number | string;
|
|
48
|
+
borderRadius?: number | string;
|
|
29
49
|
}
|
|
30
50
|
|
|
31
51
|
export interface GridColumn {
|
|
@@ -71,7 +91,7 @@ export interface ButtonProps extends LayoutProps {
|
|
|
71
91
|
variant?: "primary" | "secondary" | "tertiary" | "danger" | string;
|
|
72
92
|
disabled?: boolean | StateLike<boolean>;
|
|
73
93
|
outline?: boolean;
|
|
74
|
-
padding?: boolean;
|
|
94
|
+
padding?: number | string | boolean;
|
|
75
95
|
click?: (event?: any) => void;
|
|
76
96
|
}
|
|
77
97
|
|
|
@@ -85,6 +105,7 @@ export interface LinkButtonProps extends LayoutProps {
|
|
|
85
105
|
|
|
86
106
|
export interface TextInputProps extends LayoutProps {
|
|
87
107
|
value?: string | number | Date | StateLike<any>;
|
|
108
|
+
focused?: boolean | StateLike<boolean>;
|
|
88
109
|
placeholder?: string;
|
|
89
110
|
type?: string;
|
|
90
111
|
label?: string;
|
|
@@ -93,6 +114,62 @@ export interface TextInputProps extends LayoutProps {
|
|
|
93
114
|
input?: (event?: any) => void;
|
|
94
115
|
}
|
|
95
116
|
|
|
117
|
+
export interface TextAreaProps extends LayoutProps {
|
|
118
|
+
value?: string | number | StateLike<any>;
|
|
119
|
+
focused?: boolean | StateLike<boolean>;
|
|
120
|
+
placeholder?: string;
|
|
121
|
+
label?: string;
|
|
122
|
+
outline?: boolean;
|
|
123
|
+
disabled?: boolean;
|
|
124
|
+
minLines?: number;
|
|
125
|
+
maxLines?: number;
|
|
126
|
+
input?: (event?: any) => void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export type MenuAnchor =
|
|
130
|
+
| "bottom-left"
|
|
131
|
+
| "bottom-right"
|
|
132
|
+
| "top-left"
|
|
133
|
+
| "top-right"
|
|
134
|
+
| "bottomLeft"
|
|
135
|
+
| "bottomRight"
|
|
136
|
+
| "topLeft"
|
|
137
|
+
| "topRight";
|
|
138
|
+
|
|
139
|
+
export interface MenuItem {
|
|
140
|
+
key?: string;
|
|
141
|
+
text?: string;
|
|
142
|
+
icon?: string;
|
|
143
|
+
action?: (() => void) | null;
|
|
144
|
+
divider?: boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface PickerProps extends LayoutProps {
|
|
148
|
+
value?: string | StateLike<string>;
|
|
149
|
+
options?: MenuItem[] | StateLike<MenuItem[]>;
|
|
150
|
+
label?: string;
|
|
151
|
+
outline?: boolean;
|
|
152
|
+
disabled?: boolean | StateLike<boolean>;
|
|
153
|
+
anchor?: MenuAnchor;
|
|
154
|
+
input?: (event?: any) => void;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface SegmentedPickerItem {
|
|
158
|
+
key: string;
|
|
159
|
+
text: string;
|
|
160
|
+
icon?: string;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface SegmentedPickerProps extends LayoutProps {
|
|
164
|
+
value?: string | StateLike<string>;
|
|
165
|
+
items?: SegmentedPickerItem[] | StateLike<SegmentedPickerItem[]>;
|
|
166
|
+
label?: string;
|
|
167
|
+
outline?: boolean;
|
|
168
|
+
disabled?: boolean;
|
|
169
|
+
input?: (event?: any) => void;
|
|
170
|
+
change?: (event?: any) => void;
|
|
171
|
+
}
|
|
172
|
+
|
|
96
173
|
export interface SelectOption {
|
|
97
174
|
key?: string;
|
|
98
175
|
content?: any;
|
|
@@ -100,7 +177,7 @@ export interface SelectOption {
|
|
|
100
177
|
|
|
101
178
|
export interface SelectProps extends LayoutProps {
|
|
102
179
|
value?: string | StateLike<string>;
|
|
103
|
-
options?: SelectOption[]
|
|
180
|
+
options?: SelectOption[] | StateLike<SelectOption[]>;
|
|
104
181
|
label?: string;
|
|
105
182
|
outline?: boolean;
|
|
106
183
|
disabled?: boolean;
|
|
@@ -117,6 +194,33 @@ export interface CheckBoxProps extends LayoutProps {
|
|
|
117
194
|
input?: (event?: any) => void;
|
|
118
195
|
}
|
|
119
196
|
|
|
197
|
+
export interface SwitchProps extends LayoutProps {
|
|
198
|
+
checked?: boolean | StateLike<boolean>;
|
|
199
|
+
value?: boolean | StateLike<boolean>;
|
|
200
|
+
label?: string;
|
|
201
|
+
outline?: boolean;
|
|
202
|
+
disabled?: boolean;
|
|
203
|
+
change?: (event?: any) => void;
|
|
204
|
+
input?: (event?: any) => void;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface SliderStep {
|
|
208
|
+
value: number;
|
|
209
|
+
label?: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface SliderProps extends LayoutProps {
|
|
213
|
+
value?: number | StateLike<number>;
|
|
214
|
+
min?: number | StateLike<number>;
|
|
215
|
+
max?: number | StateLike<number>;
|
|
216
|
+
step?: number | StateLike<number>;
|
|
217
|
+
steps?: SliderStep[] | StateLike<SliderStep[]>;
|
|
218
|
+
label?: string;
|
|
219
|
+
outline?: boolean;
|
|
220
|
+
disabled?: boolean;
|
|
221
|
+
input?: (event?: any) => void;
|
|
222
|
+
}
|
|
223
|
+
|
|
120
224
|
export interface TableHeader {
|
|
121
225
|
content?: any;
|
|
122
226
|
key?: string;
|
|
@@ -124,20 +228,33 @@ export interface TableHeader {
|
|
|
124
228
|
}
|
|
125
229
|
|
|
126
230
|
export interface TableProps extends LayoutProps {
|
|
127
|
-
headers?: TableHeader[]
|
|
128
|
-
rows?: Array<Record<string, any
|
|
231
|
+
headers?: TableHeader[] | StateLike<TableHeader[]>;
|
|
232
|
+
rows?: Array<Record<string, any>> | StateLike<Array<Record<string, any>>>;
|
|
233
|
+
type?: "regular" | "alternate-rows";
|
|
234
|
+
hideHeaders?: boolean;
|
|
235
|
+
renderCell?: (
|
|
236
|
+
record: Record<string, any>,
|
|
237
|
+
rowIndex: number,
|
|
238
|
+
field: string,
|
|
239
|
+
) => BunnixChild;
|
|
129
240
|
}
|
|
130
241
|
|
|
131
|
-
export interface
|
|
242
|
+
export interface DialogAction {
|
|
132
243
|
text?: string;
|
|
133
244
|
variant?: string;
|
|
134
245
|
action?: (() => void) | null;
|
|
135
246
|
}
|
|
136
247
|
|
|
248
|
+
export interface DialogConfirmation extends DialogAction {}
|
|
249
|
+
|
|
137
250
|
export interface ShowDialogOptions {
|
|
138
|
-
title?: string;
|
|
251
|
+
title?: string | BunnixChild;
|
|
139
252
|
contents?: any[] | any;
|
|
140
|
-
|
|
253
|
+
padding?: number | string;
|
|
254
|
+
width?: number | string;
|
|
255
|
+
height?: number | string;
|
|
256
|
+
secondary?: DialogAction;
|
|
257
|
+
confirmation?: DialogAction;
|
|
141
258
|
}
|
|
142
259
|
|
|
143
260
|
export interface ProgressBarProps extends LayoutProps {
|
|
@@ -145,7 +262,53 @@ export interface ProgressBarProps extends LayoutProps {
|
|
|
145
262
|
color?: "primary" | "primary-dimmed" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "error" | "link" | string;
|
|
146
263
|
}
|
|
147
264
|
|
|
148
|
-
export
|
|
265
|
+
export interface OutlineProps extends LayoutProps {
|
|
266
|
+
/** Always-visible trigger content — accepts any Bunnix node (text, icon, row, etc.) */
|
|
267
|
+
anchor?: BunnixChild;
|
|
268
|
+
/** Collapsible content shown when expanded — accepts any Bunnix node */
|
|
269
|
+
details?: BunnixChild;
|
|
270
|
+
/** Whether to render the chevron toggle icon (default: true) */
|
|
271
|
+
showChevron?: boolean;
|
|
272
|
+
/** Controlled open/closed state — accepts a static boolean (initial value) or StateLike<boolean> for two-way binding */
|
|
273
|
+
open?: boolean | StateLike<boolean>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface MenuProps extends LayoutProps {
|
|
277
|
+
items?: MenuItem[] | StateLike<MenuItem[]>;
|
|
278
|
+
trigger?:
|
|
279
|
+
| BunnixChild
|
|
280
|
+
| ((state: { isOpen: boolean; toggle: () => void }) => BunnixChild);
|
|
281
|
+
anchor?: MenuAnchor;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** Sidebar navigation item configuration */
|
|
285
|
+
export interface SidebarItem {
|
|
286
|
+
/** Unique identifier for the sidebar item */
|
|
287
|
+
key: string;
|
|
288
|
+
/** Display text for the item */
|
|
289
|
+
text: string;
|
|
290
|
+
/** Optional official Framework7 icon name */
|
|
291
|
+
icon?: string;
|
|
292
|
+
/** If true, renders as a section header instead of a clickable item */
|
|
293
|
+
isHeader?: boolean;
|
|
294
|
+
/** Optional nested child items rendered below this item when expanded */
|
|
295
|
+
children?: SidebarItem[];
|
|
296
|
+
/** Initial expanded state for items that have nested children */
|
|
297
|
+
expanded?: boolean;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Props for the Sidebar component */
|
|
301
|
+
export interface SidebarProps extends LayoutProps {
|
|
302
|
+
/** Array of sidebar items or a state object containing items. Supports dynamic updates via StateLike */
|
|
303
|
+
items?: SidebarItem[] | StateLike<SidebarItem[]>;
|
|
304
|
+
/** Currently selected item key, null for no selection, or a state object. Updates on item click */
|
|
305
|
+
selection?: string | null | StateLike<string | null>;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export type Component<P = BaseProps> = {
|
|
309
|
+
(...children: BunnixChildren[]): any;
|
|
310
|
+
(props: P, ...children: BunnixChildren[]): any;
|
|
311
|
+
};
|
|
149
312
|
|
|
150
313
|
export const Column: Component<LayoutProps>;
|
|
151
314
|
export const Row: Component<LayoutProps>;
|
|
@@ -164,14 +327,20 @@ export const Button: Component<ButtonProps>;
|
|
|
164
327
|
export const LinkButton: Component<LinkButtonProps>;
|
|
165
328
|
|
|
166
329
|
export const TextInput: Component<TextInputProps>;
|
|
330
|
+
export const TextArea: Component<TextAreaProps>;
|
|
167
331
|
export const Select: Component<SelectProps>;
|
|
168
332
|
export const CheckBox: Component<CheckBoxProps>;
|
|
333
|
+
export const Switch: Component<SwitchProps>;
|
|
334
|
+
export const SegmentedPicker: Component<SegmentedPickerProps>;
|
|
335
|
+
export const Slider: Component<SliderProps>;
|
|
169
336
|
|
|
170
337
|
export const Table: Component<TableProps>;
|
|
171
338
|
export const Code: Component<BaseProps & { html?: string; language?: string }>;
|
|
172
339
|
|
|
173
|
-
export const Sidebar: Component<
|
|
174
|
-
export const
|
|
340
|
+
export const Sidebar: Component<SidebarProps>;
|
|
341
|
+
export const Picker: Component<PickerProps>;
|
|
342
|
+
export const Menu: Component<MenuProps>;
|
|
343
|
+
export const Outline: Component<OutlineProps>;
|
|
175
344
|
|
|
176
345
|
export function useDialog(): {
|
|
177
346
|
Dialog: Component<BaseProps>;
|
|
@@ -184,8 +353,3 @@ declare module "@bunnix/components/styles.css" {
|
|
|
184
353
|
const content: string;
|
|
185
354
|
export default content;
|
|
186
355
|
}
|
|
187
|
-
|
|
188
|
-
declare module "@bunnix/components/styles" {
|
|
189
|
-
const content: string;
|
|
190
|
-
export default content;
|
|
191
|
-
}
|
package/README.md
CHANGED
|
@@ -28,6 +28,10 @@ import {
|
|
|
28
28
|
Text,
|
|
29
29
|
Button,
|
|
30
30
|
TextInput,
|
|
31
|
+
TextArea,
|
|
32
|
+
Switch,
|
|
33
|
+
Slider,
|
|
34
|
+
Picker,
|
|
31
35
|
ProgressBar,
|
|
32
36
|
} from "@bunnix/components";
|
|
33
37
|
|
|
@@ -40,19 +44,52 @@ Column(
|
|
|
40
44
|
Button({ variant: "tertiary" }, "Cancel"),
|
|
41
45
|
),
|
|
42
46
|
TextInput({ label: "Name", placeholder: "Type here" }),
|
|
47
|
+
TextArea({
|
|
48
|
+
label: "Notes",
|
|
49
|
+
minLines: 3,
|
|
50
|
+
maxLines: 6,
|
|
51
|
+
placeholder: "Write more...",
|
|
52
|
+
}),
|
|
53
|
+
Switch({ checked: false, label: "Enable sync" }),
|
|
54
|
+
Picker({
|
|
55
|
+
value: "calendar",
|
|
56
|
+
options: [
|
|
57
|
+
{ key: "calendar", text: "Calendar", icon: "calendar" },
|
|
58
|
+
{ key: "messages", text: "Messages", icon: "chat_bubble_2" },
|
|
59
|
+
],
|
|
60
|
+
}),
|
|
61
|
+
Slider({ min: 0, max: 100, step: 5, value: 50 }),
|
|
43
62
|
ProgressBar({ value: 65, color: "success" }),
|
|
44
63
|
);
|
|
45
64
|
```
|
|
46
65
|
|
|
66
|
+
## Layout Border Prop
|
|
67
|
+
|
|
68
|
+
Layout primitives accept a resolved `border` prop:
|
|
69
|
+
|
|
70
|
+
`"none" | "primary" | "secondary" | "tertiary" | "transparent"`
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
Column(
|
|
74
|
+
{ gap: 8 },
|
|
75
|
+
Column({ border: "primary", padding: "regular", radius: "regular" }, "Primary"),
|
|
76
|
+
Column({ border: "secondary", padding: "regular", radius: "regular" }, "Secondary"),
|
|
77
|
+
Column({ border: "tertiary", padding: "regular", radius: "regular" }, "Tertiary"),
|
|
78
|
+
Column({ border: "transparent", padding: "regular", radius: "regular" }, "Transparent"),
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
These border tokens automatically adapt to light and dark color schemes, with `secondary` and `tertiary` rendered as softer tones of the primary border.
|
|
83
|
+
|
|
47
84
|
## Exported API
|
|
48
85
|
|
|
49
86
|
- Layout: `Column`, `Row`, `Spacer`, `Grid`
|
|
50
87
|
- Typography: `Heading`, `Text`
|
|
51
88
|
- Media: `Media`, `Icon`, `Spinner`, `Avatar`
|
|
52
89
|
- Buttons: `Button`, `LinkButton`
|
|
53
|
-
- Inputs: `TextInput`, `Select`, `CheckBox`
|
|
90
|
+
- Inputs: `TextInput`, `TextArea`, `Select`, `CheckBox`, `Switch`, `Slider`
|
|
54
91
|
- Data display: `Table`, `Code`
|
|
55
|
-
- Navigation: `Sidebar`, `Menu`
|
|
92
|
+
- Navigation: `Sidebar`, `Picker`, `Menu`
|
|
56
93
|
- Feedback: `useDialog`, `ProgressBar`
|
|
57
94
|
|
|
58
95
|
## ProgressBar Colors
|
|
@@ -78,9 +115,9 @@ Primary consumer stylesheet:
|
|
|
78
115
|
|
|
79
116
|
- `@bunnix/components/styles.css`
|
|
80
117
|
|
|
81
|
-
|
|
118
|
+
Canonical public stylesheet:
|
|
82
119
|
|
|
83
|
-
- `@bunnix/components/
|
|
120
|
+
- `@bunnix/components/styles.css`
|
|
84
121
|
- `@bunnix/components/src/core/input.css`
|
|
85
122
|
- `@bunnix/components/src/core/table.css`
|
|
86
123
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunnix/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Bunnix components: a set of bunnix ready components for modern web apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bunnix",
|
|
@@ -29,9 +29,7 @@
|
|
|
29
29
|
"types": "./@types/index.d.ts",
|
|
30
30
|
"default": "./src/index.mjs"
|
|
31
31
|
},
|
|
32
|
-
"./styles": "./src/core/core.css"
|
|
33
|
-
"./core.css": "./src/core/core.css",
|
|
34
|
-
"./icons/*": "./src/icons/*"
|
|
32
|
+
"./styles.css": "./src/core/core.css"
|
|
35
33
|
},
|
|
36
34
|
"sideEffects": [
|
|
37
35
|
"./src/core/*.css"
|
|
@@ -41,10 +39,7 @@
|
|
|
41
39
|
"@types"
|
|
42
40
|
],
|
|
43
41
|
"scripts": {
|
|
44
|
-
"test": "node --test"
|
|
45
|
-
"sanitize:icons": "node scripts/sanitizeSvgs.mjs",
|
|
46
|
-
"prebuild": "npm run sanitize:icons && node scripts/generateIconRegistry.mjs",
|
|
47
|
-
"build:icons": "npm run sanitize:icons && node scripts/generateIconRegistry.mjs"
|
|
42
|
+
"test": "node --test"
|
|
48
43
|
},
|
|
49
44
|
"peerDependencies": {
|
|
50
45
|
"@bunnix/core": "^0.9.4"
|
package/src/core/buttons.css
CHANGED
package/src/core/core.css
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
--color-bg-secondary: light-dark(#EDEDED, #1A1A1A);
|
|
26
26
|
|
|
27
27
|
--color-border-primary: light-dark(#D2D2D2, #3D3D3D);
|
|
28
|
+
--color-border-secondary: light-dark(#E0E0E0, #2E2E2E);
|
|
29
|
+
--color-border-tertiary: light-dark(#ECECEC, #242424);
|
|
28
30
|
--color-outline: light-dark(#000, #fff);
|
|
29
31
|
--color-outline-dimmed: light-dark(#444, #555);
|
|
30
32
|
|
|
@@ -398,12 +400,14 @@ body {
|
|
|
398
400
|
}
|
|
399
401
|
|
|
400
402
|
/* Layout positioning */
|
|
401
|
-
.sticky-top
|
|
403
|
+
.sticky-top,
|
|
404
|
+
[sticky="top"] {
|
|
402
405
|
position: sticky;
|
|
403
406
|
top: 0;
|
|
404
407
|
}
|
|
405
408
|
|
|
406
|
-
.sticky-bottom
|
|
409
|
+
.sticky-bottom,
|
|
410
|
+
[sticky="bottom"] {
|
|
407
411
|
position: sticky;
|
|
408
412
|
bottom: 0;
|
|
409
413
|
}
|
|
@@ -492,6 +496,16 @@ body {
|
|
|
492
496
|
border: 1px solid var(--color-border-primary);
|
|
493
497
|
}
|
|
494
498
|
|
|
499
|
+
.border-secondary,
|
|
500
|
+
[border="secondary"] {
|
|
501
|
+
border: 1px solid var(--color-border-secondary);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.border-tertiary,
|
|
505
|
+
[border="tertiary"] {
|
|
506
|
+
border: 1px solid var(--color-border-tertiary);
|
|
507
|
+
}
|
|
508
|
+
|
|
495
509
|
.border-transparent,
|
|
496
510
|
[border="transparent"] {
|
|
497
511
|
border: 1px solid transparent;
|
package/src/core/dialog.css
CHANGED
package/src/core/dialog.mjs
CHANGED
|
@@ -23,6 +23,14 @@ import { Icon } from "./media.mjs";
|
|
|
23
23
|
|
|
24
24
|
const { dialog } = Bunnix;
|
|
25
25
|
|
|
26
|
+
const resolveDialogSize = (value) =>
|
|
27
|
+
typeof value === "number" ? `${value}px` : value;
|
|
28
|
+
|
|
29
|
+
const renderDialogTitle = (title) =>
|
|
30
|
+
typeof title === "string"
|
|
31
|
+
? Heading({ h3: true, flexShrink: 0 }, title)
|
|
32
|
+
: title;
|
|
33
|
+
|
|
26
34
|
/**
|
|
27
35
|
* Creates a dialog controller and render component.
|
|
28
36
|
*
|
|
@@ -35,6 +43,10 @@ export const useDialog = () => {
|
|
|
35
43
|
const dialogState = useState({
|
|
36
44
|
title: "",
|
|
37
45
|
contents: [],
|
|
46
|
+
padding: "regular",
|
|
47
|
+
width: null,
|
|
48
|
+
height: null,
|
|
49
|
+
secondary: null,
|
|
38
50
|
confirmation: { text: "OK", variant: "primary" },
|
|
39
51
|
});
|
|
40
52
|
const dialogRef = useRef(null);
|
|
@@ -50,28 +62,84 @@ export const useDialog = () => {
|
|
|
50
62
|
dialogRef.current?.close();
|
|
51
63
|
};
|
|
52
64
|
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
return Show(
|
|
66
|
+
dialogState,
|
|
67
|
+
(state) => (
|
|
68
|
+
dialog(
|
|
69
|
+
{
|
|
70
|
+
ref: dialogRef,
|
|
71
|
+
cancel: closeDialog,
|
|
72
|
+
class: `dialog`,
|
|
73
|
+
style: {
|
|
74
|
+
...(state.width ? { width: resolveDialogSize(state.width) } : {}),
|
|
75
|
+
...(state.height ? { height: resolveDialogSize(state.height) } : {}),
|
|
76
|
+
},
|
|
77
|
+
},
|
|
62
78
|
Column(
|
|
63
|
-
{
|
|
79
|
+
{
|
|
80
|
+
gap: 12,
|
|
81
|
+
minWidth: state.width ? undefined : 420,
|
|
82
|
+
maxWidth: state.width ? undefined : 580,
|
|
83
|
+
maxHeight: state.height ? undefined : "calc(100vh - 32px)",
|
|
84
|
+
...(state.width ? { fillWidth: true } : {}),
|
|
85
|
+
...(state.height ? { fillHeight: true } : {}),
|
|
86
|
+
minHeight: 0,
|
|
87
|
+
overflow: "hidden",
|
|
88
|
+
},
|
|
64
89
|
Row(
|
|
65
|
-
{
|
|
66
|
-
|
|
90
|
+
{
|
|
91
|
+
gap: 24,
|
|
92
|
+
alignItems: "center",
|
|
93
|
+
paddingX: state.padding,
|
|
94
|
+
paddingTop: state.padding,
|
|
95
|
+
flexShrink: 0,
|
|
96
|
+
},
|
|
97
|
+
renderDialogTitle(state.title),
|
|
67
98
|
Spacer(),
|
|
68
99
|
Button(
|
|
69
100
|
{ variant: "tertiary", click: closeDialog },
|
|
70
|
-
Icon({ name: "
|
|
101
|
+
Icon({ name: "xmark", color: "secondary", size: 20 }),
|
|
102
|
+
),
|
|
103
|
+
),
|
|
104
|
+
state.contents.length > 0 && Column(
|
|
105
|
+
{
|
|
106
|
+
flexGrow: 1,
|
|
107
|
+
minHeight: 0,
|
|
108
|
+
},
|
|
109
|
+
Column(
|
|
110
|
+
{
|
|
111
|
+
gap: 12,
|
|
112
|
+
paddingX: state.padding,
|
|
113
|
+
fillHeight: true,
|
|
114
|
+
minHeight: 0,
|
|
115
|
+
style: {
|
|
116
|
+
overflowY: "auto",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
...state.contents,
|
|
71
120
|
),
|
|
72
121
|
),
|
|
73
|
-
state.contents.length > 0 && Column(...state.contents),
|
|
74
122
|
Row(
|
|
123
|
+
{
|
|
124
|
+
paddingX: state.padding,
|
|
125
|
+
paddingBottom: state.padding,
|
|
126
|
+
bgColor: "primary",
|
|
127
|
+
flexShrink: 0,
|
|
128
|
+
},
|
|
129
|
+
...(state.secondary ? [
|
|
130
|
+
Button(
|
|
131
|
+
{
|
|
132
|
+
minWidth: 80,
|
|
133
|
+
variant: state.secondary.variant,
|
|
134
|
+
click: () => {
|
|
135
|
+
let action = state.secondary.action;
|
|
136
|
+
(action) && action();
|
|
137
|
+
closeDialog();
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
state.secondary.text
|
|
141
|
+
),
|
|
142
|
+
] : []),
|
|
75
143
|
Spacer(),
|
|
76
144
|
Button(
|
|
77
145
|
{
|
|
@@ -86,7 +154,7 @@ export const useDialog = () => {
|
|
|
86
154
|
state.confirmation.text
|
|
87
155
|
)
|
|
88
156
|
),
|
|
89
|
-
)
|
|
157
|
+
),
|
|
90
158
|
)
|
|
91
159
|
)
|
|
92
160
|
);
|
|
@@ -95,8 +163,15 @@ export const useDialog = () => {
|
|
|
95
163
|
* Opens dialog with provided content and confirmation behavior.
|
|
96
164
|
*
|
|
97
165
|
* @param {Object} [config] - Dialog config
|
|
98
|
-
* @param {string} [config.title] - Dialog title text
|
|
166
|
+
* @param {string|*} [config.title] - Dialog title text or custom node
|
|
99
167
|
* @param {Array|*} [config.contents=[]] - Renderable content block(s)
|
|
168
|
+
* @param {number|string} [config.padding="regular"] - Shared dialog section padding
|
|
169
|
+
* @param {number|string} [config.width] - Fixed dialog width
|
|
170
|
+
* @param {number|string} [config.height] - Fixed dialog height
|
|
171
|
+
* @param {Object} [config.secondary] - Optional secondary button config
|
|
172
|
+
* @param {string} [config.secondary.text="Cancel"] - Secondary label
|
|
173
|
+
* @param {string} [config.secondary.variant="secondary"] - Button variant
|
|
174
|
+
* @param {Function|null} [config.secondary.action=null] - Action run before close
|
|
100
175
|
* @param {Object} [config.confirmation] - Confirmation button config
|
|
101
176
|
* @param {string} [config.confirmation.text=\"OK\"] - Confirmation label
|
|
102
177
|
* @param {string} [config.confirmation.variant=\"primary\"] - Button variant
|
|
@@ -106,14 +181,24 @@ export const useDialog = () => {
|
|
|
106
181
|
showDialog: ({
|
|
107
182
|
title,
|
|
108
183
|
contents = [],
|
|
184
|
+
padding = "regular",
|
|
185
|
+
width = null,
|
|
186
|
+
height = null,
|
|
187
|
+
secondary,
|
|
109
188
|
confirmation,
|
|
110
189
|
} = {}) => {
|
|
190
|
+
const defaultSecondary = { text: "Cancel", variant: "secondary", action: null };
|
|
111
191
|
const defaultConfirmation = { text: "OK", variant: "primary", action: null };
|
|
192
|
+
const mergedSecondary = secondary ? { ...defaultSecondary, ...secondary } : null;
|
|
112
193
|
const mergedConfirmation = { ...defaultConfirmation, ...confirmation };
|
|
113
194
|
|
|
114
195
|
dialogState.set({
|
|
115
196
|
title,
|
|
116
197
|
contents: Array.isArray(contents) ? contents : [contents],
|
|
198
|
+
padding,
|
|
199
|
+
width,
|
|
200
|
+
height,
|
|
201
|
+
secondary: mergedSecondary,
|
|
117
202
|
confirmation: mergedConfirmation,
|
|
118
203
|
});
|
|
119
204
|
dialogRef.current?.showModal();
|