mithril-materialized 3.3.8 → 3.4.0

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
@@ -436,6 +436,103 @@
436
436
  },
437
437
  });
438
438
 
439
+ /*!
440
+ * Waves Effect for Mithril Materialized
441
+ * Based on Waves v0.6.4 by Alfiana E. Sibuea
442
+ * Adapted for TypeScript and Mithril integration
443
+ */
444
+ class WavesEffect {
445
+ static offset(elem) {
446
+ const rect = elem.getBoundingClientRect();
447
+ return {
448
+ top: rect.top + window.pageYOffset,
449
+ left: rect.left + window.pageXOffset
450
+ };
451
+ }
452
+ static createRipple(e, element) {
453
+ // Disable right click
454
+ if (e.button === 2) {
455
+ return;
456
+ }
457
+ // Create ripple element
458
+ const ripple = document.createElement('div');
459
+ ripple.className = 'waves-ripple';
460
+ // Get click position relative to element
461
+ const pos = this.offset(element);
462
+ const relativeY = e.pageY - pos.top;
463
+ const relativeX = e.pageX - pos.left;
464
+ // Calculate scale based on element size
465
+ const scale = (element.clientWidth / 100) * 10;
466
+ // Set initial ripple position and style
467
+ ripple.style.cssText = `
468
+ top: ${relativeY}px;
469
+ left: ${relativeX}px;
470
+ transform: scale(0);
471
+ opacity: 1;
472
+ `;
473
+ // Add ripple to element
474
+ element.appendChild(ripple);
475
+ // Force reflow and animate
476
+ ripple.offsetHeight;
477
+ ripple.style.transform = `scale(${scale})`;
478
+ ripple.style.opacity = '1';
479
+ // Store reference for cleanup
480
+ ripple.setAttribute('data-created', Date.now().toString());
481
+ }
482
+ static removeRipples(element) {
483
+ const ripples = element.querySelectorAll('.waves-ripple');
484
+ ripples.forEach((ripple) => {
485
+ const created = parseInt(ripple.getAttribute('data-created') || '0');
486
+ const age = Date.now() - created;
487
+ const fadeOut = () => {
488
+ ripple.style.opacity = '0';
489
+ setTimeout(() => {
490
+ if (ripple.parentNode) {
491
+ ripple.parentNode.removeChild(ripple);
492
+ }
493
+ }, this.duration);
494
+ };
495
+ if (age >= 350) {
496
+ fadeOut();
497
+ }
498
+ else {
499
+ setTimeout(fadeOut, 350 - age);
500
+ }
501
+ });
502
+ }
503
+ }
504
+ WavesEffect.duration = 750;
505
+ WavesEffect.onMouseDown = (e) => {
506
+ const element = e.currentTarget;
507
+ if (element && element.classList.contains('waves-effect')) {
508
+ WavesEffect.createRipple(e, element);
509
+ }
510
+ };
511
+ WavesEffect.onMouseUp = (e) => {
512
+ const element = e.currentTarget;
513
+ if (element && element.classList.contains('waves-effect')) {
514
+ WavesEffect.removeRipples(element);
515
+ }
516
+ };
517
+ WavesEffect.onMouseLeave = (e) => {
518
+ const element = e.currentTarget;
519
+ if (element && element.classList.contains('waves-effect')) {
520
+ WavesEffect.removeRipples(element);
521
+ }
522
+ };
523
+ WavesEffect.onTouchStart = (e) => {
524
+ const element = e.currentTarget;
525
+ if (element && element.classList.contains('waves-effect')) {
526
+ WavesEffect.createRipple(e, element);
527
+ }
528
+ };
529
+ WavesEffect.onTouchEnd = (e) => {
530
+ const element = e.currentTarget;
531
+ if (element && element.classList.contains('waves-effect')) {
532
+ WavesEffect.removeRipples(element);
533
+ }
534
+ };
535
+
439
536
  /**
440
537
  * A factory to create new buttons.
441
538
  *
@@ -449,13 +546,18 @@
449
546
  iconName, iconClass, label, className, variant } = attrs, params = __rest(attrs, ["tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "variant"]);
450
547
  // Use variant or fallback to factory type
451
548
  const buttonType = variant || type || 'button';
452
- const cn = [tooltip ? 'tooltipped' : '', defaultClassNames, className]
453
- .filter(Boolean)
454
- .join(' ')
455
- .trim();
549
+ const cn = [tooltip ? 'tooltipped' : '', defaultClassNames, className].filter(Boolean).join(' ').trim();
456
550
  // Use tooltipPosition if available, fallback to legacy tooltipPostion
457
551
  const position = tooltipPosition || tooltipPostion || 'top';
458
- return m(element, Object.assign(Object.assign({}, params), { className: cn, 'data-position': tooltip ? position : undefined, 'data-tooltip': tooltip || undefined, type: buttonType }), iconName ? m(Icon, { iconName, className: iconClass || 'left' }) : undefined, label ? label : undefined);
552
+ // Add waves effect event handlers if waves-effect class is present
553
+ const wavesHandlers = cn.includes('waves-effect') ? {
554
+ onmousedown: WavesEffect.onMouseDown,
555
+ onmouseup: WavesEffect.onMouseUp,
556
+ onmouseleave: WavesEffect.onMouseLeave,
557
+ ontouchstart: WavesEffect.onTouchStart,
558
+ ontouchend: WavesEffect.onTouchEnd
559
+ } : {};
560
+ return m(element, Object.assign(Object.assign(Object.assign({}, params), wavesHandlers), { className: cn, 'data-position': tooltip ? position : undefined, 'data-tooltip': tooltip || undefined, type: buttonType }), iconName ? m(Icon, { iconName, className: iconClass || 'left' }) : undefined, label ? label : undefined);
459
561
  },
460
562
  };
461
563
  };
@@ -464,6 +566,7 @@
464
566
  const LargeButton = ButtonFactory('a', 'waves-effect waves-light btn-large', 'button');
465
567
  const SmallButton = ButtonFactory('a', 'waves-effect waves-light btn-small', 'button');
466
568
  const FlatButton = ButtonFactory('a', 'waves-effect waves-teal btn-flat', 'button');
569
+ const IconButton = ButtonFactory('button', 'btn-flat btn-icon waves-effect waves-teal', 'button');
467
570
  const RoundIconButton = ButtonFactory('button', 'btn-floating btn-large waves-effect waves-light', 'button');
468
571
  const SubmitButton = ButtonFactory('button', 'btn waves-effect waves-light', 'submit');
469
572
 
@@ -900,7 +1003,7 @@
900
1003
  };
901
1004
  const rotation = (_a = rotationMap[direction]) !== null && _a !== void 0 ? _a : 0;
902
1005
  const transform = rotation ? `rotate(${rotation}deg)` : undefined;
903
- return m('svg', Object.assign(Object.assign({}, props), { style: Object.assign({ transform }, style), height: '1lh', width: '24', viewBox: '0 0 24 24', xmlns: 'http://www.w3.org/2000/svg' }), iconPaths[name].map((d) => m('path', {
1006
+ return m('svg', Object.assign(Object.assign({}, props), { style: Object.assign({ transform }, style), height: '24px', width: '24px', viewBox: '0 0 24 24', xmlns: 'http://www.w3.org/2000/svg' }), iconPaths[name].map((d) => m('path', {
904
1007
  d,
905
1008
  fill: d.includes('M0 0h24v24H0z') ? 'none' : 'currentColor',
906
1009
  })));
@@ -4348,12 +4451,17 @@
4348
4451
  }
4349
4452
  : undefined,
4350
4453
  }, [
4351
- m('a.btn-floating.btn-large', {
4454
+ m('a.btn-floating.btn-large.waves-effect.waves-light', {
4352
4455
  className,
4456
+ onmousedown: WavesEffect.onMouseDown,
4457
+ onmouseup: WavesEffect.onMouseUp,
4458
+ onmouseleave: WavesEffect.onMouseLeave,
4459
+ ontouchstart: WavesEffect.onTouchStart,
4460
+ ontouchend: WavesEffect.onTouchEnd,
4353
4461
  }, m('i.material-icons', { className: iconClass }, iconName)),
4354
4462
  buttons &&
4355
4463
  buttons.length > 0 &&
4356
- m('ul', buttons.map((button, index) => m('li', m(`a.btn-floating.${button.className || 'red'}`, {
4464
+ m('ul', buttons.map((button, index) => m('li', m(`a.btn-floating.waves-effect.waves-light.${button.className || 'red'}`, {
4357
4465
  style: {
4358
4466
  opacity: state.isOpen ? '1' : '0',
4359
4467
  transform: state.isOpen ? 'scale(1)' : 'scale(0.4)',
@@ -4364,6 +4472,11 @@
4364
4472
  if (button.onclick)
4365
4473
  button.onclick(e);
4366
4474
  },
4475
+ onmousedown: WavesEffect.onMouseDown,
4476
+ onmouseup: WavesEffect.onMouseUp,
4477
+ onmouseleave: WavesEffect.onMouseLeave,
4478
+ ontouchstart: WavesEffect.onTouchStart,
4479
+ ontouchend: WavesEffect.onTouchEnd,
4367
4480
  }, m('i.material-icons', { className: button.iconClass }, button.iconName))))),
4368
4481
  ]));
4369
4482
  },
@@ -9017,6 +9130,7 @@
9017
9130
  exports.FloatingActionButton = FloatingActionButton;
9018
9131
  exports.HelperText = HelperText;
9019
9132
  exports.Icon = Icon;
9133
+ exports.IconButton = IconButton;
9020
9134
  exports.ImageList = ImageList;
9021
9135
  exports.InputCheckbox = InputCheckbox;
9022
9136
  exports.Label = Label;
@@ -0,0 +1,16 @@
1
+ /*!
2
+ * Waves Effect for Mithril Materialized
3
+ * Based on Waves v0.6.4 by Alfiana E. Sibuea
4
+ * Adapted for TypeScript and Mithril integration
5
+ */
6
+ export declare class WavesEffect {
7
+ private static duration;
8
+ private static offset;
9
+ private static createRipple;
10
+ private static removeRipples;
11
+ static onMouseDown: (e: MouseEvent) => void;
12
+ static onMouseUp: (e: MouseEvent) => void;
13
+ static onMouseLeave: (e: MouseEvent) => void;
14
+ static onTouchStart: (e: TouchEvent) => void;
15
+ static onTouchEnd: (e: TouchEvent) => void;
16
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mithril-materialized",
3
- "version": "3.3.8",
3
+ "version": "3.4.0",
4
4
  "description": "A materialize library for mithril.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -325,3 +325,24 @@ button.btn-floating {
325
325
  .btn-block {
326
326
  display: block;
327
327
  }
328
+
329
+ // Icon button - compact flat button for icons only
330
+ .btn-flat.btn-icon {
331
+ min-width: auto;
332
+ padding: 0 8px;
333
+ width: auto;
334
+ line-height: variables.$button-height;
335
+ background-color: transparent !important;
336
+
337
+ i {
338
+ margin: 0;
339
+ }
340
+
341
+ // Ensure background stays transparent in all states
342
+ &:hover,
343
+ &:focus,
344
+ &:active,
345
+ &.active {
346
+ background-color: transparent !important;
347
+ }
348
+ }
@@ -53,6 +53,12 @@
53
53
  .material-icons {
54
54
  font-size: 1rem;
55
55
  }
56
+
57
+ svg {
58
+ width: 1rem !important;
59
+ height: 1rem !important;
60
+ flex-shrink: 0;
61
+ }
56
62
 
57
63
  span {
58
64
  font-size: 0.75rem;
@@ -84,6 +90,10 @@
84
90
  .material-icons {
85
91
  font-size: 1.25rem;
86
92
  }
93
+
94
+ svg {
95
+ flex-shrink: 0;
96
+ }
87
97
  }
88
98
 
89
99
  // Navbar theme toggle specific styles