Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

feat(text-field): Added support for character counter. #4244

Merged
merged 36 commits into from
Jan 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7c46a69
feat(text-field): Character counter prototype WIP
abhiomkar Jan 9, 2019
9125939
feat(text-field): new screenshot test for char counter
abhiomkar Jan 9, 2019
e1e3d8a
feat(text-field): added character counter package to text-field
abhiomkar Jan 10, 2019
ce63281
feat(text-field): integrated character-counter into helper text
abhiomkar Jan 10, 2019
6d421ae
feat(text-field): updated screenshot test file
abhiomkar Jan 10, 2019
f371904
feat(text-field): Changes after self-review, updated screenshot tests
abhiomkar Jan 11, 2019
2573a86
feat(text-field): Fixed char counter vertical alignment
abhiomkar Jan 15, 2019
ea85ee6
feat(text-field): resolved review comments.
abhiomkar Jan 17, 2019
6129fc6
feat(text-field): minor code comment change
abhiomkar Jan 17, 2019
012c9b2
feat(text-field): address other review comments
abhiomkar Jan 18, 2019
36e2dca
feat(text-field): Fix existing unit tests WIP
abhiomkar Jan 18, 2019
0fe9be5
feat(text-field): Added test file for character counter
abhiomkar Jan 22, 2019
c4d85e3
feat(text-field): new test file for character counter and updated tes…
abhiomkar Jan 22, 2019
8228050
feat(text-field): Fix lint errors
abhiomkar Jan 22, 2019
76392f0
feat(text-field): Added more unit tests for character counter
abhiomkar Jan 22, 2019
a5129fe
feat(text-field): Updated docs
abhiomkar Jan 22, 2019
1f93c71
Merge remote-tracking branch 'origin/master' into feat/textfield_char…
abhiomkar Jan 22, 2019
dd08594
feat(text-field): Fixed closure tests
abhiomkar Jan 22, 2019
4cab28c
feat(text-field): Updated golden.json
abhiomkar Jan 22, 2019
76a2e5a
feat(text-field): Fix review comments
abhiomkar Jan 28, 2019
0bab198
feat(text-field): approve flake
abhiomkar Jan 28, 2019
f6ac37c
Merge remote-tracking branch 'origin/master' into feat/textfield_char…
abhiomkar Jan 28, 2019
72f958f
feat(text-field): doc fix
abhiomkar Jan 29, 2019
f45781d
feat(text-field): merge with master and resolved conflict with text-f…
abhiomkar Jan 29, 2019
29559a2
feat(text-field): Updated golden.json
abhiomkar Jan 29, 2019
0bf6de6
Merge branch 'master' into feat/textfield_char_counter
abhiomkar Jan 29, 2019
e898eff
Merge remote-tracking branch 'origin/master' into feat/textfield_char…
abhiomkar Jan 30, 2019
34e0b6f
Merge remote-tracking branch 'origin/feat/textfield_char_counter' int…
abhiomkar Jan 30, 2019
1b312e6
feat(text-field): merge with master and accept all incoming changes t…
abhiomkar Jan 31, 2019
d82d4df
Merge branch 'master' into feat/textfield_char_counter
abhiomkar Jan 31, 2019
256fb0e
feat(text-field): fix 3332.html screenshot test
abhiomkar Jan 31, 2019
b29545c
feat(text-field): Updated golden.json
abhiomkar Jan 31, 2019
f480450
Merge remote-tracking branch 'origin/feat/textfield_char_counter' int…
abhiomkar Jan 31, 2019
14c56ed
feat(text-field): reorder styles in fixture.scss
abhiomkar Jan 31, 2019
9bb7b71
Merge remote-tracking branch 'origin/master' into feat/textfield_char…
abhiomkar Jan 31, 2019
0809fed
feat(text-field): Updated golden.json
abhiomkar Jan 31, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions packages/mdc-textfield/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,58 @@ Add class name `mdc-text-field--no-label` and remove the label element from the
### Text Field with Helper Text

The helper text provides supplemental information and/or validation messages to users. It appears on input field focus
and disappears on input field blur by default, or it can be persistent.
See [here](helper-text/) for more information on using helper text.
and disappears on input field blur by default, or it can be persistent. Helper text should be rendered inside `.mdc-text-field-helper-line` element
which is immediate sibling of `.mdc-text-field`. See [here](helper-text/) for more information on using helper text.

```html
<div class="mdc-text-field">
<input type="text" id="my-text-field" class="mdc-text-field__input">
<label class="mdc-floating-label" for="my-text-field">My Label</label>
<div class="mdc-line-ripple"></div>
</div>
<div class="mdc-text-field-helper-line">
<div class="mdc-text-field-helper-text">helper text</div>
</div>
```

### Text Field with Character Counter

Character counter is used if there is a character limit. It displays the ratio of characters used and the total character limit.
Helper text should be rendered inside `.mdc-text-field-helper-line` element which is immediate sibling of `.mdc-text-field`.
See [here](character-counter/) for more information on using character counter.

```html
<div class="mdc-text-field">
<input type="text" id="my-text-field" class="mdc-text-field__input" maxlength="10">
<label class="mdc-floating-label" for="my-text-field">My Label</label>
<div class="mdc-line-ripple"></div>
</div>
<div class="mdc-text-field-helper-line">
<div class="mdc-text-field-character-counter">0 / 10</div>
</div>
```

### Multi-line Text Field (Textarea) with Character Counter

The layout structure of character counter for multi-line text field (textarea) is slightly different since it is rendered
inside of text field component.

```html
<div class="mdc-text-field mdc-text-field--textarea">
<div class="mdc-text-field-character-counter">0 / 140</div>
<textarea id="textarea" class="mdc-text-field__input" rows="8" cols="40" maxlength="140"></textarea>
<div class="mdc-notched-outline">
<div class="mdc-notched-outline__leading"></div>
<div class="mdc-notched-outline__notch">
<label for="textarea" class="mdc-floating-label">Textarea Label</label>
</div>
<div class="mdc-notched-outline__trailing"></div>
</div>
</div>
```

Helper text and Character counter are optional subcomponents of text field that can co-exist independently.
It is recommended that `.mdc-text-field` and `.mdc-text-field-helper-line` elements have same width for correct layout.

### Text Field with Leading and Trailing Icons

Expand Down Expand Up @@ -221,6 +271,7 @@ CSS Class | Description
`mdc-text-field--with-trailing-icon` | Styles the text field as a text field with a trailing icon.
`mdc-text-field--focused` | Styles the text field as a text field in focus.
`mdc-text-field--no-label` | Styles the text field that has no label.
`mdc-text-field-helper-line` | Styles the container of helper text and character counter elements.

#### Deprecation Notice

Expand Down Expand Up @@ -351,6 +402,7 @@ Method Signature | Description
`isDisabled() => boolean` | Returns whether or not the input is disabled.
`setDisabled(disabled: boolean) => void` | Updates the input's disabled state.
`handleTextFieldInteraction(evt: Event) => void` | Handles click and keydown events originating from inside the Text Field component.
`handleInput() => void` | Handles text input and textarea input event.
`handleValidationAttributeChange(attributesList: !Array<string>) => void` | Handles validation attribute changes.
`activateFocus() => void` | Activates the focus state of the Text Field. Normally called in response to the input focus event.
`deactivateFocus() => void` | Deactivates the focus state of the Text Field. Normally called in response to the input blur event.
Expand Down
16 changes: 12 additions & 4 deletions packages/mdc-textfield/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@import "@material/shape/mixins";
@import "@material/shape/functions";
@import "helper-text/mixins";
@import "character-counter/mixins";
@import "icon/mixins";
@import "icon/variables";
@import "./variables";
Expand Down Expand Up @@ -134,6 +135,7 @@
@include mdc-text-field-ink-color_($mdc-text-field-disabled-ink-color);
@include mdc-text-field-label-ink-color_($mdc-text-field-disabled-label-color);
@include mdc-text-field-helper-text-color_($mdc-text-field-disabled-helper-text-color);
@include mdc-text-field-character-counter-color_($mdc-text-field-disabled-helper-text-color);
@include mdc-text-field-icon-color_($mdc-text-field-disabled-icon);
@include mdc-text-field-fullwidth-bottom-line-color_($mdc-text-field-fullwidth-bottom-line-color);
@include mdc-text-field-fill-color_($mdc-text-field-disabled-background);
Expand Down Expand Up @@ -164,7 +166,7 @@
}
}

+ .mdc-text-field-helper-text--validation-msg {
+ .mdc-text-field-helper-line .mdc-text-field-helper-text--validation-msg {
opacity: 1;
}
}
Expand All @@ -176,7 +178,7 @@
@include mdc-theme-prop(color, $mdc-text-field-error);
}

+ .mdc-text-field-helper-text:not(.mdc-text-field-helper-text--validation-msg) {
+ .mdc-text-field-helper-line .mdc-text-field-helper-text:not(.mdc-text-field-helper-text--validation-msg) {
opacity: 1;
}
}
Expand Down Expand Up @@ -221,8 +223,8 @@
@include mdc-rtl-reflexive-property(padding, $radius-pixels + $mdc-notched-outline-padding, 0);
}

+ .mdc-text-field-helper-text {
@include mdc-rtl-reflexive-property(margin, $radius-pixels + $mdc-notched-outline-padding, $mdc-text-field-label-offset);
+ .mdc-text-field-helper-line {
@include mdc-rtl-reflexive-property(padding, $radius-pixels + $mdc-notched-outline-padding, $radius-pixels);
}
}
}
Expand Down Expand Up @@ -456,6 +458,7 @@
@include mdc-states-base-color(transparent);
@include mdc-text-field-fill-color(transparent);
@include mdc-notched-outline-floating-label-float-position($mdc-text-field-outlined-label-position-y, 0%);
@include mdc-text-field-character-counter-position(16px, 13px);

$padding-inset: 16px;

Expand All @@ -474,6 +477,11 @@
border: none;
}

.mdc-text-field-character-counter + .mdc-text-field__input {
abhiomkar marked this conversation as resolved.
Show resolved Hide resolved
margin-bottom: 28px; // Leaves space for character counter if it exists.
padding-bottom: 0;
}

.mdc-floating-label {
top: 17px;
bottom: auto;
Expand Down
1 change: 1 addition & 0 deletions packages/mdc-textfield/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ $mdc-text-field-outlined-dense-label-position-y: 120% !default;
$mdc-text-field-outlined-with-leading-icon-label-position-x: 0 !default;
$mdc-text-field-outlined-dense-with-leading-icon-label-position-x: 21px !default;
$mdc-text-field-textarea-label-position-y: 130% !default;
$mdc-text-field-helper-line-padding: 16px;
// Note that the scale factor is an eyeballed approximation of what's shown in the mocks.
3 changes: 3 additions & 0 deletions packages/mdc-textfield/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

/* eslint-disable no-unused-vars */
import MDCTextFieldHelperTextFoundation from './helper-text/foundation';
/* eslint-disable no-unused-vars */
import MDCTextFieldCharacterCounterFoundation from './character-counter/foundation';
import MDCTextFieldIconFoundation from './icon/foundation';

/* eslint no-unused-vars: [2, {"args": "none"}] */
Expand All @@ -43,6 +45,7 @@ let NativeInputType;
/**
* @typedef {{
* helperText: (!MDCTextFieldHelperTextFoundation|undefined),
* characterCounter: (!MDCTextFieldCharacterCounterFoundation|undefined),
* leadingIcon: (!MDCTextFieldIconFoundation|undefined),
* trailingIcon: (!MDCTextFieldIconFoundation|undefined),
* }}
Expand Down
82 changes: 82 additions & 0 deletions packages/mdc-textfield/character-counter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<!--docs:
title: "Text Field Character Counter"
layout: detail
section: components
excerpt: "Character counter displays the ratio of characters used and the total character limit"
iconId: text_field
path: /catalog/input-controls/text-field/character-counter/
-->

# Text Field Character Counter

Character counter is used if there is a character limit. It displays the ratio of characters used and the total character limit.

## Design & API Documentation

<ul class="icon-list">
<li class="icon-list-item icon-list-item--spec">
<a href="https://material.io/go/design-text-fields#text-fields-layout">Material Design guidelines: Text Fields Layout</a>
</li>
</ul>

## Basic Usage

### HTML Structure

```html
<div class="mdc-text-field-character-counter">0 / 140</div>
```

> NOTE: Place this inside `.mdc-text-field-helper-line` for single line mdc text field which is an immediate sibling of `.mdc-text-field` and
> place it as first element of `.mdc-text-field` for multi-line text field variant (textarea).

### Styles

```scss
@import "@material/textfield/character-counter/mdc-text-field-character-counter";
```

### JavaScript Instantiation

```js
import {MDCTextFieldCharacterCounter} from '@material/textfield/character-counter';

const characterCounter = new MDCTextFieldCharacterCounter(document.querySelector('.mdc-text-field-character-counter'));
```

## Style Customization

### CSS Classes

CSS Class | Description
--- | ---
`mdc-text-field-character-counter` | Mandatory.

### Sass Mixins

Mixin | Description
--- | ---
`mdc-text-field-character-counter-color($color)` | Customizes the color of the character counter associated with text field.
`mdc-text-field-character-counter-position($xOffset, $yOffset)` | Positions the character counter element inside text field. Used only for textarea variant.

## `MDCTextFieldCharacterCounter` Properties and Methods

Property | Value Type | Description
--- | --- | ---
`foundation` | `MDCTextFieldCharacterCounterFoundation` | Returns the character counter's foundation. This allows the parent `MDCTextField` component to access the public methods on the `MDCTextFieldCharacterCounterFoundation` class.

## Usage Within Frameworks

If you are using a JavaScript framework, such as React or Angular, you can create a Character Counter for your framework. Depending on your needs, you can use the _Simple Approach: Wrapping MDC Web Vanilla Components_, or the _Advanced Approach: Using Foundations and Adapters_. Please follow the instructions [here](../../../docs/integrating-into-frameworks.md).

### `MDCTextFieldCharacterCounterAdapter`

Method Signature | Description
--- | ---
`setContent(content: string) => void` | Sets the text content of character counter element.

### `MDCTextFieldCharacterCounterFoundation`

Method Signature | Description
--- | ---
`setCounterValue(currentLength: number, maxLength: number) => void` | Sets the character counter values including characters used and total character limit.
51 changes: 51 additions & 0 deletions packages/mdc-textfield/character-counter/_mixins.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Copyright 2019 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

@import "@material/rtl/mixins";

// Public mixins

@mixin mdc-text-field-character-counter-color($color) {
&:not(.mdc-text-field--disabled) {
@include mdc-text-field-character-counter-color_($color);
}
}

@mixin mdc-text-field-character-counter-position($xOffset, $yOffset) {
.mdc-text-field-character-counter {
@include mdc-rtl-reflexive-position(right, $xOffset);

position: absolute;
bottom: $yOffset;
}
}

// Private mixins

@mixin mdc-text-field-character-counter-color_($color) {
// Character counter is placed inside mdc-textfield element (for textarea variant ) or
// inside helper line which is sibling to mdc-textfield.
.mdc-text-field-character-counter,
abhiomkar marked this conversation as resolved.
Show resolved Hide resolved
+ .mdc-text-field-helper-line .mdc-text-field-character-counter {
@include mdc-theme-prop(color, $color);
}
}
44 changes: 44 additions & 0 deletions packages/mdc-textfield/character-counter/adapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/* eslint no-unused-vars: [2, {"args": "none"}] */

/**
* Adapter for MDC Text Field Character Counter.
*
* Defines the shape of the adapter expected by the foundation. Implement this
* adapter to integrate the TextField character counter into your framework. See
* https://github.com/material-components/material-components-web/blob/master/docs/authoring-components.md
* for more information.
*
* @record
*/
class MDCTextFieldCharacterCounterAdapter {
/**
* Sets the text content of character counter element.
* @param {string} content
*/
setContent(content) {}
}

export default MDCTextFieldCharacterCounterAdapter;
34 changes: 34 additions & 0 deletions packages/mdc-textfield/character-counter/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2019 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/** @enum {string} */
const cssClasses = {
ROOT: 'mdc-text-field-character-counter',
};

/** @enum {string} */
const strings = {
ROOT_SELECTOR: `.${cssClasses.ROOT}`,
};

export {strings, cssClasses};
Loading