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