85 lines
No EOL
2 KiB
JavaScript
85 lines
No EOL
2 KiB
JavaScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import useLazyRef from '@mui/utils/useLazyRef';
|
|
/**
|
|
* Lazy initialization container for the Ripple instance. This improves
|
|
* performance by delaying mounting the ripple until it's needed.
|
|
*/
|
|
export class LazyRipple {
|
|
/** React ref to the ripple instance */
|
|
|
|
/** If the ripple component should be mounted */
|
|
|
|
/** Promise that resolves when the ripple component is mounted */
|
|
|
|
/** If the ripple component has been mounted */
|
|
|
|
/** React state hook setter */
|
|
|
|
static create() {
|
|
return new LazyRipple();
|
|
}
|
|
static use() {
|
|
/* eslint-disable */
|
|
const ripple = useLazyRef(LazyRipple.create).current;
|
|
const [shouldMount, setShouldMount] = React.useState(false);
|
|
ripple.shouldMount = shouldMount;
|
|
ripple.setShouldMount = setShouldMount;
|
|
React.useEffect(ripple.mountEffect, [shouldMount]);
|
|
/* eslint-enable */
|
|
|
|
return ripple;
|
|
}
|
|
constructor() {
|
|
this.ref = {
|
|
current: null
|
|
};
|
|
this.mounted = null;
|
|
this.didMount = false;
|
|
this.shouldMount = false;
|
|
this.setShouldMount = null;
|
|
}
|
|
mount() {
|
|
if (!this.mounted) {
|
|
this.mounted = createControlledPromise();
|
|
this.shouldMount = true;
|
|
this.setShouldMount(this.shouldMount);
|
|
}
|
|
return this.mounted;
|
|
}
|
|
mountEffect = () => {
|
|
if (this.shouldMount && !this.didMount) {
|
|
if (this.ref.current !== null) {
|
|
this.didMount = true;
|
|
this.mounted.resolve();
|
|
}
|
|
}
|
|
};
|
|
|
|
/* Ripple API */
|
|
|
|
start(...args) {
|
|
this.mount().then(() => this.ref.current?.start(...args));
|
|
}
|
|
stop(...args) {
|
|
this.mount().then(() => this.ref.current?.stop(...args));
|
|
}
|
|
pulsate(...args) {
|
|
this.mount().then(() => this.ref.current?.pulsate(...args));
|
|
}
|
|
}
|
|
export default function useLazyRipple() {
|
|
return LazyRipple.use();
|
|
}
|
|
function createControlledPromise() {
|
|
let resolve;
|
|
let reject;
|
|
const p = new Promise((resolveFn, rejectFn) => {
|
|
resolve = resolveFn;
|
|
reject = rejectFn;
|
|
});
|
|
p.resolve = resolve;
|
|
p.reject = reject;
|
|
return p;
|
|
} |