mithril-materialized 3.5.4 → 3.5.6

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.umd.js CHANGED
@@ -3304,8 +3304,8 @@
3304
3304
  const shouldValidate = !isNonInteractive && (validate || type === 'email' || type === 'url' || isNumeric);
3305
3305
  return m('.input-field', { className: cn, style }, [
3306
3306
  iconName ? m('i.material-icons.prefix', iconName) : undefined,
3307
- m('input', Object.assign(Object.assign({ class: shouldValidate ? 'validate' : undefined }, params), { type, tabindex: 0, id,
3308
- placeholder, value: controlled ? value : undefined, class: type === 'range' && attrs.vertical ? 'range-slider vertical' : undefined, style: type === 'range' && attrs.vertical
3307
+ m('input', Object.assign(Object.assign({ class: type === 'range' && attrs.vertical ? 'range-slider vertical' : shouldValidate ? 'validate' : undefined }, params), { type, tabindex: 0, id,
3308
+ placeholder, value: controlled ? value : undefined, style: type === 'range' && attrs.vertical
3309
3309
  ? {
3310
3310
  height: attrs.height || '200px',
3311
3311
  width: '6px',
@@ -4898,7 +4898,7 @@
4898
4898
  closeModal(attrs);
4899
4899
  }
4900
4900
  }
4901
- const { id, title, description, fixedFooter, bottomSheet, buttons, richContent, className, showCloseButton = true, closeOnBackdropClick = true, } = attrs;
4901
+ const { id, title, description, fixedFooter, bottomSheet, buttons, richContent, className, showCloseButton = true, closeOnBackdropClick = true, closeOnButtonClick = true, } = attrs;
4902
4902
  const modalClasses = [
4903
4903
  'modal',
4904
4904
  className || '',
@@ -4995,7 +4995,7 @@
4995
4995
  }, buttons.map((buttonProps) => m(FlatButton, Object.assign(Object.assign({}, buttonProps), { className: `modal-close ${buttonProps.className || ''}`, onclick: (e) => {
4996
4996
  if (buttonProps.onclick)
4997
4997
  buttonProps.onclick(e);
4998
- closeModal(attrs);
4998
+ closeOnButtonClick && closeModal(attrs);
4999
4999
  } })))),
5000
5000
  ]),
5001
5001
  ]);
@@ -5173,6 +5173,7 @@
5173
5173
  autoClose: false,
5174
5174
  twelveHour: true,
5175
5175
  vibrate: true,
5176
+ roundBy5: false,
5176
5177
  onOpen: () => { },
5177
5178
  onOpenStart: () => { },
5178
5179
  onOpenEnd: () => { },
@@ -5224,7 +5225,7 @@
5224
5225
  const clickPos = getPos(e);
5225
5226
  state.dx = clickPos.x - state.x0;
5226
5227
  state.dy = clickPos.y - state.y0;
5227
- setHand(state.dx, state.dy, false);
5228
+ setHand(state.dx, state.dy, options.roundBy5);
5228
5229
  document.addEventListener('mousemove', handleDocumentClickMove);
5229
5230
  document.addEventListener('touchmove', handleDocumentClickMove);
5230
5231
  document.addEventListener('mouseup', handleDocumentClickEnd);
@@ -5236,7 +5237,7 @@
5236
5237
  const x = clickPos.x - state.x0;
5237
5238
  const y = clickPos.y - state.y0;
5238
5239
  state.moved = true;
5239
- setHand(x, y, false);
5240
+ setHand(x, y, options.roundBy5);
5240
5241
  m.redraw();
5241
5242
  };
5242
5243
  const handleDocumentClickEnd = (e) => {
@@ -7816,9 +7817,19 @@
7816
7817
 
7817
7818
  // List of MaterialIcon SVG icons that are available
7818
7819
  const materialIconSvgNames = [
7819
- 'caret', 'close', 'chevron', 'chevron_left', 'chevron_right', 'menu',
7820
- 'expand', 'collapse', 'check', 'radio_checked', 'radio_unchecked',
7821
- 'light_mode', 'dark_mode'
7820
+ 'caret',
7821
+ 'close',
7822
+ 'chevron',
7823
+ 'chevron_left',
7824
+ 'chevron_right',
7825
+ 'menu',
7826
+ 'expand',
7827
+ 'collapse',
7828
+ 'check',
7829
+ 'radio_checked',
7830
+ 'radio_unchecked',
7831
+ 'light_mode',
7832
+ 'dark_mode',
7822
7833
  ];
7823
7834
  /**
7824
7835
  * Helper function to render icons based on IconDefinition type
@@ -7848,31 +7859,42 @@
7848
7859
  return null;
7849
7860
  };
7850
7861
  /**
7851
- * Helper function to render a single sidenav item (for header/footer items)
7862
+ * Sidenav Header/Footer Item Component
7852
7863
  */
7853
- const renderSidenavItem = (item, isExpanded, position) => {
7854
- const { text, icon, onclick, href, className = '' } = item;
7855
- const isRightAligned = position === 'right';
7856
- const content = isRightAligned
7857
- ? [
7858
- isExpanded && m('span.sidenav-item-text', { style: { 'flex': '1', 'text-align': 'left', 'margin-right': '8px' } }, text),
7859
- renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
7860
- ]
7861
- : [
7862
- renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
7863
- isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', 'flex': '1' } }, text),
7864
- ];
7865
- const linkStyle = {
7866
- display: 'flex',
7867
- 'align-items': 'center',
7868
- padding: isExpanded ? '12px 16px' : '12px 18px',
7869
- 'justify-content': isExpanded ? (isRightAligned ? 'flex-end' : 'flex-start') : 'center',
7870
- };
7871
- return m('li', { class: className }, m('a', {
7872
- href: href || '#!',
7873
- onclick: onclick,
7874
- style: linkStyle,
7875
- }, content));
7864
+ const SidenavHeaderFooterItem = () => {
7865
+ return {
7866
+ view: ({ attrs }) => {
7867
+ const { text, icon, onclick, href, className = '', _isExpanded = true, _position = 'left' } = attrs;
7868
+ const isRightAligned = _position === 'right';
7869
+ const handleClick = (e) => {
7870
+ if (onclick) {
7871
+ e.preventDefault();
7872
+ onclick(e);
7873
+ }
7874
+ };
7875
+ const content = isRightAligned
7876
+ ? [
7877
+ _isExpanded &&
7878
+ m('span.sidenav-item-text', { style: { flex: '1', 'text-align': 'left', 'margin-right': '8px' } }, text),
7879
+ renderIcon(icon, { 'min-width': '24px', width: '24px' }),
7880
+ ]
7881
+ : [
7882
+ renderIcon(icon, { 'min-width': '24px', width: '24px' }),
7883
+ _isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', flex: '1' } }, text),
7884
+ ];
7885
+ const linkStyle = {
7886
+ display: 'flex',
7887
+ 'align-items': 'center',
7888
+ padding: _isExpanded ? '12px 16px' : '12px 18px',
7889
+ 'justify-content': _isExpanded ? (isRightAligned ? 'flex-end' : 'flex-start') : 'center',
7890
+ };
7891
+ return m('li', { class: className }, m('a', {
7892
+ href: href || '#!',
7893
+ onclick: handleClick,
7894
+ style: linkStyle,
7895
+ }, content));
7896
+ },
7897
+ };
7876
7898
  };
7877
7899
  /**
7878
7900
  * Sidenav Component
@@ -7997,7 +8019,8 @@
7997
8019
  style: { width: '24px', height: '24px' },
7998
8020
  })),
7999
8021
  // Header item (if provided, appears before expand/collapse toggle)
8000
- attrs.header && renderSidenavItem(attrs.header, isExpanded, position),
8022
+ attrs.header &&
8023
+ m(SidenavHeaderFooterItem, Object.assign(Object.assign({}, attrs.header), { _isExpanded: isExpanded, _position: position })),
8001
8024
  // Expand/collapse toggle button (if expandable, right below hamburger)
8002
8025
  expandable &&
8003
8026
  m('li.sidenav-expand-toggle', {
@@ -8012,8 +8035,12 @@
8012
8035
  onclick: () => toggleExpanded(attrs),
8013
8036
  }, m(MaterialIcon, {
8014
8037
  name: position === 'right'
8015
- ? (isExpanded ? 'chevron_right' : 'chevron_left')
8016
- : (isExpanded ? 'chevron_left' : 'chevron_right'),
8038
+ ? isExpanded
8039
+ ? 'chevron_right'
8040
+ : 'chevron_left'
8041
+ : isExpanded
8042
+ ? 'chevron_left'
8043
+ : 'chevron_right',
8017
8044
  style: { width: '24px', height: '24px' },
8018
8045
  })),
8019
8046
  // Children (menu items) - inject internal props
@@ -8027,7 +8054,8 @@
8027
8054
  })
8028
8055
  : children,
8029
8056
  // Footer item (if provided, appears at the bottom)
8030
- attrs.footer && renderSidenavItem(attrs.footer, isExpanded, position),
8057
+ attrs.footer &&
8058
+ m(SidenavHeaderFooterItem, Object.assign(Object.assign({}, attrs.footer), { _isExpanded: isExpanded, _position: position, className: 'sidenav-footer-item' })),
8031
8059
  ]),
8032
8060
  ];
8033
8061
  },
@@ -8060,7 +8088,7 @@
8060
8088
  const submenuContent = isRightAligned
8061
8089
  ? [
8062
8090
  // Right-aligned: text on left, icons on right
8063
- isExpanded && m('span', { style: { 'flex': '1', 'text-align': 'left' } }, text),
8091
+ isExpanded && m('span', { style: { flex: '1', 'text-align': 'left' } }, text),
8064
8092
  icon && isExpanded && renderIcon(icon, { 'font-size': '18px' }),
8065
8093
  indicatorIcon,
8066
8094
  ]
@@ -8104,12 +8132,7 @@
8104
8132
  return m('li.subheader', text || children);
8105
8133
  }
8106
8134
  const hasSubmenu = submenu && submenu.length > 0;
8107
- const itemClasses = [
8108
- active ? 'active' : '',
8109
- disabled ? 'disabled' : '',
8110
- hasSubmenu ? 'has-submenu' : '',
8111
- className,
8112
- ]
8135
+ const itemClasses = [active ? 'active' : '', disabled ? 'disabled' : '', hasSubmenu ? 'has-submenu' : '', className]
8113
8136
  .filter(Boolean)
8114
8137
  .join(' ') || undefined;
8115
8138
  const handleMainClick = (e) => {
@@ -8118,6 +8141,7 @@
8118
8141
  isSubmenuOpen = active ? !isSubmenuOpen : true;
8119
8142
  }
8120
8143
  if (onclick && !disabled) {
8144
+ e.preventDefault();
8121
8145
  onclick(e);
8122
8146
  }
8123
8147
  };
@@ -8130,13 +8154,14 @@
8130
8154
  const content = isRightAligned
8131
8155
  ? [
8132
8156
  // Right-aligned: text on left, icon on right
8133
- isExpanded && m('span.sidenav-item-text', { style: { 'flex': '1', 'text-align': 'left', 'margin-right': '8px' } }, text || children),
8134
- renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
8157
+ isExpanded &&
8158
+ m('span.sidenav-item-text', { style: { flex: '1', 'text-align': 'left', 'margin-right': '8px' } }, text || children),
8159
+ renderIcon(icon, { 'min-width': '24px', width: '24px' }),
8135
8160
  ]
8136
8161
  : [
8137
8162
  // Left-aligned: icon on left, text on right
8138
- renderIcon(icon, { 'min-width': '24px', 'width': '24px' }),
8139
- isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', 'flex': '1' } }, text || children),
8163
+ renderIcon(icon, { 'min-width': '24px', width: '24px' }),
8164
+ isExpanded && m('span.sidenav-item-text', { style: { 'margin-left': '8px', flex: '1' } }, text || children),
8140
8165
  ];
8141
8166
  const linkStyle = {
8142
8167
  display: 'flex',
package/dist/modal.d.ts CHANGED
@@ -27,10 +27,12 @@ export interface ModalAttrs extends Attributes {
27
27
  onToggle?: (open: boolean) => void;
28
28
  /** Called when modal is closed */
29
29
  onClose?: () => void;
30
- /** Show close button in top right */
30
+ /** Show close button in top right (default true) */
31
31
  showCloseButton?: boolean;
32
- /** Close modal when clicking backdrop */
32
+ /** Close modal when clicking backdrop (default true) */
33
33
  closeOnBackdropClick?: boolean;
34
+ /** Close modal when clicking a button (default true) */
35
+ closeOnButtonClick?: boolean;
34
36
  /** Close modal when pressing escape key */
35
37
  closeOnEsc?: boolean;
36
38
  }
@@ -19,6 +19,7 @@ export interface TimepickerOptions {
19
19
  autoClose?: boolean;
20
20
  twelveHour?: boolean;
21
21
  vibrate?: boolean;
22
+ roundBy5?: boolean;
22
23
  onOpen?: () => void;
23
24
  onOpenStart?: () => void;
24
25
  onOpenEnd?: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mithril-materialized",
3
- "version": "3.5.4",
3
+ "version": "3.5.6",
4
4
  "description": "A materialize library for mithril.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -38,7 +38,7 @@
38
38
  "build": "rollup -c rollup.config.mjs && npm run build:css-min",
39
39
  "build:css-min": "sass --no-source-map --style=compressed --no-charset ./src/index.scss ./dist/index.min.css && npm run build:css-modules",
40
40
  "build:css-modules": "sass --no-source-map ./src/core.scss ./dist/core.css && sass --no-source-map ./src/components.scss ./dist/components.css && sass --no-source-map ./src/forms.scss ./dist/forms.css && sass --no-source-map ./src/pickers.scss ./dist/pickers.css && sass --no-source-map ./src/advanced.scss ./dist/advanced.css && sass --no-source-map ./src/utilities.scss ./dist/utilities.css",
41
- "dev": "concurrently \"rollup -c rollup.config.mjs -w\" \"npm run css:watch\"",
41
+ "dev": "concurrently \"rollup -c rollup.config.mjs -w\" \"pnpm run css:watch\"",
42
42
  "start": "pnpm run dev",
43
43
  "clean": "rimraf dist node_modules/.cache",
44
44
  "test": "jest",
@@ -55,7 +55,7 @@
55
55
  "dry-run": "npm publish --dry-run",
56
56
  "sass:watch": "sass --watch ./sass/materialize.scss ./dist/index.css",
57
57
  "css:watch": "sass --watch --no-source-map --style=compressed --no-charset ./src/index.scss ./dist/index.min.css",
58
- "dev:full": "npm run dev & npm run css:watch",
58
+ "dev:full": "pnpm run dev & pnpm run css:watch",
59
59
  "patch-release": "npm run clean && npm run build && npm version patch --force -m \"Patch release\" && npm publish && git push --follow-tags",
60
60
  "minor-release": "npm run clean && npm run build && npm version minor --force -m \"Minor release\" && npm publish && git push --follow-tags",
61
61
  "major-release": "npm run clean && npm run build && npm version major --force -m \"Major release\" && npm publish && git push --follow-tags"
@@ -72,30 +72,29 @@
72
72
  "author": "Erik Vullings <erik.vullings@gmail.com> (http://www.tno.nl)",
73
73
  "license": "MIT",
74
74
  "dependencies": {
75
- "mithril": "^2.3.7"
75
+ "mithril": "^2.3.8"
76
76
  },
77
77
  "devDependencies": {
78
- "@playwright/test": "^1.56.1",
78
+ "@playwright/test": "^1.57.0",
79
79
  "@rollup/plugin-typescript": "^12.3.0",
80
80
  "@testing-library/dom": "^10.4.1",
81
81
  "@testing-library/jest-dom": "^6.9.1",
82
82
  "@testing-library/user-event": "^14.6.1",
83
83
  "@types/jest": "^30.0.0",
84
84
  "@types/mithril": "^2.2.7",
85
- "autoprefixer": "^10.4.21",
85
+ "autoprefixer": "^10.4.23",
86
86
  "concurrently": "^9.2.1",
87
- "express": "^5.1.0",
88
87
  "identity-obj-proxy": "^3.0.0",
89
88
  "jest": "^30.2.0",
90
89
  "jest-environment-jsdom": "^30.2.0",
91
- "js-yaml": "^4.1.0",
92
- "rimraf": "^6.1.0",
93
- "rollup": "^4.52.5",
90
+ "js-yaml": "^4.1.1",
91
+ "rimraf": "^6.1.2",
92
+ "rollup": "^4.54.0",
94
93
  "rollup-plugin-postcss": "^4.0.2",
95
- "sass": "^1.93.2",
96
- "ts-jest": "^29.4.5",
94
+ "sass": "^1.97.1",
95
+ "ts-jest": "^29.4.6",
97
96
  "tslib": "^2.8.1",
98
- "typedoc": "^0.28.14",
97
+ "typedoc": "^0.28.15",
99
98
  "typescript": "^5.9.3"
100
99
  }
101
100
  }
@@ -130,6 +130,8 @@ ul.sidenav.right-aligned li > a:not(.btn):not(.btn-large):not(.btn-flat):not(.bt
130
130
  backface-visibility: hidden;
131
131
  transform: translateX(-105%);
132
132
  transition: transform 0.3s ease, left 0.3s ease, right 0.3s ease;
133
+ display: flex;
134
+ flex-direction: column;
133
135
 
134
136
  @extend .z-depth-1 !optional;
135
137
 
@@ -590,6 +592,11 @@ ul.sidenav.right-aligned li > a:not(.btn):not(.btn-large):not(.btn-flat):not(.bt
590
592
  }
591
593
  }
592
594
 
595
+ // Footer item positioning
596
+ .sidenav-footer-item {
597
+ margin-top: auto;
598
+ }
599
+
593
600
  // Animation for smooth width transitions
594
601
  .sidenav {
595
602
  transition: transform 0.3s ease, width 0.3s ease;