mirror of
https://github.com/material-components/material-web.git
synced 2024-09-21 10:38:19 +03:00
chore(chips): Fork foundation, adapter, and Sass files: ChipSet
PiperOrigin-RevId: 468108061
This commit is contained in:
parent
9dce0bc59a
commit
dc8045e568
48
chips/chipset/lib/_chip-set-theme.scss
Normal file
48
chips/chipset/lib/_chip-set-theme.scss
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
@use 'sass:math';
|
||||
|
||||
// stylelint-disable selector-class-pattern -- MDC internal usage.
|
||||
|
||||
$space-between-chips: 8px;
|
||||
|
||||
///
|
||||
/// Sets the horiontal space between the chips in the chip set.
|
||||
/// @param {Number} $space - The horizontal space between the chips.
|
||||
///
|
||||
@mixin horizontal-space-between-chips($space) {
|
||||
///
|
||||
/// We should use the column-gap property when our browser matrix allows.
|
||||
///
|
||||
|
||||
.md3-chip-set__chips {
|
||||
// Set the margin to the negative horizontal space to account for chips
|
||||
// being inset on the leading edge.
|
||||
// TODO(kainby): Explore using CSS grid layout instead.
|
||||
margin-inline-start: -$space;
|
||||
}
|
||||
|
||||
.md3-chip {
|
||||
margin-inline-start: $space;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Sets the vertical space between the chips in the chip set.
|
||||
/// @param {Number} $space - The vertical space between the chips.
|
||||
///
|
||||
@mixin vertical-space-between-chips($space) {
|
||||
///
|
||||
/// We should use the row-gap property when our browser matrix allows.
|
||||
///
|
||||
|
||||
.md3-chip {
|
||||
// Set top and bottom to half the vertical space since there's no
|
||||
// well supported method for vertical wrapping gaps.
|
||||
margin-block: math.div($space, 2);
|
||||
}
|
||||
}
|
46
chips/chipset/lib/_chip-set.scss
Normal file
46
chips/chipset/lib/_chip-set.scss
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
@use './chip-set-theme';
|
||||
|
||||
// stylelint-disable selector-class-pattern -- MDC internal usage.
|
||||
|
||||
@mixin core-styles() {
|
||||
@include _static-styles();
|
||||
@include _theme-styles();
|
||||
}
|
||||
|
||||
@mixin _static-styles() {
|
||||
.md3-chip-set {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.md3-chip-set:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.md3-chip-set__chips {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.md3-chip-set--overflow .md3-chip-set__chips {
|
||||
flex-flow: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _theme-styles() {
|
||||
.md3-chip-set {
|
||||
@include chip-set-theme.horizontal-space-between-chips(
|
||||
chip-set-theme.$space-between-chips
|
||||
);
|
||||
|
||||
@include chip-set-theme.vertical-space-between-chips(
|
||||
chip-set-theme.$space-between-chips
|
||||
);
|
||||
}
|
||||
}
|
66
chips/chipset/lib/adapter.ts
Normal file
66
chips/chipset/lib/adapter.ts
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {MDCChipActionFocusBehavior, MDCChipActionType} from '../../action/lib/constants';
|
||||
import {MDCChipAnimation} from '../../chip/lib/constants';
|
||||
|
||||
import {MDCChipSetAttributes, MDCChipSetEvents} from './constants';
|
||||
|
||||
/**
|
||||
* Defines the shape of the adapter expected by the foundation.
|
||||
* Implement this adapter for your framework of choice to delegate updates to
|
||||
* the component in your framework of choice. See architecture documentation
|
||||
* for more details.
|
||||
* https://github.com/material-components/material-components-web/blob/master/docs/code/architecture.md
|
||||
*/
|
||||
export interface MDCChipSetAdapter {
|
||||
/** Announces the message via an aria-live region */
|
||||
announceMessage(message: string): void;
|
||||
|
||||
/** Emits the given event with the given detail. */
|
||||
emitEvent<D extends object>(eventName: MDCChipSetEvents, eventDetail: D):
|
||||
void;
|
||||
|
||||
/** Returns the value for the given attribute, if it exists. */
|
||||
getAttribute(attrName: MDCChipSetAttributes): string|null;
|
||||
|
||||
/** Returns the actions provided by the child chip at the given index. */
|
||||
getChipActionsAtIndex(index: number): MDCChipActionType[];
|
||||
|
||||
/** Returns the number of child chips. */
|
||||
getChipCount(): number;
|
||||
|
||||
/** Returns the ID of the chip at the given index. */
|
||||
getChipIdAtIndex(index: number): string;
|
||||
|
||||
/** Returns the index of the child chip with the matching ID. */
|
||||
getChipIndexById(chipID: string): number;
|
||||
|
||||
/** Proxies to the MDCChip#isActionFocusable method. */
|
||||
isChipFocusableAtIndex(index: number, actionType: MDCChipActionType): boolean;
|
||||
|
||||
/** Proxies to the MDCChip#isActionSelectable method. */
|
||||
isChipSelectableAtIndex(index: number, actionType: MDCChipActionType):
|
||||
boolean;
|
||||
|
||||
/** Proxies to the MDCChip#isActionSelected method. */
|
||||
isChipSelectedAtIndex(index: number, actionType: MDCChipActionType): boolean;
|
||||
|
||||
/** Removes the chip at the given index. */
|
||||
removeChipAtIndex(index: number): void;
|
||||
|
||||
/** Proxies to the MDCChip#setActionFocus method. */
|
||||
setChipFocusAtIndex(
|
||||
index: number, action: MDCChipActionType,
|
||||
focus: MDCChipActionFocusBehavior): void;
|
||||
|
||||
/** Proxies to the MDCChip#setActionSelected method. */
|
||||
setChipSelectedAtIndex(
|
||||
index: number, actionType: MDCChipActionType, isSelected: boolean): void;
|
||||
|
||||
/** Starts the chip animation at the given index. */
|
||||
startChipAnimationAtIndex(index: number, animation: MDCChipAnimation): void;
|
||||
}
|
29
chips/chipset/lib/constants.ts
Normal file
29
chips/chipset/lib/constants.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* MDCChipSetAttributes provides the named constants for attributes used by the
|
||||
* foundation.
|
||||
*/
|
||||
export enum MDCChipSetAttributes {
|
||||
ARIA_MULTISELECTABLE = 'aria-multiselectable',
|
||||
}
|
||||
|
||||
/**
|
||||
* MDCChipSetCssClasses provides the named constants for class names.
|
||||
*/
|
||||
export enum MDCChipSetCssClasses {
|
||||
CHIP = 'md3-chip',
|
||||
}
|
||||
|
||||
/**
|
||||
* MDCChipSetEvents provides the constants for emitted events.
|
||||
*/
|
||||
export enum MDCChipSetEvents {
|
||||
INTERACTION = 'MDCChipSet:interaction',
|
||||
REMOVAL = 'MDCChipSet:removal',
|
||||
SELECTION = 'MDCChipSet:selection',
|
||||
}
|
397
chips/chipset/lib/foundation.ts
Normal file
397
chips/chipset/lib/foundation.ts
Normal file
@ -0,0 +1,397 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {KEY} from '@material/web/compat/dom/keyboard';
|
||||
|
||||
import {MDCChipActionFocusBehavior, MDCChipActionType} from '../../action/lib/constants';
|
||||
import {MDCChipAnimation} from '../../chip/lib/constants';
|
||||
|
||||
import {MDCChipSetAdapter} from './adapter';
|
||||
import {MDCChipSetAttributes, MDCChipSetEvents} from './constants';
|
||||
import {ChipAnimationEvent, ChipInteractionEvent, ChipNavigationEvent, MDCChipSetInteractionEventDetail, MDCChipSetRemovalEventDetail, MDCChipSetSelectionEventDetail} from './types';
|
||||
|
||||
interface FocusAction {
|
||||
action: MDCChipActionType;
|
||||
index: number;
|
||||
}
|
||||
|
||||
enum Operator {
|
||||
INCREMENT,
|
||||
DECREMENT,
|
||||
}
|
||||
|
||||
/**
|
||||
* MDCChipSetFoundation provides a foundation for all chips.
|
||||
*/
|
||||
export class MDCChipSetFoundation {
|
||||
private readonly adapter: MDCChipSetAdapter;
|
||||
|
||||
static get defaultAdapter(): MDCChipSetAdapter {
|
||||
return {
|
||||
announceMessage: () => undefined,
|
||||
emitEvent: () => undefined,
|
||||
getAttribute: () => null,
|
||||
getChipActionsAtIndex: () => [],
|
||||
getChipCount: () => 0,
|
||||
getChipIdAtIndex: () => '',
|
||||
getChipIndexById: () => 0,
|
||||
isChipFocusableAtIndex: () => false,
|
||||
isChipSelectableAtIndex: () => false,
|
||||
isChipSelectedAtIndex: () => false,
|
||||
removeChipAtIndex: () => {},
|
||||
setChipFocusAtIndex: () => undefined,
|
||||
setChipSelectedAtIndex: () => undefined,
|
||||
startChipAnimationAtIndex: () => undefined,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(adapter?: Partial<MDCChipSetAdapter>) {
|
||||
this.adapter = {...MDCChipSetFoundation.defaultAdapter, ...adapter};
|
||||
}
|
||||
|
||||
handleChipAnimation({detail}: ChipAnimationEvent) {
|
||||
const {
|
||||
chipID,
|
||||
animation,
|
||||
isComplete,
|
||||
addedAnnouncement,
|
||||
removedAnnouncement
|
||||
} = detail;
|
||||
const index = this.adapter.getChipIndexById(chipID);
|
||||
|
||||
if (animation === MDCChipAnimation.EXIT && isComplete) {
|
||||
if (removedAnnouncement) {
|
||||
this.adapter.announceMessage(removedAnnouncement);
|
||||
}
|
||||
this.removeAfterAnimation(index, chipID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (animation === MDCChipAnimation.ENTER && isComplete && addedAnnouncement) {
|
||||
this.adapter.announceMessage(addedAnnouncement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
handleChipInteraction({detail}: ChipInteractionEvent) {
|
||||
const {source, chipID, isSelectable, isSelected, shouldRemove} = detail;
|
||||
const index = this.adapter.getChipIndexById(chipID);
|
||||
|
||||
if (shouldRemove) {
|
||||
this.removeChip(index);
|
||||
return;
|
||||
}
|
||||
|
||||
this.focusChip(index, source, MDCChipActionFocusBehavior.FOCUSABLE);
|
||||
this.adapter.emitEvent<MDCChipSetInteractionEventDetail>(
|
||||
MDCChipSetEvents.INTERACTION, {
|
||||
chipIndex: index,
|
||||
chipID,
|
||||
});
|
||||
|
||||
if (isSelectable) {
|
||||
this.setSelection(index, source, !isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
handleChipNavigation({detail}: ChipNavigationEvent) {
|
||||
const {chipID, key, isRTL, source} = detail;
|
||||
const index = this.adapter.getChipIndexById(chipID);
|
||||
|
||||
const toNextChip = (key === KEY.ARROW_RIGHT && !isRTL) ||
|
||||
(key === KEY.ARROW_LEFT && isRTL);
|
||||
if (toNextChip) {
|
||||
// Start from the next chip so we increment the index
|
||||
this.focusNextChipFrom(index + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
const toPreviousChip = (key === KEY.ARROW_LEFT && !isRTL) ||
|
||||
(key === KEY.ARROW_RIGHT && isRTL);
|
||||
if (toPreviousChip) {
|
||||
// Start from the previous chip so we decrement the index
|
||||
this.focusPrevChipFrom(index - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === KEY.ARROW_DOWN) {
|
||||
// Start from the next chip so we increment the index
|
||||
this.focusNextChipFrom(index + 1, source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === KEY.ARROW_UP) {
|
||||
// Start from the previous chip so we decrement the index
|
||||
this.focusPrevChipFrom(index - 1, source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === KEY.HOME) {
|
||||
this.focusNextChipFrom(0, source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === KEY.END) {
|
||||
this.focusPrevChipFrom(this.adapter.getChipCount() - 1, source);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the unique selected indexes of the chips. */
|
||||
getSelectedChipIndexes(): ReadonlySet<number> {
|
||||
const selectedIndexes = new Set<number>();
|
||||
const chipCount = this.adapter.getChipCount();
|
||||
for (let i = 0; i < chipCount; i++) {
|
||||
const actions = this.adapter.getChipActionsAtIndex(i);
|
||||
for (const action of actions) {
|
||||
if (this.adapter.isChipSelectedAtIndex(i, action)) {
|
||||
selectedIndexes.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectedIndexes;
|
||||
}
|
||||
|
||||
/** Sets the selected state of the chip at the given index and action. */
|
||||
setChipSelected(
|
||||
index: number, action: MDCChipActionType, isSelected: boolean) {
|
||||
if (this.adapter.isChipSelectableAtIndex(index, action)) {
|
||||
this.setSelection(index, action, isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the selected state of the chip at the given index and action. */
|
||||
isChipSelected(index: number, action: MDCChipActionType): boolean {
|
||||
return this.adapter.isChipSelectedAtIndex(index, action);
|
||||
}
|
||||
|
||||
/** Removes the chip at the given index. */
|
||||
removeChip(index: number) {
|
||||
// Early exit if the index is out of bounds
|
||||
if (index >= this.adapter.getChipCount() || index < 0) return;
|
||||
this.adapter.startChipAnimationAtIndex(index, MDCChipAnimation.EXIT);
|
||||
this.adapter.emitEvent<MDCChipSetRemovalEventDetail>(
|
||||
MDCChipSetEvents.REMOVAL, {
|
||||
chipID: this.adapter.getChipIdAtIndex(index),
|
||||
chipIndex: index,
|
||||
isComplete: false,
|
||||
});
|
||||
}
|
||||
|
||||
addChip(index: number) {
|
||||
// Early exit if the index is out of bounds
|
||||
if (index >= this.adapter.getChipCount() || index < 0) return;
|
||||
this.adapter.startChipAnimationAtIndex(index, MDCChipAnimation.ENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments to find the first focusable chip.
|
||||
*/
|
||||
private focusNextChipFrom(
|
||||
startIndex: number, targetAction?: MDCChipActionType) {
|
||||
const chipCount = this.adapter.getChipCount();
|
||||
for (let i = startIndex; i < chipCount; i++) {
|
||||
const focusableAction =
|
||||
this.getFocusableAction(i, Operator.INCREMENT, targetAction);
|
||||
if (focusableAction) {
|
||||
this.focusChip(
|
||||
i, focusableAction,
|
||||
MDCChipActionFocusBehavior.FOCUSABLE_AND_FOCUSED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements to find the first focusable chip. Takes an optional target
|
||||
* action that can be used to focus the first matching focusable action.
|
||||
*/
|
||||
private focusPrevChipFrom(
|
||||
startIndex: number, targetAction?: MDCChipActionType) {
|
||||
for (let i = startIndex; i > -1; i--) {
|
||||
const focusableAction =
|
||||
this.getFocusableAction(i, Operator.DECREMENT, targetAction);
|
||||
if (focusableAction) {
|
||||
this.focusChip(
|
||||
i, focusableAction,
|
||||
MDCChipActionFocusBehavior.FOCUSABLE_AND_FOCUSED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the appropriate focusable action, or null if none exist. */
|
||||
private getFocusableAction(
|
||||
index: number, op: Operator,
|
||||
targetAction?: MDCChipActionType): MDCChipActionType|null {
|
||||
const actions = this.adapter.getChipActionsAtIndex(index);
|
||||
// Reverse the actions if decrementing
|
||||
if (op === Operator.DECREMENT) actions.reverse();
|
||||
|
||||
if (targetAction) {
|
||||
return this.getMatchingFocusableAction(index, actions, targetAction);
|
||||
}
|
||||
|
||||
return this.getFirstFocusableAction(index, actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returs the first focusable action, regardless of type, or null if no
|
||||
* focusable actions exist.
|
||||
*/
|
||||
private getFirstFocusableAction(index: number, actions: MDCChipActionType[]):
|
||||
MDCChipActionType|null {
|
||||
for (const action of actions) {
|
||||
if (this.adapter.isChipFocusableAtIndex(index, action)) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the actions contain a focusable action that matches the target action,
|
||||
* return that. Otherwise, return the first focusable action, or null if no
|
||||
* focusable action exists.
|
||||
*/
|
||||
private getMatchingFocusableAction(
|
||||
index: number, actions: MDCChipActionType[],
|
||||
targetAction: MDCChipActionType): MDCChipActionType|null {
|
||||
let focusableAction = null;
|
||||
for (const action of actions) {
|
||||
if (this.adapter.isChipFocusableAtIndex(index, action)) {
|
||||
focusableAction = action;
|
||||
}
|
||||
|
||||
// Exit and return the focusable action if it matches the target
|
||||
if (focusableAction === targetAction) {
|
||||
return focusableAction;
|
||||
}
|
||||
}
|
||||
return focusableAction;
|
||||
}
|
||||
|
||||
private focusChip(
|
||||
index: number, action: MDCChipActionType,
|
||||
focus: MDCChipActionFocusBehavior) {
|
||||
this.adapter.setChipFocusAtIndex(index, action, focus);
|
||||
const chipCount = this.adapter.getChipCount();
|
||||
for (let i = 0; i < chipCount; i++) {
|
||||
const actions = this.adapter.getChipActionsAtIndex(i);
|
||||
for (const chipAction of actions) {
|
||||
// Skip the action and index provided since we set it above
|
||||
if (chipAction === action && i === index) continue;
|
||||
this.adapter.setChipFocusAtIndex(
|
||||
i, chipAction, MDCChipActionFocusBehavior.NOT_FOCUSABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private supportsMultiSelect(): boolean {
|
||||
return this.adapter.getAttribute(
|
||||
MDCChipSetAttributes.ARIA_MULTISELECTABLE) === 'true';
|
||||
}
|
||||
|
||||
private setSelection(
|
||||
index: number, action: MDCChipActionType, isSelected: boolean) {
|
||||
this.adapter.setChipSelectedAtIndex(index, action, isSelected);
|
||||
this.adapter.emitEvent<MDCChipSetSelectionEventDetail>(
|
||||
MDCChipSetEvents.SELECTION, {
|
||||
chipID: this.adapter.getChipIdAtIndex(index),
|
||||
chipIndex: index,
|
||||
isSelected,
|
||||
});
|
||||
// Early exit if we support multi-selection
|
||||
if (this.supportsMultiSelect()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we get here, we ony support single selection. This means we need to
|
||||
// unselect all chips
|
||||
const chipCount = this.adapter.getChipCount();
|
||||
for (let i = 0; i < chipCount; i++) {
|
||||
const actions = this.adapter.getChipActionsAtIndex(i);
|
||||
for (const chipAction of actions) {
|
||||
// Skip the action and index provided since we set it above
|
||||
if (chipAction === action && i === index) continue;
|
||||
this.adapter.setChipSelectedAtIndex(i, chipAction, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private removeAfterAnimation(index: number, chipID: string) {
|
||||
this.adapter.removeChipAtIndex(index);
|
||||
this.adapter.emitEvent<MDCChipSetRemovalEventDetail>(
|
||||
MDCChipSetEvents.REMOVAL, {
|
||||
chipIndex: index,
|
||||
isComplete: true,
|
||||
chipID,
|
||||
});
|
||||
|
||||
const chipCount = this.adapter.getChipCount();
|
||||
// Early exit if we have an empty chip set
|
||||
if (chipCount <= 0) return;
|
||||
this.focusNearestFocusableAction(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first focusable action by moving bidirectionally horizontally
|
||||
* from the start index.
|
||||
*
|
||||
* Given chip set [A, B, C, D, E, F, G]...
|
||||
* Let's say we remove chip "F". We don't know where the nearest focusable
|
||||
* action is since any of them could be disabled. The nearest focusable
|
||||
* action could be E, it could be G, it could even be A. To find it, we
|
||||
* start from the source index (5 for "F" in this case) and move out
|
||||
* horizontally, checking each chip at each index.
|
||||
*
|
||||
*/
|
||||
private focusNearestFocusableAction(index: number) {
|
||||
const chipCount = this.adapter.getChipCount();
|
||||
let decrIndex = index;
|
||||
let incrIndex = index;
|
||||
while (decrIndex > -1 || incrIndex < chipCount) {
|
||||
const focusAction = this.getNearestFocusableAction(
|
||||
decrIndex, incrIndex, MDCChipActionType.TRAILING);
|
||||
if (focusAction) {
|
||||
this.focusChip(
|
||||
focusAction.index, focusAction.action,
|
||||
MDCChipActionFocusBehavior.FOCUSABLE_AND_FOCUSED);
|
||||
return;
|
||||
}
|
||||
|
||||
decrIndex--;
|
||||
incrIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private getNearestFocusableAction(
|
||||
decrIndex: number, incrIndex: number,
|
||||
actionType?: MDCChipActionType): FocusAction|null {
|
||||
const decrAction =
|
||||
this.getFocusableAction(decrIndex, Operator.DECREMENT, actionType);
|
||||
if (decrAction) {
|
||||
return {
|
||||
index: decrIndex,
|
||||
action: decrAction,
|
||||
};
|
||||
}
|
||||
|
||||
// Early exit if the incremented and decremented indices are identical
|
||||
if (incrIndex === decrIndex) return null;
|
||||
|
||||
const incrAction =
|
||||
this.getFocusableAction(incrIndex, Operator.INCREMENT, actionType);
|
||||
if (incrAction) {
|
||||
return {
|
||||
index: incrIndex,
|
||||
action: incrAction,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
48
chips/chipset/lib/types.ts
Normal file
48
chips/chipset/lib/types.ts
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {MDCChipAnimationEventDetail, MDCChipInteractionEventDetail, MDCChipNavigationEventDetail} from '../../chip/lib/types';
|
||||
|
||||
/**
|
||||
* MDCChipSetInteractionEventDetail provides detail about the interaction event.
|
||||
*/
|
||||
export interface MDCChipSetInteractionEventDetail {
|
||||
chipID: string;
|
||||
chipIndex: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* MDCChipSetRemovalEventDetail provides detail about the removal event.
|
||||
*/
|
||||
export interface MDCChipSetRemovalEventDetail {
|
||||
chipID: string;
|
||||
chipIndex: number;
|
||||
isComplete: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* MDCChipSetSelectionEventDetail provides detail about the selection event.
|
||||
*/
|
||||
export interface MDCChipSetSelectionEventDetail {
|
||||
chipID: string;
|
||||
chipIndex: number;
|
||||
isSelected: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* ChipInteractionEvent is the custom event for the interaction event.
|
||||
*/
|
||||
export type ChipInteractionEvent = CustomEvent<MDCChipInteractionEventDetail>;
|
||||
|
||||
/**
|
||||
* ChipNavigationEvent is the custom event for the navigation event.
|
||||
*/
|
||||
export type ChipNavigationEvent = CustomEvent<MDCChipNavigationEventDetail>;
|
||||
|
||||
/**
|
||||
* ChipAnimationEvent is the custom event for the animation event.
|
||||
*/
|
||||
export type ChipAnimationEvent = CustomEvent<MDCChipAnimationEventDetail>;
|
Loading…
Reference in New Issue
Block a user