Skip to content

Commit 92883af

Browse files
asynclizcopybara-github
authored andcommitted
chore(labs): add helper factories for component directives
PiperOrigin-RevId: 900872331
1 parent ec8c7d9 commit 92883af

9 files changed

Lines changed: 361 additions & 257 deletions

File tree

labs/gb/components/button/button.ts

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,9 @@ import {
1313
rippleClasses,
1414
setupRipple,
1515
} from '@material/web/labs/gb/components/ripple/ripple.js';
16+
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
1617
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
17-
import {
18-
AsyncDirective,
19-
AttributePart,
20-
directive,
21-
DirectiveParameters,
22-
} from 'lit/async-directive.js';
23-
import {classMap, type ClassInfo} from 'lit/directives/class-map.js';
18+
import {type ClassInfo} from 'lit/directives/class-map.js';
2419

2520
/** Button color configuration types. */
2621
export type ButtonColor = 'filled' | 'elevated' | 'tonal' | 'outlined' | 'text';
@@ -168,48 +163,6 @@ export function setupButton(
168163
);
169164
}
170165

171-
/** The state provided to the `button()` directive. */
172-
export interface ButtonDirectiveState extends ButtonClassesState {
173-
/** Additional classes to apply to the element. */
174-
classes?: ClassInfo;
175-
}
176-
177-
class ButtonDirective extends AsyncDirective {
178-
private element?: HTMLElement;
179-
private cleanup?: AbortController;
180-
181-
render(state: ButtonDirectiveState = {}) {
182-
return classMap({
183-
...(state.classes || {}),
184-
...buttonClasses(state),
185-
});
186-
}
187-
188-
override update(
189-
{element}: AttributePart,
190-
[state]: DirectiveParameters<this>,
191-
) {
192-
if (this.isConnected && element !== this.element) {
193-
this.element = element as HTMLElement;
194-
this.disconnected();
195-
this.reconnected();
196-
}
197-
198-
return this.render(state);
199-
}
200-
201-
protected override disconnected() {
202-
this.cleanup?.abort();
203-
}
204-
205-
protected override reconnected() {
206-
if (this.element) {
207-
this.cleanup = new AbortController();
208-
setupButton(this.element, {signal: this.cleanup.signal});
209-
}
210-
}
211-
}
212-
213166
/**
214167
* A Lit directive that adds button styling and functionality to its element.
215168
*
@@ -218,4 +171,7 @@ class ButtonDirective extends AsyncDirective {
218171
* html`<button class="${button({color: 'filled'})}">Filled</button>`;
219172
* ```
220173
*/
221-
export const button = directive(ButtonDirective);
174+
export const button = createClassMapDirective({
175+
getClasses: buttonClasses,
176+
setupElement: setupButton,
177+
});

labs/gb/components/card/card.ts

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
*/
66

77
import {FOCUS_RING_CLASSES} from '@material/web/labs/gb/components/focus/focus-ring.js';
8+
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
89
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
9-
import {Directive, directive} from 'lit/directive.js';
10-
import {classMap, type ClassInfo} from 'lit/directives/class-map.js';
10+
import {type ClassInfo} from 'lit/directives/class-map.js';
1111

1212
/** Card color configuration types. */
1313
export type CardColor = 'elevated' | 'filled' | 'outlined';
@@ -69,21 +69,6 @@ export function cardClasses({
6969
};
7070
}
7171

72-
/** The state provided to the `card()` directive. */
73-
export interface CardDirectiveState extends CardClassesState {
74-
/** Additional classes to apply to the element. */
75-
classes?: ClassInfo;
76-
}
77-
78-
class CardDirective extends Directive {
79-
render(state: CardDirectiveState = {}) {
80-
return classMap({
81-
...(state.classes || {}),
82-
...cardClasses(state),
83-
});
84-
}
85-
}
86-
8772
/**
8873
* A Lit directive that adds card styling and functionality to its element.
8974
*
@@ -96,4 +81,6 @@ class CardDirective extends Directive {
9681
* `
9782
* ```
9883
*/
99-
export const card = directive(CardDirective);
84+
export const card = createClassMapDirective({
85+
getClasses: cardClasses,
86+
});

labs/gb/components/checkbox/checkbox.ts

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ import {
99
rippleClasses,
1010
setupRipple,
1111
} from '@material/web/labs/gb/components/ripple/ripple.js';
12+
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
1213
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
13-
import {
14-
AsyncDirective,
15-
AttributePart,
16-
directive,
17-
DirectiveParameters,
18-
} from 'lit/async-directive.js';
19-
import {classMap, type ClassInfo} from 'lit/directives/class-map.js';
14+
import {type ClassInfo} from 'lit/directives/class-map.js';
2015

2116
/** Checkbox classes. */
2217
export const CHECKBOX_CLASSES = {
@@ -90,48 +85,6 @@ export function setupCheckbox(
9085
setupRipple(checkbox, opts);
9186
}
9287

93-
/** The state provided to the `checkbox()` directive. */
94-
export interface CheckboxDirectiveState extends CheckboxClassesState {
95-
/** Additional classes to apply to the element. */
96-
classes?: ClassInfo;
97-
}
98-
99-
class CheckboxDirective extends AsyncDirective {
100-
private element?: HTMLElement;
101-
private cleanup?: AbortController;
102-
103-
render(state: CheckboxDirectiveState = {}) {
104-
return classMap({
105-
...(state.classes || {}),
106-
...checkboxClasses(state),
107-
});
108-
}
109-
110-
override update(
111-
{element}: AttributePart,
112-
[state]: DirectiveParameters<this>,
113-
) {
114-
if (this.isConnected && element !== this.element) {
115-
this.element = element as HTMLElement;
116-
this.disconnected();
117-
this.reconnected();
118-
}
119-
120-
return this.render(state);
121-
}
122-
123-
protected override disconnected() {
124-
this.cleanup?.abort();
125-
}
126-
127-
protected override reconnected() {
128-
if (this.element) {
129-
this.cleanup = new AbortController();
130-
setupCheckbox(this.element, {signal: this.cleanup.signal});
131-
}
132-
}
133-
}
134-
13588
/**
13689
* A Lit directive that adds checkbox styling and functionality to its element.
13790
*
@@ -140,4 +93,7 @@ class CheckboxDirective extends AsyncDirective {
14093
* html`<input type="checkbox" class="${checkbox()}">`;
14194
* ```
14295
*/
143-
export const checkbox = directive(CheckboxDirective);
96+
export const checkbox = createClassMapDirective({
97+
getClasses: checkboxClasses,
98+
setupElement: setupCheckbox,
99+
});

labs/gb/components/divider/divider.ts

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import {Directive, directive} from 'lit/directive.js';
8-
import {classMap, type ClassInfo} from 'lit/directives/class-map.js';
7+
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
8+
import {type ClassInfo} from 'lit/directives/class-map.js';
99

1010
/** Divider classes. */
1111
export const DIVIDER_CLASSES = {
@@ -34,21 +34,6 @@ export function dividerClasses({
3434
};
3535
}
3636

37-
/** The state provided to the `divider()` directive. */
38-
export interface DividerDirectiveState extends DividerClassesState {
39-
/** Additional classes to apply to the element. */
40-
classes?: ClassInfo;
41-
}
42-
43-
class DividerDirective extends Directive {
44-
render(state: DividerDirectiveState = {}) {
45-
return classMap({
46-
...(state.classes || {}),
47-
...dividerClasses(state),
48-
});
49-
}
50-
}
51-
5237
/**
5338
* A Lit directive that adds divider styling to its element.
5439
*
@@ -69,4 +54,6 @@ class DividerDirective extends Directive {
6954
* `;
7055
* ```
7156
*/
72-
export const divider = directive(DividerDirective);
57+
export const divider = createClassMapDirective({
58+
getClasses: dividerClasses,
59+
});

labs/gb/components/fab/fab.ts

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ import {
99
rippleClasses,
1010
setupRipple,
1111
} from '@material/web/labs/gb/components/ripple/ripple.js';
12+
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
1213
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
13-
import {
14-
AsyncDirective,
15-
AttributePart,
16-
directive,
17-
DirectiveParameters,
18-
} from 'lit/async-directive.js';
19-
import {classMap, type ClassInfo} from 'lit/directives/class-map.js';
14+
import {type ClassInfo} from 'lit/directives/class-map.js';
2015

2116
/** Fab color configuration types. */
2217
export type FabColor =
@@ -118,48 +113,6 @@ export function setupFab(
118113
setupRipple(fab, opts);
119114
}
120115

121-
/** The state provided to the `fab()` directive. */
122-
export interface FabDirectiveState extends FabClassesState {
123-
/** Additional classes to apply to the element. */
124-
classes?: ClassInfo;
125-
}
126-
127-
class FabDirective extends AsyncDirective {
128-
private element?: HTMLElement;
129-
private cleanup?: AbortController;
130-
131-
render(state: FabDirectiveState = {}) {
132-
return classMap({
133-
...(state.classes || {}),
134-
...fabClasses(state),
135-
});
136-
}
137-
138-
override update(
139-
{element}: AttributePart,
140-
[state]: DirectiveParameters<this>,
141-
) {
142-
if (this.isConnected && element !== this.element) {
143-
this.element = element as HTMLElement;
144-
this.disconnected();
145-
this.reconnected();
146-
}
147-
148-
return this.render(state);
149-
}
150-
151-
protected override disconnected() {
152-
this.cleanup?.abort();
153-
}
154-
155-
protected override reconnected() {
156-
if (this.element) {
157-
this.cleanup = new AbortController();
158-
setupFab(this.element, {signal: this.cleanup.signal});
159-
}
160-
}
161-
}
162-
163116
/**
164117
* A Lit directive that adds fab styling and functionality to its element.
165118
*
@@ -177,4 +130,7 @@ class FabDirective extends AsyncDirective {
177130
* `;
178131
* ```
179132
*/
180-
export const fab = directive(FabDirective);
133+
export const fab = createClassMapDirective({
134+
getClasses: fabClasses,
135+
setupElement: setupFab,
136+
});

labs/gb/components/radio/radio.ts

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ import {
99
rippleClasses,
1010
setupRipple,
1111
} from '@material/web/labs/gb/components/ripple/ripple.js';
12+
import {createClassMapDirective} from '@material/web/labs/gb/components/shared/directives.js';
1213
import {PSEUDO_CLASSES} from '@material/web/labs/gb/components/shared/pseudo-classes.js';
13-
import {
14-
AttributePart,
15-
Directive,
16-
directive,
17-
DirectiveParameters,
18-
} from 'lit/async-directive.js';
19-
import {classMap, type ClassInfo} from 'lit/directives/class-map.js';
14+
import {type ClassInfo} from 'lit/directives/class-map.js';
2015

2116
/** Radio classes. */
2217
export const RADIO_CLASSES = {
@@ -80,38 +75,6 @@ export function setupRadio(
8075
setupRipple(radio, opts);
8176
}
8277

83-
/** The state provided to the `radio()` directive. */
84-
export interface RadioDirectiveState extends RadioClassesState {
85-
/** Additional classes to apply to the element. */
86-
classes?: ClassInfo;
87-
}
88-
89-
class RadioDirective extends Directive {
90-
private element?: HTMLElement;
91-
private cleanup?: AbortController;
92-
93-
render(state: RadioDirectiveState = {}) {
94-
return classMap({
95-
...(state.classes || {}),
96-
...radioClasses(state),
97-
});
98-
}
99-
100-
override update(
101-
{element}: AttributePart,
102-
[state]: DirectiveParameters<this>,
103-
) {
104-
if (element !== this.element) {
105-
this.element = element as HTMLElement;
106-
this.cleanup?.abort();
107-
this.cleanup = new AbortController();
108-
setupRadio(this.element, {signal: this.cleanup.signal});
109-
}
110-
111-
return this.render(state);
112-
}
113-
}
114-
11578
/**
11679
* A Lit directive that adds radio styling and functionality to its element.
11780
*
@@ -124,4 +87,7 @@ class RadioDirective extends Directive {
12487
* `;
12588
* ```
12689
*/
127-
export const radio = directive(RadioDirective);
90+
export const radio = createClassMapDirective({
91+
getClasses: radioClasses,
92+
setupElement: setupRadio,
93+
});

0 commit comments

Comments
 (0)