Skip to content

Commit c143895

Browse files
committed
feat(TextInputs): add showError, showWarn props to MoneyInput, TextArea and TextField
These props will use: --mdc-theme-status-error or --mdc-theme-error and --mdc-theme-status---mdc-theme-warn selectors to display the compoments in the themes warn and error colors
1 parent 27bd3e7 commit c143895

File tree

8 files changed

+74
-4
lines changed

8 files changed

+74
-4
lines changed

components/mdc/TextInput/MoneyInput.svelte

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!-- https://github.com/material-components/material-components-web/tree/master/packages/mdc-textfield -->
22
<script>
33
/** A Svelte component that represents a text input for money values. */
4-
import { getDecimalPlacesLength } from './helpers'
4+
import { addOrRemoveInvalidClass, getDecimalPlacesLength } from './helpers'
55
import { generateRandomID } from '../../../random'
66
import { MDCTextField } from '@material/textfield'
77
import { afterUpdate, onMount } from 'svelte'
@@ -28,6 +28,10 @@ export let disabled = false
2828
export let required = false
2929
/** @type {string} The description to display below the input. */
3030
export let description = ''
31+
/** @type {boolean} lets the component know to use error class. */
32+
export let showError = false
33+
/** @type {boolean} lets the component know to use warn class. */
34+
export let showWarn = false
3135
3236
const labelID = generateRandomID('text-label-')
3337
@@ -49,6 +53,8 @@ $: valueHasTooManyDecPlaces = getDecimalPlacesLength(internalValue) > getDecimal
4953
$: valueNotDivisibleByStep =
5054
(internalValue && (internalValue / Number(step)).toFixed(2) % 1 !== 0) || valueHasTooManyDecPlaces
5155
$: internalValue = Number(value) || 0
56+
$: warn = showWarn
57+
$: addOrRemoveInvalidClass(showError || showWarn, element)
5258
5359
onMount(() => {
5460
mdcTextField = new MDCTextField(element)
@@ -80,9 +86,11 @@ const focus = (node) => autofocus && node.focus()
8086
class:mdc-text-field--no-label={!label}
8187
class:mdc-text-field--disabled={disabled}
8288
class:mdc-text-field--invalid={error}
89+
class:warn
90+
class:showError
8391
bind:this={element}
8492
>
85-
<i class="material-icons" class:error aria-hidden="true">attach_money</i>
93+
<i class="material-icons mdc-text-field__icon--leading" class:error aria-hidden="true">attach_money</i>
8694
<input
8795
{step}
8896
type="number"

components/mdc/TextInput/TextArea.svelte

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export let required = false
2525
export let description = ''
2626
/** @type {string} The name of the textarea field. */
2727
export let name = ''
28+
/** @type {boolean} lets the component know to use error class. */
29+
export let showError = false
30+
/** @type {boolean} lets the component know to use warn class. */
31+
export let showWarn = false
2832
2933
const labelID = generateRandomID('textarea-label-')
3034
@@ -37,7 +41,9 @@ let hasBlurred = false
3741
$: hasExceededMaxLength = maxlength && value.length > maxlength
3842
$: error = hasExceededMaxLength || (hasFocused && hasBlurred && required && valueIsEmpty)
3943
$: valueIsEmpty = value === ' ' || !value
44+
$: warn = showWarn
4045
$: !valueIsEmpty && addOrRemoveInvalidClass(error, element)
46+
$: addOrRemoveInvalidClass(showError || showWarn, element)
4147
4248
onMount(() => {
4349
resize()
@@ -78,6 +84,8 @@ label {
7884
class:mdc-text-field--no-label={!label}
7985
class:mdc-text-field--label-floating={label}
8086
class:mdc-text-field--with-internal-counter={maxlength}
87+
class:warn
88+
class:showError
8189
bind:this={element}
8290
>
8391
<textarea

components/mdc/TextInput/TextField.svelte

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export let icon = ''
2525
export let description = ''
2626
/** @type {string} The name of the text input field. */
2727
export let name = ''
28+
/** @type {boolean} lets the component know to use error class. */
29+
export let showError = false
30+
/** @type {boolean} lets the component know to use warn class. */
31+
export let showWarn = false
2832
2933
const labelID = generateRandomID('text-label-')
3034
@@ -37,8 +41,10 @@ let hasBlurred = false
3741
$: mdcTextField.value = value
3842
$: hasExceededMaxLength = maxlength && value.length > maxlength
3943
$: error = hasExceededMaxLength || (hasFocused && hasBlurred && required && !value)
44+
$: warn = showWarn
4045
$: showCounter = maxlength && value.length / maxlength > 0.85
4146
$: value && addOrRemoveInvalidClass(error, element)
47+
$: addOrRemoveInvalidClass(showError || showWarn, element)
4248
4349
onMount(() => {
4450
mdcTextField = new MDCTextField(element)
@@ -71,9 +77,11 @@ const focus = (node) => autofocus && node.focus()
7177
class="mdc-text-field mdc-text-field--outlined {$$props.class || ''} textfield-radius"
7278
class:mdc-text-field--no-label={!label}
7379
class:mdc-text-field--disabled={disabled}
80+
class:warn
81+
class:showError
7482
bind:this={element}
7583
>
76-
<i class="material-icons" class:error aria-hidden="true">{icon}</i>
84+
<i class="material-icons mdc-text-field__icon--leading" class:error aria-hidden="true"> {icon}</i>
7785
<input
7886
type="text"
7987
class="mdc-text-field__input"
@@ -97,7 +105,7 @@ const focus = (node) => autofocus && node.focus()
97105
/>
98106
{#if hasExceededMaxLength}
99107
<span class="mdc-text-field__affix mdc-text-field__affix--suffix"
100-
><i class="material-icons error" aria-hidden="true">error</i></span
108+
><i class="material-icons mdc-text-field__icon--trailing error" aria-hidden="true">error</i></span
101109
>
102110
{/if}
103111

components/mdc/TextInput/_index.scss

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,19 @@
22
//@use "@material/line-ripple/mdc-line-ripple"; // Only needed if using ripple.
33
@use '@material/notched-outline/mdc-notched-outline';
44
@use '@material/textfield';
5+
@use '@material/textfield/icon';
56

67
@include textfield.core-styles;
8+
@include icon.icon-core-styles;
9+
10+
:root {
11+
--mdc-theme-error: #c30000;
12+
--mdc-theme-warn: #f48c03;
13+
}
714

815
$radius: 8px !default;
16+
$error: var(--mdc-theme-status-error, var(--mdc-theme-error)) !default;
17+
$warn: var(--mdc-theme-status-warn, var(--mdc-theme-warn)) !default;
918

1019
/* TODO should be cleaned up later, this code is in multiple files but only needs to be in the master css*/
1120

@@ -20,6 +29,30 @@ $radius: 8px !default;
2029
.error {
2130
color: var(--mdc-theme-status-error, var(--mdc-theme-error)) !important;
2231
}
32+
.showError.mdc-text-field--invalid {
33+
@include textfield.outline-color($error);
34+
@include textfield.hover-outline-color($error);
35+
@include textfield.ink-color($error);
36+
@include textfield.placeholder-color($error);
37+
@include textfield.label-color($error);
38+
@include icon.leading-icon-color($error);
39+
@include icon.trailing-icon-color($error);
40+
@include textfield.caret-color($error);
41+
@include textfield.prefix-color($error);
42+
@include textfield.suffix-color($error);
43+
}
44+
.warn.mdc-text-field--invalid {
45+
@include textfield.outline-color($warn);
46+
@include textfield.hover-outline-color($warn);
47+
@include textfield.ink-color($warn);
48+
@include textfield.placeholder-color($warn);
49+
@include textfield.label-color($warn);
50+
@include icon.leading-icon-color($warn);
51+
@include icon.trailing-icon-color($warn);
52+
@include textfield.caret-color($warn);
53+
@include textfield.prefix-color($warn);
54+
@include textfield.suffix-color($warn);
55+
}
2356
.required {
2457
color: var(--mdc-required-input, rgba(0, 0, 0, 0.6));
2558
}

stories/MoneyInput.stories.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,7 @@ function setValues(max, step) {
8484
<Story name="Test step" args={{ ...args, label: '' }} />
8585

8686
<Story name="Name" args={copyAndModifyArgs(args, { name: 'money' })} />
87+
88+
<Story name="showError" args={copyAndModifyArgs(args, { showError: true })} />
89+
90+
<Story name="showWarn" args={copyAndModifyArgs(args, { showWarn: true })} />

stories/TextArea.stories.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ const args = {
3838
<Story name="Description" args={copyAndModifyArgs(args, { description: 'a description' })} />
3939

4040
<Story name="Name" args={copyAndModifyArgs(args, { name: 'area' })} />
41+
42+
<Story name="showError" args={copyAndModifyArgs(args, { showError: true })} />
43+
44+
<Story name="showWarn" args={copyAndModifyArgs(args, { showWarn: true })} />

stories/TextField.stories.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ let lastKey = ''
5151
<Story name="Description" args={copyAndModifyArgs(args, { description: 'a description' })} />
5252

5353
<Story name="Name" args={copyAndModifyArgs(args, { name: 'field' })} />
54+
55+
<Story name="showError" args={copyAndModifyArgs(args, { showError: true })} />
56+
57+
<Story name="showWarn" args={copyAndModifyArgs(args, { showWarn: true })} />

stories/_theme.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
--mdc-theme-primary-variant: #0078af;
66
--mdc-theme-secondary: #ff4800;
77
--mdc-theme-error: #c30000;
8+
--mdc-theme-warn: #f48c03;
89
--mdc-theme-neutral: #6d7580;
910
--mdc-required-input: gray;
1011
--progress-bar-color: #005cb9;

0 commit comments

Comments
 (0)