mithril-materialized 3.1.0 → 3.2.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/dist/components.css +3 -0
- package/dist/core.css +136 -14
- package/dist/dropdown.d.ts +8 -5
- package/dist/forms.css +136 -0
- package/dist/index.css +144 -14
- package/dist/index.esm.js +604 -399
- package/dist/index.js +604 -398
- package/dist/index.min.css +2 -2
- package/dist/index.umd.js +604 -398
- package/dist/input-options.d.ts +10 -2
- package/dist/input.d.ts +1 -1
- package/dist/option.d.ts +16 -3
- package/dist/radio.d.ts +11 -5
- package/dist/search-select.d.ts +14 -20
- package/dist/select.d.ts +10 -6
- package/dist/switch.d.ts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +5 -4
- package/sass/components/_dropdown.scss +3 -0
- package/sass/components/forms/_checkboxes.scss +10 -6
- package/sass/components/forms/_forms.scss +0 -15
- package/sass/components/forms/_select.scss +164 -0
- package/sass/components/forms/_switches.scss +1 -0
package/dist/input-options.d.ts
CHANGED
|
@@ -6,8 +6,16 @@ export interface InputAttrs<T = string> extends Attributes {
|
|
|
6
6
|
id?: string;
|
|
7
7
|
/** Unique key for use of the element in an array. */
|
|
8
8
|
key?: string | number;
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Current value of the input field. If provided along with `oninput`, the component operates in controlled mode
|
|
11
|
+
* where the parent manages the state. The parent must update this value in response to `oninput` callbacks.
|
|
12
|
+
*/
|
|
13
|
+
value?: T;
|
|
14
|
+
/**
|
|
15
|
+
* Initial value for uncontrolled mode. Only used when `value` and `oninput` are not provided.
|
|
16
|
+
* In uncontrolled mode, the component manages its own internal state.
|
|
17
|
+
*/
|
|
18
|
+
defaultValue?: T;
|
|
11
19
|
/**
|
|
12
20
|
* The autocomplete property sets or returns the value of the autocomplete
|
|
13
21
|
* attribute in a text field. When autocomplete is on, the browser automatically
|
package/dist/input.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface FileInputAttrs extends Attributes {
|
|
|
26
26
|
/** Displayed on the button, @default File */
|
|
27
27
|
label?: string;
|
|
28
28
|
/** Current value of the file input, write only */
|
|
29
|
-
|
|
29
|
+
value?: string;
|
|
30
30
|
/** Adds a placeholder message */
|
|
31
31
|
placeholder?: string;
|
|
32
32
|
/** If true, upload multiple files */
|
package/dist/option.d.ts
CHANGED
|
@@ -39,9 +39,9 @@ export interface OptionsAttrs<T extends string | number> extends Attributes {
|
|
|
39
39
|
/** The options that you have */
|
|
40
40
|
options: InputOption<T>[];
|
|
41
41
|
/** Event handler that is called when an option is changed */
|
|
42
|
-
onchange?: (
|
|
43
|
-
/**
|
|
44
|
-
|
|
42
|
+
onchange?: (checkedIds: T[]) => void;
|
|
43
|
+
/** Currently selected ids. This property controls the component state and should be updated externally to change selection programmatically. */
|
|
44
|
+
checkedId?: T | T[];
|
|
45
45
|
/** Optional description */
|
|
46
46
|
description?: string;
|
|
47
47
|
/** Optional CSS that is added to the input checkbox, e.g. if you add col s4, the items will be put inline */
|
|
@@ -56,6 +56,19 @@ export interface OptionsAttrs<T extends string | number> extends Attributes {
|
|
|
56
56
|
layout?: 'vertical' | 'horizontal';
|
|
57
57
|
/** If true, show select all/none buttons */
|
|
58
58
|
showSelectAll?: boolean;
|
|
59
|
+
/** Text for select all button */
|
|
60
|
+
selectAllText?: string;
|
|
61
|
+
/** Text for select none button */
|
|
62
|
+
selectNoneText?: string;
|
|
59
63
|
}
|
|
64
|
+
/** Reusable layout component for rendering options horizontally or vertically */
|
|
65
|
+
export declare const OptionsList: Component<{
|
|
66
|
+
options: Array<{
|
|
67
|
+
component: any;
|
|
68
|
+
props: any;
|
|
69
|
+
key: string | number;
|
|
70
|
+
}>;
|
|
71
|
+
layout: 'vertical' | 'horizontal';
|
|
72
|
+
}>;
|
|
60
73
|
/** A list of checkboxes */
|
|
61
74
|
export declare const Options: <T extends string | number>() => Component<OptionsAttrs<T>>;
|
package/dist/radio.d.ts
CHANGED
|
@@ -7,12 +7,18 @@ export interface RadioButtonsAttrs<T extends string | number> extends Attributes
|
|
|
7
7
|
label?: string;
|
|
8
8
|
/** The options that you have */
|
|
9
9
|
options: InputOption<T>[];
|
|
10
|
-
/** Event handler that is called when an option is changed */
|
|
11
|
-
onchange
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
/** Event handler that is called when an option is changed. Optional for uncontrolled mode. */
|
|
11
|
+
onchange?: (id: T) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Currently selected id for controlled mode. If provided along with `onchange`, the component operates in controlled mode
|
|
14
|
+
* where the parent manages the state. The parent must update this value in response to `onchange` callbacks.
|
|
15
|
+
*/
|
|
15
16
|
checkedId?: T;
|
|
17
|
+
/**
|
|
18
|
+
* Default selected id for uncontrolled mode. Only used when `checkedId` and `onchange` are not provided.
|
|
19
|
+
* The component will manage its own internal state in uncontrolled mode.
|
|
20
|
+
*/
|
|
21
|
+
defaultCheckedId?: T;
|
|
16
22
|
/** Optional description */
|
|
17
23
|
description?: string;
|
|
18
24
|
/** If true, start on a new row */
|
package/dist/search-select.d.ts
CHANGED
|
@@ -1,38 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { Component } from 'mithril';
|
|
2
|
+
import { SelectAttrs } from './select';
|
|
3
|
+
import { InputOption } from './option';
|
|
4
|
+
export interface SearchSelectI18n {
|
|
5
|
+
/** Text shown when no options match the search */
|
|
6
|
+
noOptionsFound?: string;
|
|
7
|
+
/** Prefix for adding new option */
|
|
8
|
+
addNewPrefix?: string;
|
|
6
9
|
}
|
|
7
|
-
export interface SearchSelectAttrs<T extends string | number> extends
|
|
8
|
-
/** Options to display in the select */
|
|
9
|
-
options?: Option<T>[];
|
|
10
|
-
/** Initial value */
|
|
11
|
-
initialValue?: T[];
|
|
12
|
-
/** Callback when user selects or deselects an option */
|
|
13
|
-
onchange?: (selectedOptions: T[]) => void | Promise<void>;
|
|
10
|
+
export interface SearchSelectAttrs<T extends string | number> extends SelectAttrs<T> {
|
|
14
11
|
/** Callback when user creates a new option: should return new ID */
|
|
15
|
-
oncreateNewOption?: (term: string) =>
|
|
16
|
-
/** Label for the search select, no default */
|
|
17
|
-
label?: string;
|
|
18
|
-
/** Placeholder text for the search input, no default */
|
|
19
|
-
placeholder?: string;
|
|
12
|
+
oncreateNewOption?: (term: string) => InputOption<T> | Promise<InputOption<T>>;
|
|
20
13
|
/** Placeholder text for the search input, default 'Search options...' */
|
|
21
14
|
searchPlaceholder?: string;
|
|
22
15
|
/** When no options are left, displays this text, default 'No options found' */
|
|
23
16
|
noOptionsFound?: string;
|
|
24
17
|
/** Max height of the dropdown menu, default '25rem' */
|
|
25
18
|
maxHeight?: string;
|
|
19
|
+
/** Internationalization options */
|
|
20
|
+
i18n?: SearchSelectI18n;
|
|
26
21
|
}
|
|
27
22
|
interface SearchSelectState<T extends string | number> {
|
|
23
|
+
id: string;
|
|
28
24
|
isOpen: boolean;
|
|
29
|
-
selectedOptions: Option<T>[];
|
|
30
25
|
searchTerm: string;
|
|
31
|
-
options: Option<T>[];
|
|
32
26
|
inputRef: HTMLElement | null;
|
|
33
27
|
dropdownRef: HTMLElement | null;
|
|
34
28
|
focusedIndex: number;
|
|
35
|
-
|
|
29
|
+
internalSelectedIds: T[];
|
|
36
30
|
}
|
|
37
31
|
/**
|
|
38
32
|
* Mithril Factory Component for Multi-Select Dropdown with search
|
package/dist/select.d.ts
CHANGED
|
@@ -3,15 +3,19 @@ import { InputOption } from './option';
|
|
|
3
3
|
export interface SelectAttrs<T extends string | number> extends Attributes {
|
|
4
4
|
/** Options to select from */
|
|
5
5
|
options: InputOption<T>[];
|
|
6
|
-
/** Called when the
|
|
7
|
-
onchange
|
|
6
|
+
/** Called when the selection changes, contains all selected (checked) ids as an array */
|
|
7
|
+
onchange?: (checkedIds: T[]) => void;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Currently selected id or ids. For controlled mode, pass the current selection and provide onchange.
|
|
10
|
+
* For single select, pass a single value or array with one item.
|
|
11
|
+
* For multiple select, pass an array of selected ids.
|
|
11
12
|
*/
|
|
12
13
|
checkedId?: T | T[];
|
|
13
|
-
/**
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Default selected id or ids for uncontrolled mode. Only used when checkedId and onchange are not provided.
|
|
16
|
+
* The component will manage its own internal state in uncontrolled mode.
|
|
17
|
+
*/
|
|
18
|
+
defaultCheckedId?: T | T[];
|
|
15
19
|
/** Select a single option or multiple options */
|
|
16
20
|
multiple?: boolean;
|
|
17
21
|
/** Optional label. */
|
package/dist/switch.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface SwitchOptions extends Partial<InputAttrs<boolean>> {
|
|
|
5
5
|
left?: string;
|
|
6
6
|
/** Right text label */
|
|
7
7
|
right?: string;
|
|
8
|
-
/** If checked is true, the switch is set in the right position.
|
|
8
|
+
/** If checked is true, the switch is set in the right position. */
|
|
9
9
|
checked?: boolean;
|
|
10
10
|
}
|
|
11
11
|
/** Component to display a switch with two values. */
|
package/dist/types.d.ts
CHANGED
|
@@ -122,7 +122,7 @@ export type InputValue<T extends InputType> = T extends 'number' | 'range' ? num
|
|
|
122
122
|
/**
|
|
123
123
|
* Icon class using template literal types for better IntelliSense
|
|
124
124
|
*/
|
|
125
|
-
export type IconClass = ComponentSize | MaterialPosition | `${ComponentSize} ${MaterialPosition}
|
|
125
|
+
export type IconClass = ComponentSize | MaterialPosition | `${ComponentSize} ${MaterialPosition}` | string;
|
|
126
126
|
/**
|
|
127
127
|
* Modal type discriminated union
|
|
128
128
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mithril-materialized",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "A materialize library for mithril.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"type": "git",
|
|
65
65
|
"url": "git://github.com/erikvullings/mithril-materialized.git"
|
|
66
66
|
},
|
|
67
|
+
"homepage": "https://erikvullings.github.io/mithril-materialized/index.html#!/home",
|
|
67
68
|
"keywords": [
|
|
68
69
|
"mithril",
|
|
69
70
|
"materialize-css"
|
|
@@ -85,11 +86,11 @@
|
|
|
85
86
|
"concurrently": "^9.2.1",
|
|
86
87
|
"express": "^5.1.0",
|
|
87
88
|
"identity-obj-proxy": "^3.0.0",
|
|
88
|
-
"jest": "^30.
|
|
89
|
-
"jest-environment-jsdom": "^30.
|
|
89
|
+
"jest": "^30.1.1",
|
|
90
|
+
"jest-environment-jsdom": "^30.1.1",
|
|
90
91
|
"js-yaml": "^4.1.0",
|
|
91
92
|
"rimraf": "^6.0.1",
|
|
92
|
-
"rollup": "^4.
|
|
93
|
+
"rollup": "^4.49.0",
|
|
93
94
|
"rollup-plugin-postcss": "^4.0.2",
|
|
94
95
|
"sass": "^1.91.0",
|
|
95
96
|
"ts-jest": "^29.4.1",
|
|
@@ -4,15 +4,19 @@
|
|
|
4
4
|
========================================================================== */
|
|
5
5
|
|
|
6
6
|
/* Remove default checkbox */
|
|
7
|
-
[type=
|
|
8
|
-
[type=
|
|
7
|
+
[type=checkbox]:not(:checked),
|
|
8
|
+
[type=checkbox]:checked {
|
|
9
9
|
position: absolute;
|
|
10
10
|
opacity: 0;
|
|
11
11
|
pointer-events: none;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
[type=checkbox]:disabled + span {
|
|
15
|
+
color: var(--mm-text-disabled, rgba(0, 0, 0, 0.42));
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
// Checkbox Styles
|
|
15
|
-
[type=
|
|
19
|
+
[type=checkbox] {
|
|
16
20
|
// Text Label Style
|
|
17
21
|
+ span:not(.lever) {
|
|
18
22
|
position: relative;
|
|
@@ -61,7 +65,7 @@
|
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
[type=
|
|
68
|
+
[type=checkbox]:checked {
|
|
65
69
|
+ span:not(.lever):before {
|
|
66
70
|
top: -4px;
|
|
67
71
|
left: -5px;
|
|
@@ -83,7 +87,7 @@
|
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
/* Indeterminate checkbox */
|
|
86
|
-
[type=
|
|
90
|
+
[type=checkbox]:indeterminate {
|
|
87
91
|
+ span:not(.lever):before {
|
|
88
92
|
top: -11px;
|
|
89
93
|
left: -12px;
|
|
@@ -106,7 +110,7 @@
|
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
// Filled in Style
|
|
109
|
-
[type=
|
|
113
|
+
[type=checkbox].filled-in {
|
|
110
114
|
// General
|
|
111
115
|
+ span:not(.lever):after {
|
|
112
116
|
border-radius: 2px;
|
|
@@ -7,18 +7,3 @@
|
|
|
7
7
|
@use "file-input";
|
|
8
8
|
@use "range"; // Standard HTML5 range input styles
|
|
9
9
|
@use "form-groups";
|
|
10
|
-
|
|
11
|
-
// Remove Focus Boxes
|
|
12
|
-
select:focus {
|
|
13
|
-
outline: variables.$select-focus;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
button:focus {
|
|
17
|
-
outline: none;
|
|
18
|
-
background-color: variables.$button-background-focus;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
label {
|
|
22
|
-
font-size: variables.$label-font-size;
|
|
23
|
-
color: variables.$input-border-color;
|
|
24
|
-
}
|
|
@@ -191,3 +191,167 @@ body.keyboard-focused {
|
|
|
191
191
|
padding-left: 1rem;
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
+
|
|
195
|
+
/* Dark theme overrides to ensure proper colors */
|
|
196
|
+
[data-theme="dark"] {
|
|
197
|
+
.select-dropdown.dropdown-content li:hover,
|
|
198
|
+
.dropdown-content li:hover,
|
|
199
|
+
.dropdown-content li.active {
|
|
200
|
+
background-color: #444 !important;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.chip {
|
|
204
|
+
background-color: #424242 !important;
|
|
205
|
+
color: var(--mm-text-secondary) !important;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* Auto dark mode support */
|
|
210
|
+
@media (prefers-color-scheme: dark) {
|
|
211
|
+
:root:not([data-theme="light"]) {
|
|
212
|
+
.select-dropdown.dropdown-content li:hover,
|
|
213
|
+
.dropdown-content li:hover,
|
|
214
|
+
.dropdown-content li.active {
|
|
215
|
+
background-color: #444 !important;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.chip {
|
|
219
|
+
background-color: #424242 !important;
|
|
220
|
+
color: var(--mm-text-secondary) !important;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* SearchSelect Specific Styles
|
|
226
|
+
========================================================================== */
|
|
227
|
+
|
|
228
|
+
// Search input wrapper
|
|
229
|
+
.search-wrapper {
|
|
230
|
+
padding: 0 16px;
|
|
231
|
+
position: relative;
|
|
232
|
+
// Removed border-bottom that was causing extra divider
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Search input field
|
|
236
|
+
.search-select-input {
|
|
237
|
+
width: 100%;
|
|
238
|
+
outline: none;
|
|
239
|
+
font-size: 0.875rem;
|
|
240
|
+
border: none;
|
|
241
|
+
padding: 8px 0;
|
|
242
|
+
border-bottom: 1px solid var(--mm-input-border, #9e9e9e);
|
|
243
|
+
background-color: transparent;
|
|
244
|
+
color: var(--mm-text-primary, inherit);
|
|
245
|
+
|
|
246
|
+
&:focus {
|
|
247
|
+
border-bottom-color: var(--mm-primary-color, #2196F3);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
&::placeholder {
|
|
251
|
+
color: var(--mm-text-hint, #9e9e9e);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// No options found message
|
|
256
|
+
.search-select-no-options {
|
|
257
|
+
padding: 8px 16px;
|
|
258
|
+
color: var(--mm-text-hint, #9e9e9e);
|
|
259
|
+
font-style: italic;
|
|
260
|
+
text-align: center;
|
|
261
|
+
border-bottom: none;
|
|
262
|
+
|
|
263
|
+
&:hover {
|
|
264
|
+
background-color: transparent;
|
|
265
|
+
cursor: default;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Option labels for proper checkbox accessibility
|
|
270
|
+
.search-select-option-label {
|
|
271
|
+
display: flex;
|
|
272
|
+
align-items: center;
|
|
273
|
+
width: 100%;
|
|
274
|
+
cursor: pointer;
|
|
275
|
+
padding: 0;
|
|
276
|
+
margin: 0;
|
|
277
|
+
// Ensure it inherits the same padding as regular dropdown items
|
|
278
|
+
min-height: var(--mm-dropdown-item-height, 50px);
|
|
279
|
+
|
|
280
|
+
input[type="checkbox"] {
|
|
281
|
+
margin-right: 8px;
|
|
282
|
+
position: relative;
|
|
283
|
+
// Reset any default checkbox styles
|
|
284
|
+
appearance: none;
|
|
285
|
+
width: 18px;
|
|
286
|
+
height: 18px;
|
|
287
|
+
border: 2px solid var(--mm-border-color, #9e9e9e);
|
|
288
|
+
border-radius: 2px;
|
|
289
|
+
background-color: transparent;
|
|
290
|
+
|
|
291
|
+
&:checked {
|
|
292
|
+
background-color: var(--mm-primary-color, #2196F3);
|
|
293
|
+
border-color: var(--mm-primary-color, #2196F3);
|
|
294
|
+
|
|
295
|
+
&:after {
|
|
296
|
+
content: '✓';
|
|
297
|
+
color: white;
|
|
298
|
+
font-size: 12px;
|
|
299
|
+
position: absolute;
|
|
300
|
+
top: -2px;
|
|
301
|
+
left: 2px;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
&:focus {
|
|
306
|
+
outline: 2px solid var(--mm-primary-color, #2196F3);
|
|
307
|
+
outline-offset: 2px;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
span {
|
|
312
|
+
flex: 1;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Multi-select chips styling improvements
|
|
317
|
+
.multi-select-dropdown {
|
|
318
|
+
.chips-container {
|
|
319
|
+
display: flex;
|
|
320
|
+
align-items: flex-end;
|
|
321
|
+
flex-wrap: wrap;
|
|
322
|
+
cursor: pointer;
|
|
323
|
+
position: relative;
|
|
324
|
+
min-height: var(--mm-input-height, 3rem);
|
|
325
|
+
padding: 4px 0;
|
|
326
|
+
|
|
327
|
+
.chip {
|
|
328
|
+
margin: 2px 4px 2px 0;
|
|
329
|
+
// Let existing chip system handle background colors for theme compatibility
|
|
330
|
+
|
|
331
|
+
.material-icons.close {
|
|
332
|
+
cursor: pointer;
|
|
333
|
+
font-size: 16px;
|
|
334
|
+
margin-left: 4px;
|
|
335
|
+
|
|
336
|
+
&:hover {
|
|
337
|
+
color: var(--mm-error-color, #f44336);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.placeholder {
|
|
343
|
+
color: var(--mm-text-hint, #9e9e9e);
|
|
344
|
+
flex-grow: 1;
|
|
345
|
+
padding: 8px 0;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.spacer {
|
|
349
|
+
flex-grow: 1;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.caret {
|
|
353
|
+
margin-left: auto;
|
|
354
|
+
cursor: pointer;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|