UNPKG

10.8 kBMarkdownView Raw
1<!--docs:
2title: "Icon Toggle Buttons"
3layout: detail
4section: components
5iconId: button
6path: /catalog/buttons/icon-toggle-buttons/
7-->
8
9## Important - Deprecation Notice
10
11The existing `MDCIconToggle` component and styles will be removed in a future release. Some of its functionality
12will be available in the [MDC Icon Button](../mdc-icon-button) package instead. Bugs and feature requests
13will no longer be accepted for the `mdc-icon-toggle` package. It is recommended that you migrate to the
14`mdc-icon-button` package to continue to receive new features and updates.
15
16# Icon Toggle Buttons
17
18<!--<div class="article__asset">
19 <a class="article__asset-link"
20 href="https://material-components.github.io/material-components-web-catalog/#/component/icon-button">
21 <img src="{{ site.rootpath }}/images/mdc_web_screenshots/icon-toggles.png" width="20" alt="Icon toggles screenshot">
22 </a>
23</div>-->
24
25MDC Icon Toggle provides a Material Design icon toggle button. It is fully accessible, and is
26designed to work with any icon set.
27
28## Design & API Documentation
29
30<ul class="icon-list">
31 <li class="icon-list-item icon-list-item--spec">
32 <a href="https://material.io/go/design-buttons#toggle-button">Material Design guidelines: Toggle buttons</a>
33 </li>
34 <li class="icon-list-item icon-list-item--link">
35 <a href="https://material-components.github.io/material-components-web-catalog/#/component/icon-button">Demo (for Icon Button)</a>
36 </li>
37</ul>
38
39## Installation
40
41```
42npm install @material/icon-toggle
43```
44
45## Basic Usage
46
47### HTML Structure
48
49```html
50<i class="mdc-icon-toggle material-icons" role="button" aria-pressed="false"
51 aria-label="Add to favorites" tabindex="0"
52 data-toggle-on='{"label": "Remove from favorites", "content": "favorite"}'
53 data-toggle-off='{"label": "Add to favorites", "content": "favorite_border"}'>
54 favorite_border
55</i>
56```
57
58Then in JS:
59
60```js
61import {MDCIconToggle} from '@material/icon-toggle';
62
63MDCIconToggle.attachTo(document.querySelector('.mdc-icon-toggle'));
64```
65
66Note that you can access `MDCIconToggle` via CommonJS/AMD using the `default` property of the
67`require`d object, as well as globally via `mdc.IconToggle`.
68
69Also note that you may omit the initial `aria-label` attribute and `favorite_border` content since
70they will be added by the component. However, we recommend adding to prevent an initial flash of
71un-styled content.
72
73### Icon set
74
75In order to use MDC Icon Toggle, you will need to import an icon set.
76
77We recommend using [Material Icons](https://material.io/tools/icons/) from Google Fonts:
78
79```html
80<head>
81 <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
82</head>
83```
84
85However, you can use any icon set you like! See the [Font Awesome section](#font-awesome) below for details.
86
87<a id="font-awesome"></a>
88#### Using with Font Awesome and similar libraries
89
90[Font Awesome](https://fontawesome.com/) and other popular icon font libraries use pseudo-elements in order to
91provide the icon, via the `content` property. However, MDC Web uses pseudo-elements for ripple styles.
92In order to get around this, you can nest the icon itself inside the icon toggle.
93
94```html
95<span class="mdc-icon-toggle" role="button" aria-pressed="false"
96 aria-label="Star this item" tabindex="0"
97 data-icon-inner-selector=".fa"
98 data-toggle-on='{"cssClass": "fa-star", "label": "Unstar this item"}'
99 data-toggle-off='{"cssClass": "fa-star-o", "label": "Star this item"}'>
100 <i class="fa fa-star-o" aria-hidden="true"></i>
101</span>
102```
103
104`data-icon-inner-selector` tells MDCIconToggle to look for an element within itself that matches
105that selector, and treat it as the element containing the icon. Also note the `aria-hidden`
106attribute on the icon. This is important to ensure that screen readers produce the correct output
107when reading this element.
108
109### Configuring the icon toggle states
110
111Note the use of `data-toggle-on` and `data-toggle-off` in the above examples. When an MDCIconToggle
112instance is toggled, it looks at this data to determine how to update the element. This is what
113allows MDCIconToggle to be so flexible. The `data-toggle-on` configuration will be used when the is
114MDCIconToggle is toggled on, and vice versa for `data-toggle-off`. Both data attributes are encoded
115as JSON and can contain the following properties:
116
117Property | Description
118--- | ---
119`label` | The value to apply to the element's "aria-label" attribute.
120`content` | The text content to set on the element. Note that if an inner icon is used, the text content will be set on that element instead.
121`cssClass` | A css class to apply to the icon element for the given toggle state. The same rules regarding inner icon elements described for `content` apply here as well.
122
123### Disabled icon toggles
124
125```html
126<i class="material-icon mdc-icon-toggle mdc-icon-toggle--disabled"
127 role="button" tabindex="-1" aria-pressed="false" aria-disabled="true"
128 data-toggle-on='{"content": "favorite"}' data-toggle-off='{"content": "favorite_border"}'></i>
129```
130
131### Listening for change events
132
133`MDCIconToggle` emits an `MDCIconToggle:change` custom event when the value of the icon toggle
134changes _as a result of user input_. This decision was made to align with how `change` events work
135for normal inputs. In addition, these events do not bubble and cannot be cancelled.
136
137The custom event's `detail` object contains a property `isOn` denoting whether or not the component
138is toggled on.
139
140```js
141const iconEl = document.querySelector('.mdc-icon-toggle');
142const status = document.getElementById('status');
143iconEl.addEventListener('MDCIconToggle:change', ({detail}) => {
144 status.textContent = `Icon Toggle is ${detail.isOn ? 'on' : 'off'}`;
145});
146```
147
148### Refreshing the toggle data via the vanilla component.
149
150When the icon toggle is initialized, the `data-toggle-on` and `data-toggle-off` attributes are
151cached to prevent redundant JSON parsing whenever the element is interacted with. However, if you
152need to, you can call `refreshToggleData()`:
153
154```js
155iconToggle.refreshToggleData();
156```
157
158This simply forwards a call to the foundation's `refreshToggleData()` method, causing the
159`data-toggle-*` attributes to be re-parsed and updated.
160
161This method is useful for frameworks that incrementally render DOM. If an icon toggle's data
162attributes change, the component needs a way to update itself. This is the reason why this method is
163exposed on the foundation, and simply proxied by the vanilla component.
164
165### `MDCIconToggle` API
166
167Similar to regular DOM elements, the `MDCIconToggle` functionality is exposed through accessor
168methods.
169
170#### `MDCIconToggle.on`
171
172Boolean. Returns whether or not the icon toggle is currently toggled on. Setting this property
173will update the toggle state.
174
175#### `MDCIconToggle.disabled`
176
177Boolean. Returns whether or not the icon toggle is currently disabled. Setting this property will
178update the disabled state.
179
180### Using the Foundation Class
181
182MDCIconToggle ships with an `MDCIconToggleFoundation` class that external frameworks and libraries
183can use to build their own MDCIconToggle components with minimal effort. As with all foundation
184classes, an adapter object must be provided. The adapter for icon toggles must provide the following
185functions, with correct signatures:
186
187Method Signature | Description
188--- | ---
189`addClass(className: string) => void` | Adds a class to the root element, or the inner icon element.
190`removeClass(className: string) => void` | Removes a class from the root element, or the inner icon element.
191`registerInteractionHandler(type: string, handler: EventListener) => void` | Registers an event handler for an interaction event, such as `click` or `keydown`.
192`deregisterInteractionHandler(type: string, handler: EventListener) => void` | Removes an event handler for an interaction event, such as `click` or `keydown`.
193`setText(text: string) => void` | Sets the text content of the root element, or the inner icon element.
194`getTabIndex() => number` | Returns the tab index of the root element.
195`setTabIndex(tabIndex: number) => void` | Sets the tab index of the root element.
196`getAttr(name: string) => string` | Returns the value of the attribute `name` on the root element. Can also return `null`, similar to `getAttribute()`.
197`setAttr(name: string, value: string) => void` | Sets the attribute `name` to `value` on the root element.
198`rmAttr(name: string) => void` | Removes the attribute `name` on the root element.
199`notifyChange(evtData: {isOn: boolean}) => void` | Broadcasts a change notification, passing along the `evtData` to the environment's event handling system. In our vanilla implementation, Custom Events are used for this.
200
201#### Adapter implementer considerations
202
203If you are writing your own adapter, one thing that needs to be considered is the use of
204`data-icon-inner-selector`. This is handled by us at the _component_ level, which means our
205foundation is completely unaware of it. To that end, if your framework's Icon Toggle support inner
206icon elements, you must ensure that `addClass`, `removeClass`, and `setText` apply to the correct
207icon element.
208
209Also note that _ripples require their own foundation at the component level_. Check out our vanilla
210implementation in `index.js` as a starting point.
211
212#### Full foundation API
213
214##### `MDCIconToggleFoundation.refreshToggleData() => void`
215
216As described above, the `data-toggle-*` attributes are cached so as not to have to perform redundant
217parsing. If your framework performs incremental rendering, and these attributes change without
218re-rendering the component itself, you can call this method to re-parse the data attributes and keep
219the foundation updated.
220
221##### `MDCIconToggleFoundation.isOn() => boolean`
222
223Returns true if the foundation's state is toggled on, false otherwise.
224
225##### `MDCIconToggleFoundation.toggle(isOn: boolean = !this.isOn()) => void`
226
227Toggles the foundation's state, updating the component via the adapter methods. Defaults to the
228toggling the opposite of the current state if no argument given. If an argument is given, will
229toggle on if true, off if false.
230
231##### `MDCIconToggleFoundation.isDisabled() => boolean`
232
233Returns `true` if the foundation's state is disabled, `false` otherwise.
234
235##### `MDCIconToggleFoundation.setDisabled(isDisabled: boolean) => void`
236
237Enables / disables the foundation's state, updating the component via the adapter methods.
238
239##### `MDCIconToggleFoundation.isKeyboardActivated() => boolean`
240
241Returns `true` if the foundation is currently activated by a keyboard event, `false` otherwise.
242Useful for the `MDCRippleFoundation.isSurfaceActive()` adapter method.
243
244### Sass Mixins
245
246Mixin | Description
247--- | ---
248`mdc-icon-toggle-ink-color($color)` | Sets the ink color of the icon toggle