mithril-materialized 3.2.1 → 3.2.2

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/core.css CHANGED
@@ -2673,6 +2673,9 @@ textarea.materialize-textarea {
2673
2673
  /* Character Counter */
2674
2674
  .character-counter {
2675
2675
  min-height: 18px;
2676
+ font-size: 12px;
2677
+ display: block;
2678
+ text-align: right;
2676
2679
  }
2677
2680
 
2678
2681
  /* Input Clear Button */
package/dist/forms.css CHANGED
@@ -1282,6 +1282,9 @@ textarea.materialize-textarea {
1282
1282
  /* Character Counter */
1283
1283
  .character-counter {
1284
1284
  min-height: 18px;
1285
+ font-size: 12px;
1286
+ display: block;
1287
+ text-align: right;
1285
1288
  }
1286
1289
 
1287
1290
  /* Input Clear Button */
package/dist/index.css CHANGED
@@ -6325,6 +6325,9 @@ textarea.materialize-textarea {
6325
6325
  /* Character Counter */
6326
6326
  .character-counter {
6327
6327
  min-height: 18px;
6328
+ font-size: 12px;
6329
+ display: block;
6330
+ text-align: right;
6328
6331
  }
6329
6332
 
6330
6333
  /* Input Clear Button */
package/dist/index.esm.js CHANGED
@@ -2789,10 +2789,6 @@ const CharacterCounter = () => {
2789
2789
  return m('span.character-counter', {
2790
2790
  style: {
2791
2791
  color: isOverLimit ? '#F44336' : '#9e9e9e',
2792
- fontSize: '12px',
2793
- display: 'block',
2794
- textAlign: 'right',
2795
- marginTop: '8px',
2796
2792
  },
2797
2793
  }, `${currentLength}/${maxLength}`);
2798
2794
  },
@@ -2809,10 +2805,51 @@ const TextArea = () => {
2809
2805
  textarea: undefined,
2810
2806
  internalValue: '',
2811
2807
  };
2812
- const updateHeight = (textarea) => {
2813
- textarea.style.height = 'auto';
2814
- const newHeight = textarea.scrollHeight + 'px';
2815
- state.height = textarea.value.length === 0 ? undefined : newHeight;
2808
+ const updateHeight = (textarea, hiddenDiv) => {
2809
+ if (!textarea || !hiddenDiv)
2810
+ return;
2811
+ // Copy font properties from textarea to hidden div
2812
+ const computedStyle = window.getComputedStyle(textarea);
2813
+ hiddenDiv.style.fontFamily = computedStyle.fontFamily;
2814
+ hiddenDiv.style.fontSize = computedStyle.fontSize;
2815
+ hiddenDiv.style.lineHeight = computedStyle.lineHeight;
2816
+ // Copy padding from textarea (important for accurate measurement)
2817
+ hiddenDiv.style.paddingTop = computedStyle.paddingTop;
2818
+ hiddenDiv.style.paddingRight = computedStyle.paddingRight;
2819
+ hiddenDiv.style.paddingBottom = computedStyle.paddingBottom;
2820
+ hiddenDiv.style.paddingLeft = computedStyle.paddingLeft;
2821
+ // Handle text wrapping
2822
+ if (textarea.getAttribute('wrap') === 'off') {
2823
+ hiddenDiv.style.overflowWrap = 'normal';
2824
+ hiddenDiv.style.whiteSpace = 'pre';
2825
+ }
2826
+ else {
2827
+ hiddenDiv.style.overflowWrap = 'break-word';
2828
+ hiddenDiv.style.whiteSpace = 'pre-wrap';
2829
+ }
2830
+ // Set content with extra newline for measurement
2831
+ hiddenDiv.textContent = textarea.value + '\n';
2832
+ const content = hiddenDiv.innerHTML.replace(/\n/g, '<br>');
2833
+ hiddenDiv.innerHTML = content;
2834
+ // Set width to match textarea
2835
+ if (textarea.offsetWidth > 0) {
2836
+ hiddenDiv.style.width = textarea.offsetWidth + 'px';
2837
+ }
2838
+ else {
2839
+ hiddenDiv.style.width = window.innerWidth / 2 + 'px';
2840
+ }
2841
+ // Get the original/natural height of the textarea
2842
+ const originalHeight = textarea.offsetHeight;
2843
+ const measuredHeight = hiddenDiv.offsetHeight;
2844
+ // Key logic: Only set custom height when content requires MORE space than original height
2845
+ // This matches the Materialize CSS reference behavior
2846
+ if (originalHeight <= measuredHeight) {
2847
+ state.height = measuredHeight + 'px';
2848
+ }
2849
+ else {
2850
+ // Single line content or content that fits in original height - let CSS handle it
2851
+ state.height = undefined;
2852
+ }
2816
2853
  };
2817
2854
  const isControlled = (attrs) => attrs.value !== undefined && attrs.oninput !== undefined;
2818
2855
  return {
@@ -2828,92 +2865,117 @@ const TextArea = () => {
2828
2865
  const { className = 'col s12', helperText, iconName, id = state.id, value, placeholder, isMandatory, label, maxLength, oninput, onchange, onkeydown, onkeypress, onkeyup, onblur, style } = attrs, params = __rest(attrs, ["className", "helperText", "iconName", "id", "value", "placeholder", "isMandatory", "label", "maxLength", "oninput", "onchange", "onkeydown", "onkeypress", "onkeyup", "onblur", "style"]);
2829
2866
  const controlled = isControlled(attrs);
2830
2867
  const currentValue = controlled ? value || '' : state.internalValue;
2831
- return m('.input-field', { className, style }, [
2832
- iconName ? m('i.material-icons.prefix', iconName) : '',
2833
- m('textarea.materialize-textarea', Object.assign(Object.assign({}, params), { id, tabindex: 0, value: controlled ? currentValue : undefined, style: {
2834
- height: state.height,
2835
- }, oncreate: ({ dom }) => {
2836
- const textarea = (state.textarea = dom);
2837
- // For uncontrolled mode, set initial value only
2838
- if (!controlled && attrs.defaultValue !== undefined) {
2839
- textarea.value = String(attrs.defaultValue);
2840
- }
2841
- updateHeight(textarea);
2842
- // Update character count state for counter component
2843
- if (maxLength) {
2844
- state.currentLength = textarea.value.length;
2845
- m.redraw();
2846
- }
2847
- }, onupdate: ({ dom }) => {
2848
- const textarea = dom;
2849
- if (state.height)
2850
- textarea.style.height = state.height;
2851
- // No need to manually sync in onupdate since value attribute handles it
2852
- }, onfocus: () => {
2853
- state.active = true;
2854
- }, oninput: (e) => {
2855
- state.active = true;
2856
- state.hasInteracted = false;
2857
- const target = e.target;
2858
- // Update height for auto-resize
2859
- updateHeight(target);
2860
- // Update character count
2861
- if (maxLength) {
2862
- state.currentLength = target.value.length;
2863
- state.hasInteracted = target.value.length > 0;
2864
- }
2865
- // Update internal state for uncontrolled mode
2866
- if (!controlled) {
2867
- state.internalValue = target.value;
2868
- }
2869
- // Call oninput handler
2870
- if (oninput) {
2871
- oninput(target.value);
2872
- }
2873
- }, onblur: (e) => {
2874
- state.active = false;
2875
- // const target = e.target as HTMLTextAreaElement;
2876
- state.hasInteracted = true;
2877
- // Call original onblur if provided
2878
- if (onblur) {
2879
- onblur(e);
2880
- }
2881
- if (onchange && state.textarea) {
2882
- onchange(state.textarea.value);
2883
- }
2884
- }, onkeyup: onkeyup
2885
- ? (ev) => {
2886
- onkeyup(ev, ev.target.value);
2887
- }
2888
- : undefined, onkeydown: onkeydown
2889
- ? (ev) => {
2890
- onkeydown(ev, ev.target.value);
2868
+ return [
2869
+ // Hidden div for height measurement - positioned outside the input-field
2870
+ m('.hiddendiv', {
2871
+ style: {
2872
+ visibility: 'hidden',
2873
+ position: 'absolute',
2874
+ top: '0',
2875
+ left: '0',
2876
+ zIndex: '-1',
2877
+ whiteSpace: 'pre-wrap',
2878
+ wordWrap: 'break-word',
2879
+ overflowWrap: 'break-word',
2880
+ },
2881
+ oncreate: ({ dom }) => {
2882
+ const hiddenDiv = dom;
2883
+ if (state.textarea) {
2884
+ updateHeight(state.textarea, hiddenDiv);
2891
2885
  }
2892
- : undefined, onkeypress: onkeypress
2893
- ? (ev) => {
2894
- onkeypress(ev, ev.target.value);
2886
+ },
2887
+ onupdate: ({ dom }) => {
2888
+ const hiddenDiv = dom;
2889
+ if (state.textarea) {
2890
+ updateHeight(state.textarea, hiddenDiv);
2895
2891
  }
2896
- : undefined })),
2897
- m(Label, {
2898
- label,
2899
- id,
2900
- isMandatory,
2901
- isActive: currentValue || placeholder || state.active,
2902
- initialValue: currentValue !== '',
2903
- }),
2904
- m(HelperText, {
2905
- helperText,
2906
- dataError: state.hasInteracted && attrs.dataError ? attrs.dataError : undefined,
2907
- dataSuccess: state.hasInteracted && attrs.dataSuccess ? attrs.dataSuccess : undefined,
2892
+ },
2908
2893
  }),
2909
- maxLength
2910
- ? m(CharacterCounter, {
2911
- currentLength: state.currentLength,
2912
- maxLength,
2913
- show: state.currentLength > 0,
2914
- })
2915
- : undefined,
2916
- ]);
2894
+ m('.input-field', { className, style }, [
2895
+ iconName ? m('i.material-icons.prefix', iconName) : '',
2896
+ m('textarea.materialize-textarea', Object.assign(Object.assign({}, params), { id, tabindex: 0, value: controlled ? currentValue : undefined, style: {
2897
+ height: state.height,
2898
+ }, oncreate: ({ dom }) => {
2899
+ const textarea = (state.textarea = dom);
2900
+ // For uncontrolled mode, set initial value only
2901
+ if (!controlled && attrs.defaultValue !== undefined) {
2902
+ textarea.value = String(attrs.defaultValue);
2903
+ }
2904
+ // Height will be calculated by hidden div
2905
+ // Update character count state for counter component
2906
+ if (maxLength) {
2907
+ state.currentLength = textarea.value.length;
2908
+ }
2909
+ }, onupdate: ({ dom }) => {
2910
+ const textarea = dom;
2911
+ if (state.height)
2912
+ textarea.style.height = state.height;
2913
+ // No need to manually sync in onupdate since value attribute handles it
2914
+ }, onfocus: () => {
2915
+ state.active = true;
2916
+ }, oninput: (e) => {
2917
+ state.active = true;
2918
+ state.hasInteracted = false;
2919
+ const target = e.target;
2920
+ // Height will be recalculated by hidden div on next update
2921
+ // Update character count
2922
+ if (maxLength) {
2923
+ state.currentLength = target.value.length;
2924
+ state.hasInteracted = target.value.length > 0;
2925
+ }
2926
+ // Update internal state for uncontrolled mode
2927
+ if (!controlled) {
2928
+ state.internalValue = target.value;
2929
+ }
2930
+ // Call oninput handler
2931
+ if (oninput) {
2932
+ oninput(target.value);
2933
+ }
2934
+ }, onblur: (e) => {
2935
+ state.active = false;
2936
+ // const target = e.target as HTMLTextAreaElement;
2937
+ state.hasInteracted = true;
2938
+ // Call original onblur if provided
2939
+ if (onblur) {
2940
+ onblur(e);
2941
+ }
2942
+ if (onchange && state.textarea) {
2943
+ onchange(state.textarea.value);
2944
+ }
2945
+ }, onkeyup: onkeyup
2946
+ ? (ev) => {
2947
+ onkeyup(ev, ev.target.value);
2948
+ }
2949
+ : undefined, onkeydown: onkeydown
2950
+ ? (ev) => {
2951
+ onkeydown(ev, ev.target.value);
2952
+ }
2953
+ : undefined, onkeypress: onkeypress
2954
+ ? (ev) => {
2955
+ onkeypress(ev, ev.target.value);
2956
+ }
2957
+ : undefined })),
2958
+ m(Label, {
2959
+ label,
2960
+ id,
2961
+ isMandatory,
2962
+ isActive: currentValue || placeholder || state.active,
2963
+ initialValue: currentValue !== '',
2964
+ }),
2965
+ m(HelperText, {
2966
+ helperText,
2967
+ dataError: state.hasInteracted && attrs.dataError ? attrs.dataError : undefined,
2968
+ dataSuccess: state.hasInteracted && attrs.dataSuccess ? attrs.dataSuccess : undefined,
2969
+ }),
2970
+ maxLength
2971
+ ? m(CharacterCounter, {
2972
+ currentLength: state.currentLength,
2973
+ maxLength,
2974
+ show: state.currentLength > 0,
2975
+ })
2976
+ : undefined,
2977
+ ]),
2978
+ ];
2917
2979
  },
2918
2980
  };
2919
2981
  };
@@ -3085,7 +3147,9 @@ const InputField = (type, defaultClass = '') => () => {
3085
3147
  state.isValid = true;
3086
3148
  }
3087
3149
  }
3088
- else if ((type === 'email' || type === 'url') && target.classList.contains('invalid') && target.value.length > 0) {
3150
+ else if ((type === 'email' || type === 'url') &&
3151
+ target.classList.contains('invalid') &&
3152
+ target.value.length > 0) {
3089
3153
  // Clear native validation errors if user is typing and input becomes valid
3090
3154
  if (target.validity.valid) {
3091
3155
  target.classList.remove('invalid');
package/dist/index.js CHANGED
@@ -2791,10 +2791,6 @@ const CharacterCounter = () => {
2791
2791
  return m('span.character-counter', {
2792
2792
  style: {
2793
2793
  color: isOverLimit ? '#F44336' : '#9e9e9e',
2794
- fontSize: '12px',
2795
- display: 'block',
2796
- textAlign: 'right',
2797
- marginTop: '8px',
2798
2794
  },
2799
2795
  }, `${currentLength}/${maxLength}`);
2800
2796
  },
@@ -2811,10 +2807,51 @@ const TextArea = () => {
2811
2807
  textarea: undefined,
2812
2808
  internalValue: '',
2813
2809
  };
2814
- const updateHeight = (textarea) => {
2815
- textarea.style.height = 'auto';
2816
- const newHeight = textarea.scrollHeight + 'px';
2817
- state.height = textarea.value.length === 0 ? undefined : newHeight;
2810
+ const updateHeight = (textarea, hiddenDiv) => {
2811
+ if (!textarea || !hiddenDiv)
2812
+ return;
2813
+ // Copy font properties from textarea to hidden div
2814
+ const computedStyle = window.getComputedStyle(textarea);
2815
+ hiddenDiv.style.fontFamily = computedStyle.fontFamily;
2816
+ hiddenDiv.style.fontSize = computedStyle.fontSize;
2817
+ hiddenDiv.style.lineHeight = computedStyle.lineHeight;
2818
+ // Copy padding from textarea (important for accurate measurement)
2819
+ hiddenDiv.style.paddingTop = computedStyle.paddingTop;
2820
+ hiddenDiv.style.paddingRight = computedStyle.paddingRight;
2821
+ hiddenDiv.style.paddingBottom = computedStyle.paddingBottom;
2822
+ hiddenDiv.style.paddingLeft = computedStyle.paddingLeft;
2823
+ // Handle text wrapping
2824
+ if (textarea.getAttribute('wrap') === 'off') {
2825
+ hiddenDiv.style.overflowWrap = 'normal';
2826
+ hiddenDiv.style.whiteSpace = 'pre';
2827
+ }
2828
+ else {
2829
+ hiddenDiv.style.overflowWrap = 'break-word';
2830
+ hiddenDiv.style.whiteSpace = 'pre-wrap';
2831
+ }
2832
+ // Set content with extra newline for measurement
2833
+ hiddenDiv.textContent = textarea.value + '\n';
2834
+ const content = hiddenDiv.innerHTML.replace(/\n/g, '<br>');
2835
+ hiddenDiv.innerHTML = content;
2836
+ // Set width to match textarea
2837
+ if (textarea.offsetWidth > 0) {
2838
+ hiddenDiv.style.width = textarea.offsetWidth + 'px';
2839
+ }
2840
+ else {
2841
+ hiddenDiv.style.width = window.innerWidth / 2 + 'px';
2842
+ }
2843
+ // Get the original/natural height of the textarea
2844
+ const originalHeight = textarea.offsetHeight;
2845
+ const measuredHeight = hiddenDiv.offsetHeight;
2846
+ // Key logic: Only set custom height when content requires MORE space than original height
2847
+ // This matches the Materialize CSS reference behavior
2848
+ if (originalHeight <= measuredHeight) {
2849
+ state.height = measuredHeight + 'px';
2850
+ }
2851
+ else {
2852
+ // Single line content or content that fits in original height - let CSS handle it
2853
+ state.height = undefined;
2854
+ }
2818
2855
  };
2819
2856
  const isControlled = (attrs) => attrs.value !== undefined && attrs.oninput !== undefined;
2820
2857
  return {
@@ -2830,92 +2867,117 @@ const TextArea = () => {
2830
2867
  const { className = 'col s12', helperText, iconName, id = state.id, value, placeholder, isMandatory, label, maxLength, oninput, onchange, onkeydown, onkeypress, onkeyup, onblur, style } = attrs, params = __rest(attrs, ["className", "helperText", "iconName", "id", "value", "placeholder", "isMandatory", "label", "maxLength", "oninput", "onchange", "onkeydown", "onkeypress", "onkeyup", "onblur", "style"]);
2831
2868
  const controlled = isControlled(attrs);
2832
2869
  const currentValue = controlled ? value || '' : state.internalValue;
2833
- return m('.input-field', { className, style }, [
2834
- iconName ? m('i.material-icons.prefix', iconName) : '',
2835
- m('textarea.materialize-textarea', Object.assign(Object.assign({}, params), { id, tabindex: 0, value: controlled ? currentValue : undefined, style: {
2836
- height: state.height,
2837
- }, oncreate: ({ dom }) => {
2838
- const textarea = (state.textarea = dom);
2839
- // For uncontrolled mode, set initial value only
2840
- if (!controlled && attrs.defaultValue !== undefined) {
2841
- textarea.value = String(attrs.defaultValue);
2842
- }
2843
- updateHeight(textarea);
2844
- // Update character count state for counter component
2845
- if (maxLength) {
2846
- state.currentLength = textarea.value.length;
2847
- m.redraw();
2848
- }
2849
- }, onupdate: ({ dom }) => {
2850
- const textarea = dom;
2851
- if (state.height)
2852
- textarea.style.height = state.height;
2853
- // No need to manually sync in onupdate since value attribute handles it
2854
- }, onfocus: () => {
2855
- state.active = true;
2856
- }, oninput: (e) => {
2857
- state.active = true;
2858
- state.hasInteracted = false;
2859
- const target = e.target;
2860
- // Update height for auto-resize
2861
- updateHeight(target);
2862
- // Update character count
2863
- if (maxLength) {
2864
- state.currentLength = target.value.length;
2865
- state.hasInteracted = target.value.length > 0;
2866
- }
2867
- // Update internal state for uncontrolled mode
2868
- if (!controlled) {
2869
- state.internalValue = target.value;
2870
- }
2871
- // Call oninput handler
2872
- if (oninput) {
2873
- oninput(target.value);
2874
- }
2875
- }, onblur: (e) => {
2876
- state.active = false;
2877
- // const target = e.target as HTMLTextAreaElement;
2878
- state.hasInteracted = true;
2879
- // Call original onblur if provided
2880
- if (onblur) {
2881
- onblur(e);
2882
- }
2883
- if (onchange && state.textarea) {
2884
- onchange(state.textarea.value);
2885
- }
2886
- }, onkeyup: onkeyup
2887
- ? (ev) => {
2888
- onkeyup(ev, ev.target.value);
2889
- }
2890
- : undefined, onkeydown: onkeydown
2891
- ? (ev) => {
2892
- onkeydown(ev, ev.target.value);
2870
+ return [
2871
+ // Hidden div for height measurement - positioned outside the input-field
2872
+ m('.hiddendiv', {
2873
+ style: {
2874
+ visibility: 'hidden',
2875
+ position: 'absolute',
2876
+ top: '0',
2877
+ left: '0',
2878
+ zIndex: '-1',
2879
+ whiteSpace: 'pre-wrap',
2880
+ wordWrap: 'break-word',
2881
+ overflowWrap: 'break-word',
2882
+ },
2883
+ oncreate: ({ dom }) => {
2884
+ const hiddenDiv = dom;
2885
+ if (state.textarea) {
2886
+ updateHeight(state.textarea, hiddenDiv);
2893
2887
  }
2894
- : undefined, onkeypress: onkeypress
2895
- ? (ev) => {
2896
- onkeypress(ev, ev.target.value);
2888
+ },
2889
+ onupdate: ({ dom }) => {
2890
+ const hiddenDiv = dom;
2891
+ if (state.textarea) {
2892
+ updateHeight(state.textarea, hiddenDiv);
2897
2893
  }
2898
- : undefined })),
2899
- m(Label, {
2900
- label,
2901
- id,
2902
- isMandatory,
2903
- isActive: currentValue || placeholder || state.active,
2904
- initialValue: currentValue !== '',
2905
- }),
2906
- m(HelperText, {
2907
- helperText,
2908
- dataError: state.hasInteracted && attrs.dataError ? attrs.dataError : undefined,
2909
- dataSuccess: state.hasInteracted && attrs.dataSuccess ? attrs.dataSuccess : undefined,
2894
+ },
2910
2895
  }),
2911
- maxLength
2912
- ? m(CharacterCounter, {
2913
- currentLength: state.currentLength,
2914
- maxLength,
2915
- show: state.currentLength > 0,
2916
- })
2917
- : undefined,
2918
- ]);
2896
+ m('.input-field', { className, style }, [
2897
+ iconName ? m('i.material-icons.prefix', iconName) : '',
2898
+ m('textarea.materialize-textarea', Object.assign(Object.assign({}, params), { id, tabindex: 0, value: controlled ? currentValue : undefined, style: {
2899
+ height: state.height,
2900
+ }, oncreate: ({ dom }) => {
2901
+ const textarea = (state.textarea = dom);
2902
+ // For uncontrolled mode, set initial value only
2903
+ if (!controlled && attrs.defaultValue !== undefined) {
2904
+ textarea.value = String(attrs.defaultValue);
2905
+ }
2906
+ // Height will be calculated by hidden div
2907
+ // Update character count state for counter component
2908
+ if (maxLength) {
2909
+ state.currentLength = textarea.value.length;
2910
+ }
2911
+ }, onupdate: ({ dom }) => {
2912
+ const textarea = dom;
2913
+ if (state.height)
2914
+ textarea.style.height = state.height;
2915
+ // No need to manually sync in onupdate since value attribute handles it
2916
+ }, onfocus: () => {
2917
+ state.active = true;
2918
+ }, oninput: (e) => {
2919
+ state.active = true;
2920
+ state.hasInteracted = false;
2921
+ const target = e.target;
2922
+ // Height will be recalculated by hidden div on next update
2923
+ // Update character count
2924
+ if (maxLength) {
2925
+ state.currentLength = target.value.length;
2926
+ state.hasInteracted = target.value.length > 0;
2927
+ }
2928
+ // Update internal state for uncontrolled mode
2929
+ if (!controlled) {
2930
+ state.internalValue = target.value;
2931
+ }
2932
+ // Call oninput handler
2933
+ if (oninput) {
2934
+ oninput(target.value);
2935
+ }
2936
+ }, onblur: (e) => {
2937
+ state.active = false;
2938
+ // const target = e.target as HTMLTextAreaElement;
2939
+ state.hasInteracted = true;
2940
+ // Call original onblur if provided
2941
+ if (onblur) {
2942
+ onblur(e);
2943
+ }
2944
+ if (onchange && state.textarea) {
2945
+ onchange(state.textarea.value);
2946
+ }
2947
+ }, onkeyup: onkeyup
2948
+ ? (ev) => {
2949
+ onkeyup(ev, ev.target.value);
2950
+ }
2951
+ : undefined, onkeydown: onkeydown
2952
+ ? (ev) => {
2953
+ onkeydown(ev, ev.target.value);
2954
+ }
2955
+ : undefined, onkeypress: onkeypress
2956
+ ? (ev) => {
2957
+ onkeypress(ev, ev.target.value);
2958
+ }
2959
+ : undefined })),
2960
+ m(Label, {
2961
+ label,
2962
+ id,
2963
+ isMandatory,
2964
+ isActive: currentValue || placeholder || state.active,
2965
+ initialValue: currentValue !== '',
2966
+ }),
2967
+ m(HelperText, {
2968
+ helperText,
2969
+ dataError: state.hasInteracted && attrs.dataError ? attrs.dataError : undefined,
2970
+ dataSuccess: state.hasInteracted && attrs.dataSuccess ? attrs.dataSuccess : undefined,
2971
+ }),
2972
+ maxLength
2973
+ ? m(CharacterCounter, {
2974
+ currentLength: state.currentLength,
2975
+ maxLength,
2976
+ show: state.currentLength > 0,
2977
+ })
2978
+ : undefined,
2979
+ ]),
2980
+ ];
2919
2981
  },
2920
2982
  };
2921
2983
  };
@@ -3087,7 +3149,9 @@ const InputField = (type, defaultClass = '') => () => {
3087
3149
  state.isValid = true;
3088
3150
  }
3089
3151
  }
3090
- else if ((type === 'email' || type === 'url') && target.classList.contains('invalid') && target.value.length > 0) {
3152
+ else if ((type === 'email' || type === 'url') &&
3153
+ target.classList.contains('invalid') &&
3154
+ target.value.length > 0) {
3091
3155
  // Clear native validation errors if user is typing and input becomes valid
3092
3156
  if (target.validity.valid) {
3093
3157
  target.classList.remove('invalid');