UNPKG

11 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2017 Google Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23import { __assign, __extends } from "tslib";
24import { MDCFoundation } from '@material/base/foundation';
25import { Direction, EventSource, jumpChipKeys, navigationKeys, strings as chipStrings } from '../chip/constants';
26import { cssClasses, strings } from './constants';
27var MDCChipSetFoundation = /** @class */ (function (_super) {
28 __extends(MDCChipSetFoundation, _super);
29 function MDCChipSetFoundation(adapter) {
30 var _this = _super.call(this, __assign(__assign({}, MDCChipSetFoundation.defaultAdapter), adapter)) || this;
31 /**
32 * The ids of the selected chips in the set. Only used for choice chip set or filter chip set.
33 */
34 _this.selectedChipIds = [];
35 return _this;
36 }
37 Object.defineProperty(MDCChipSetFoundation, "strings", {
38 get: function () {
39 return strings;
40 },
41 enumerable: false,
42 configurable: true
43 });
44 Object.defineProperty(MDCChipSetFoundation, "cssClasses", {
45 get: function () {
46 return cssClasses;
47 },
48 enumerable: false,
49 configurable: true
50 });
51 Object.defineProperty(MDCChipSetFoundation, "defaultAdapter", {
52 get: function () {
53 return {
54 announceMessage: function () { return undefined; },
55 focusChipPrimaryActionAtIndex: function () { return undefined; },
56 focusChipTrailingActionAtIndex: function () { return undefined; },
57 getChipListCount: function () { return -1; },
58 getIndexOfChipById: function () { return -1; },
59 hasClass: function () { return false; },
60 isRTL: function () { return false; },
61 removeChipAtIndex: function () { return undefined; },
62 removeFocusFromChipAtIndex: function () { return undefined; },
63 selectChipAtIndex: function () { return undefined; },
64 };
65 },
66 enumerable: false,
67 configurable: true
68 });
69 /**
70 * Returns an array of the IDs of all selected chips.
71 */
72 MDCChipSetFoundation.prototype.getSelectedChipIds = function () {
73 return this.selectedChipIds.slice();
74 };
75 /**
76 * Selects the chip with the given id. Deselects all other chips if the chip set is of the choice variant.
77 * Does not notify clients of the updated selection state.
78 */
79 MDCChipSetFoundation.prototype.select = function (chipId) {
80 this.selectImpl(chipId, false);
81 };
82 /**
83 * Handles a chip interaction event
84 */
85 MDCChipSetFoundation.prototype.handleChipInteraction = function (_a) {
86 var chipId = _a.chipId;
87 var index = this.adapter.getIndexOfChipById(chipId);
88 this.removeFocusFromChipsExcept(index);
89 if (this.adapter.hasClass(cssClasses.CHOICE) ||
90 this.adapter.hasClass(cssClasses.FILTER)) {
91 this.toggleSelect(chipId);
92 }
93 };
94 /**
95 * Handles a chip selection event, used to handle discrepancy when selection state is set directly on the Chip.
96 */
97 MDCChipSetFoundation.prototype.handleChipSelection = function (_a) {
98 var chipId = _a.chipId, selected = _a.selected, shouldIgnore = _a.shouldIgnore;
99 // Early exit if we should ignore the event
100 if (shouldIgnore) {
101 return;
102 }
103 var chipIsSelected = this.selectedChipIds.indexOf(chipId) >= 0;
104 if (selected && !chipIsSelected) {
105 this.select(chipId);
106 }
107 else if (!selected && chipIsSelected) {
108 this.deselectImpl(chipId);
109 }
110 };
111 /**
112 * Handles the event when a chip is removed.
113 */
114 MDCChipSetFoundation.prototype.handleChipRemoval = function (_a) {
115 var chipId = _a.chipId, removedAnnouncement = _a.removedAnnouncement;
116 if (removedAnnouncement) {
117 this.adapter.announceMessage(removedAnnouncement);
118 }
119 var index = this.adapter.getIndexOfChipById(chipId);
120 this.deselectAndNotifyClients(chipId);
121 this.adapter.removeChipAtIndex(index);
122 var maxIndex = this.adapter.getChipListCount() - 1;
123 if (maxIndex < 0) {
124 return;
125 }
126 var nextIndex = Math.min(index, maxIndex);
127 this.removeFocusFromChipsExcept(nextIndex);
128 // After removing a chip, we should focus the trailing action for the next chip.
129 this.adapter.focusChipTrailingActionAtIndex(nextIndex);
130 };
131 /**
132 * Handles a chip navigation event.
133 */
134 MDCChipSetFoundation.prototype.handleChipNavigation = function (_a) {
135 var chipId = _a.chipId, key = _a.key, source = _a.source;
136 var maxIndex = this.adapter.getChipListCount() - 1;
137 var index = this.adapter.getIndexOfChipById(chipId);
138 // Early exit if the index is out of range or the key is unusable
139 if (index === -1 || !navigationKeys.has(key)) {
140 return;
141 }
142 var isRTL = this.adapter.isRTL();
143 var isLeftKey = key === chipStrings.ARROW_LEFT_KEY ||
144 key === chipStrings.IE_ARROW_LEFT_KEY;
145 var isRightKey = key === chipStrings.ARROW_RIGHT_KEY ||
146 key === chipStrings.IE_ARROW_RIGHT_KEY;
147 var isDownKey = key === chipStrings.ARROW_DOWN_KEY ||
148 key === chipStrings.IE_ARROW_DOWN_KEY;
149 var shouldIncrement = !isRTL && isRightKey || isRTL && isLeftKey || isDownKey;
150 var isHome = key === chipStrings.HOME_KEY;
151 var isEnd = key === chipStrings.END_KEY;
152 if (shouldIncrement) {
153 index++;
154 }
155 else if (isHome) {
156 index = 0;
157 }
158 else if (isEnd) {
159 index = maxIndex;
160 }
161 else {
162 index--;
163 }
164 // Early exit if the index is out of bounds
165 if (index < 0 || index > maxIndex) {
166 return;
167 }
168 this.removeFocusFromChipsExcept(index);
169 this.focusChipAction(index, key, source);
170 };
171 MDCChipSetFoundation.prototype.focusChipAction = function (index, key, source) {
172 var shouldJumpChips = jumpChipKeys.has(key);
173 if (shouldJumpChips && source === EventSource.PRIMARY) {
174 return this.adapter.focusChipPrimaryActionAtIndex(index);
175 }
176 if (shouldJumpChips && source === EventSource.TRAILING) {
177 return this.adapter.focusChipTrailingActionAtIndex(index);
178 }
179 var dir = this.getDirection(key);
180 if (dir === Direction.LEFT) {
181 return this.adapter.focusChipTrailingActionAtIndex(index);
182 }
183 if (dir === Direction.RIGHT) {
184 return this.adapter.focusChipPrimaryActionAtIndex(index);
185 }
186 };
187 MDCChipSetFoundation.prototype.getDirection = function (key) {
188 var isRTL = this.adapter.isRTL();
189 var isLeftKey = key === chipStrings.ARROW_LEFT_KEY ||
190 key === chipStrings.IE_ARROW_LEFT_KEY;
191 var isRightKey = key === chipStrings.ARROW_RIGHT_KEY ||
192 key === chipStrings.IE_ARROW_RIGHT_KEY;
193 if (!isRTL && isLeftKey || isRTL && isRightKey) {
194 return Direction.LEFT;
195 }
196 return Direction.RIGHT;
197 };
198 /**
199 * Deselects the chip with the given id and optionally notifies clients.
200 */
201 MDCChipSetFoundation.prototype.deselectImpl = function (chipId, shouldNotifyClients) {
202 if (shouldNotifyClients === void 0) { shouldNotifyClients = false; }
203 var index = this.selectedChipIds.indexOf(chipId);
204 if (index >= 0) {
205 this.selectedChipIds.splice(index, 1);
206 var chipIndex = this.adapter.getIndexOfChipById(chipId);
207 this.adapter.selectChipAtIndex(chipIndex, /** isSelected */ false, shouldNotifyClients);
208 }
209 };
210 /**
211 * Deselects the chip with the given id and notifies clients.
212 */
213 MDCChipSetFoundation.prototype.deselectAndNotifyClients = function (chipId) {
214 this.deselectImpl(chipId, true);
215 };
216 /**
217 * Toggles selection of the chip with the given id.
218 */
219 MDCChipSetFoundation.prototype.toggleSelect = function (chipId) {
220 if (this.selectedChipIds.indexOf(chipId) >= 0) {
221 this.deselectAndNotifyClients(chipId);
222 }
223 else {
224 this.selectAndNotifyClients(chipId);
225 }
226 };
227 MDCChipSetFoundation.prototype.removeFocusFromChipsExcept = function (index) {
228 var chipCount = this.adapter.getChipListCount();
229 for (var i = 0; i < chipCount; i++) {
230 if (i !== index) {
231 this.adapter.removeFocusFromChipAtIndex(i);
232 }
233 }
234 };
235 MDCChipSetFoundation.prototype.selectAndNotifyClients = function (chipId) {
236 this.selectImpl(chipId, true);
237 };
238 MDCChipSetFoundation.prototype.selectImpl = function (chipId, shouldNotifyClients) {
239 if (this.selectedChipIds.indexOf(chipId) >= 0) {
240 return;
241 }
242 if (this.adapter.hasClass(cssClasses.CHOICE) &&
243 this.selectedChipIds.length > 0) {
244 var previouslySelectedChip = this.selectedChipIds[0];
245 var previouslySelectedIndex = this.adapter.getIndexOfChipById(previouslySelectedChip);
246 this.selectedChipIds = [];
247 this.adapter.selectChipAtIndex(previouslySelectedIndex, /** isSelected */ false, shouldNotifyClients);
248 }
249 this.selectedChipIds.push(chipId);
250 var index = this.adapter.getIndexOfChipById(chipId);
251 this.adapter.selectChipAtIndex(index, /** isSelected */ true, shouldNotifyClients);
252 };
253 return MDCChipSetFoundation;
254}(MDCFoundation));
255export { MDCChipSetFoundation };
256// tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier.
257export default MDCChipSetFoundation;
258//# sourceMappingURL=foundation.js.map
\No newline at end of file