mithril-materialized 3.4.5 → 3.5.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/advanced.css +141 -2
- package/dist/components.css +141 -2
- package/dist/core.css +126 -126
- package/dist/forms.css +126 -126
- package/dist/index.css +269 -128
- package/dist/index.esm.js +231 -18
- package/dist/index.js +231 -18
- package/dist/index.min.css +1 -1
- package/dist/index.umd.js +231 -18
- package/dist/material-icon.d.ts +6 -0
- package/dist/sidenav.d.ts +29 -1
- package/package.json +1 -1
- package/sass/components/_sidenav.scss +194 -3
- package/sass/components/forms/_input-fields.scss +10 -10
package/dist/index.esm.js
CHANGED
|
@@ -963,6 +963,18 @@ const iconPaths = {
|
|
|
963
963
|
'M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z', // chevron down
|
|
964
964
|
'M0 0h24v24H0z', // background
|
|
965
965
|
],
|
|
966
|
+
chevron_left: [
|
|
967
|
+
'M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z', // chevron left
|
|
968
|
+
'M0 0h24v24H0z', // background
|
|
969
|
+
],
|
|
970
|
+
chevron_right: [
|
|
971
|
+
'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z', // chevron right
|
|
972
|
+
'M0 0h24v24H0z', // background
|
|
973
|
+
],
|
|
974
|
+
menu: [
|
|
975
|
+
'M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z', // hamburger menu
|
|
976
|
+
'M0 0h24v24H0z', // background
|
|
977
|
+
],
|
|
966
978
|
expand: [
|
|
967
979
|
'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z', // plus
|
|
968
980
|
'M0 0h24v24H0z', // background
|
|
@@ -971,6 +983,18 @@ const iconPaths = {
|
|
|
971
983
|
'M19 13H5v-2h14v2z', // minus
|
|
972
984
|
'M0 0h24v24H0z', // background
|
|
973
985
|
],
|
|
986
|
+
check: [
|
|
987
|
+
'M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z', // checkmark
|
|
988
|
+
'M0 0h24v24H0z', // background
|
|
989
|
+
],
|
|
990
|
+
radio_checked: [
|
|
991
|
+
'M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z', // radio button checked
|
|
992
|
+
'M0 0h24v24H0z', // background
|
|
993
|
+
],
|
|
994
|
+
radio_unchecked: [
|
|
995
|
+
'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z', // radio button unchecked
|
|
996
|
+
'M0 0h24v24H0z', // background
|
|
997
|
+
],
|
|
974
998
|
light_mode: [
|
|
975
999
|
'M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5M2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1m18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1m0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1M5.99 4.58a.996.996 0 0 0-1.41 0 .996.996 0 0 0 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41zm12.4 12.4a.996.996 0 0 0-1.41 0 .996.996 0 0 0 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0a.996.996 0 0 0 0-1.41zm1.06-11a.996.996 0 0 0 0-1.41.996.996 0 0 0-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0zM7.05 18.4a.996.996 0 0 0 0-1.41.996.996 0 0 0-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0z',
|
|
976
1000
|
'M0 0h24v24H0z', // background
|
|
@@ -3272,9 +3296,11 @@ const InputField = (type, defaultClass = '') => () => {
|
|
|
3272
3296
|
? true
|
|
3273
3297
|
: false;
|
|
3274
3298
|
const rangeType = type === 'range' && !attrs.minmax;
|
|
3299
|
+
// Only add validate class if input is interactive and validation is needed
|
|
3300
|
+
const shouldValidate = !isNonInteractive && (validate || type === 'email' || type === 'url' || isNumeric);
|
|
3275
3301
|
return m('.input-field', { className: cn, style }, [
|
|
3276
3302
|
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
3277
|
-
m('input
|
|
3303
|
+
m('input', Object.assign(Object.assign({ class: shouldValidate ? 'validate' : undefined }, params), { type, tabindex: 0, id,
|
|
3278
3304
|
placeholder, value: controlled ? value : undefined, class: type === 'range' && attrs.vertical ? 'range-slider vertical' : undefined, style: type === 'range' && attrs.vertical
|
|
3279
3305
|
? {
|
|
3280
3306
|
height: attrs.height || '200px',
|
|
@@ -3355,6 +3381,17 @@ const InputField = (type, defaultClass = '') => () => {
|
|
|
3355
3381
|
state.active = false;
|
|
3356
3382
|
const target = e.target;
|
|
3357
3383
|
state.hasInteracted = true;
|
|
3384
|
+
// Skip validation for readonly/disabled inputs
|
|
3385
|
+
if (attrs.readonly || attrs.disabled) {
|
|
3386
|
+
// Call original onblur if provided
|
|
3387
|
+
if (attrs.onblur) {
|
|
3388
|
+
attrs.onblur(e);
|
|
3389
|
+
}
|
|
3390
|
+
if (onchange && state.inputElement) {
|
|
3391
|
+
onchange(getValue(state.inputElement));
|
|
3392
|
+
}
|
|
3393
|
+
return;
|
|
3394
|
+
}
|
|
3358
3395
|
if (target && validate) {
|
|
3359
3396
|
const value = getValue(target);
|
|
3360
3397
|
// Only validate if user has entered some text
|
|
@@ -7797,12 +7834,27 @@ const Sidenav = () => {
|
|
|
7797
7834
|
document.body.style.overflow = isOpen && mode === 'overlay' ? 'hidden' : '';
|
|
7798
7835
|
}
|
|
7799
7836
|
};
|
|
7837
|
+
const toggleExpanded = (attrs) => {
|
|
7838
|
+
const newExpandedState = !(attrs.isExpanded !== false);
|
|
7839
|
+
if (attrs.onExpandChange) {
|
|
7840
|
+
attrs.onExpandChange(newExpandedState);
|
|
7841
|
+
}
|
|
7842
|
+
};
|
|
7843
|
+
const toggleHamburger = (attrs) => {
|
|
7844
|
+
const newOpenState = !state.isOpen;
|
|
7845
|
+
if (attrs.onToggle) {
|
|
7846
|
+
attrs.onToggle(newOpenState);
|
|
7847
|
+
}
|
|
7848
|
+
};
|
|
7800
7849
|
return {
|
|
7801
7850
|
oninit: ({ attrs }) => {
|
|
7802
7851
|
state = {
|
|
7803
7852
|
id: attrs.id || uniqueId(),
|
|
7804
7853
|
isOpen: attrs.isOpen || false,
|
|
7805
7854
|
isAnimating: false,
|
|
7855
|
+
isExpanded: attrs.isExpanded !== false,
|
|
7856
|
+
activeItemIndex: null,
|
|
7857
|
+
selectedSubmenuItems: new Map(),
|
|
7806
7858
|
};
|
|
7807
7859
|
// Set up keyboard listener
|
|
7808
7860
|
if (typeof document !== 'undefined' && attrs.closeOnEscape !== false) {
|
|
@@ -7831,12 +7883,16 @@ const Sidenav = () => {
|
|
|
7831
7883
|
}
|
|
7832
7884
|
},
|
|
7833
7885
|
view: ({ attrs, children }) => {
|
|
7834
|
-
const { position = 'left', mode = 'overlay', width = 300, className = '', showBackdrop = true, animationDuration = 300, fixed = false, } = attrs;
|
|
7886
|
+
const { position = 'left', mode = 'overlay', width = 300, className = '', showBackdrop = true, animationDuration = 300, fixed = false, showHamburger = false, expandable = false, } = attrs;
|
|
7835
7887
|
const isOpen = state.isOpen;
|
|
7888
|
+
const collapsedWidth = 60;
|
|
7889
|
+
const isExpanded = attrs.isExpanded !== false;
|
|
7890
|
+
const currentWidth = expandable && !isExpanded ? collapsedWidth : width;
|
|
7836
7891
|
return [
|
|
7837
|
-
// Backdrop (using existing materialize class)
|
|
7892
|
+
// Backdrop (using existing materialize class) - only for overlay mode
|
|
7838
7893
|
showBackdrop &&
|
|
7839
7894
|
mode === 'overlay' &&
|
|
7895
|
+
!fixed &&
|
|
7840
7896
|
m('.sidenav-overlay', {
|
|
7841
7897
|
style: {
|
|
7842
7898
|
display: isOpen ? 'block' : 'none',
|
|
@@ -7847,49 +7903,206 @@ const Sidenav = () => {
|
|
|
7847
7903
|
// Sidenav (using existing materialize structure)
|
|
7848
7904
|
m('ul.sidenav', {
|
|
7849
7905
|
id: state.id,
|
|
7850
|
-
class: [
|
|
7906
|
+
class: [
|
|
7907
|
+
position === 'right' ? 'right-aligned' : '',
|
|
7908
|
+
fixed ? 'sidenav-fixed' : '',
|
|
7909
|
+
expandable && !isExpanded ? 'sidenav-collapsed' : '',
|
|
7910
|
+
className,
|
|
7911
|
+
]
|
|
7851
7912
|
.filter(Boolean)
|
|
7852
7913
|
.join(' ') || undefined,
|
|
7853
7914
|
style: {
|
|
7854
|
-
width: `${
|
|
7915
|
+
width: `${currentWidth}px`,
|
|
7855
7916
|
transform: isOpen ? 'translateX(0)' : position === 'left' ? 'translateX(-105%)' : 'translateX(105%)',
|
|
7856
7917
|
'transition-duration': `${animationDuration}ms`,
|
|
7918
|
+
'transition-property': 'transform, width',
|
|
7857
7919
|
},
|
|
7858
|
-
},
|
|
7920
|
+
}, [
|
|
7921
|
+
// Hamburger toggle button (inside sidenav, at the top)
|
|
7922
|
+
showHamburger &&
|
|
7923
|
+
m('li.sidenav-hamburger-item', {
|
|
7924
|
+
style: {
|
|
7925
|
+
display: 'flex',
|
|
7926
|
+
'justify-content': position === 'right' ? 'flex-end' : 'flex-start',
|
|
7927
|
+
'align-items': 'center',
|
|
7928
|
+
padding: '12px 16px',
|
|
7929
|
+
cursor: 'pointer',
|
|
7930
|
+
'border-bottom': '1px solid rgba(0,0,0,0.1)',
|
|
7931
|
+
},
|
|
7932
|
+
onclick: () => toggleHamburger(attrs),
|
|
7933
|
+
}, m(MaterialIcon, {
|
|
7934
|
+
name: 'menu',
|
|
7935
|
+
style: { width: '24px', height: '24px' },
|
|
7936
|
+
})),
|
|
7937
|
+
// Expand/collapse toggle button (if expandable, right below hamburger)
|
|
7938
|
+
expandable &&
|
|
7939
|
+
m('li.sidenav-expand-toggle', {
|
|
7940
|
+
style: {
|
|
7941
|
+
display: 'flex',
|
|
7942
|
+
'justify-content': position === 'right' ? 'flex-end' : 'flex-start',
|
|
7943
|
+
'align-items': 'center',
|
|
7944
|
+
padding: '12px 16px',
|
|
7945
|
+
cursor: 'pointer',
|
|
7946
|
+
'border-bottom': '1px solid rgba(0,0,0,0.1)',
|
|
7947
|
+
},
|
|
7948
|
+
onclick: () => toggleExpanded(attrs),
|
|
7949
|
+
}, m(MaterialIcon, {
|
|
7950
|
+
name: position === 'right'
|
|
7951
|
+
? (isExpanded ? 'chevron_right' : 'chevron_left')
|
|
7952
|
+
: (isExpanded ? 'chevron_left' : 'chevron_right'),
|
|
7953
|
+
style: { width: '24px', height: '24px' },
|
|
7954
|
+
})),
|
|
7955
|
+
// Children (menu items) - inject internal props
|
|
7956
|
+
Array.isArray(children)
|
|
7957
|
+
? children.map((child) => {
|
|
7958
|
+
if (child && typeof child === 'object' && 'tag' in child) {
|
|
7959
|
+
// Clone the vnode and add internal props
|
|
7960
|
+
return Object.assign(Object.assign({}, child), { attrs: Object.assign(Object.assign({}, child.attrs), { _isExpanded: isExpanded, _position: position }) });
|
|
7961
|
+
}
|
|
7962
|
+
return child;
|
|
7963
|
+
})
|
|
7964
|
+
: children,
|
|
7965
|
+
]),
|
|
7859
7966
|
];
|
|
7860
7967
|
},
|
|
7861
7968
|
};
|
|
7862
7969
|
};
|
|
7970
|
+
/**
|
|
7971
|
+
* Sidenav Submenu Item Component
|
|
7972
|
+
*/
|
|
7973
|
+
const NavbarSubItem = () => {
|
|
7974
|
+
return {
|
|
7975
|
+
view: ({ attrs }) => {
|
|
7976
|
+
const { text, icon, selected = false, value, onSelect, mode, isExpanded, position = 'left' } = attrs;
|
|
7977
|
+
const handleClick = () => {
|
|
7978
|
+
if (onSelect) {
|
|
7979
|
+
onSelect(value !== undefined ? value : text, !selected);
|
|
7980
|
+
}
|
|
7981
|
+
};
|
|
7982
|
+
const isRightAligned = position === 'right';
|
|
7983
|
+
const submenuContent = isRightAligned
|
|
7984
|
+
? [
|
|
7985
|
+
// Right-aligned: text on left, icons on right
|
|
7986
|
+
isExpanded && m('span', { style: { 'flex': '1', 'text-align': 'left' } }, text),
|
|
7987
|
+
icon && isExpanded && m('i.material-icons', { style: { 'font-size': '18px' } }, icon),
|
|
7988
|
+
m(MaterialIcon, {
|
|
7989
|
+
name: mode === 'checkbox' ? (selected ? 'check' : 'close') : selected ? 'radio_checked' : 'radio_unchecked',
|
|
7990
|
+
style: {
|
|
7991
|
+
width: '18px',
|
|
7992
|
+
height: '18px',
|
|
7993
|
+
opacity: mode === 'checkbox' && !selected ? '0.3' : '1',
|
|
7994
|
+
},
|
|
7995
|
+
}),
|
|
7996
|
+
]
|
|
7997
|
+
: [
|
|
7998
|
+
// Left-aligned: indicator on left, text and icon on right
|
|
7999
|
+
m(MaterialIcon, {
|
|
8000
|
+
name: mode === 'checkbox' ? (selected ? 'check' : 'close') : selected ? 'radio_checked' : 'radio_unchecked',
|
|
8001
|
+
style: {
|
|
8002
|
+
width: '18px',
|
|
8003
|
+
height: '18px',
|
|
8004
|
+
opacity: mode === 'checkbox' && !selected ? '0.3' : '1',
|
|
8005
|
+
},
|
|
8006
|
+
}),
|
|
8007
|
+
icon && isExpanded && m('i.material-icons', { style: { 'font-size': '18px', 'margin-left': '8px' } }, icon),
|
|
8008
|
+
isExpanded && m('span', { style: { 'margin-left': icon ? '8px' : '8px' } }, text),
|
|
8009
|
+
];
|
|
8010
|
+
return m('li.sidenav-subitem', {
|
|
8011
|
+
class: selected ? 'selected' : '',
|
|
8012
|
+
style: {
|
|
8013
|
+
padding: isExpanded ? '8px 16px 8px 48px' : '8px 16px',
|
|
8014
|
+
cursor: 'pointer',
|
|
8015
|
+
display: 'flex',
|
|
8016
|
+
'align-items': 'center',
|
|
8017
|
+
gap: '8px',
|
|
8018
|
+
'font-size': '0.9em',
|
|
8019
|
+
'justify-content': isRightAligned ? 'space-between' : 'flex-start',
|
|
8020
|
+
},
|
|
8021
|
+
onclick: handleClick,
|
|
8022
|
+
}, submenuContent);
|
|
8023
|
+
},
|
|
8024
|
+
};
|
|
8025
|
+
};
|
|
7863
8026
|
/**
|
|
7864
8027
|
* Sidenav Item Component
|
|
7865
8028
|
* Individual items for the sidenav menu
|
|
7866
8029
|
*/
|
|
7867
8030
|
const SidenavItem = () => {
|
|
8031
|
+
let isSubmenuOpen = false;
|
|
7868
8032
|
return {
|
|
7869
8033
|
view: ({ attrs, children }) => {
|
|
7870
|
-
const { text, icon, active = false, disabled = false, onclick, href, className = '', divider = false, subheader = false, } = attrs;
|
|
8034
|
+
const { text, icon, active = false, disabled = false, onclick, href, className = '', divider = false, subheader = false, submenu = [], submenuMode = 'checkbox', } = attrs;
|
|
7871
8035
|
if (divider) {
|
|
7872
8036
|
return m('li.divider');
|
|
7873
8037
|
}
|
|
7874
8038
|
if (subheader) {
|
|
7875
8039
|
return m('li.subheader', text || children);
|
|
7876
8040
|
}
|
|
7877
|
-
const
|
|
7878
|
-
const
|
|
7879
|
-
|
|
7880
|
-
|
|
8041
|
+
const hasSubmenu = submenu && submenu.length > 0;
|
|
8042
|
+
const itemClasses = [
|
|
8043
|
+
active ? 'active' : '',
|
|
8044
|
+
disabled ? 'disabled' : '',
|
|
8045
|
+
hasSubmenu ? 'has-submenu' : '',
|
|
8046
|
+
className,
|
|
8047
|
+
]
|
|
8048
|
+
.filter(Boolean)
|
|
8049
|
+
.join(' ') || undefined;
|
|
8050
|
+
const handleMainClick = (e) => {
|
|
8051
|
+
e.preventDefault();
|
|
8052
|
+
if (hasSubmenu) {
|
|
8053
|
+
isSubmenuOpen = active ? !isSubmenuOpen : true;
|
|
8054
|
+
}
|
|
8055
|
+
if (onclick && !disabled) {
|
|
8056
|
+
onclick(e);
|
|
8057
|
+
}
|
|
8058
|
+
};
|
|
8059
|
+
// Get internal props passed from parent Sidenav
|
|
8060
|
+
const isExpanded = attrs._isExpanded !== false;
|
|
8061
|
+
const position = attrs._position || 'left';
|
|
8062
|
+
const isRightAligned = position === 'right';
|
|
8063
|
+
// In expanded mode, icons are at the outside edge
|
|
8064
|
+
// In collapsed mode, icons are centered
|
|
8065
|
+
const content = isRightAligned
|
|
8066
|
+
? [
|
|
8067
|
+
// Right-aligned: text on left, icon on right
|
|
8068
|
+
isExpanded && m('span.sidenav-item-text', { style: { 'flex': '1', 'text-align': 'left', 'margin-right': '8px' } }, text || children),
|
|
8069
|
+
m('i.material-icons', { style: { 'min-width': '24px', 'width': '24px' } }, icon || ''),
|
|
8070
|
+
]
|
|
8071
|
+
: [
|
|
8072
|
+
// Left-aligned: icon on left, text on right
|
|
8073
|
+
m('i.material-icons', { style: { 'min-width': '24px', 'width': '24px' } }, icon || ''),
|
|
8074
|
+
isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', 'flex': '1' } }, text || children),
|
|
8075
|
+
];
|
|
8076
|
+
const linkStyle = {
|
|
8077
|
+
display: 'flex',
|
|
8078
|
+
'align-items': 'center',
|
|
8079
|
+
padding: isExpanded ? '12px 16px' : '12px 18px',
|
|
8080
|
+
'justify-content': isExpanded ? (isRightAligned ? 'flex-end' : 'flex-start') : 'center',
|
|
8081
|
+
};
|
|
8082
|
+
const mainItem = href && !disabled
|
|
8083
|
+
? m('li', { class: itemClasses }, [
|
|
7881
8084
|
m('a', {
|
|
7882
8085
|
href,
|
|
7883
|
-
onclick:
|
|
8086
|
+
onclick: handleMainClick,
|
|
8087
|
+
style: linkStyle,
|
|
8088
|
+
}, content),
|
|
8089
|
+
])
|
|
8090
|
+
: m('li', { class: itemClasses }, [
|
|
8091
|
+
m('a', {
|
|
8092
|
+
onclick: handleMainClick,
|
|
8093
|
+
href: '#!',
|
|
8094
|
+
style: linkStyle,
|
|
7884
8095
|
}, content),
|
|
7885
8096
|
]);
|
|
8097
|
+
// Return main item with submenu if applicable
|
|
8098
|
+
if (hasSubmenu && active && isSubmenuOpen) {
|
|
8099
|
+
return [
|
|
8100
|
+
mainItem,
|
|
8101
|
+
submenu.map((subItem) => m(NavbarSubItem, Object.assign(Object.assign({}, subItem), { mode: submenuMode, isExpanded,
|
|
8102
|
+
position }))),
|
|
8103
|
+
];
|
|
7886
8104
|
}
|
|
7887
|
-
return
|
|
7888
|
-
m('a', {
|
|
7889
|
-
onclick: disabled ? undefined : onclick,
|
|
7890
|
-
href: '#!',
|
|
7891
|
-
}, content),
|
|
7892
|
-
]);
|
|
8105
|
+
return mainItem;
|
|
7893
8106
|
},
|
|
7894
8107
|
};
|
|
7895
8108
|
};
|