mithril-materialized 2.0.0 → 3.0.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/button.d.ts CHANGED
@@ -21,16 +21,16 @@ export interface HtmlAttrs {
21
21
  *
22
22
  * // Submit button with icon
23
23
  * m(Button, {
24
- * variant: { type: 'submit' },
24
+ * variant: 'submit',
25
25
  * label: 'Save',
26
26
  * iconName: 'save',
27
27
  * iconClass: 'small left'
28
28
  * })
29
29
  *
30
- * // Modal trigger button
30
+ * // Reset button
31
31
  * m(Button, {
32
- * variant: { type: 'modal', modalId: 'my-modal' },
33
- * label: 'Open Modal'
32
+ * variant: 'reset',
33
+ * label: 'Clear Form'
34
34
  * })
35
35
  * ```
36
36
  */
@@ -45,19 +45,21 @@ export interface ButtonAttrs extends Attributes {
45
45
  */
46
46
  iconClass?: IconClass;
47
47
  /**
48
- * Button behavior variant - determines button type and behavior
48
+ * Button type - determines the HTML button behavior
49
+ * @default 'button'
49
50
  * @example
50
- * { type: 'button' } - Standard button
51
- * { type: 'submit' } - Form submit button
52
- * { type: 'modal', modalId: 'my-modal' } - Modal trigger
53
- * { type: 'reset' } - Form reset button
51
+ * ```typescript
52
+ * // Standard clickable button (default)
53
+ * variant: 'button'
54
+ *
55
+ * // Form submission button
56
+ * variant: 'submit'
57
+ *
58
+ * // Form reset button
59
+ * variant: 'reset'
60
+ * ```
54
61
  */
55
62
  variant?: ButtonVariant;
56
- /**
57
- * @deprecated Use variant instead
58
- * If the button is intended to open a modal, specify its modal id so we can trigger it
59
- */
60
- modalId?: string;
61
63
  /**
62
64
  * @deprecated Use native HTML attributes directly instead
63
65
  * Some additional HTML attributes that can be attached to the button
package/dist/index.esm.js CHANGED
@@ -161,7 +161,7 @@ const getDropdownStyles = (inputRef, overlap = false, options, isDropDown = fals
161
161
  const range = (a, b) => Array.from({ length: b - a + 1 }, (_, i) => a + i);
162
162
 
163
163
  // import './styles/input.css';
164
- const Mandatory = { view: ({ attrs }) => m('span.mandatory', attrs, '*') };
164
+ const Mandatory = { view: ({ attrs }) => m('span.mandatory', Object.assign({}, attrs), '*') };
165
165
  /** Simple label element, used for most components. */
166
166
  const Label = () => {
167
167
  return {
@@ -416,22 +416,17 @@ const ButtonFactory = (element, defaultClassNames, type = '') => {
416
416
  return () => {
417
417
  return {
418
418
  view: ({ attrs }) => {
419
- const { modalId, tooltip, tooltipPosition, tooltipPostion, // Keep for backwards compatibility
420
- iconName, iconClass, label, className, attr, variant } = attrs, params = __rest(attrs, ["modalId", "tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "attr", "variant"]);
421
- // Handle both new variant prop and legacy modalId/type
422
- const buttonType = (variant === null || variant === void 0 ? void 0 : variant.type) || (modalId ? 'modal' : type || 'button');
423
- const modalTarget = (variant === null || variant === void 0 ? void 0 : variant.type) === 'modal' ? variant.modalId : modalId;
424
- const cn = [modalTarget ? 'modal-trigger' : '', tooltip ? 'tooltipped' : '', defaultClassNames, className]
419
+ const { tooltip, tooltipPosition, tooltipPostion, // Keep for backwards compatibility
420
+ iconName, iconClass, label, className, variant } = attrs, params = __rest(attrs, ["tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "variant"]);
421
+ // Use variant or fallback to factory type
422
+ const buttonType = variant || type || 'button';
423
+ const cn = [tooltip ? 'tooltipped' : '', defaultClassNames, className]
425
424
  .filter(Boolean)
426
425
  .join(' ')
427
426
  .trim();
428
427
  // Use tooltipPosition if available, fallback to legacy tooltipPostion
429
428
  const position = tooltipPosition || tooltipPostion || 'top';
430
- return m(element, Object.assign(Object.assign(Object.assign({}, params), attr), { className: cn, href: modalTarget ? `#${modalTarget}` : undefined, 'data-position': tooltip ? position : undefined, 'data-tooltip': tooltip || undefined, type: buttonType === 'modal' ? 'button' : buttonType }),
431
- // `${dca}${modalId ? `.modal-trigger[href=#${modalId}]` : ''}${
432
- // tooltip ? `.tooltipped[data-position=${tooltipPostion || 'top'}][data-tooltip=${tooltip}]` : ''
433
- // }${toAttributeString(attr)}`, {}
434
- iconName ? m(Icon, { iconName, className: iconClass || 'left' }) : undefined, label ? label : undefined);
429
+ 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);
435
430
  },
436
431
  };
437
432
  };
@@ -483,7 +478,10 @@ const Carousel = () => {
483
478
  dim: 1, // Make sure dim is non zero for divisions
484
479
  // Animation
485
480
  ticker: null,
486
- scrollingTimeout: null};
481
+ scrollingTimeout: null,
482
+ // Instance options (properly typed with defaults)
483
+ options: Object.assign({}, defaults),
484
+ };
487
485
  // Utility functions
488
486
  const xpos = (e) => {
489
487
  // Touch event
@@ -516,7 +514,7 @@ const Carousel = () => {
516
514
  const autoScroll = () => {
517
515
  if (state.amplitude) {
518
516
  const elapsed = Date.now() - state.timestamp;
519
- const delta = state.amplitude * Math.exp(-elapsed / defaults.duration);
517
+ const delta = state.amplitude * Math.exp(-elapsed / state.options.duration);
520
518
  if (delta > 2 || delta < -2) {
521
519
  scroll(state.target - delta);
522
520
  requestAnimationFrame(autoScroll);
@@ -545,14 +543,14 @@ const Carousel = () => {
545
543
  }
546
544
  state.scrollingTimeout = window.setTimeout(() => {
547
545
  carouselEl.classList.remove('scrolling');
548
- }, defaults.duration);
546
+ }, state.options.duration);
549
547
  // Start actual scroll
550
548
  const items = Array.from(carouselEl.querySelectorAll('.carousel-item'));
551
549
  const count = items.length;
552
550
  if (count === 0)
553
551
  return;
554
552
  const lastCenter = state.center;
555
- const numVisibleOffset = 1 / defaults.numVisible;
553
+ const numVisibleOffset = 1 / state.options.numVisible;
556
554
  state.offset = typeof x === 'number' ? x : state.offset;
557
555
  state.center = Math.floor((state.offset + state.dim / 2) / state.dim);
558
556
  const delta = state.offset - state.center * state.dim;
@@ -561,7 +559,7 @@ const Carousel = () => {
561
559
  const half = count >> 1;
562
560
  let alignment;
563
561
  let centerTweenedOpacity;
564
- if (defaults.fullWidth) {
562
+ if (state.options.fullWidth) {
565
563
  alignment = 'translateX(0)';
566
564
  centerTweenedOpacity = 1;
567
565
  }
@@ -584,7 +582,7 @@ const Carousel = () => {
584
582
  // Add active class to center item
585
583
  items.forEach((item) => item.classList.remove('active'));
586
584
  el.classList.add('active');
587
- const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * defaults.shift * tween}px) translateZ(${defaults.dist * tween}px)`;
585
+ const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * state.options.shift * tween}px) translateZ(${state.options.dist * tween}px)`;
588
586
  updateItemStyle(el, centerTweenedOpacity, 0, transformString);
589
587
  }
590
588
  // Side items
@@ -592,31 +590,31 @@ const Carousel = () => {
592
590
  let zTranslation;
593
591
  let tweenedOpacity;
594
592
  // Right side
595
- if (defaults.fullWidth) {
596
- zTranslation = defaults.dist;
593
+ if (state.options.fullWidth) {
594
+ zTranslation = state.options.dist;
597
595
  tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
598
596
  }
599
597
  else {
600
- zTranslation = defaults.dist * (i * 2 + tween * dir);
598
+ zTranslation = state.options.dist * (i * 2 + tween * dir);
601
599
  tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
602
600
  }
603
601
  if (!state.noWrap || state.center + i < count) {
604
602
  const el = items[wrap(state.center + i, count)];
605
- const transformString = `${alignment} translateX(${defaults.shift + (state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
603
+ const transformString = `${alignment} translateX(${state.options.shift + (state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
606
604
  updateItemStyle(el, tweenedOpacity, -i, transformString);
607
605
  }
608
606
  // Left side
609
- if (defaults.fullWidth) {
610
- zTranslation = defaults.dist;
607
+ if (state.options.fullWidth) {
608
+ zTranslation = state.options.dist;
611
609
  tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
612
610
  }
613
611
  else {
614
- zTranslation = defaults.dist * (i * 2 - tween * dir);
612
+ zTranslation = state.options.dist * (i * 2 - tween * dir);
615
613
  tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
616
614
  }
617
615
  if (!state.noWrap || state.center - i >= 0) {
618
616
  const el = items[wrap(state.center - i, count)];
619
- const transformString = `${alignment} translateX(${-defaults.shift + (-state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
617
+ const transformString = `${alignment} translateX(${-state.options.shift + (-state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
620
618
  updateItemStyle(el, tweenedOpacity, -i, transformString);
621
619
  }
622
620
  }
@@ -749,7 +747,7 @@ const Carousel = () => {
749
747
  e.stopPropagation();
750
748
  return false;
751
749
  }
752
- else if (!defaults.fullWidth) {
750
+ else if (!state.options.fullWidth) {
753
751
  const target = e.target.closest('.carousel-item');
754
752
  if (target) {
755
753
  const items = Array.from(document.querySelectorAll('.carousel-item'));
@@ -778,24 +776,27 @@ const Carousel = () => {
778
776
  const { items, indicators = false } = attrs;
779
777
  if (!items || items.length === 0)
780
778
  return undefined;
781
- // Merge options
782
- Object.assign(defaults, attrs);
779
+ // Create instance-specific options without mutating globals
780
+ const instanceOptions = Object.assign(Object.assign({}, defaults), attrs);
781
+ // Update state options for this render
782
+ state.options = instanceOptions;
783
783
  const supportTouch = typeof window.ontouchstart !== 'undefined';
784
784
  return m('.carousel', {
785
785
  oncreate: ({ attrs, dom }) => {
786
786
  const carouselEl = dom;
787
787
  const items = carouselEl.querySelectorAll('.carousel-item');
788
788
  state.hasMultipleSlides = items.length > 1;
789
- state.showIndicators = defaults.indicators && state.hasMultipleSlides;
790
- state.noWrap = defaults.noWrap || !state.hasMultipleSlides;
789
+ state.showIndicators = instanceOptions.indicators && state.hasMultipleSlides;
790
+ state.noWrap = instanceOptions.noWrap || !state.hasMultipleSlides;
791
791
  if (items.length > 0) {
792
792
  const firstItem = items[0];
793
793
  state.itemWidth = firstItem.offsetWidth;
794
794
  state.itemHeight = firstItem.offsetHeight;
795
- state.dim = state.itemWidth * 2 + defaults.padding || 1;
795
+ state.dim = state.itemWidth * 2 + instanceOptions.padding || 1;
796
796
  }
797
797
  // Cap numVisible at count
798
- defaults.numVisible = Math.min(items.length, defaults.numVisible);
798
+ instanceOptions.numVisible = Math.min(items.length, instanceOptions.numVisible);
799
+ state.options = instanceOptions;
799
800
  // Initial scroll
800
801
  scroll(state.offset, attrs);
801
802
  },
@@ -1168,7 +1169,7 @@ const CodeBlock = () => ({
1168
1169
  const label = lang.replace('lang-', '');
1169
1170
  const cb = code instanceof Array ? code.join('\n') : code;
1170
1171
  const cn = [newRow ? 'clear' : '', lang, className].filter(Boolean).join(' ').trim() || undefined;
1171
- return m(`pre.codeblock${newRow ? '.clear' : ''}`, attrs, [
1172
+ return m(`pre.codeblock${newRow ? '.clear' : ''}`, params, [
1172
1173
  m('div', m('label', label)),
1173
1174
  m('code', Object.assign(Object.assign({}, params), { className: cn }), cb),
1174
1175
  ]);
package/dist/index.js CHANGED
@@ -163,7 +163,7 @@ const getDropdownStyles = (inputRef, overlap = false, options, isDropDown = fals
163
163
  const range = (a, b) => Array.from({ length: b - a + 1 }, (_, i) => a + i);
164
164
 
165
165
  // import './styles/input.css';
166
- const Mandatory = { view: ({ attrs }) => m('span.mandatory', attrs, '*') };
166
+ const Mandatory = { view: ({ attrs }) => m('span.mandatory', Object.assign({}, attrs), '*') };
167
167
  /** Simple label element, used for most components. */
168
168
  const Label = () => {
169
169
  return {
@@ -418,22 +418,17 @@ const ButtonFactory = (element, defaultClassNames, type = '') => {
418
418
  return () => {
419
419
  return {
420
420
  view: ({ attrs }) => {
421
- const { modalId, tooltip, tooltipPosition, tooltipPostion, // Keep for backwards compatibility
422
- iconName, iconClass, label, className, attr, variant } = attrs, params = __rest(attrs, ["modalId", "tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "attr", "variant"]);
423
- // Handle both new variant prop and legacy modalId/type
424
- const buttonType = (variant === null || variant === void 0 ? void 0 : variant.type) || (modalId ? 'modal' : type || 'button');
425
- const modalTarget = (variant === null || variant === void 0 ? void 0 : variant.type) === 'modal' ? variant.modalId : modalId;
426
- const cn = [modalTarget ? 'modal-trigger' : '', tooltip ? 'tooltipped' : '', defaultClassNames, className]
421
+ const { tooltip, tooltipPosition, tooltipPostion, // Keep for backwards compatibility
422
+ iconName, iconClass, label, className, variant } = attrs, params = __rest(attrs, ["tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "variant"]);
423
+ // Use variant or fallback to factory type
424
+ const buttonType = variant || type || 'button';
425
+ const cn = [tooltip ? 'tooltipped' : '', defaultClassNames, className]
427
426
  .filter(Boolean)
428
427
  .join(' ')
429
428
  .trim();
430
429
  // Use tooltipPosition if available, fallback to legacy tooltipPostion
431
430
  const position = tooltipPosition || tooltipPostion || 'top';
432
- return m(element, Object.assign(Object.assign(Object.assign({}, params), attr), { className: cn, href: modalTarget ? `#${modalTarget}` : undefined, 'data-position': tooltip ? position : undefined, 'data-tooltip': tooltip || undefined, type: buttonType === 'modal' ? 'button' : buttonType }),
433
- // `${dca}${modalId ? `.modal-trigger[href=#${modalId}]` : ''}${
434
- // tooltip ? `.tooltipped[data-position=${tooltipPostion || 'top'}][data-tooltip=${tooltip}]` : ''
435
- // }${toAttributeString(attr)}`, {}
436
- iconName ? m(Icon, { iconName, className: iconClass || 'left' }) : undefined, label ? label : undefined);
431
+ 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);
437
432
  },
438
433
  };
439
434
  };
@@ -485,7 +480,10 @@ const Carousel = () => {
485
480
  dim: 1, // Make sure dim is non zero for divisions
486
481
  // Animation
487
482
  ticker: null,
488
- scrollingTimeout: null};
483
+ scrollingTimeout: null,
484
+ // Instance options (properly typed with defaults)
485
+ options: Object.assign({}, defaults),
486
+ };
489
487
  // Utility functions
490
488
  const xpos = (e) => {
491
489
  // Touch event
@@ -518,7 +516,7 @@ const Carousel = () => {
518
516
  const autoScroll = () => {
519
517
  if (state.amplitude) {
520
518
  const elapsed = Date.now() - state.timestamp;
521
- const delta = state.amplitude * Math.exp(-elapsed / defaults.duration);
519
+ const delta = state.amplitude * Math.exp(-elapsed / state.options.duration);
522
520
  if (delta > 2 || delta < -2) {
523
521
  scroll(state.target - delta);
524
522
  requestAnimationFrame(autoScroll);
@@ -547,14 +545,14 @@ const Carousel = () => {
547
545
  }
548
546
  state.scrollingTimeout = window.setTimeout(() => {
549
547
  carouselEl.classList.remove('scrolling');
550
- }, defaults.duration);
548
+ }, state.options.duration);
551
549
  // Start actual scroll
552
550
  const items = Array.from(carouselEl.querySelectorAll('.carousel-item'));
553
551
  const count = items.length;
554
552
  if (count === 0)
555
553
  return;
556
554
  const lastCenter = state.center;
557
- const numVisibleOffset = 1 / defaults.numVisible;
555
+ const numVisibleOffset = 1 / state.options.numVisible;
558
556
  state.offset = typeof x === 'number' ? x : state.offset;
559
557
  state.center = Math.floor((state.offset + state.dim / 2) / state.dim);
560
558
  const delta = state.offset - state.center * state.dim;
@@ -563,7 +561,7 @@ const Carousel = () => {
563
561
  const half = count >> 1;
564
562
  let alignment;
565
563
  let centerTweenedOpacity;
566
- if (defaults.fullWidth) {
564
+ if (state.options.fullWidth) {
567
565
  alignment = 'translateX(0)';
568
566
  centerTweenedOpacity = 1;
569
567
  }
@@ -586,7 +584,7 @@ const Carousel = () => {
586
584
  // Add active class to center item
587
585
  items.forEach((item) => item.classList.remove('active'));
588
586
  el.classList.add('active');
589
- const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * defaults.shift * tween}px) translateZ(${defaults.dist * tween}px)`;
587
+ const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * state.options.shift * tween}px) translateZ(${state.options.dist * tween}px)`;
590
588
  updateItemStyle(el, centerTweenedOpacity, 0, transformString);
591
589
  }
592
590
  // Side items
@@ -594,31 +592,31 @@ const Carousel = () => {
594
592
  let zTranslation;
595
593
  let tweenedOpacity;
596
594
  // Right side
597
- if (defaults.fullWidth) {
598
- zTranslation = defaults.dist;
595
+ if (state.options.fullWidth) {
596
+ zTranslation = state.options.dist;
599
597
  tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
600
598
  }
601
599
  else {
602
- zTranslation = defaults.dist * (i * 2 + tween * dir);
600
+ zTranslation = state.options.dist * (i * 2 + tween * dir);
603
601
  tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
604
602
  }
605
603
  if (!state.noWrap || state.center + i < count) {
606
604
  const el = items[wrap(state.center + i, count)];
607
- const transformString = `${alignment} translateX(${defaults.shift + (state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
605
+ const transformString = `${alignment} translateX(${state.options.shift + (state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
608
606
  updateItemStyle(el, tweenedOpacity, -i, transformString);
609
607
  }
610
608
  // Left side
611
- if (defaults.fullWidth) {
612
- zTranslation = defaults.dist;
609
+ if (state.options.fullWidth) {
610
+ zTranslation = state.options.dist;
613
611
  tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
614
612
  }
615
613
  else {
616
- zTranslation = defaults.dist * (i * 2 - tween * dir);
614
+ zTranslation = state.options.dist * (i * 2 - tween * dir);
617
615
  tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
618
616
  }
619
617
  if (!state.noWrap || state.center - i >= 0) {
620
618
  const el = items[wrap(state.center - i, count)];
621
- const transformString = `${alignment} translateX(${-defaults.shift + (-state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
619
+ const transformString = `${alignment} translateX(${-state.options.shift + (-state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
622
620
  updateItemStyle(el, tweenedOpacity, -i, transformString);
623
621
  }
624
622
  }
@@ -751,7 +749,7 @@ const Carousel = () => {
751
749
  e.stopPropagation();
752
750
  return false;
753
751
  }
754
- else if (!defaults.fullWidth) {
752
+ else if (!state.options.fullWidth) {
755
753
  const target = e.target.closest('.carousel-item');
756
754
  if (target) {
757
755
  const items = Array.from(document.querySelectorAll('.carousel-item'));
@@ -780,24 +778,27 @@ const Carousel = () => {
780
778
  const { items, indicators = false } = attrs;
781
779
  if (!items || items.length === 0)
782
780
  return undefined;
783
- // Merge options
784
- Object.assign(defaults, attrs);
781
+ // Create instance-specific options without mutating globals
782
+ const instanceOptions = Object.assign(Object.assign({}, defaults), attrs);
783
+ // Update state options for this render
784
+ state.options = instanceOptions;
785
785
  const supportTouch = typeof window.ontouchstart !== 'undefined';
786
786
  return m('.carousel', {
787
787
  oncreate: ({ attrs, dom }) => {
788
788
  const carouselEl = dom;
789
789
  const items = carouselEl.querySelectorAll('.carousel-item');
790
790
  state.hasMultipleSlides = items.length > 1;
791
- state.showIndicators = defaults.indicators && state.hasMultipleSlides;
792
- state.noWrap = defaults.noWrap || !state.hasMultipleSlides;
791
+ state.showIndicators = instanceOptions.indicators && state.hasMultipleSlides;
792
+ state.noWrap = instanceOptions.noWrap || !state.hasMultipleSlides;
793
793
  if (items.length > 0) {
794
794
  const firstItem = items[0];
795
795
  state.itemWidth = firstItem.offsetWidth;
796
796
  state.itemHeight = firstItem.offsetHeight;
797
- state.dim = state.itemWidth * 2 + defaults.padding || 1;
797
+ state.dim = state.itemWidth * 2 + instanceOptions.padding || 1;
798
798
  }
799
799
  // Cap numVisible at count
800
- defaults.numVisible = Math.min(items.length, defaults.numVisible);
800
+ instanceOptions.numVisible = Math.min(items.length, instanceOptions.numVisible);
801
+ state.options = instanceOptions;
801
802
  // Initial scroll
802
803
  scroll(state.offset, attrs);
803
804
  },
@@ -1170,7 +1171,7 @@ const CodeBlock = () => ({
1170
1171
  const label = lang.replace('lang-', '');
1171
1172
  const cb = code instanceof Array ? code.join('\n') : code;
1172
1173
  const cn = [newRow ? 'clear' : '', lang, className].filter(Boolean).join(' ').trim() || undefined;
1173
- return m(`pre.codeblock${newRow ? '.clear' : ''}`, attrs, [
1174
+ return m(`pre.codeblock${newRow ? '.clear' : ''}`, params, [
1174
1175
  m('div', m('label', label)),
1175
1176
  m('code', Object.assign(Object.assign({}, params), { className: cn }), cb),
1176
1177
  ]);
package/dist/index.umd.js CHANGED
@@ -165,7 +165,7 @@
165
165
  const range = (a, b) => Array.from({ length: b - a + 1 }, (_, i) => a + i);
166
166
 
167
167
  // import './styles/input.css';
168
- const Mandatory = { view: ({ attrs }) => m('span.mandatory', attrs, '*') };
168
+ const Mandatory = { view: ({ attrs }) => m('span.mandatory', Object.assign({}, attrs), '*') };
169
169
  /** Simple label element, used for most components. */
170
170
  const Label = () => {
171
171
  return {
@@ -420,22 +420,17 @@
420
420
  return () => {
421
421
  return {
422
422
  view: ({ attrs }) => {
423
- const { modalId, tooltip, tooltipPosition, tooltipPostion, // Keep for backwards compatibility
424
- iconName, iconClass, label, className, attr, variant } = attrs, params = __rest(attrs, ["modalId", "tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "attr", "variant"]);
425
- // Handle both new variant prop and legacy modalId/type
426
- const buttonType = (variant === null || variant === void 0 ? void 0 : variant.type) || (modalId ? 'modal' : type || 'button');
427
- const modalTarget = (variant === null || variant === void 0 ? void 0 : variant.type) === 'modal' ? variant.modalId : modalId;
428
- const cn = [modalTarget ? 'modal-trigger' : '', tooltip ? 'tooltipped' : '', defaultClassNames, className]
423
+ const { tooltip, tooltipPosition, tooltipPostion, // Keep for backwards compatibility
424
+ iconName, iconClass, label, className, variant } = attrs, params = __rest(attrs, ["tooltip", "tooltipPosition", "tooltipPostion", "iconName", "iconClass", "label", "className", "variant"]);
425
+ // Use variant or fallback to factory type
426
+ const buttonType = variant || type || 'button';
427
+ const cn = [tooltip ? 'tooltipped' : '', defaultClassNames, className]
429
428
  .filter(Boolean)
430
429
  .join(' ')
431
430
  .trim();
432
431
  // Use tooltipPosition if available, fallback to legacy tooltipPostion
433
432
  const position = tooltipPosition || tooltipPostion || 'top';
434
- return m(element, Object.assign(Object.assign(Object.assign({}, params), attr), { className: cn, href: modalTarget ? `#${modalTarget}` : undefined, 'data-position': tooltip ? position : undefined, 'data-tooltip': tooltip || undefined, type: buttonType === 'modal' ? 'button' : buttonType }),
435
- // `${dca}${modalId ? `.modal-trigger[href=#${modalId}]` : ''}${
436
- // tooltip ? `.tooltipped[data-position=${tooltipPostion || 'top'}][data-tooltip=${tooltip}]` : ''
437
- // }${toAttributeString(attr)}`, {}
438
- iconName ? m(Icon, { iconName, className: iconClass || 'left' }) : undefined, label ? label : undefined);
433
+ 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);
439
434
  },
440
435
  };
441
436
  };
@@ -487,7 +482,10 @@
487
482
  dim: 1, // Make sure dim is non zero for divisions
488
483
  // Animation
489
484
  ticker: null,
490
- scrollingTimeout: null};
485
+ scrollingTimeout: null,
486
+ // Instance options (properly typed with defaults)
487
+ options: Object.assign({}, defaults),
488
+ };
491
489
  // Utility functions
492
490
  const xpos = (e) => {
493
491
  // Touch event
@@ -520,7 +518,7 @@
520
518
  const autoScroll = () => {
521
519
  if (state.amplitude) {
522
520
  const elapsed = Date.now() - state.timestamp;
523
- const delta = state.amplitude * Math.exp(-elapsed / defaults.duration);
521
+ const delta = state.amplitude * Math.exp(-elapsed / state.options.duration);
524
522
  if (delta > 2 || delta < -2) {
525
523
  scroll(state.target - delta);
526
524
  requestAnimationFrame(autoScroll);
@@ -549,14 +547,14 @@
549
547
  }
550
548
  state.scrollingTimeout = window.setTimeout(() => {
551
549
  carouselEl.classList.remove('scrolling');
552
- }, defaults.duration);
550
+ }, state.options.duration);
553
551
  // Start actual scroll
554
552
  const items = Array.from(carouselEl.querySelectorAll('.carousel-item'));
555
553
  const count = items.length;
556
554
  if (count === 0)
557
555
  return;
558
556
  const lastCenter = state.center;
559
- const numVisibleOffset = 1 / defaults.numVisible;
557
+ const numVisibleOffset = 1 / state.options.numVisible;
560
558
  state.offset = typeof x === 'number' ? x : state.offset;
561
559
  state.center = Math.floor((state.offset + state.dim / 2) / state.dim);
562
560
  const delta = state.offset - state.center * state.dim;
@@ -565,7 +563,7 @@
565
563
  const half = count >> 1;
566
564
  let alignment;
567
565
  let centerTweenedOpacity;
568
- if (defaults.fullWidth) {
566
+ if (state.options.fullWidth) {
569
567
  alignment = 'translateX(0)';
570
568
  centerTweenedOpacity = 1;
571
569
  }
@@ -588,7 +586,7 @@
588
586
  // Add active class to center item
589
587
  items.forEach((item) => item.classList.remove('active'));
590
588
  el.classList.add('active');
591
- const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * defaults.shift * tween}px) translateZ(${defaults.dist * tween}px)`;
589
+ const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir * state.options.shift * tween}px) translateZ(${state.options.dist * tween}px)`;
592
590
  updateItemStyle(el, centerTweenedOpacity, 0, transformString);
593
591
  }
594
592
  // Side items
@@ -596,31 +594,31 @@
596
594
  let zTranslation;
597
595
  let tweenedOpacity;
598
596
  // Right side
599
- if (defaults.fullWidth) {
600
- zTranslation = defaults.dist;
597
+ if (state.options.fullWidth) {
598
+ zTranslation = state.options.dist;
601
599
  tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
602
600
  }
603
601
  else {
604
- zTranslation = defaults.dist * (i * 2 + tween * dir);
602
+ zTranslation = state.options.dist * (i * 2 + tween * dir);
605
603
  tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
606
604
  }
607
605
  if (!state.noWrap || state.center + i < count) {
608
606
  const el = items[wrap(state.center + i, count)];
609
- const transformString = `${alignment} translateX(${defaults.shift + (state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
607
+ const transformString = `${alignment} translateX(${state.options.shift + (state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
610
608
  updateItemStyle(el, tweenedOpacity, -i, transformString);
611
609
  }
612
610
  // Left side
613
- if (defaults.fullWidth) {
614
- zTranslation = defaults.dist;
611
+ if (state.options.fullWidth) {
612
+ zTranslation = state.options.dist;
615
613
  tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
616
614
  }
617
615
  else {
618
- zTranslation = defaults.dist * (i * 2 - tween * dir);
616
+ zTranslation = state.options.dist * (i * 2 - tween * dir);
619
617
  tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
620
618
  }
621
619
  if (!state.noWrap || state.center - i >= 0) {
622
620
  const el = items[wrap(state.center - i, count)];
623
- const transformString = `${alignment} translateX(${-defaults.shift + (-state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
621
+ const transformString = `${alignment} translateX(${-state.options.shift + (-state.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
624
622
  updateItemStyle(el, tweenedOpacity, -i, transformString);
625
623
  }
626
624
  }
@@ -753,7 +751,7 @@
753
751
  e.stopPropagation();
754
752
  return false;
755
753
  }
756
- else if (!defaults.fullWidth) {
754
+ else if (!state.options.fullWidth) {
757
755
  const target = e.target.closest('.carousel-item');
758
756
  if (target) {
759
757
  const items = Array.from(document.querySelectorAll('.carousel-item'));
@@ -782,24 +780,27 @@
782
780
  const { items, indicators = false } = attrs;
783
781
  if (!items || items.length === 0)
784
782
  return undefined;
785
- // Merge options
786
- Object.assign(defaults, attrs);
783
+ // Create instance-specific options without mutating globals
784
+ const instanceOptions = Object.assign(Object.assign({}, defaults), attrs);
785
+ // Update state options for this render
786
+ state.options = instanceOptions;
787
787
  const supportTouch = typeof window.ontouchstart !== 'undefined';
788
788
  return m('.carousel', {
789
789
  oncreate: ({ attrs, dom }) => {
790
790
  const carouselEl = dom;
791
791
  const items = carouselEl.querySelectorAll('.carousel-item');
792
792
  state.hasMultipleSlides = items.length > 1;
793
- state.showIndicators = defaults.indicators && state.hasMultipleSlides;
794
- state.noWrap = defaults.noWrap || !state.hasMultipleSlides;
793
+ state.showIndicators = instanceOptions.indicators && state.hasMultipleSlides;
794
+ state.noWrap = instanceOptions.noWrap || !state.hasMultipleSlides;
795
795
  if (items.length > 0) {
796
796
  const firstItem = items[0];
797
797
  state.itemWidth = firstItem.offsetWidth;
798
798
  state.itemHeight = firstItem.offsetHeight;
799
- state.dim = state.itemWidth * 2 + defaults.padding || 1;
799
+ state.dim = state.itemWidth * 2 + instanceOptions.padding || 1;
800
800
  }
801
801
  // Cap numVisible at count
802
- defaults.numVisible = Math.min(items.length, defaults.numVisible);
802
+ instanceOptions.numVisible = Math.min(items.length, instanceOptions.numVisible);
803
+ state.options = instanceOptions;
803
804
  // Initial scroll
804
805
  scroll(state.offset, attrs);
805
806
  },
@@ -1172,7 +1173,7 @@
1172
1173
  const label = lang.replace('lang-', '');
1173
1174
  const cb = code instanceof Array ? code.join('\n') : code;
1174
1175
  const cn = [newRow ? 'clear' : '', lang, className].filter(Boolean).join(' ').trim() || undefined;
1175
- return m(`pre.codeblock${newRow ? '.clear' : ''}`, attrs, [
1176
+ return m(`pre.codeblock${newRow ? '.clear' : ''}`, params, [
1176
1177
  m('div', m('label', label)),
1177
1178
  m('code', Object.assign(Object.assign({}, params), { className: cn }), cb),
1178
1179
  ]);
package/dist/types.d.ts CHANGED
@@ -96,24 +96,20 @@ export declare const isValidationSuccess: (result: ValidationResult) => result i
96
96
  */
97
97
  export declare const isValidationError: (result: ValidationResult) => result is ValidationError;
98
98
  /**
99
- * Button variant discriminated union for type-safe button configurations
99
+ * Button type - determines the HTML button behavior
100
+ * @example
101
+ * ```typescript
102
+ * // Standard clickable button (default)
103
+ * variant: 'button'
104
+ *
105
+ * // Form submission button
106
+ * variant: 'submit'
107
+ *
108
+ * // Form reset button
109
+ * variant: 'reset'
110
+ * ```
100
111
  */
101
- export type ButtonVariant = {
102
- type: 'button';
103
- submit?: never;
104
- modalId?: never;
105
- } | {
106
- type: 'submit';
107
- modalId?: never;
108
- } | {
109
- type: 'modal';
110
- modalId: string;
111
- submit?: never;
112
- } | {
113
- type: 'reset';
114
- modalId?: never;
115
- submit?: never;
116
- };
112
+ export type ButtonVariant = 'button' | 'submit' | 'reset';
117
113
  /**
118
114
  * Input type union with proper HTML input types
119
115
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mithril-materialized",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "A materialize library for mithril.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",