0
# Foundation API
1
2
The MDCRippleFoundation handles the core ripple logic, including activation/deactivation animations, event coordination, and CSS variable management. It follows the Material Components architecture pattern of separating business logic from DOM interactions.
3
4
## Capabilities
5
6
### MDCRippleFoundation Class
7
8
Core ripple logic and state management foundation.
9
10
```typescript { .api }
11
/**
12
* Core ripple logic and state management
13
* Handles activation/deactivation animations, event coordination, and CSS variable updates
14
*/
15
class MDCRippleFoundation extends MDCFoundation<MDCRippleAdapter> {
16
/** CSS class constants used by the foundation */
17
static readonly cssClasses: {
18
BG_FOCUSED: 'mdc-ripple-upgraded--background-focused';
19
FG_ACTIVATION: 'mdc-ripple-upgraded--foreground-activation';
20
FG_DEACTIVATION: 'mdc-ripple-upgraded--foreground-deactivation';
21
ROOT: 'mdc-ripple-upgraded';
22
UNBOUNDED: 'mdc-ripple-upgraded--unbounded';
23
};
24
25
/** CSS custom property name constants */
26
static readonly strings: {
27
VAR_FG_SCALE: '--mdc-ripple-fg-scale';
28
VAR_FG_SIZE: '--mdc-ripple-fg-size';
29
VAR_FG_TRANSLATE_END: '--mdc-ripple-fg-translate-end';
30
VAR_FG_TRANSLATE_START: '--mdc-ripple-fg-translate-start';
31
VAR_LEFT: '--mdc-ripple-left';
32
VAR_TOP: '--mdc-ripple-top';
33
};
34
35
/** Timing and dimension constants */
36
static readonly numbers: {
37
DEACTIVATION_TIMEOUT_MS: 225;
38
FG_DEACTIVATION_MS: 150;
39
INITIAL_ORIGIN_SCALE: 0.6;
40
PADDING: 10;
41
TAP_DELAY_MS: 300;
42
};
43
44
/** Default adapter implementation for testing */
45
static readonly defaultAdapter: MDCRippleAdapter;
46
47
/** Trigger ripple activation with optional event context */
48
activate(evt?: Event): void;
49
50
/** Trigger ripple deactivation */
51
deactivate(): void;
52
53
/** Recompute layout properties and CSS variables */
54
layout(): void;
55
56
/** Set whether ripple is bounded or unbounded */
57
setUnbounded(unbounded: boolean): void;
58
59
/** Handle focus events by adding focus state styles */
60
handleFocus(): void;
61
62
/** Handle blur events by removing focus state styles */
63
handleBlur(): void;
64
}
65
```
66
67
**Usage Examples:**
68
69
```typescript
70
import { MDCRippleFoundation, MDCRippleAdapter } from "@material/ripple";
71
72
// Create custom adapter
73
const adapter: MDCRippleAdapter = {
74
addClass: (className) => element.classList.add(className),
75
removeClass: (className) => element.classList.remove(className),
76
browserSupportsCssVars: () => CSS.supports('--css-vars', 'yes'),
77
// ... implement all required methods
78
};
79
80
// Create foundation with custom adapter
81
const foundation = new MDCRippleFoundation(adapter);
82
83
// Initialize ripple system
84
foundation.init();
85
86
// Programmatic control
87
foundation.activate(); // Trigger activation animation
88
foundation.deactivate(); // Trigger deactivation animation
89
foundation.layout(); // Recompute dimensions
90
91
// Configuration
92
foundation.setUnbounded(true); // Make ripple unbounded
93
94
// Event handling
95
foundation.handleFocus(); // Add focus styles
96
foundation.handleBlur(); // Remove focus styles
97
98
// Cleanup
99
foundation.destroy();
100
```
101
102
### Static Properties
103
104
#### cssClasses
105
106
CSS class constants used throughout the ripple system.
107
108
```typescript { .api }
109
/**
110
* CSS class constants used by the foundation
111
*/
112
static readonly cssClasses: {
113
/** Background focus state class */
114
BG_FOCUSED: 'mdc-ripple-upgraded--background-focused';
115
/** Foreground activation animation class */
116
FG_ACTIVATION: 'mdc-ripple-upgraded--foreground-activation';
117
/** Foreground deactivation animation class */
118
FG_DEACTIVATION: 'mdc-ripple-upgraded--foreground-deactivation';
119
/** Root ripple upgrade class */
120
ROOT: 'mdc-ripple-upgraded';
121
/** Unbounded ripple class */
122
UNBOUNDED: 'mdc-ripple-upgraded--unbounded';
123
};
124
```
125
126
#### strings
127
128
CSS custom property name constants.
129
130
```typescript { .api }
131
/**
132
* CSS custom property name constants
133
*/
134
static readonly strings: {
135
/** Foreground scale CSS variable */
136
VAR_FG_SCALE: '--mdc-ripple-fg-scale';
137
/** Foreground size CSS variable */
138
VAR_FG_SIZE: '--mdc-ripple-fg-size';
139
/** Translation end position CSS variable */
140
VAR_FG_TRANSLATE_END: '--mdc-ripple-fg-translate-end';
141
/** Translation start position CSS variable */
142
VAR_FG_TRANSLATE_START: '--mdc-ripple-fg-translate-start';
143
/** Left position CSS variable */
144
VAR_LEFT: '--mdc-ripple-left';
145
/** Top position CSS variable */
146
VAR_TOP: '--mdc-ripple-top';
147
};
148
```
149
150
#### numbers
151
152
Timing and dimension constants used for animations.
153
154
```typescript { .api }
155
/**
156
* Timing and dimension constants
157
*/
158
static readonly numbers: {
159
/** Activation animation duration in milliseconds */
160
DEACTIVATION_TIMEOUT_MS: 225;
161
/** Deactivation animation duration in milliseconds */
162
FG_DEACTIVATION_MS: 150;
163
/** Initial ripple scale factor */
164
INITIAL_ORIGIN_SCALE: 0.6;
165
/** Bounded ripple padding in pixels */
166
PADDING: 10;
167
/** Touch to mouse event delay in milliseconds */
168
TAP_DELAY_MS: 300;
169
};
170
```
171
172
#### defaultAdapter
173
174
Default adapter implementation for testing and reference.
175
176
```typescript { .api }
177
/**
178
* Default adapter implementation for testing
179
* All methods return safe default values
180
*/
181
static readonly defaultAdapter: MDCRippleAdapter;
182
```
183
184
### Instance Methods
185
186
#### activate
187
188
Triggers ripple activation animation, optionally using event coordinates.
189
190
```typescript { .api }
191
/**
192
* Trigger ripple activation with optional event context
193
* @param evt - Optional event containing position information for ripple origin
194
*/
195
activate(evt?: Event): void;
196
```
197
198
#### deactivate
199
200
Triggers ripple deactivation animation.
201
202
```typescript { .api }
203
/**
204
* Trigger ripple deactivation
205
* Completes the ripple animation cycle
206
*/
207
deactivate(): void;
208
```
209
210
#### layout
211
212
Recomputes all layout properties and updates CSS variables.
213
214
```typescript { .api }
215
/**
216
* Recompute layout properties and CSS variables
217
* Call this when element dimensions change
218
*/
219
layout(): void;
220
```
221
222
#### setUnbounded
223
224
Configures whether the ripple is bounded by element dimensions.
225
226
```typescript { .api }
227
/**
228
* Set whether ripple is bounded or unbounded
229
* @param unbounded - True for unbounded ripples (extend beyond element)
230
*/
231
setUnbounded(unbounded: boolean): void;
232
```
233
234
#### handleFocus
235
236
Handles focus events by applying focus state styling.
237
238
```typescript { .api }
239
/**
240
* Handle focus events by adding focus state styles
241
* Adds background focus highlighting
242
*/
243
handleFocus(): void;
244
```
245
246
#### handleBlur
247
248
Handles blur events by removing focus state styling.
249
250
```typescript { .api }
251
/**
252
* Handle blur events by removing focus state styles
253
* Removes background focus highlighting
254
*/
255
handleBlur(): void;
256
```
257
258
## Advanced Usage
259
260
### Custom Foundation with Mixed Adapter
261
262
```typescript
263
import { MDCRippleFoundation, MDCRipple } from "@material/ripple";
264
265
class CustomRippleComponent {
266
constructor(element) {
267
this.root = element;
268
this.unbounded = false;
269
this.disabled = false;
270
this.isPressed = false;
271
272
// Create foundation with custom behavior
273
const foundation = new MDCRippleFoundation({
274
...MDCRipple.createAdapter(this),
275
// Override for custom active state detection
276
isSurfaceActive: () => this.isPressed,
277
// Custom CSS variable updates
278
updateCssVariable: (varName, value) => {
279
this.root.style.setProperty(varName, value);
280
console.log(`Updated ${varName} to ${value}`);
281
}
282
});
283
284
this.foundation = foundation;
285
this.foundation.init();
286
}
287
288
// Custom press handling
289
onPress() {
290
this.isPressed = true;
291
this.foundation.activate();
292
}
293
294
onRelease() {
295
this.isPressed = false;
296
this.foundation.deactivate();
297
}
298
}
299
```
300
301
### Event-Driven Activation
302
303
```typescript
304
import { MDCRippleFoundation } from "@material/ripple";
305
306
// Foundation automatically handles standard activation events:
307
// - touchstart, pointerdown, mousedown, keydown
308
// - touchend, pointerup, mouseup, contextmenu, keyup
309
310
const foundation = new MDCRippleFoundation(adapter);
311
foundation.init(); // Registers event handlers automatically
312
313
// The foundation will:
314
// 1. Listen for activation events (touchstart, mousedown, etc.)
315
// 2. Calculate ripple origin from event coordinates
316
// 3. Trigger activation animation
317
// 4. Listen for deactivation events (touchend, mouseup, etc.)
318
// 5. Trigger deactivation animation
319
```
320
321
### CSS Variable Management
322
323
```typescript
324
import { MDCRippleFoundation } from "@material/ripple";
325
326
// The foundation manages these CSS variables automatically:
327
const { strings } = MDCRippleFoundation;
328
329
// Size and positioning
330
console.log(strings.VAR_FG_SIZE); // '--mdc-ripple-fg-size'
331
console.log(strings.VAR_LEFT); // '--mdc-ripple-left'
332
console.log(strings.VAR_TOP); // '--mdc-ripple-top'
333
334
// Animation properties
335
console.log(strings.VAR_FG_SCALE); // '--mdc-ripple-fg-scale'
336
console.log(strings.VAR_FG_TRANSLATE_START); // '--mdc-ripple-fg-translate-start'
337
console.log(strings.VAR_FG_TRANSLATE_END); // '--mdc-ripple-fg-translate-end'
338
339
// Variables are updated automatically during:
340
// - layout() calls
341
// - activate() calls
342
// - Animation state changes
343
```
344
345
### State Management
346
347
```typescript
348
// The foundation tracks several internal states:
349
// - isActivated: Whether ripple is currently active
350
// - wasActivatedByPointer: Whether activation came from touch/mouse
351
// - isProgrammatic: Whether activation was called programmatically
352
// - hasDeactivationUXRun: Whether deactivation animation has started
353
354
// These states ensure:
355
// - Proper animation sequencing
356
// - Avoiding duplicate activations
357
// - Coordinating with nested interactive elements
358
// - Managing focus and keyboard interactions
359
```