mithril-materialized 2.0.0-rc.1 → 2.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.
@@ -1,4 +1,25 @@
1
1
  import { FactoryComponent, Attributes } from 'mithril';
2
+ export interface FileUploadI18n {
3
+ /** Default label text for upload area */
4
+ label?: string;
5
+ /** Text for selected files section */
6
+ selectedFiles?: string;
7
+ /** Text for accepted file types */
8
+ acceptedTypes?: string;
9
+ /** Remove file button title */
10
+ removeFile?: string;
11
+ /** File size limit error message template (use {maxSize} placeholder) */
12
+ fileSizeExceeds?: string;
13
+ /** File type not accepted error message template (use {accept} placeholder) */
14
+ fileTypeNotAccepted?: string;
15
+ /** File size units */
16
+ fileSizeUnits?: {
17
+ bytes?: string;
18
+ kb?: string;
19
+ mb?: string;
20
+ gb?: string;
21
+ };
22
+ }
2
23
  export interface FileUploadAttrs extends Attributes {
3
24
  /** Accept specific file types (e.g., "image/*", ".pdf,.doc") */
4
25
  accept?: string;
@@ -26,6 +47,8 @@ export interface FileUploadAttrs extends Attributes {
26
47
  className?: string;
27
48
  /** Validation error message */
28
49
  error?: string;
50
+ /** Internationalization */
51
+ i18n?: FileUploadI18n;
29
52
  }
30
53
  /**
31
54
  * File Upload Component with Drag and Drop
@@ -22,7 +22,7 @@ export interface FloatingActionButtonAttrs {
22
22
  /** Classes of the icon */
23
23
  iconClass?: string;
24
24
  /** On click function */
25
- onClick?: (e: UIEvent) => void;
25
+ onclick?: (e: UIEvent) => void;
26
26
  }>;
27
27
  /** Direction to open the buttons */
28
28
  direction?: 'top' | 'bottom' | 'left' | 'right';
package/dist/index.esm.js CHANGED
@@ -1350,7 +1350,7 @@ const Collection = () => {
1350
1350
  };
1351
1351
  };
1352
1352
 
1353
- const defaultI18n = {
1353
+ const defaultI18n$2 = {
1354
1354
  cancel: 'Cancel',
1355
1355
  clear: 'Clear',
1356
1356
  done: 'Ok',
@@ -1458,9 +1458,9 @@ const DatePicker = () => {
1458
1458
  else if (attrs.displayFormat) {
1459
1459
  finalFormat = attrs.displayFormat;
1460
1460
  }
1461
- const merged = Object.assign({ autoClose: false, format: finalFormat, parse: null, defaultDate: null, setDefaultDate: false, disableWeekends: false, disableDayFn: null, firstDay: 0, minDate: null, maxDate: null, yearRange, showClearBtn: false, showWeekNumbers: false, weekNumbering: 'iso', i18n: defaultI18n, onSelect: null, onOpen: null, onClose: null }, attrs);
1461
+ const merged = Object.assign({ autoClose: false, format: finalFormat, parse: null, defaultDate: null, setDefaultDate: false, disableWeekends: false, disableDayFn: null, firstDay: 0, minDate: null, maxDate: null, yearRange, showClearBtn: false, showWeekNumbers: false, weekNumbering: 'iso', i18n: defaultI18n$2, onSelect: null, onOpen: null, onClose: null }, attrs);
1462
1462
  // Merge i18n properly
1463
- merged.i18n = Object.assign(Object.assign({}, defaultI18n), attrs.i18n);
1463
+ merged.i18n = Object.assign(Object.assign({}, defaultI18n$2), attrs.i18n);
1464
1464
  return merged;
1465
1465
  };
1466
1466
  const toString = (date, format) => {
@@ -4083,8 +4083,8 @@ const FloatingActionButton = () => {
4083
4083
  },
4084
4084
  onclick: (e) => {
4085
4085
  e.stopPropagation();
4086
- if (button.onClick)
4087
- button.onClick(e);
4086
+ if (button.onclick)
4087
+ button.onclick(e);
4088
4088
  },
4089
4089
  }, m('i.material-icons', { className: button.iconClass }, button.iconName))))),
4090
4090
  ]));
@@ -6673,6 +6673,17 @@ const initTooltips = (selector = '[data-tooltip]', options = {}) => {
6673
6673
  return tooltips;
6674
6674
  };
6675
6675
 
6676
+ const defaultI18n$1 = {
6677
+ theme: 'Theme:',
6678
+ light: 'Light',
6679
+ dark: 'Dark',
6680
+ auto: 'Auto',
6681
+ lightTitle: 'Light theme',
6682
+ darkTitle: 'Dark theme',
6683
+ autoTitle: 'Auto theme (system preference)',
6684
+ switchToDark: 'Switch to dark theme',
6685
+ switchToLight: 'Switch to light theme',
6686
+ };
6676
6687
  /**
6677
6688
  * Theme switching utilities and component
6678
6689
  */
@@ -6755,44 +6766,36 @@ const ThemeSwitcher = () => {
6755
6766
  ThemeManager.initialize();
6756
6767
  }
6757
6768
  },
6758
- view: ({ attrs }) => {
6759
- const { theme = ThemeManager.getTheme(), onThemeChange, showLabels = true, className = '' } = attrs;
6769
+ view: ({ attrs = {} }) => {
6770
+ const { theme = ThemeManager.getTheme(), onThemeChange, showLabels = true, className, i18n } = attrs;
6771
+ const labels = Object.assign(Object.assign({}, defaultI18n$1), i18n);
6760
6772
  const handleThemeChange = (newTheme) => {
6761
6773
  ThemeManager.setTheme(newTheme);
6762
6774
  if (onThemeChange) {
6763
6775
  onThemeChange(newTheme);
6764
6776
  }
6765
6777
  };
6766
- return m('.theme-switcher', { class: className }, [
6767
- showLabels && m('span.theme-switcher-label', 'Theme:'),
6778
+ return m('.theme-switcher', { className }, [
6779
+ showLabels && m('span.theme-switcher-label', labels.theme),
6768
6780
  m('.theme-switcher-buttons', [
6769
6781
  m('button.btn-flat', {
6770
6782
  class: theme === 'light' ? 'active' : '',
6771
6783
  onclick: () => handleThemeChange('light'),
6772
- title: 'Light theme'
6773
- }, [
6774
- m('i.material-icons', 'light_mode'),
6775
- showLabels && m('span', 'Light')
6776
- ]),
6784
+ title: labels.lightTitle,
6785
+ }, [m('i.material-icons', 'light_mode'), showLabels && m('span', labels.light)]),
6777
6786
  m('button.btn-flat', {
6778
6787
  class: theme === 'auto' ? 'active' : '',
6779
6788
  onclick: () => handleThemeChange('auto'),
6780
- title: 'Auto theme (system preference)'
6781
- }, [
6782
- m('i.material-icons', 'brightness_auto'),
6783
- showLabels && m('span', 'Auto')
6784
- ]),
6789
+ title: labels.autoTitle,
6790
+ }, [m('i.material-icons', 'brightness_auto'), showLabels && m('span', labels.auto)]),
6785
6791
  m('button.btn-flat', {
6786
6792
  class: theme === 'dark' ? 'active' : '',
6787
6793
  onclick: () => handleThemeChange('dark'),
6788
- title: 'Dark theme'
6789
- }, [
6790
- m('i.material-icons', 'dark_mode'),
6791
- showLabels && m('span', 'Dark')
6792
- ])
6793
- ])
6794
+ title: labels.darkTitle,
6795
+ }, [m('i.material-icons', 'dark_mode'), showLabels && m('span', labels.dark)]),
6796
+ ]),
6794
6797
  ]);
6795
- }
6798
+ },
6796
6799
  };
6797
6800
  };
6798
6801
  /**
@@ -6806,36 +6809,50 @@ const ThemeToggle = () => {
6806
6809
  ThemeManager.initialize();
6807
6810
  }
6808
6811
  },
6809
- view: ({ attrs }) => {
6812
+ view: ({ attrs = {} }) => {
6810
6813
  const currentTheme = ThemeManager.getEffectiveTheme();
6814
+ const labels = Object.assign(Object.assign({}, defaultI18n$1), attrs.i18n);
6811
6815
  return m('button.btn-flat.theme-toggle', {
6812
6816
  class: attrs.className || '',
6813
6817
  onclick: () => {
6814
6818
  ThemeManager.toggle();
6815
- m.redraw();
6816
6819
  },
6817
- title: `Switch to ${currentTheme === 'light' ? 'dark' : 'light'} theme`,
6818
- style: 'margin: 0; height: 64px; line-height: 64px; border-radius: 0; min-width: 64px; padding: 0;'
6820
+ title: currentTheme === 'light' ? labels.switchToDark : labels.switchToLight,
6821
+ style: 'margin: 0; height: 64px; line-height: 64px; border-radius: 0; min-width: 64px; padding: 0;',
6819
6822
  }, [
6820
6823
  m('i.material-icons', {
6821
- style: 'color: inherit; font-size: 24px;'
6822
- }, currentTheme === 'light' ? 'dark_mode' : 'light_mode')
6824
+ style: 'color: inherit; font-size: 24px;',
6825
+ }, currentTheme === 'light' ? 'dark_mode' : 'light_mode'),
6823
6826
  ]);
6824
- }
6827
+ },
6825
6828
  };
6826
6829
  };
6827
6830
 
6831
+ const defaultI18n = {
6832
+ label: 'Choose files or drag them here',
6833
+ selectedFiles: 'Selected Files:',
6834
+ acceptedTypes: 'Accepted:',
6835
+ removeFile: 'Remove file',
6836
+ fileSizeExceeds: 'File size exceeds {maxSize}MB limit',
6837
+ fileTypeNotAccepted: 'File type not accepted. Accepted: {accept}',
6838
+ fileSizeUnits: {
6839
+ bytes: 'B',
6840
+ kb: 'KB',
6841
+ mb: 'MB',
6842
+ gb: 'GB',
6843
+ },
6844
+ };
6828
6845
  /**
6829
6846
  * File Upload Component with Drag and Drop
6830
6847
  * Supports multiple files, file type validation, size limits, and image preview
6831
6848
  */
6832
6849
  const FileUpload = () => {
6833
6850
  let state;
6834
- const validateFile = (file, attrs) => {
6851
+ const validateFile = (file, attrs, labels) => {
6835
6852
  // Check file size
6836
6853
  if (attrs.maxSize && file.size > attrs.maxSize) {
6837
6854
  const maxSizeMB = (attrs.maxSize / (1024 * 1024)).toFixed(1);
6838
- return `File size exceeds ${maxSizeMB}MB limit`;
6855
+ return labels.fileSizeExceeds.replace('{maxSize}', maxSizeMB);
6839
6856
  }
6840
6857
  // Check file type
6841
6858
  if (attrs.accept) {
@@ -6851,7 +6868,7 @@ const FileUpload = () => {
6851
6868
  }
6852
6869
  });
6853
6870
  if (!isAccepted) {
6854
- return `File type not accepted. Accepted: ${attrs.accept}`;
6871
+ return labels.fileTypeNotAccepted.replace('{accept}', attrs.accept);
6855
6872
  }
6856
6873
  }
6857
6874
  return null;
@@ -6867,12 +6884,12 @@ const FileUpload = () => {
6867
6884
  reader.readAsDataURL(file);
6868
6885
  }
6869
6886
  };
6870
- const handleFiles = (fileList, attrs) => {
6887
+ const handleFiles = (fileList, attrs, labels) => {
6871
6888
  const newFiles = Array.from(fileList);
6872
6889
  const validFiles = [];
6873
6890
  // Validate each file
6874
6891
  for (const file of newFiles) {
6875
- const error = validateFile(file, attrs);
6892
+ const error = validateFile(file, attrs, labels);
6876
6893
  if (error) {
6877
6894
  file.uploadError = error;
6878
6895
  }
@@ -6909,11 +6926,11 @@ const FileUpload = () => {
6909
6926
  attrs.onFileRemoved(fileToRemove);
6910
6927
  }
6911
6928
  };
6912
- const formatFileSize = (bytes) => {
6929
+ const formatFileSize = (bytes, labels) => {
6913
6930
  if (bytes === 0)
6914
- return '0 B';
6931
+ return `0 ${labels.fileSizeUnits.bytes}`;
6915
6932
  const k = 1024;
6916
- const sizes = ['B', 'KB', 'MB', 'GB'];
6933
+ const sizes = [labels.fileSizeUnits.bytes, labels.fileSizeUnits.kb, labels.fileSizeUnits.mb, labels.fileSizeUnits.gb];
6917
6934
  const i = Math.floor(Math.log(bytes) / Math.log(k));
6918
6935
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
6919
6936
  };
@@ -6927,7 +6944,9 @@ const FileUpload = () => {
6927
6944
  };
6928
6945
  },
6929
6946
  view: ({ attrs }) => {
6930
- const { accept, multiple = false, disabled = false, label = 'Choose files or drag them here', helperText, showPreview = true, className = '', error, } = attrs;
6947
+ const { accept, multiple = false, disabled = false, label, helperText, showPreview = true, className = '', error, i18n, } = attrs;
6948
+ const labels = Object.assign(Object.assign({}, defaultI18n), i18n);
6949
+ const displayLabel = label || labels.label;
6931
6950
  return m('.file-upload-container', { class: className }, [
6932
6951
  // Upload area
6933
6952
  m('.file-upload-area', {
@@ -6961,7 +6980,7 @@ const FileUpload = () => {
6961
6980
  e.stopPropagation();
6962
6981
  state.isDragOver = false;
6963
6982
  if ((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) {
6964
- handleFiles(e.dataTransfer.files, attrs);
6983
+ handleFiles(e.dataTransfer.files, attrs, labels);
6965
6984
  }
6966
6985
  },
6967
6986
  onclick: () => {
@@ -6980,15 +6999,15 @@ const FileUpload = () => {
6980
6999
  onchange: (e) => {
6981
7000
  const target = e.target;
6982
7001
  if (target.files) {
6983
- handleFiles(target.files, attrs);
7002
+ handleFiles(target.files, attrs, labels);
6984
7003
  }
6985
7004
  },
6986
7005
  }),
6987
7006
  m('.file-upload-content', [
6988
7007
  m('i.material-icons.file-upload-icon', 'cloud_upload'),
6989
- m('p.file-upload-label', label),
7008
+ m('p.file-upload-label', displayLabel),
6990
7009
  helperText && m('p.file-upload-helper', helperText),
6991
- accept && m('p.file-upload-types', `Accepted: ${accept}`),
7010
+ accept && m('p.file-upload-types', `${labels.acceptedTypes} ${accept}`),
6992
7011
  ]),
6993
7012
  ]),
6994
7013
  // Error message
@@ -6996,7 +7015,7 @@ const FileUpload = () => {
6996
7015
  // File list
6997
7016
  state.files.length > 0 &&
6998
7017
  m('.file-upload-list', [
6999
- m('h6', 'Selected Files:'),
7018
+ m('h6', labels.selectedFiles),
7000
7019
  state.files.map((file) => m('.file-upload-item', { key: file.name + file.size }, [
7001
7020
  // Preview thumbnail
7002
7021
  showPreview && file.preview && m('.file-preview', [m('img', { src: file.preview, alt: file.name })]),
@@ -7004,7 +7023,7 @@ const FileUpload = () => {
7004
7023
  m('.file-info', [
7005
7024
  m('.file-name', file.name),
7006
7025
  m('.file-details', [
7007
- m('span.file-size', formatFileSize(file.size)),
7026
+ m('span.file-size', formatFileSize(file.size, labels)),
7008
7027
  file.type && m('span.file-type', file.type),
7009
7028
  ]),
7010
7029
  // Progress bar (if uploading)
@@ -7025,7 +7044,7 @@ const FileUpload = () => {
7025
7044
  e.stopPropagation();
7026
7045
  removeFile(file, attrs);
7027
7046
  },
7028
- title: 'Remove file',
7047
+ title: labels.removeFile,
7029
7048
  }, [m('i.material-icons', 'close')]),
7030
7049
  ])),
7031
7050
  ]),
@@ -7866,18 +7885,18 @@ const Timeline = () => {
7866
7885
  const handleItemClick = (e) => {
7867
7886
  if (item.disabled)
7868
7887
  return;
7869
- if (item.onClick) {
7888
+ if (item.onclick) {
7870
7889
  e.preventDefault();
7871
- item.onClick(item, e);
7890
+ item.onclick(item, e);
7872
7891
  }
7873
7892
  };
7874
7893
  const isVertical = orientation === 'vertical';
7875
7894
  return m('div', {
7876
7895
  key: item.id || index,
7877
7896
  className: itemClasses,
7878
- onclick: item.onClick ? handleItemClick : undefined,
7879
- role: item.onClick ? 'button' : undefined,
7880
- tabindex: item.onClick && !item.disabled ? 0 : undefined,
7897
+ onclick: item.onclick ? handleItemClick : undefined,
7898
+ role: item.onclick ? 'button' : undefined,
7899
+ tabindex: item.onclick && !item.disabled ? 0 : undefined,
7881
7900
  'aria-disabled': item.disabled ? 'true' : undefined,
7882
7901
  }, [
7883
7902
  // Timestamp (on opposite side of content from bullet)
package/dist/index.js CHANGED
@@ -1352,7 +1352,7 @@ const Collection = () => {
1352
1352
  };
1353
1353
  };
1354
1354
 
1355
- const defaultI18n = {
1355
+ const defaultI18n$2 = {
1356
1356
  cancel: 'Cancel',
1357
1357
  clear: 'Clear',
1358
1358
  done: 'Ok',
@@ -1460,9 +1460,9 @@ const DatePicker = () => {
1460
1460
  else if (attrs.displayFormat) {
1461
1461
  finalFormat = attrs.displayFormat;
1462
1462
  }
1463
- const merged = Object.assign({ autoClose: false, format: finalFormat, parse: null, defaultDate: null, setDefaultDate: false, disableWeekends: false, disableDayFn: null, firstDay: 0, minDate: null, maxDate: null, yearRange, showClearBtn: false, showWeekNumbers: false, weekNumbering: 'iso', i18n: defaultI18n, onSelect: null, onOpen: null, onClose: null }, attrs);
1463
+ const merged = Object.assign({ autoClose: false, format: finalFormat, parse: null, defaultDate: null, setDefaultDate: false, disableWeekends: false, disableDayFn: null, firstDay: 0, minDate: null, maxDate: null, yearRange, showClearBtn: false, showWeekNumbers: false, weekNumbering: 'iso', i18n: defaultI18n$2, onSelect: null, onOpen: null, onClose: null }, attrs);
1464
1464
  // Merge i18n properly
1465
- merged.i18n = Object.assign(Object.assign({}, defaultI18n), attrs.i18n);
1465
+ merged.i18n = Object.assign(Object.assign({}, defaultI18n$2), attrs.i18n);
1466
1466
  return merged;
1467
1467
  };
1468
1468
  const toString = (date, format) => {
@@ -4085,8 +4085,8 @@ const FloatingActionButton = () => {
4085
4085
  },
4086
4086
  onclick: (e) => {
4087
4087
  e.stopPropagation();
4088
- if (button.onClick)
4089
- button.onClick(e);
4088
+ if (button.onclick)
4089
+ button.onclick(e);
4090
4090
  },
4091
4091
  }, m('i.material-icons', { className: button.iconClass }, button.iconName))))),
4092
4092
  ]));
@@ -6675,6 +6675,17 @@ const initTooltips = (selector = '[data-tooltip]', options = {}) => {
6675
6675
  return tooltips;
6676
6676
  };
6677
6677
 
6678
+ const defaultI18n$1 = {
6679
+ theme: 'Theme:',
6680
+ light: 'Light',
6681
+ dark: 'Dark',
6682
+ auto: 'Auto',
6683
+ lightTitle: 'Light theme',
6684
+ darkTitle: 'Dark theme',
6685
+ autoTitle: 'Auto theme (system preference)',
6686
+ switchToDark: 'Switch to dark theme',
6687
+ switchToLight: 'Switch to light theme',
6688
+ };
6678
6689
  /**
6679
6690
  * Theme switching utilities and component
6680
6691
  */
@@ -6757,44 +6768,36 @@ const ThemeSwitcher = () => {
6757
6768
  ThemeManager.initialize();
6758
6769
  }
6759
6770
  },
6760
- view: ({ attrs }) => {
6761
- const { theme = ThemeManager.getTheme(), onThemeChange, showLabels = true, className = '' } = attrs;
6771
+ view: ({ attrs = {} }) => {
6772
+ const { theme = ThemeManager.getTheme(), onThemeChange, showLabels = true, className, i18n } = attrs;
6773
+ const labels = Object.assign(Object.assign({}, defaultI18n$1), i18n);
6762
6774
  const handleThemeChange = (newTheme) => {
6763
6775
  ThemeManager.setTheme(newTheme);
6764
6776
  if (onThemeChange) {
6765
6777
  onThemeChange(newTheme);
6766
6778
  }
6767
6779
  };
6768
- return m('.theme-switcher', { class: className }, [
6769
- showLabels && m('span.theme-switcher-label', 'Theme:'),
6780
+ return m('.theme-switcher', { className }, [
6781
+ showLabels && m('span.theme-switcher-label', labels.theme),
6770
6782
  m('.theme-switcher-buttons', [
6771
6783
  m('button.btn-flat', {
6772
6784
  class: theme === 'light' ? 'active' : '',
6773
6785
  onclick: () => handleThemeChange('light'),
6774
- title: 'Light theme'
6775
- }, [
6776
- m('i.material-icons', 'light_mode'),
6777
- showLabels && m('span', 'Light')
6778
- ]),
6786
+ title: labels.lightTitle,
6787
+ }, [m('i.material-icons', 'light_mode'), showLabels && m('span', labels.light)]),
6779
6788
  m('button.btn-flat', {
6780
6789
  class: theme === 'auto' ? 'active' : '',
6781
6790
  onclick: () => handleThemeChange('auto'),
6782
- title: 'Auto theme (system preference)'
6783
- }, [
6784
- m('i.material-icons', 'brightness_auto'),
6785
- showLabels && m('span', 'Auto')
6786
- ]),
6791
+ title: labels.autoTitle,
6792
+ }, [m('i.material-icons', 'brightness_auto'), showLabels && m('span', labels.auto)]),
6787
6793
  m('button.btn-flat', {
6788
6794
  class: theme === 'dark' ? 'active' : '',
6789
6795
  onclick: () => handleThemeChange('dark'),
6790
- title: 'Dark theme'
6791
- }, [
6792
- m('i.material-icons', 'dark_mode'),
6793
- showLabels && m('span', 'Dark')
6794
- ])
6795
- ])
6796
+ title: labels.darkTitle,
6797
+ }, [m('i.material-icons', 'dark_mode'), showLabels && m('span', labels.dark)]),
6798
+ ]),
6796
6799
  ]);
6797
- }
6800
+ },
6798
6801
  };
6799
6802
  };
6800
6803
  /**
@@ -6808,36 +6811,50 @@ const ThemeToggle = () => {
6808
6811
  ThemeManager.initialize();
6809
6812
  }
6810
6813
  },
6811
- view: ({ attrs }) => {
6814
+ view: ({ attrs = {} }) => {
6812
6815
  const currentTheme = ThemeManager.getEffectiveTheme();
6816
+ const labels = Object.assign(Object.assign({}, defaultI18n$1), attrs.i18n);
6813
6817
  return m('button.btn-flat.theme-toggle', {
6814
6818
  class: attrs.className || '',
6815
6819
  onclick: () => {
6816
6820
  ThemeManager.toggle();
6817
- m.redraw();
6818
6821
  },
6819
- title: `Switch to ${currentTheme === 'light' ? 'dark' : 'light'} theme`,
6820
- style: 'margin: 0; height: 64px; line-height: 64px; border-radius: 0; min-width: 64px; padding: 0;'
6822
+ title: currentTheme === 'light' ? labels.switchToDark : labels.switchToLight,
6823
+ style: 'margin: 0; height: 64px; line-height: 64px; border-radius: 0; min-width: 64px; padding: 0;',
6821
6824
  }, [
6822
6825
  m('i.material-icons', {
6823
- style: 'color: inherit; font-size: 24px;'
6824
- }, currentTheme === 'light' ? 'dark_mode' : 'light_mode')
6826
+ style: 'color: inherit; font-size: 24px;',
6827
+ }, currentTheme === 'light' ? 'dark_mode' : 'light_mode'),
6825
6828
  ]);
6826
- }
6829
+ },
6827
6830
  };
6828
6831
  };
6829
6832
 
6833
+ const defaultI18n = {
6834
+ label: 'Choose files or drag them here',
6835
+ selectedFiles: 'Selected Files:',
6836
+ acceptedTypes: 'Accepted:',
6837
+ removeFile: 'Remove file',
6838
+ fileSizeExceeds: 'File size exceeds {maxSize}MB limit',
6839
+ fileTypeNotAccepted: 'File type not accepted. Accepted: {accept}',
6840
+ fileSizeUnits: {
6841
+ bytes: 'B',
6842
+ kb: 'KB',
6843
+ mb: 'MB',
6844
+ gb: 'GB',
6845
+ },
6846
+ };
6830
6847
  /**
6831
6848
  * File Upload Component with Drag and Drop
6832
6849
  * Supports multiple files, file type validation, size limits, and image preview
6833
6850
  */
6834
6851
  const FileUpload = () => {
6835
6852
  let state;
6836
- const validateFile = (file, attrs) => {
6853
+ const validateFile = (file, attrs, labels) => {
6837
6854
  // Check file size
6838
6855
  if (attrs.maxSize && file.size > attrs.maxSize) {
6839
6856
  const maxSizeMB = (attrs.maxSize / (1024 * 1024)).toFixed(1);
6840
- return `File size exceeds ${maxSizeMB}MB limit`;
6857
+ return labels.fileSizeExceeds.replace('{maxSize}', maxSizeMB);
6841
6858
  }
6842
6859
  // Check file type
6843
6860
  if (attrs.accept) {
@@ -6853,7 +6870,7 @@ const FileUpload = () => {
6853
6870
  }
6854
6871
  });
6855
6872
  if (!isAccepted) {
6856
- return `File type not accepted. Accepted: ${attrs.accept}`;
6873
+ return labels.fileTypeNotAccepted.replace('{accept}', attrs.accept);
6857
6874
  }
6858
6875
  }
6859
6876
  return null;
@@ -6869,12 +6886,12 @@ const FileUpload = () => {
6869
6886
  reader.readAsDataURL(file);
6870
6887
  }
6871
6888
  };
6872
- const handleFiles = (fileList, attrs) => {
6889
+ const handleFiles = (fileList, attrs, labels) => {
6873
6890
  const newFiles = Array.from(fileList);
6874
6891
  const validFiles = [];
6875
6892
  // Validate each file
6876
6893
  for (const file of newFiles) {
6877
- const error = validateFile(file, attrs);
6894
+ const error = validateFile(file, attrs, labels);
6878
6895
  if (error) {
6879
6896
  file.uploadError = error;
6880
6897
  }
@@ -6911,11 +6928,11 @@ const FileUpload = () => {
6911
6928
  attrs.onFileRemoved(fileToRemove);
6912
6929
  }
6913
6930
  };
6914
- const formatFileSize = (bytes) => {
6931
+ const formatFileSize = (bytes, labels) => {
6915
6932
  if (bytes === 0)
6916
- return '0 B';
6933
+ return `0 ${labels.fileSizeUnits.bytes}`;
6917
6934
  const k = 1024;
6918
- const sizes = ['B', 'KB', 'MB', 'GB'];
6935
+ const sizes = [labels.fileSizeUnits.bytes, labels.fileSizeUnits.kb, labels.fileSizeUnits.mb, labels.fileSizeUnits.gb];
6919
6936
  const i = Math.floor(Math.log(bytes) / Math.log(k));
6920
6937
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
6921
6938
  };
@@ -6929,7 +6946,9 @@ const FileUpload = () => {
6929
6946
  };
6930
6947
  },
6931
6948
  view: ({ attrs }) => {
6932
- const { accept, multiple = false, disabled = false, label = 'Choose files or drag them here', helperText, showPreview = true, className = '', error, } = attrs;
6949
+ const { accept, multiple = false, disabled = false, label, helperText, showPreview = true, className = '', error, i18n, } = attrs;
6950
+ const labels = Object.assign(Object.assign({}, defaultI18n), i18n);
6951
+ const displayLabel = label || labels.label;
6933
6952
  return m('.file-upload-container', { class: className }, [
6934
6953
  // Upload area
6935
6954
  m('.file-upload-area', {
@@ -6963,7 +6982,7 @@ const FileUpload = () => {
6963
6982
  e.stopPropagation();
6964
6983
  state.isDragOver = false;
6965
6984
  if ((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) {
6966
- handleFiles(e.dataTransfer.files, attrs);
6985
+ handleFiles(e.dataTransfer.files, attrs, labels);
6967
6986
  }
6968
6987
  },
6969
6988
  onclick: () => {
@@ -6982,15 +7001,15 @@ const FileUpload = () => {
6982
7001
  onchange: (e) => {
6983
7002
  const target = e.target;
6984
7003
  if (target.files) {
6985
- handleFiles(target.files, attrs);
7004
+ handleFiles(target.files, attrs, labels);
6986
7005
  }
6987
7006
  },
6988
7007
  }),
6989
7008
  m('.file-upload-content', [
6990
7009
  m('i.material-icons.file-upload-icon', 'cloud_upload'),
6991
- m('p.file-upload-label', label),
7010
+ m('p.file-upload-label', displayLabel),
6992
7011
  helperText && m('p.file-upload-helper', helperText),
6993
- accept && m('p.file-upload-types', `Accepted: ${accept}`),
7012
+ accept && m('p.file-upload-types', `${labels.acceptedTypes} ${accept}`),
6994
7013
  ]),
6995
7014
  ]),
6996
7015
  // Error message
@@ -6998,7 +7017,7 @@ const FileUpload = () => {
6998
7017
  // File list
6999
7018
  state.files.length > 0 &&
7000
7019
  m('.file-upload-list', [
7001
- m('h6', 'Selected Files:'),
7020
+ m('h6', labels.selectedFiles),
7002
7021
  state.files.map((file) => m('.file-upload-item', { key: file.name + file.size }, [
7003
7022
  // Preview thumbnail
7004
7023
  showPreview && file.preview && m('.file-preview', [m('img', { src: file.preview, alt: file.name })]),
@@ -7006,7 +7025,7 @@ const FileUpload = () => {
7006
7025
  m('.file-info', [
7007
7026
  m('.file-name', file.name),
7008
7027
  m('.file-details', [
7009
- m('span.file-size', formatFileSize(file.size)),
7028
+ m('span.file-size', formatFileSize(file.size, labels)),
7010
7029
  file.type && m('span.file-type', file.type),
7011
7030
  ]),
7012
7031
  // Progress bar (if uploading)
@@ -7027,7 +7046,7 @@ const FileUpload = () => {
7027
7046
  e.stopPropagation();
7028
7047
  removeFile(file, attrs);
7029
7048
  },
7030
- title: 'Remove file',
7049
+ title: labels.removeFile,
7031
7050
  }, [m('i.material-icons', 'close')]),
7032
7051
  ])),
7033
7052
  ]),
@@ -7868,18 +7887,18 @@ const Timeline = () => {
7868
7887
  const handleItemClick = (e) => {
7869
7888
  if (item.disabled)
7870
7889
  return;
7871
- if (item.onClick) {
7890
+ if (item.onclick) {
7872
7891
  e.preventDefault();
7873
- item.onClick(item, e);
7892
+ item.onclick(item, e);
7874
7893
  }
7875
7894
  };
7876
7895
  const isVertical = orientation === 'vertical';
7877
7896
  return m('div', {
7878
7897
  key: item.id || index,
7879
7898
  className: itemClasses,
7880
- onclick: item.onClick ? handleItemClick : undefined,
7881
- role: item.onClick ? 'button' : undefined,
7882
- tabindex: item.onClick && !item.disabled ? 0 : undefined,
7899
+ onclick: item.onclick ? handleItemClick : undefined,
7900
+ role: item.onclick ? 'button' : undefined,
7901
+ tabindex: item.onclick && !item.disabled ? 0 : undefined,
7883
7902
  'aria-disabled': item.disabled ? 'true' : undefined,
7884
7903
  }, [
7885
7904
  // Timestamp (on opposite side of content from bullet)
package/dist/index.umd.js CHANGED
@@ -1354,7 +1354,7 @@
1354
1354
  };
1355
1355
  };
1356
1356
 
1357
- const defaultI18n = {
1357
+ const defaultI18n$2 = {
1358
1358
  cancel: 'Cancel',
1359
1359
  clear: 'Clear',
1360
1360
  done: 'Ok',
@@ -1462,9 +1462,9 @@
1462
1462
  else if (attrs.displayFormat) {
1463
1463
  finalFormat = attrs.displayFormat;
1464
1464
  }
1465
- const merged = Object.assign({ autoClose: false, format: finalFormat, parse: null, defaultDate: null, setDefaultDate: false, disableWeekends: false, disableDayFn: null, firstDay: 0, minDate: null, maxDate: null, yearRange, showClearBtn: false, showWeekNumbers: false, weekNumbering: 'iso', i18n: defaultI18n, onSelect: null, onOpen: null, onClose: null }, attrs);
1465
+ const merged = Object.assign({ autoClose: false, format: finalFormat, parse: null, defaultDate: null, setDefaultDate: false, disableWeekends: false, disableDayFn: null, firstDay: 0, minDate: null, maxDate: null, yearRange, showClearBtn: false, showWeekNumbers: false, weekNumbering: 'iso', i18n: defaultI18n$2, onSelect: null, onOpen: null, onClose: null }, attrs);
1466
1466
  // Merge i18n properly
1467
- merged.i18n = Object.assign(Object.assign({}, defaultI18n), attrs.i18n);
1467
+ merged.i18n = Object.assign(Object.assign({}, defaultI18n$2), attrs.i18n);
1468
1468
  return merged;
1469
1469
  };
1470
1470
  const toString = (date, format) => {
@@ -4087,8 +4087,8 @@
4087
4087
  },
4088
4088
  onclick: (e) => {
4089
4089
  e.stopPropagation();
4090
- if (button.onClick)
4091
- button.onClick(e);
4090
+ if (button.onclick)
4091
+ button.onclick(e);
4092
4092
  },
4093
4093
  }, m('i.material-icons', { className: button.iconClass }, button.iconName))))),
4094
4094
  ]));
@@ -6677,6 +6677,17 @@
6677
6677
  return tooltips;
6678
6678
  };
6679
6679
 
6680
+ const defaultI18n$1 = {
6681
+ theme: 'Theme:',
6682
+ light: 'Light',
6683
+ dark: 'Dark',
6684
+ auto: 'Auto',
6685
+ lightTitle: 'Light theme',
6686
+ darkTitle: 'Dark theme',
6687
+ autoTitle: 'Auto theme (system preference)',
6688
+ switchToDark: 'Switch to dark theme',
6689
+ switchToLight: 'Switch to light theme',
6690
+ };
6680
6691
  /**
6681
6692
  * Theme switching utilities and component
6682
6693
  */
@@ -6759,44 +6770,36 @@
6759
6770
  ThemeManager.initialize();
6760
6771
  }
6761
6772
  },
6762
- view: ({ attrs }) => {
6763
- const { theme = ThemeManager.getTheme(), onThemeChange, showLabels = true, className = '' } = attrs;
6773
+ view: ({ attrs = {} }) => {
6774
+ const { theme = ThemeManager.getTheme(), onThemeChange, showLabels = true, className, i18n } = attrs;
6775
+ const labels = Object.assign(Object.assign({}, defaultI18n$1), i18n);
6764
6776
  const handleThemeChange = (newTheme) => {
6765
6777
  ThemeManager.setTheme(newTheme);
6766
6778
  if (onThemeChange) {
6767
6779
  onThemeChange(newTheme);
6768
6780
  }
6769
6781
  };
6770
- return m('.theme-switcher', { class: className }, [
6771
- showLabels && m('span.theme-switcher-label', 'Theme:'),
6782
+ return m('.theme-switcher', { className }, [
6783
+ showLabels && m('span.theme-switcher-label', labels.theme),
6772
6784
  m('.theme-switcher-buttons', [
6773
6785
  m('button.btn-flat', {
6774
6786
  class: theme === 'light' ? 'active' : '',
6775
6787
  onclick: () => handleThemeChange('light'),
6776
- title: 'Light theme'
6777
- }, [
6778
- m('i.material-icons', 'light_mode'),
6779
- showLabels && m('span', 'Light')
6780
- ]),
6788
+ title: labels.lightTitle,
6789
+ }, [m('i.material-icons', 'light_mode'), showLabels && m('span', labels.light)]),
6781
6790
  m('button.btn-flat', {
6782
6791
  class: theme === 'auto' ? 'active' : '',
6783
6792
  onclick: () => handleThemeChange('auto'),
6784
- title: 'Auto theme (system preference)'
6785
- }, [
6786
- m('i.material-icons', 'brightness_auto'),
6787
- showLabels && m('span', 'Auto')
6788
- ]),
6793
+ title: labels.autoTitle,
6794
+ }, [m('i.material-icons', 'brightness_auto'), showLabels && m('span', labels.auto)]),
6789
6795
  m('button.btn-flat', {
6790
6796
  class: theme === 'dark' ? 'active' : '',
6791
6797
  onclick: () => handleThemeChange('dark'),
6792
- title: 'Dark theme'
6793
- }, [
6794
- m('i.material-icons', 'dark_mode'),
6795
- showLabels && m('span', 'Dark')
6796
- ])
6797
- ])
6798
+ title: labels.darkTitle,
6799
+ }, [m('i.material-icons', 'dark_mode'), showLabels && m('span', labels.dark)]),
6800
+ ]),
6798
6801
  ]);
6799
- }
6802
+ },
6800
6803
  };
6801
6804
  };
6802
6805
  /**
@@ -6810,36 +6813,50 @@
6810
6813
  ThemeManager.initialize();
6811
6814
  }
6812
6815
  },
6813
- view: ({ attrs }) => {
6816
+ view: ({ attrs = {} }) => {
6814
6817
  const currentTheme = ThemeManager.getEffectiveTheme();
6818
+ const labels = Object.assign(Object.assign({}, defaultI18n$1), attrs.i18n);
6815
6819
  return m('button.btn-flat.theme-toggle', {
6816
6820
  class: attrs.className || '',
6817
6821
  onclick: () => {
6818
6822
  ThemeManager.toggle();
6819
- m.redraw();
6820
6823
  },
6821
- title: `Switch to ${currentTheme === 'light' ? 'dark' : 'light'} theme`,
6822
- style: 'margin: 0; height: 64px; line-height: 64px; border-radius: 0; min-width: 64px; padding: 0;'
6824
+ title: currentTheme === 'light' ? labels.switchToDark : labels.switchToLight,
6825
+ style: 'margin: 0; height: 64px; line-height: 64px; border-radius: 0; min-width: 64px; padding: 0;',
6823
6826
  }, [
6824
6827
  m('i.material-icons', {
6825
- style: 'color: inherit; font-size: 24px;'
6826
- }, currentTheme === 'light' ? 'dark_mode' : 'light_mode')
6828
+ style: 'color: inherit; font-size: 24px;',
6829
+ }, currentTheme === 'light' ? 'dark_mode' : 'light_mode'),
6827
6830
  ]);
6828
- }
6831
+ },
6829
6832
  };
6830
6833
  };
6831
6834
 
6835
+ const defaultI18n = {
6836
+ label: 'Choose files or drag them here',
6837
+ selectedFiles: 'Selected Files:',
6838
+ acceptedTypes: 'Accepted:',
6839
+ removeFile: 'Remove file',
6840
+ fileSizeExceeds: 'File size exceeds {maxSize}MB limit',
6841
+ fileTypeNotAccepted: 'File type not accepted. Accepted: {accept}',
6842
+ fileSizeUnits: {
6843
+ bytes: 'B',
6844
+ kb: 'KB',
6845
+ mb: 'MB',
6846
+ gb: 'GB',
6847
+ },
6848
+ };
6832
6849
  /**
6833
6850
  * File Upload Component with Drag and Drop
6834
6851
  * Supports multiple files, file type validation, size limits, and image preview
6835
6852
  */
6836
6853
  const FileUpload = () => {
6837
6854
  let state;
6838
- const validateFile = (file, attrs) => {
6855
+ const validateFile = (file, attrs, labels) => {
6839
6856
  // Check file size
6840
6857
  if (attrs.maxSize && file.size > attrs.maxSize) {
6841
6858
  const maxSizeMB = (attrs.maxSize / (1024 * 1024)).toFixed(1);
6842
- return `File size exceeds ${maxSizeMB}MB limit`;
6859
+ return labels.fileSizeExceeds.replace('{maxSize}', maxSizeMB);
6843
6860
  }
6844
6861
  // Check file type
6845
6862
  if (attrs.accept) {
@@ -6855,7 +6872,7 @@
6855
6872
  }
6856
6873
  });
6857
6874
  if (!isAccepted) {
6858
- return `File type not accepted. Accepted: ${attrs.accept}`;
6875
+ return labels.fileTypeNotAccepted.replace('{accept}', attrs.accept);
6859
6876
  }
6860
6877
  }
6861
6878
  return null;
@@ -6871,12 +6888,12 @@
6871
6888
  reader.readAsDataURL(file);
6872
6889
  }
6873
6890
  };
6874
- const handleFiles = (fileList, attrs) => {
6891
+ const handleFiles = (fileList, attrs, labels) => {
6875
6892
  const newFiles = Array.from(fileList);
6876
6893
  const validFiles = [];
6877
6894
  // Validate each file
6878
6895
  for (const file of newFiles) {
6879
- const error = validateFile(file, attrs);
6896
+ const error = validateFile(file, attrs, labels);
6880
6897
  if (error) {
6881
6898
  file.uploadError = error;
6882
6899
  }
@@ -6913,11 +6930,11 @@
6913
6930
  attrs.onFileRemoved(fileToRemove);
6914
6931
  }
6915
6932
  };
6916
- const formatFileSize = (bytes) => {
6933
+ const formatFileSize = (bytes, labels) => {
6917
6934
  if (bytes === 0)
6918
- return '0 B';
6935
+ return `0 ${labels.fileSizeUnits.bytes}`;
6919
6936
  const k = 1024;
6920
- const sizes = ['B', 'KB', 'MB', 'GB'];
6937
+ const sizes = [labels.fileSizeUnits.bytes, labels.fileSizeUnits.kb, labels.fileSizeUnits.mb, labels.fileSizeUnits.gb];
6921
6938
  const i = Math.floor(Math.log(bytes) / Math.log(k));
6922
6939
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
6923
6940
  };
@@ -6931,7 +6948,9 @@
6931
6948
  };
6932
6949
  },
6933
6950
  view: ({ attrs }) => {
6934
- const { accept, multiple = false, disabled = false, label = 'Choose files or drag them here', helperText, showPreview = true, className = '', error, } = attrs;
6951
+ const { accept, multiple = false, disabled = false, label, helperText, showPreview = true, className = '', error, i18n, } = attrs;
6952
+ const labels = Object.assign(Object.assign({}, defaultI18n), i18n);
6953
+ const displayLabel = label || labels.label;
6935
6954
  return m('.file-upload-container', { class: className }, [
6936
6955
  // Upload area
6937
6956
  m('.file-upload-area', {
@@ -6965,7 +6984,7 @@
6965
6984
  e.stopPropagation();
6966
6985
  state.isDragOver = false;
6967
6986
  if ((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) {
6968
- handleFiles(e.dataTransfer.files, attrs);
6987
+ handleFiles(e.dataTransfer.files, attrs, labels);
6969
6988
  }
6970
6989
  },
6971
6990
  onclick: () => {
@@ -6984,15 +7003,15 @@
6984
7003
  onchange: (e) => {
6985
7004
  const target = e.target;
6986
7005
  if (target.files) {
6987
- handleFiles(target.files, attrs);
7006
+ handleFiles(target.files, attrs, labels);
6988
7007
  }
6989
7008
  },
6990
7009
  }),
6991
7010
  m('.file-upload-content', [
6992
7011
  m('i.material-icons.file-upload-icon', 'cloud_upload'),
6993
- m('p.file-upload-label', label),
7012
+ m('p.file-upload-label', displayLabel),
6994
7013
  helperText && m('p.file-upload-helper', helperText),
6995
- accept && m('p.file-upload-types', `Accepted: ${accept}`),
7014
+ accept && m('p.file-upload-types', `${labels.acceptedTypes} ${accept}`),
6996
7015
  ]),
6997
7016
  ]),
6998
7017
  // Error message
@@ -7000,7 +7019,7 @@
7000
7019
  // File list
7001
7020
  state.files.length > 0 &&
7002
7021
  m('.file-upload-list', [
7003
- m('h6', 'Selected Files:'),
7022
+ m('h6', labels.selectedFiles),
7004
7023
  state.files.map((file) => m('.file-upload-item', { key: file.name + file.size }, [
7005
7024
  // Preview thumbnail
7006
7025
  showPreview && file.preview && m('.file-preview', [m('img', { src: file.preview, alt: file.name })]),
@@ -7008,7 +7027,7 @@
7008
7027
  m('.file-info', [
7009
7028
  m('.file-name', file.name),
7010
7029
  m('.file-details', [
7011
- m('span.file-size', formatFileSize(file.size)),
7030
+ m('span.file-size', formatFileSize(file.size, labels)),
7012
7031
  file.type && m('span.file-type', file.type),
7013
7032
  ]),
7014
7033
  // Progress bar (if uploading)
@@ -7029,7 +7048,7 @@
7029
7048
  e.stopPropagation();
7030
7049
  removeFile(file, attrs);
7031
7050
  },
7032
- title: 'Remove file',
7051
+ title: labels.removeFile,
7033
7052
  }, [m('i.material-icons', 'close')]),
7034
7053
  ])),
7035
7054
  ]),
@@ -7870,18 +7889,18 @@
7870
7889
  const handleItemClick = (e) => {
7871
7890
  if (item.disabled)
7872
7891
  return;
7873
- if (item.onClick) {
7892
+ if (item.onclick) {
7874
7893
  e.preventDefault();
7875
- item.onClick(item, e);
7894
+ item.onclick(item, e);
7876
7895
  }
7877
7896
  };
7878
7897
  const isVertical = orientation === 'vertical';
7879
7898
  return m('div', {
7880
7899
  key: item.id || index,
7881
7900
  className: itemClasses,
7882
- onclick: item.onClick ? handleItemClick : undefined,
7883
- role: item.onClick ? 'button' : undefined,
7884
- tabindex: item.onClick && !item.disabled ? 0 : undefined,
7901
+ onclick: item.onclick ? handleItemClick : undefined,
7902
+ role: item.onclick ? 'button' : undefined,
7903
+ tabindex: item.onclick && !item.disabled ? 0 : undefined,
7885
7904
  'aria-disabled': item.disabled ? 'true' : undefined,
7886
7905
  }, [
7887
7906
  // Timestamp (on opposite side of content from bullet)
@@ -1,5 +1,25 @@
1
1
  import { FactoryComponent } from 'mithril';
2
2
  export type Theme = 'light' | 'dark' | 'auto';
3
+ export interface ThemeSwitcherI18n {
4
+ /** Label for the theme switcher */
5
+ theme?: string;
6
+ /** Light theme label */
7
+ light?: string;
8
+ /** Dark theme label */
9
+ dark?: string;
10
+ /** Auto theme label */
11
+ auto?: string;
12
+ /** Light theme title/tooltip */
13
+ lightTitle?: string;
14
+ /** Dark theme title/tooltip */
15
+ darkTitle?: string;
16
+ /** Auto theme title/tooltip */
17
+ autoTitle?: string;
18
+ /** Toggle button title when switching to dark */
19
+ switchToDark?: string;
20
+ /** Toggle button title when switching to light */
21
+ switchToLight?: string;
22
+ }
3
23
  export interface ThemeSwitcherAttrs {
4
24
  /** Current theme selection */
5
25
  theme?: Theme;
@@ -9,6 +29,8 @@ export interface ThemeSwitcherAttrs {
9
29
  showLabels?: boolean;
10
30
  /** Custom class for the container */
11
31
  className?: string;
32
+ /** Internationalization */
33
+ i18n?: ThemeSwitcherI18n;
12
34
  }
13
35
  /**
14
36
  * Theme switching utilities and component
@@ -46,4 +68,5 @@ export declare const ThemeSwitcher: FactoryComponent<ThemeSwitcherAttrs>;
46
68
  */
47
69
  export declare const ThemeToggle: FactoryComponent<{
48
70
  className?: string;
71
+ i18n?: ThemeSwitcherI18n;
49
72
  }>;
@@ -3,7 +3,7 @@ export interface TimelineItemAttrs {
3
3
  /** Unique identifier for the timeline item */
4
4
  id?: string;
5
5
  /** Main label/title for the timeline item */
6
- label: string;
6
+ label?: string;
7
7
  /** Optional description text */
8
8
  description?: string;
9
9
  /** Timestamp for the item (string or Date object) */
@@ -15,7 +15,7 @@ export interface TimelineItemAttrs {
15
15
  /** Color theme for the timeline item */
16
16
  color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
17
17
  /** Click handler for the timeline item */
18
- onClick?: (item: TimelineItemAttrs, event: Event) => void;
18
+ onclick?: (item: TimelineItemAttrs, event: Event) => void;
19
19
  /** Whether the item is disabled */
20
20
  disabled?: boolean;
21
21
  /** Custom CSS class for the item */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mithril-materialized",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0",
4
4
  "description": "A materialize library for mithril.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",