mithril-materialized 3.5.2 → 3.5.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/dist/index.js CHANGED
@@ -3616,9 +3616,7 @@ const InputCheckbox = () => {
3616
3616
  const OptionsList = {
3617
3617
  view: ({ attrs: { options, layout } }) => {
3618
3618
  const optionElements = options.map(({ component, props, key }) => m(component, Object.assign(Object.assign({}, props), { key })));
3619
- return layout === 'horizontal'
3620
- ? m('div.grid-container', optionElements)
3621
- : optionElements;
3619
+ return layout === 'horizontal' ? m('div.grid-container', optionElements) : optionElements;
3622
3620
  },
3623
3621
  };
3624
3622
  /** A list of checkboxes */
@@ -3644,7 +3642,7 @@ const Options = () => {
3644
3642
  oninit: ({ attrs }) => {
3645
3643
  state.componentId = attrs.id || uniqueId();
3646
3644
  },
3647
- view: ({ attrs: { checkedId, label, options, description, className = 'col s12', style, disabled, checkboxClass, newRow, isMandatory, layout = 'vertical', showSelectAll = false, selectAllText = 'Select All', selectNoneText = 'Select None', onchange, }, }) => {
3645
+ view: ({ attrs: { checkedId, label, options = [], description, className = 'col s12', style, disabled, checkboxClass, newRow, isMandatory, layout = 'vertical', showSelectAll = false, selectAllText = 'Select All', selectNoneText = 'Select None', onchange, }, }) => {
3648
3646
  // Derive checked IDs from props
3649
3647
  const checkedIds = checkedId !== undefined ? (Array.isArray(checkedId) ? checkedId : [checkedId]) : [];
3650
3648
  const isChecked = (id) => checkedIds.includes(id);
@@ -7814,6 +7812,66 @@ const FileUpload = () => {
7814
7812
  };
7815
7813
  };
7816
7814
 
7815
+ // List of MaterialIcon SVG icons that are available
7816
+ const materialIconSvgNames = [
7817
+ 'caret', 'close', 'chevron', 'chevron_left', 'chevron_right', 'menu',
7818
+ 'expand', 'collapse', 'check', 'radio_checked', 'radio_unchecked',
7819
+ 'light_mode', 'dark_mode'
7820
+ ];
7821
+ /**
7822
+ * Helper function to render icons based on IconDefinition type
7823
+ */
7824
+ const renderIcon = (icon, style) => {
7825
+ if (!icon)
7826
+ return null;
7827
+ if (typeof icon === 'string') {
7828
+ // Check if this is a MaterialIcon SVG name
7829
+ if (materialIconSvgNames.includes(icon)) {
7830
+ return m(MaterialIcon, { name: icon, style });
7831
+ }
7832
+ // Fall back to Material Icons font for other icon names
7833
+ return m('i.material-icons', { style }, icon);
7834
+ }
7835
+ if (icon.type === 'svg') {
7836
+ // Inline SVG
7837
+ return m.trust(icon.content);
7838
+ }
7839
+ if (icon.type === 'image') {
7840
+ // Image URL
7841
+ return m('img', {
7842
+ src: icon.content,
7843
+ style: Object.assign(Object.assign({}, style), { width: '24px', height: '24px', objectFit: 'contain' }),
7844
+ });
7845
+ }
7846
+ return null;
7847
+ };
7848
+ /**
7849
+ * Helper function to render a single sidenav item (for header/footer items)
7850
+ */
7851
+ const renderSidenavItem = (item, isExpanded, position) => {
7852
+ const { text, icon, onclick, href, className = '' } = item;
7853
+ const isRightAligned = position === 'right';
7854
+ const content = isRightAligned
7855
+ ? [
7856
+ isExpanded && m('span.sidenav-item-text', { style: { 'flex': '1', 'text-align': 'left', 'margin-right': '8px' } }, text),
7857
+ renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
7858
+ ]
7859
+ : [
7860
+ renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
7861
+ isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', 'flex': '1' } }, text),
7862
+ ];
7863
+ const linkStyle = {
7864
+ display: 'flex',
7865
+ 'align-items': 'center',
7866
+ padding: isExpanded ? '12px 16px' : '12px 18px',
7867
+ 'justify-content': isExpanded ? (isRightAligned ? 'flex-end' : 'flex-start') : 'center',
7868
+ };
7869
+ return m('li', { class: className }, m('a', {
7870
+ href: href || '#!',
7871
+ onclick: onclick,
7872
+ style: linkStyle,
7873
+ }, content));
7874
+ };
7817
7875
  /**
7818
7876
  * Sidenav Component
7819
7877
  * A responsive navigation drawer that slides in from the side
@@ -7936,6 +7994,8 @@ const Sidenav = () => {
7936
7994
  name: 'menu',
7937
7995
  style: { width: '24px', height: '24px' },
7938
7996
  })),
7997
+ // Header item (if provided, appears before expand/collapse toggle)
7998
+ attrs.header && renderSidenavItem(attrs.header, isExpanded, position),
7939
7999
  // Expand/collapse toggle button (if expandable, right below hamburger)
7940
8000
  expandable &&
7941
8001
  m('li.sidenav-expand-toggle', {
@@ -7964,6 +8024,8 @@ const Sidenav = () => {
7964
8024
  return child;
7965
8025
  })
7966
8026
  : children,
8027
+ // Footer item (if provided, appears at the bottom)
8028
+ attrs.footer && renderSidenavItem(attrs.footer, isExpanded, position),
7967
8029
  ]),
7968
8030
  ];
7969
8031
  },
@@ -7982,43 +8044,42 @@ const NavbarSubItem = () => {
7982
8044
  }
7983
8045
  };
7984
8046
  const isRightAligned = position === 'right';
8047
+ // Render indicator icon for checkbox/radio modes
8048
+ const indicatorIcon = mode !== 'none'
8049
+ ? m(MaterialIcon, {
8050
+ name: mode === 'checkbox' ? (selected ? 'check' : 'close') : selected ? 'radio_checked' : 'radio_unchecked',
8051
+ style: {
8052
+ width: '18px',
8053
+ height: '18px',
8054
+ opacity: mode === 'checkbox' && !selected ? '0.3' : '1',
8055
+ },
8056
+ })
8057
+ : null;
7985
8058
  const submenuContent = isRightAligned
7986
8059
  ? [
7987
8060
  // Right-aligned: text on left, icons on right
7988
8061
  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
- }),
8062
+ icon && isExpanded && renderIcon(icon, { 'font-size': '18px' }),
8063
+ indicatorIcon,
7998
8064
  ]
7999
8065
  : [
8000
8066
  // 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),
8067
+ indicatorIcon,
8068
+ icon && isExpanded && renderIcon(icon, { 'font-size': '18px', 'margin-left': indicatorIcon ? '8px' : '0' }),
8069
+ isExpanded && m('span', { style: { 'margin-left': icon || indicatorIcon ? '8px' : '0' } }, text),
8011
8070
  ];
8012
8071
  return m('li.sidenav-subitem', {
8013
8072
  class: selected ? 'selected' : '',
8014
8073
  style: {
8015
- padding: isExpanded ? '8px 16px 8px 48px' : '8px 16px',
8074
+ padding: isExpanded ? '0 16px 0 48px' : '0 16px',
8016
8075
  cursor: 'pointer',
8017
8076
  display: 'flex',
8018
8077
  'align-items': 'center',
8019
8078
  gap: '8px',
8020
8079
  'font-size': '0.9em',
8021
8080
  'justify-content': isRightAligned ? 'space-between' : 'flex-start',
8081
+ height: '48px',
8082
+ 'min-height': '48px',
8022
8083
  },
8023
8084
  onclick: handleClick,
8024
8085
  }, submenuContent);
@@ -8050,8 +8111,8 @@ const SidenavItem = () => {
8050
8111
  .filter(Boolean)
8051
8112
  .join(' ') || undefined;
8052
8113
  const handleMainClick = (e) => {
8053
- e.preventDefault();
8054
8114
  if (hasSubmenu) {
8115
+ e.preventDefault();
8055
8116
  isSubmenuOpen = active ? !isSubmenuOpen : true;
8056
8117
  }
8057
8118
  if (onclick && !disabled) {
@@ -8068,11 +8129,11 @@ const SidenavItem = () => {
8068
8129
  ? [
8069
8130
  // Right-aligned: text on left, icon on right
8070
8131
  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 || ''),
8132
+ renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
8072
8133
  ]
8073
8134
  : [
8074
8135
  // Left-aligned: icon on left, text on right
8075
- m('i.material-icons', { style: { 'min-width': '24px', 'width': '24px' } }, icon || ''),
8136
+ renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
8076
8137
  isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', 'flex': '1' } }, text || children),
8077
8138
  ];
8078
8139
  const linkStyle = {