1 |
|
2 | title: "Icon Toggle Buttons"
|
3 | layout: detail
|
4 | section: components
|
5 | iconId: button
|
6 | path: /catalog/buttons/icon-toggle-buttons/
|
7 | -->
|
8 |
|
9 | ## Important - Deprecation Notice
|
10 |
|
11 | The existing `MDCIconToggle` component and styles will be removed in a future release. Some of its functionality
|
12 | will be available in the [MDC Icon Button](../mdc-icon-button) package instead. Bugs and feature requests
|
13 | will 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 |
|
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 |
|
25 | MDC Icon Toggle provides a Material Design icon toggle button. It is fully accessible, and is
|
26 | designed 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 | ```
|
42 | npm 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 |
|
58 | Then in JS:
|
59 |
|
60 | ```js
|
61 | import {MDCIconToggle} from '@material/icon-toggle';
|
62 |
|
63 | MDCIconToggle.attachTo(document.querySelector('.mdc-icon-toggle'));
|
64 | ```
|
65 |
|
66 | Note 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 |
|
69 | Also note that you may omit the initial `aria-label` attribute and `favorite_border` content since
|
70 | they will be added by the component. However, we recommend adding to prevent an initial flash of
|
71 | un-styled content.
|
72 |
|
73 | ### Icon set
|
74 |
|
75 | In order to use MDC Icon Toggle, you will need to import an icon set.
|
76 |
|
77 | We 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 |
|
85 | However, 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
|
91 | provide the icon, via the `content` property. However, MDC Web uses pseudo-elements for ripple styles.
|
92 | In 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
|
105 | that selector, and treat it as the element containing the icon. Also note the `aria-hidden`
|
106 | attribute on the icon. This is important to ensure that screen readers produce the correct output
|
107 | when reading this element.
|
108 |
|
109 | ### Configuring the icon toggle states
|
110 |
|
111 | Note the use of `data-toggle-on` and `data-toggle-off` in the above examples. When an MDCIconToggle
|
112 | instance is toggled, it looks at this data to determine how to update the element. This is what
|
113 | allows MDCIconToggle to be so flexible. The `data-toggle-on` configuration will be used when the is
|
114 | MDCIconToggle is toggled on, and vice versa for `data-toggle-off`. Both data attributes are encoded
|
115 | as JSON and can contain the following properties:
|
116 |
|
117 | Property | 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
|
134 | changes _as a result of user input_. This decision was made to align with how `change` events work
|
135 | for normal inputs. In addition, these events do not bubble and cannot be cancelled.
|
136 |
|
137 | The custom event's `detail` object contains a property `isOn` denoting whether or not the component
|
138 | is toggled on.
|
139 |
|
140 | ```js
|
141 | const iconEl = document.querySelector('.mdc-icon-toggle');
|
142 | const status = document.getElementById('status');
|
143 | iconEl.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 |
|
150 | When the icon toggle is initialized, the `data-toggle-on` and `data-toggle-off` attributes are
|
151 | cached to prevent redundant JSON parsing whenever the element is interacted with. However, if you
|
152 | need to, you can call `refreshToggleData()`:
|
153 |
|
154 | ```js
|
155 | iconToggle.refreshToggleData();
|
156 | ```
|
157 |
|
158 | This simply forwards a call to the foundation's `refreshToggleData()` method, causing the
|
159 | `data-toggle-*` attributes to be re-parsed and updated.
|
160 |
|
161 | This method is useful for frameworks that incrementally render DOM. If an icon toggle's data
|
162 | attributes change, the component needs a way to update itself. This is the reason why this method is
|
163 | exposed on the foundation, and simply proxied by the vanilla component.
|
164 |
|
165 | ### `MDCIconToggle` API
|
166 |
|
167 | Similar to regular DOM elements, the `MDCIconToggle` functionality is exposed through accessor
|
168 | methods.
|
169 |
|
170 | #### `MDCIconToggle.on`
|
171 |
|
172 | Boolean. Returns whether or not the icon toggle is currently toggled on. Setting this property
|
173 | will update the toggle state.
|
174 |
|
175 | #### `MDCIconToggle.disabled`
|
176 |
|
177 | Boolean. Returns whether or not the icon toggle is currently disabled. Setting this property will
|
178 | update the disabled state.
|
179 |
|
180 | ### Using the Foundation Class
|
181 |
|
182 | MDCIconToggle ships with an `MDCIconToggleFoundation` class that external frameworks and libraries
|
183 | can use to build their own MDCIconToggle components with minimal effort. As with all foundation
|
184 | classes, an adapter object must be provided. The adapter for icon toggles must provide the following
|
185 | functions, with correct signatures:
|
186 |
|
187 | Method 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 |
|
203 | If 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
|
205 | foundation is completely unaware of it. To that end, if your framework's Icon Toggle support inner
|
206 | icon elements, you must ensure that `addClass`, `removeClass`, and `setText` apply to the correct
|
207 | icon element.
|
208 |
|
209 | Also note that _ripples require their own foundation at the component level_. Check out our vanilla
|
210 | implementation in `index.js` as a starting point.
|
211 |
|
212 | #### Full foundation API
|
213 |
|
214 | ##### `MDCIconToggleFoundation.refreshToggleData() => void`
|
215 |
|
216 | As described above, the `data-toggle-*` attributes are cached so as not to have to perform redundant
|
217 | parsing. If your framework performs incremental rendering, and these attributes change without
|
218 | re-rendering the component itself, you can call this method to re-parse the data attributes and keep
|
219 | the foundation updated.
|
220 |
|
221 | ##### `MDCIconToggleFoundation.isOn() => boolean`
|
222 |
|
223 | Returns true if the foundation's state is toggled on, false otherwise.
|
224 |
|
225 | ##### `MDCIconToggleFoundation.toggle(isOn: boolean = !this.isOn()) => void`
|
226 |
|
227 | Toggles the foundation's state, updating the component via the adapter methods. Defaults to the
|
228 | toggling the opposite of the current state if no argument given. If an argument is given, will
|
229 | toggle on if true, off if false.
|
230 |
|
231 | ##### `MDCIconToggleFoundation.isDisabled() => boolean`
|
232 |
|
233 | Returns `true` if the foundation's state is disabled, `false` otherwise.
|
234 |
|
235 | ##### `MDCIconToggleFoundation.setDisabled(isDisabled: boolean) => void`
|
236 |
|
237 | Enables / disables the foundation's state, updating the component via the adapter methods.
|
238 |
|
239 | ##### `MDCIconToggleFoundation.isKeyboardActivated() => boolean`
|
240 |
|
241 | Returns `true` if the foundation is currently activated by a keyboard event, `false` otherwise.
|
242 | Useful for the `MDCRippleFoundation.isSurfaceActive()` adapter method.
|
243 |
|
244 | ### Sass Mixins
|
245 |
|
246 | Mixin | Description
|
247 | --- | ---
|
248 | `mdc-icon-toggle-ink-color($color)` | Sets the ink color of the icon toggle
|