first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
/**
* Bugs often appear in async code when stuff gets disposed, but async operations don't get canceled.
* This Async helper class solves these issues by tying async code to the lifetime of a disposable object.
*
* Usage: Anything class extending from BaseModel can access this helper via this.async. Otherwise create a
* new instance of the class and remember to call dispose() during your code's dispose handler.
*
* @public
*/
export declare class Async {
private _timeoutIds;
private _immediateIds;
private _intervalIds;
private _animationFrameIds;
private _isDisposed;
private _parent;
private _onErrorHandler;
private _noop;
constructor(parent?: object, onError?: (e: any) => void);
/**
* Dispose function, clears all async operations.
*/
dispose(): void;
/**
* SetTimeout override, which will auto cancel the timeout during dispose.
* @param callback - Callback to execute.
* @param duration - Duration in milliseconds.
* @returns The setTimeout id.
*/
setTimeout(callback: () => void, duration: number): number;
/**
* Clears the timeout.
* @param id - Id to cancel.
*/
clearTimeout(id: number): void;
/**
* SetImmediate override, which will auto cancel the immediate during dispose.
* @param callback - Callback to execute.
* @param targetElement - Optional target element to use for identifying the correct window.
* @returns The setTimeout id.
*/
setImmediate(callback: () => void, targetElement?: Element | null): number;
/**
* Clears the immediate.
* @param id - Id to cancel.
* @param targetElement - Optional target element to use for identifying the correct window.
*/
clearImmediate(id: number, targetElement?: Element | null): void;
/**
* SetInterval override, which will auto cancel the timeout during dispose.
* @param callback - Callback to execute.
* @param duration - Duration in milliseconds.
* @returns The setTimeout id.
*/
setInterval(callback: () => void, duration: number): number;
/**
* Clears the interval.
* @param id - Id to cancel.
*/
clearInterval(id: number): void;
/**
* Creates a function that, when executed, will only call the func function at most once per
* every wait milliseconds. Provide an options object to indicate that func should be invoked
* on the leading and/or trailing edge of the wait timeout. Subsequent calls to the throttled
* function will return the result of the last func call.
*
* Note: If leading and trailing options are true func will be called on the trailing edge of
* the timeout only if the throttled function is invoked more than once during the wait timeout.
*
* @param func - The function to throttle.
* @param wait - The number of milliseconds to throttle executions to. Defaults to 0.
* @param options - The options object.
* @returns The new throttled function.
*/
throttle<T extends (...args: any[]) => any>(func: T, wait?: number, options?: {
leading?: boolean;
trailing?: boolean;
}): T;
/**
* Creates a function that will delay the execution of func until after wait milliseconds have
* elapsed since the last time it was invoked. Provide an options object to indicate that func
* should be invoked on the leading and/or trailing edge of the wait timeout. Subsequent calls
* to the debounced function will return the result of the last func call.
*
* Note: If leading and trailing options are true func will be called on the trailing edge of
* the timeout only if the debounced function is invoked more than once during the wait
* timeout.
*
* @param func - The function to debounce.
* @param wait - The number of milliseconds to delay.
* @param options - The options object.
* @returns The new debounced function.
*/
debounce<T extends (...args: any[]) => any>(func: T, wait?: number, options?: {
leading?: boolean;
maxWait?: number;
trailing?: boolean;
}): ICancelable<T> & T;
requestAnimationFrame(callback: () => void, targetElement?: Element | null): number;
cancelAnimationFrame(id: number, targetElement?: Element | null): void;
protected _logError(e: any): void;
}
export type ICancelable<T extends (...args: any[]) => any> = {
flush: () => ReturnType<T>;
cancel: () => void;
pending: () => boolean;
};
+415
View File
@@ -0,0 +1,415 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Async = void 0;
var getWindow_1 = require("./dom/getWindow");
/**
* Bugs often appear in async code when stuff gets disposed, but async operations don't get canceled.
* This Async helper class solves these issues by tying async code to the lifetime of a disposable object.
*
* Usage: Anything class extending from BaseModel can access this helper via this.async. Otherwise create a
* new instance of the class and remember to call dispose() during your code's dispose handler.
*
* @public
*/
var Async = /** @class */ (function () {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function Async(parent, onError) {
this._timeoutIds = null;
this._immediateIds = null;
this._intervalIds = null;
this._animationFrameIds = null;
this._isDisposed = false;
this._parent = parent || null;
this._onErrorHandler = onError;
this._noop = function () {
/* do nothing */
};
}
/**
* Dispose function, clears all async operations.
*/
Async.prototype.dispose = function () {
var id;
this._isDisposed = true;
this._parent = null;
// Clear timeouts.
if (this._timeoutIds) {
for (id in this._timeoutIds) {
if (this._timeoutIds.hasOwnProperty(id)) {
this.clearTimeout(parseInt(id, 10));
}
}
this._timeoutIds = null;
}
// Clear immediates.
if (this._immediateIds) {
for (id in this._immediateIds) {
if (this._immediateIds.hasOwnProperty(id)) {
this.clearImmediate(parseInt(id, 10));
}
}
this._immediateIds = null;
}
// Clear intervals.
if (this._intervalIds) {
for (id in this._intervalIds) {
if (this._intervalIds.hasOwnProperty(id)) {
this.clearInterval(parseInt(id, 10));
}
}
this._intervalIds = null;
}
// Clear animation frames.
if (this._animationFrameIds) {
for (id in this._animationFrameIds) {
if (this._animationFrameIds.hasOwnProperty(id)) {
this.cancelAnimationFrame(parseInt(id, 10));
}
}
this._animationFrameIds = null;
}
};
/**
* SetTimeout override, which will auto cancel the timeout during dispose.
* @param callback - Callback to execute.
* @param duration - Duration in milliseconds.
* @returns The setTimeout id.
*/
Async.prototype.setTimeout = function (callback, duration) {
var _this = this;
var timeoutId = 0;
if (!this._isDisposed) {
if (!this._timeoutIds) {
this._timeoutIds = {};
}
timeoutId = setTimeout(function () {
// Time to execute the timeout, enqueue it as a foreground task to be executed.
try {
// Now delete the record and call the callback.
if (_this._timeoutIds) {
delete _this._timeoutIds[timeoutId];
}
callback.apply(_this._parent);
}
catch (e) {
_this._logError(e);
}
}, duration);
this._timeoutIds[timeoutId] = true;
}
return timeoutId;
};
/**
* Clears the timeout.
* @param id - Id to cancel.
*/
Async.prototype.clearTimeout = function (id) {
if (this._timeoutIds && this._timeoutIds[id]) {
clearTimeout(id);
delete this._timeoutIds[id];
}
};
/**
* SetImmediate override, which will auto cancel the immediate during dispose.
* @param callback - Callback to execute.
* @param targetElement - Optional target element to use for identifying the correct window.
* @returns The setTimeout id.
*/
Async.prototype.setImmediate = function (callback, targetElement) {
var _this = this;
var immediateId = 0;
var win = (0, getWindow_1.getWindow)(targetElement);
if (!this._isDisposed) {
if (!this._immediateIds) {
this._immediateIds = {};
}
var setImmediateCallback = function () {
// Time to execute the timeout, enqueue it as a foreground task to be executed.
try {
// Now delete the record and call the callback.
if (_this._immediateIds) {
delete _this._immediateIds[immediateId];
}
callback.apply(_this._parent);
}
catch (e) {
_this._logError(e);
}
};
immediateId = win.setTimeout(setImmediateCallback, 0);
this._immediateIds[immediateId] = true;
}
return immediateId;
};
/**
* Clears the immediate.
* @param id - Id to cancel.
* @param targetElement - Optional target element to use for identifying the correct window.
*/
Async.prototype.clearImmediate = function (id, targetElement) {
var win = (0, getWindow_1.getWindow)(targetElement);
if (this._immediateIds && this._immediateIds[id]) {
win.clearTimeout(id);
delete this._immediateIds[id];
}
};
/**
* SetInterval override, which will auto cancel the timeout during dispose.
* @param callback - Callback to execute.
* @param duration - Duration in milliseconds.
* @returns The setTimeout id.
*/
Async.prototype.setInterval = function (callback, duration) {
var _this = this;
var intervalId = 0;
if (!this._isDisposed) {
if (!this._intervalIds) {
this._intervalIds = {};
}
intervalId = setInterval(function () {
// Time to execute the interval callback, enqueue it as a foreground task to be executed.
try {
callback.apply(_this._parent);
}
catch (e) {
_this._logError(e);
}
}, duration);
this._intervalIds[intervalId] = true;
}
return intervalId;
};
/**
* Clears the interval.
* @param id - Id to cancel.
*/
Async.prototype.clearInterval = function (id) {
if (this._intervalIds && this._intervalIds[id]) {
clearInterval(id);
delete this._intervalIds[id];
}
};
/**
* Creates a function that, when executed, will only call the func function at most once per
* every wait milliseconds. Provide an options object to indicate that func should be invoked
* on the leading and/or trailing edge of the wait timeout. Subsequent calls to the throttled
* function will return the result of the last func call.
*
* Note: If leading and trailing options are true func will be called on the trailing edge of
* the timeout only if the throttled function is invoked more than once during the wait timeout.
*
* @param func - The function to throttle.
* @param wait - The number of milliseconds to throttle executions to. Defaults to 0.
* @param options - The options object.
* @returns The new throttled function.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Async.prototype.throttle = function (func, wait, options) {
var _this = this;
if (this._isDisposed) {
return this._noop;
}
var waitMS = wait || 0;
var leading = true;
var trailing = true;
var lastExecuteTime = 0;
var lastResult;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var lastArgs;
var timeoutId = null;
if (options && typeof options.leading === 'boolean') {
leading = options.leading;
}
if (options && typeof options.trailing === 'boolean') {
trailing = options.trailing;
}
var callback = function (userCall) {
var now = Date.now();
var delta = now - lastExecuteTime;
var waitLength = leading ? waitMS - delta : waitMS;
if (delta >= waitMS && (!userCall || leading)) {
lastExecuteTime = now;
if (timeoutId) {
_this.clearTimeout(timeoutId);
timeoutId = null;
}
lastResult = func.apply(_this._parent, lastArgs);
}
else if (timeoutId === null && trailing) {
timeoutId = _this.setTimeout(callback, waitLength);
}
return lastResult;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var resultFunction = (function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
lastArgs = args;
return callback(true);
});
return resultFunction;
};
/**
* Creates a function that will delay the execution of func until after wait milliseconds have
* elapsed since the last time it was invoked. Provide an options object to indicate that func
* should be invoked on the leading and/or trailing edge of the wait timeout. Subsequent calls
* to the debounced function will return the result of the last func call.
*
* Note: If leading and trailing options are true func will be called on the trailing edge of
* the timeout only if the debounced function is invoked more than once during the wait
* timeout.
*
* @param func - The function to debounce.
* @param wait - The number of milliseconds to delay.
* @param options - The options object.
* @returns The new debounced function.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Async.prototype.debounce = function (func, wait, options) {
var _this = this;
if (this._isDisposed) {
var noOpFunction = (function () {
/** Do nothing */
});
noOpFunction.cancel = function () {
return;
};
noOpFunction.flush = (function () { return null; });
noOpFunction.pending = function () { return false; };
return noOpFunction;
}
var waitMS = wait || 0;
var leading = false;
var trailing = true;
var maxWait = null;
var lastCallTime = 0;
var lastExecuteTime = Date.now();
var lastResult;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var lastArgs;
var timeoutId = null;
if (options && typeof options.leading === 'boolean') {
leading = options.leading;
}
if (options && typeof options.trailing === 'boolean') {
trailing = options.trailing;
}
if (options && typeof options.maxWait === 'number' && !isNaN(options.maxWait)) {
maxWait = options.maxWait;
}
var markExecuted = function (time) {
if (timeoutId) {
_this.clearTimeout(timeoutId);
timeoutId = null;
}
lastExecuteTime = time;
};
var invokeFunction = function (time) {
markExecuted(time);
lastResult = func.apply(_this._parent, lastArgs);
};
var callback = function (userCall) {
var now = Date.now();
var executeImmediately = false;
if (userCall) {
if (leading && now - lastCallTime >= waitMS) {
executeImmediately = true;
}
lastCallTime = now;
}
var delta = now - lastCallTime;
var waitLength = waitMS - delta;
var maxWaitDelta = now - lastExecuteTime;
var maxWaitExpired = false;
if (maxWait !== null) {
// maxWait only matters when there is a pending callback
if (maxWaitDelta >= maxWait && timeoutId) {
maxWaitExpired = true;
}
else {
waitLength = Math.min(waitLength, maxWait - maxWaitDelta);
}
}
if (delta >= waitMS || maxWaitExpired || executeImmediately) {
invokeFunction(now);
}
else if ((timeoutId === null || !userCall) && trailing) {
timeoutId = _this.setTimeout(callback, waitLength);
}
return lastResult;
};
var pending = function () {
return !!timeoutId;
};
var cancel = function () {
if (pending()) {
// Mark the debounced function as having executed
markExecuted(Date.now());
}
};
var flush = function () {
if (pending()) {
invokeFunction(Date.now());
}
return lastResult;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var resultFunction = (function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
lastArgs = args;
return callback(true);
});
resultFunction.cancel = cancel;
resultFunction.flush = flush;
resultFunction.pending = pending;
return resultFunction;
};
Async.prototype.requestAnimationFrame = function (callback, targetElement) {
var _this = this;
var animationFrameId = 0;
var win = (0, getWindow_1.getWindow)(targetElement);
if (!this._isDisposed) {
if (!this._animationFrameIds) {
this._animationFrameIds = {};
}
var animationFrameCallback = function () {
try {
// Now delete the record and call the callback.
if (_this._animationFrameIds) {
delete _this._animationFrameIds[animationFrameId];
}
callback.apply(_this._parent);
}
catch (e) {
_this._logError(e);
}
};
animationFrameId = win.requestAnimationFrame
? win.requestAnimationFrame(animationFrameCallback)
: win.setTimeout(animationFrameCallback, 0);
this._animationFrameIds[animationFrameId] = true;
}
return animationFrameId;
};
Async.prototype.cancelAnimationFrame = function (id, targetElement) {
var win = (0, getWindow_1.getWindow)(targetElement);
if (this._animationFrameIds && this._animationFrameIds[id]) {
win.cancelAnimationFrame ? win.cancelAnimationFrame(id) : win.clearTimeout(id);
delete this._animationFrameIds[id];
}
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Async.prototype._logError = function (e) {
if (this._onErrorHandler) {
this._onErrorHandler(e);
}
};
return Async;
}());
exports.Async = Async;
//# sourceMappingURL=Async.js.map
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export {};
+92
View File
@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Async_1 = require("./Async");
describe('Async', function () {
describe('debounce', function () {
// Increase count by a specific number, to test the arguments
// of the debounced function;
var callCount = 0;
var fnMock = function (increaseCount) {
callCount += increaseCount;
return callCount;
};
var fn;
var async;
var debouncedFn;
beforeEach(function () {
jest.useFakeTimers();
fn = jest.fn(fnMock);
async = new Async_1.Async();
debouncedFn = async.debounce(fn, 100);
});
afterEach(function () {
callCount = 0;
fn.mockClear();
});
it('should debounce multiple calls', function () {
// Mock Date.now to return each call
// First one is the first debouncedFn(1)
// Second one is debouncedFn(2)
// A last one will be when the timer fires after we run pending timers in jest.
var dateMock = jest
.spyOn(Date, 'now')
.mockImplementationOnce(function () { return 10; })
.mockImplementationOnce(function () { return 11; })
.mockImplementation(function () { return 2000; });
debouncedFn(1);
expect(debouncedFn.pending()).toBeTruthy();
debouncedFn(2);
expect(debouncedFn.pending()).toBeTruthy();
jest.runOnlyPendingTimers();
expect(fn).toHaveBeenCalledTimes(1);
expect(callCount).toEqual(2);
dateMock.mockRestore();
});
it('should flush the last value', function () {
debouncedFn(10);
debouncedFn(20);
expect(debouncedFn.pending()).toBeTruthy();
expect(debouncedFn.flush()).toEqual(20);
});
it('should be marked pending as expected', function () {
debouncedFn(100);
expect(debouncedFn.pending()).toBeTruthy();
debouncedFn(200);
expect(debouncedFn.pending()).toBeTruthy();
debouncedFn.flush();
expect(debouncedFn.pending()).toBeFalsy();
});
it('should be cancellable', function () {
debouncedFn(1000);
debouncedFn.cancel();
expect(debouncedFn.pending()).toBeFalsy();
expect(debouncedFn.flush()).toBeUndefined();
});
});
describe('throttle', function () {
it('should throttle multiple calls', function () {
jest.useFakeTimers();
// Mock Date.now to return each call
// First one is the first throttledFn(1)
// Second one is throttledFn(2)
// A last one will be when the timer fires after we run pending timers in jest.
var dateMock = jest
.spyOn(Date, 'now')
.mockImplementationOnce(function () { return 10; })
.mockImplementationOnce(function () { return 11; })
.mockImplementation(function () { return 2000; });
var fn = jest.fn(function (num) { return num; });
var async = new Async_1.Async();
var throttledFn = async.throttle(fn, 1000);
var result = throttledFn(1);
expect(result).toBeUndefined();
result = throttledFn(2);
expect(result).toBeUndefined();
jest.runOnlyPendingTimers();
expect(fn).toHaveBeenCalledTimes(1);
dateMock.mockRestore();
jest.useRealTimers();
});
});
});
//# sourceMappingURL=Async.test.js.map
File diff suppressed because one or more lines are too long
+25
View File
@@ -0,0 +1,25 @@
/**
* AutoScroll simply hooks up mouse events given a parent element, and scrolls the container
* up/down depending on how close the mouse is to the top/bottom of the container.
*
* Once you don't want autoscroll any more, just dispose the helper and it will unhook events.
*
* @public
* {@docCategory AutoScroll}
*/
export declare class AutoScroll {
private _events;
private _scrollableParent;
private _scrollRect;
private _scrollVelocity;
private _isVerticalScroll;
private _timeoutId?;
constructor(element: HTMLElement, win?: Window);
dispose(): void;
private _onMouseMove;
private _onTouchMove;
private _computeScrollVelocity;
private _startScroll;
private _incrementScroll;
private _stopScroll;
}
+125
View File
@@ -0,0 +1,125 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AutoScroll = void 0;
var EventGroup_1 = require("./EventGroup");
var scroll_1 = require("./scroll");
var getRect_1 = require("./dom/getRect");
var dom_1 = require("./dom");
var SCROLL_ITERATION_DELAY = 16;
var SCROLL_GUTTER = 100;
var MAX_SCROLL_VELOCITY = 15;
/**
* AutoScroll simply hooks up mouse events given a parent element, and scrolls the container
* up/down depending on how close the mouse is to the top/bottom of the container.
*
* Once you don't want autoscroll any more, just dispose the helper and it will unhook events.
*
* @public
* {@docCategory AutoScroll}
*/
var AutoScroll = /** @class */ (function () {
function AutoScroll(element, win) {
var theWin = win !== null && win !== void 0 ? win : (0, dom_1.getWindow)(element);
this._events = new EventGroup_1.EventGroup(this);
this._scrollableParent = (0, scroll_1.findScrollableParent)(element);
this._incrementScroll = this._incrementScroll.bind(this);
this._scrollRect = (0, getRect_1.getRect)(this._scrollableParent, theWin);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (this._scrollableParent === theWin) {
this._scrollableParent = theWin.document.body;
}
if (this._scrollableParent) {
this._events.on(theWin, 'mousemove', this._onMouseMove, true);
this._events.on(theWin, 'touchmove', this._onTouchMove, true);
}
}
AutoScroll.prototype.dispose = function () {
this._events.dispose();
this._stopScroll();
};
AutoScroll.prototype._onMouseMove = function (ev) {
this._computeScrollVelocity(ev);
};
AutoScroll.prototype._onTouchMove = function (ev) {
if (ev.touches.length > 0) {
this._computeScrollVelocity(ev);
}
};
AutoScroll.prototype._computeScrollVelocity = function (ev) {
if (!this._scrollRect) {
return;
}
var clientX;
var clientY;
if ('clientX' in ev) {
clientX = ev.clientX;
clientY = ev.clientY;
}
else {
clientX = ev.touches[0].clientX;
clientY = ev.touches[0].clientY;
}
var scrollRectTop = this._scrollRect.top;
var scrollRectLeft = this._scrollRect.left;
var scrollClientBottom = scrollRectTop + this._scrollRect.height - SCROLL_GUTTER;
var scrollClientRight = scrollRectLeft + this._scrollRect.width - SCROLL_GUTTER;
// variables to use for alternating scroll direction
var scrollRect;
var clientDirection;
var scrollClient;
// if either of these conditions are met we are scrolling vertically else horizontally
if (clientY < scrollRectTop + SCROLL_GUTTER || clientY > scrollClientBottom) {
clientDirection = clientY;
scrollRect = scrollRectTop;
scrollClient = scrollClientBottom;
this._isVerticalScroll = true;
}
else {
clientDirection = clientX;
scrollRect = scrollRectLeft;
scrollClient = scrollClientRight;
this._isVerticalScroll = false;
}
// calculate scroll velocity and direction
if (clientDirection < scrollRect + SCROLL_GUTTER) {
this._scrollVelocity = Math.max(-MAX_SCROLL_VELOCITY, -MAX_SCROLL_VELOCITY * ((SCROLL_GUTTER - (clientDirection - scrollRect)) / SCROLL_GUTTER));
}
else if (clientDirection > scrollClient) {
this._scrollVelocity = Math.min(MAX_SCROLL_VELOCITY, MAX_SCROLL_VELOCITY * ((clientDirection - scrollClient) / SCROLL_GUTTER));
}
else {
this._scrollVelocity = 0;
}
if (this._scrollVelocity) {
this._startScroll();
}
else {
this._stopScroll();
}
};
AutoScroll.prototype._startScroll = function () {
if (!this._timeoutId) {
this._incrementScroll();
}
};
AutoScroll.prototype._incrementScroll = function () {
if (this._scrollableParent) {
if (this._isVerticalScroll) {
this._scrollableParent.scrollTop += Math.round(this._scrollVelocity);
}
else {
this._scrollableParent.scrollLeft += Math.round(this._scrollVelocity);
}
}
this._timeoutId = setTimeout(this._incrementScroll, SCROLL_ITERATION_DELAY);
};
AutoScroll.prototype._stopScroll = function () {
if (this._timeoutId) {
clearTimeout(this._timeoutId);
delete this._timeoutId;
}
};
return AutoScroll;
}());
exports.AutoScroll = AutoScroll;
//# sourceMappingURL=AutoScroll.js.map
File diff suppressed because one or more lines are too long
+111
View File
@@ -0,0 +1,111 @@
import * as React from 'react';
import { Async } from './Async';
import { EventGroup } from './EventGroup';
import type { IDisposable } from './IDisposable';
import type { ISettingsMap } from './warn/warn';
import type { IBaseProps } from './BaseComponent.types';
import type { JSXElement } from './jsx';
/**
* BaseComponent class, which provides basic helpers for all components.
*
* @public
* {@docCategory BaseComponent}
*
* @deprecated Do not use. We are moving away from class component.
*/
export declare class BaseComponent<TProps extends IBaseProps = {}, TState extends {} = {}> extends React.Component<TProps, TState> {
/**
* @deprecated Use React's error boundaries instead.
*/
static onError: (errorMessage?: string, ex?: any) => void;
/**
* Controls whether the componentRef prop will be resolved by this component instance. If you are
* implementing a passthrough (higher-order component), you would set this to false and pass through
* the props to the inner component, allowing it to resolve the componentRef.
*/
protected _skipComponentRefResolution: boolean;
private __async;
private __events;
private __disposables;
private __resolves;
private __className;
/**
* BaseComponent constructor
* @param props - The props for the component.
* @param context - The context for the component.
*/
constructor(props: TProps, context?: any);
/**
* When the component receives props, make sure the componentRef is updated.
*/
componentDidUpdate(prevProps: TProps, prevState: TState): void;
/**
* When the component has mounted, update the componentRef.
*/
componentDidMount(): void;
/**
* If we have disposables, dispose them automatically on unmount.
*/
componentWillUnmount(): void;
/**
* Gets the object's class name.
*/
get className(): string;
/**
* Allows subclasses to push things to this._disposables to be auto disposed.
*/
protected get _disposables(): IDisposable[];
/**
* Gets the async instance associated with the component, created on demand. The async instance gives
* subclasses a way to execute setTimeout/setInterval async calls safely, where the callbacks
* will be cleared/ignored automatically after unmounting. The helpers within the async object also
* preserve the this pointer so that you don't need to "bind" the callbacks.
*/
protected get _async(): Async;
/**
* Gets the event group instance assocaited with the component, created on demand. The event instance
* provides on/off methods for listening to DOM (or regular javascript object) events. The event callbacks
* will be automatically disconnected after unmounting. The helpers within the events object also
* preserve the this reference so that you don't need to "bind" the callbacks.
*/
protected get _events(): EventGroup;
/**
* Helper to return a memoized ref resolver function.
* @param refName - Name of the member to assign the ref to.
* @returns A function instance keyed from the given refname.
* @deprecated Use `createRef` from React.createRef.
*/
protected _resolveRef(refName: string): (ref: React.ReactNode) => React.ReactNode;
/**
* Updates the componentRef (by calling it with "this" when necessary.)
*/
protected _updateComponentRef(currentProps: IBaseProps, newProps?: IBaseProps): void;
/**
* Warns when a deprecated props are being used.
*
* @param deprecationMap - The map of deprecations, where key is the prop name and the value is
* either null or a replacement prop name.
*/
protected _warnDeprecations(deprecationMap: ISettingsMap<TProps>): void;
/**
* Warns when props which are mutually exclusive with each other are both used.
*
* @param mutuallyExclusiveMap - The map of mutually exclusive props.
*/
protected _warnMutuallyExclusive(mutuallyExclusiveMap: ISettingsMap<TProps>): void;
/**
* Warns when props are required if a condition is met.
*
* @param requiredProps - The name of the props that are required when the condition is met.
* @param conditionalPropName - The name of the prop that the condition is based on.
* @param condition - Whether the condition is met.
*/
protected _warnConditionallyRequiredProps(requiredProps: string[], conditionalPropName: string, condition: boolean): void;
private _setComponentRef;
}
/**
* Simple constant function for returning null, used to render empty templates in JSX.
*
* @public
*/
export declare function nullRender(): JSXElement | null;
+245
View File
@@ -0,0 +1,245 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseComponent = void 0;
exports.nullRender = nullRender;
var tslib_1 = require("tslib");
var React = require("react");
var Async_1 = require("./Async");
var EventGroup_1 = require("./EventGroup");
var warnConditionallyRequiredProps_1 = require("./warn/warnConditionallyRequiredProps");
var warnMutuallyExclusive_1 = require("./warn/warnMutuallyExclusive");
var warnDeprecations_1 = require("./warn/warnDeprecations");
/**
* BaseComponent class, which provides basic helpers for all components.
*
* @public
* {@docCategory BaseComponent}
*
* @deprecated Do not use. We are moving away from class component.
*/
var BaseComponent = /** @class */ (function (_super) {
tslib_1.__extends(BaseComponent, _super);
/**
* BaseComponent constructor
* @param props - The props for the component.
* @param context - The context for the component.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function BaseComponent(props, context) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
var _this = _super.call(this, props, context) || this;
// eslint-disable-next-line @typescript-eslint/no-deprecated
_makeAllSafe(_this, BaseComponent.prototype, [
'componentDidMount',
'shouldComponentUpdate',
'getSnapshotBeforeUpdate',
'render',
'componentDidUpdate',
'componentWillUnmount',
]);
return _this;
}
/**
* When the component receives props, make sure the componentRef is updated.
*/
BaseComponent.prototype.componentDidUpdate = function (prevProps, prevState) {
this._updateComponentRef(prevProps, this.props);
};
/**
* When the component has mounted, update the componentRef.
*/
BaseComponent.prototype.componentDidMount = function () {
this._setComponentRef(this.props.componentRef, this);
};
/**
* If we have disposables, dispose them automatically on unmount.
*/
BaseComponent.prototype.componentWillUnmount = function () {
this._setComponentRef(this.props.componentRef, null);
if (this.__disposables) {
for (var i = 0, len = this._disposables.length; i < len; i++) {
var disposable = this.__disposables[i];
if (disposable.dispose) {
disposable.dispose();
}
}
this.__disposables = null;
}
};
Object.defineProperty(BaseComponent.prototype, "className", {
/**
* Gets the object's class name.
*/
get: function () {
if (!this.__className) {
var funcNameRegex = /function (.{1,})\(/;
var results = funcNameRegex.exec(this.constructor.toString());
this.__className = results && results.length > 1 ? results[1] : '';
}
return this.__className;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseComponent.prototype, "_disposables", {
/**
* Allows subclasses to push things to this._disposables to be auto disposed.
*/
get: function () {
if (!this.__disposables) {
this.__disposables = [];
}
return this.__disposables;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseComponent.prototype, "_async", {
/**
* Gets the async instance associated with the component, created on demand. The async instance gives
* subclasses a way to execute setTimeout/setInterval async calls safely, where the callbacks
* will be cleared/ignored automatically after unmounting. The helpers within the async object also
* preserve the this pointer so that you don't need to "bind" the callbacks.
*/
get: function () {
if (!this.__async) {
this.__async = new Async_1.Async(this);
this._disposables.push(this.__async);
}
return this.__async;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseComponent.prototype, "_events", {
/**
* Gets the event group instance assocaited with the component, created on demand. The event instance
* provides on/off methods for listening to DOM (or regular javascript object) events. The event callbacks
* will be automatically disconnected after unmounting. The helpers within the events object also
* preserve the this reference so that you don't need to "bind" the callbacks.
*/
get: function () {
if (!this.__events) {
this.__events = new EventGroup_1.EventGroup(this);
this._disposables.push(this.__events);
}
return this.__events;
},
enumerable: false,
configurable: true
});
/**
* Helper to return a memoized ref resolver function.
* @param refName - Name of the member to assign the ref to.
* @returns A function instance keyed from the given refname.
* @deprecated Use `createRef` from React.createRef.
*/
BaseComponent.prototype._resolveRef = function (refName) {
var _this = this;
if (!this.__resolves) {
this.__resolves = {};
}
if (!this.__resolves[refName]) {
this.__resolves[refName] = function (ref) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (_this[refName] = ref);
};
}
return this.__resolves[refName];
};
/**
* Updates the componentRef (by calling it with "this" when necessary.)
*/
BaseComponent.prototype._updateComponentRef = function (currentProps, newProps) {
if (newProps === void 0) { newProps = {}; }
// currentProps *should* always be defined, but verify that just in case a subclass is manually
// calling a lifecycle method with no parameters (which has happened) or other odd usage.
if (currentProps && newProps && currentProps.componentRef !== newProps.componentRef) {
this._setComponentRef(currentProps.componentRef, null);
this._setComponentRef(newProps.componentRef, this);
}
};
/**
* Warns when a deprecated props are being used.
*
* @param deprecationMap - The map of deprecations, where key is the prop name and the value is
* either null or a replacement prop name.
*/
BaseComponent.prototype._warnDeprecations = function (deprecationMap) {
(0, warnDeprecations_1.warnDeprecations)(this.className, this.props, deprecationMap);
};
/**
* Warns when props which are mutually exclusive with each other are both used.
*
* @param mutuallyExclusiveMap - The map of mutually exclusive props.
*/
BaseComponent.prototype._warnMutuallyExclusive = function (mutuallyExclusiveMap) {
(0, warnMutuallyExclusive_1.warnMutuallyExclusive)(this.className, this.props, mutuallyExclusiveMap);
};
/**
* Warns when props are required if a condition is met.
*
* @param requiredProps - The name of the props that are required when the condition is met.
* @param conditionalPropName - The name of the prop that the condition is based on.
* @param condition - Whether the condition is met.
*/
BaseComponent.prototype._warnConditionallyRequiredProps = function (requiredProps, conditionalPropName, condition) {
(0, warnConditionallyRequiredProps_1.warnConditionallyRequiredProps)(this.className, this.props, requiredProps, conditionalPropName, condition);
};
BaseComponent.prototype._setComponentRef = function (ref, value) {
if (!this._skipComponentRefResolution && ref) {
if (typeof ref === 'function') {
ref(value);
}
if (typeof ref === 'object') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ref.current = value;
}
}
};
return BaseComponent;
}(React.Component));
exports.BaseComponent = BaseComponent;
/**
* Helper to override a given method with a wrapper method that can try/catch the original, but also
* ensures that the BaseComponent's methods are called before the subclass's. This ensures that
* componentWillUnmount in the base is called and that things in the _disposables array are disposed.
*/
// eslint-disable-next-line @typescript-eslint/no-deprecated
function _makeAllSafe(obj, prototype, methodNames) {
for (var i = 0, len = methodNames.length; i < len; i++) {
_makeSafe(obj, prototype, methodNames[i]);
}
}
// eslint-disable-next-line @typescript-eslint/no-deprecated
function _makeSafe(obj, prototype, methodName) {
/* eslint-disable @typescript-eslint/no-explicit-any */
var classMethod = obj[methodName];
var prototypeMethod = prototype[methodName];
if (classMethod || prototypeMethod) {
obj[methodName] = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
/* eslint-enable @typescript-eslint/no-explicit-any */
var retVal;
if (prototypeMethod) {
retVal = prototypeMethod.apply(this, args);
}
if (classMethod !== prototypeMethod) {
retVal = classMethod.apply(this, args);
}
return retVal;
};
}
}
/**
* Simple constant function for returning null, used to render empty templates in JSX.
*
* @public
*/
function nullRender() {
return null;
}
//# sourceMappingURL=BaseComponent.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
export {};
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var React = require("react");
var react_1 = require("@testing-library/react");
var BaseComponent_1 = require("./BaseComponent");
describe('BaseComponent', function () {
it('can resolve refs', function () {
var Foo = /** @class */ (function (_super) {
tslib_1.__extends(Foo, _super);
function Foo() {
return _super !== null && _super.apply(this, arguments) || this;
}
Foo.prototype.render = function () {
return (React.createElement("div", {
// @ts-expect-error - react 18 types issue
ref: this._resolveRef('root') }));
};
return Foo;
}(BaseComponent_1.BaseComponent));
var container = (0, react_1.render)(React.createElement(Foo, null)).container;
var component = container.firstChild;
expect(component).toBeTruthy();
});
});
//# sourceMappingURL=BaseComponent.test.js.map
@@ -0,0 +1 @@
{"version":3,"file":"BaseComponent.test.js","sourceRoot":"../src/","sources":["BaseComponent.test.tsx"],"names":[],"mappings":";;;AAAA,6BAA+B;AAC/B,gDAAgD;AAChD,iDAAgD;AAIhD,QAAQ,CAAC,eAAe,EAAE;IACxB,EAAE,CAAC,kBAAkB,EAAE;QACrB;YAAkB,+BAAqB;YAAvC;;YAWA,CAAC;YARQ,oBAAM,GAAb;gBACE,OAAO,CACL;oBACE,0CAA0C;oBAC1C,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAC7B,CACH,CAAC;YACJ,CAAC;YACH,UAAC;QAAD,CAAC,AAXD,CAAkB,6BAAa,GAW9B;QAEO,IAAA,SAAS,GAAK,IAAA,cAAM,EAAC,oBAAC,GAAG,OAAG,CAAC,UAApB,CAAqB;QACtC,IAAM,SAAS,GAAG,SAAS,CAAC,UAAyB,CAAC;QAEtD,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { render } from '@testing-library/react';\nimport { BaseComponent } from './BaseComponent';\n\nimport type { JSXElement } from './jsx';\n\ndescribe('BaseComponent', () => {\n it('can resolve refs', () => {\n class Foo extends BaseComponent<{}, {}> {\n public root!: HTMLElement;\n\n public render(): JSXElement {\n return (\n <div\n // @ts-expect-error - react 18 types issue\n ref={this._resolveRef('root')}\n />\n );\n }\n }\n\n const { container } = render(<Foo />);\n const component = container.firstChild as HTMLElement;\n\n expect(component).toBeTruthy();\n });\n});\n"]}
+10
View File
@@ -0,0 +1,10 @@
import type { IRefObject } from './createRef';
/**
* BaseProps interface.
*
* @public
* {@docCategory IBaseProps}
*/
export interface IBaseProps<T = any> {
componentRef?: IRefObject<T>;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=BaseComponent.types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"BaseComponent.types.js","sourceRoot":"../src/","sources":["BaseComponent.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { IRefObject } from './createRef';\n\n/**\n * BaseProps interface.\n *\n * @public\n * {@docCategory IBaseProps}\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface IBaseProps<T = any> {\n componentRef?: IRefObject<T>;\n}\n"]}
+42
View File
@@ -0,0 +1,42 @@
import * as React from 'react';
import { IReactProps } from './React.types';
/**
* DelayedRender component props.
*
* @public
*/
export interface IDelayedRenderProps extends IReactProps<{}> {
/**
* Number of milliseconds to delay rendering children.
*/
delay?: number;
}
/**
* DelayedRender component state.
*
* @internal
*/
export interface IDelayedRenderState {
/**
* Whether the component is rendered or not.
*/
isRendered: boolean;
}
/**
* Utility component for delaying the render of a child component after a given delay. This component
* requires a single child component; don't pass in many components. Wrap multiple components in a DIV
* if necessary.
*
* @public
* {@docCategory DelayedRender}
*/
export declare class DelayedRender extends React.Component<IDelayedRenderProps, IDelayedRenderState> {
static defaultProps: {
delay: number;
};
private _timeoutId;
constructor(props: IDelayedRenderProps);
componentDidMount(): void;
componentWillUnmount(): void;
render(): React.ReactElement<{}> | null;
}
+48
View File
@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DelayedRender = void 0;
var tslib_1 = require("tslib");
var React = require("react");
var getWindow_1 = require("./dom/getWindow");
/**
* Utility component for delaying the render of a child component after a given delay. This component
* requires a single child component; don't pass in many components. Wrap multiple components in a DIV
* if necessary.
*
* @public
* {@docCategory DelayedRender}
*/
var DelayedRender = /** @class */ (function (_super) {
tslib_1.__extends(DelayedRender, _super);
function DelayedRender(props) {
var _this = _super.call(this, props) || this;
_this.state = {
isRendered: (0, getWindow_1.getWindow)() === undefined,
};
return _this;
}
DelayedRender.prototype.componentDidMount = function () {
var _this = this;
var delay = this.props.delay;
// eslint-disable-next-line no-restricted-globals
this._timeoutId = window.setTimeout(function () {
_this.setState({
isRendered: true,
});
}, delay);
};
DelayedRender.prototype.componentWillUnmount = function () {
if (this._timeoutId) {
clearTimeout(this._timeoutId);
}
};
DelayedRender.prototype.render = function () {
return this.state.isRendered ? React.Children.only(this.props.children) : null;
};
DelayedRender.defaultProps = {
delay: 0,
};
return DelayedRender;
}(React.Component));
exports.DelayedRender = DelayedRender;
//# sourceMappingURL=DelayedRender.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"DelayedRender.js","sourceRoot":"../src/","sources":["DelayedRender.tsx"],"names":[],"mappings":";;;;AAAA,6BAA+B;AAC/B,6CAA4C;AA2B5C;;;;;;;GAOG;AACH;IAAmC,yCAAyD;IAO1F,uBAAY,KAA0B;QACpC,YAAA,MAAK,YAAC,KAAK,CAAC,SAAC;QACb,KAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,IAAA,qBAAS,GAAE,KAAK,SAAS;SACtC,CAAC;;IACJ,CAAC;IAEM,yCAAiB,GAAxB;QAAA,iBAQC;QAPO,IAAA,KAAK,GAAK,IAAI,CAAC,KAAK,MAAf,CAAgB;QAC3B,iDAAiD;QACjD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;YAClC,KAAI,CAAC,QAAQ,CAAC;gBACZ,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;QACL,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAEM,4CAAoB,GAA3B;QACE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAEM,8BAAM,GAAb;QACE,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAA4B,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7G,CAAC;IA/Ba,0BAAY,GAAG;QAC3B,KAAK,EAAE,CAAC;KACT,CAAC;IA8BJ,oBAAC;CAAA,AAjCD,CAAmC,KAAK,CAAC,SAAS,GAiCjD;AAjCY,sCAAa","sourcesContent":["import * as React from 'react';\nimport { getWindow } from './dom/getWindow';\nimport { IReactProps } from './React.types';\n\n/**\n * DelayedRender component props.\n *\n * @public\n */\nexport interface IDelayedRenderProps extends IReactProps<{}> {\n /**\n * Number of milliseconds to delay rendering children.\n */\n delay?: number;\n}\n\n/**\n * DelayedRender component state.\n *\n * @internal\n */\nexport interface IDelayedRenderState {\n /**\n * Whether the component is rendered or not.\n */\n isRendered: boolean;\n}\n\n/**\n * Utility component for delaying the render of a child component after a given delay. This component\n * requires a single child component; don't pass in many components. Wrap multiple components in a DIV\n * if necessary.\n *\n * @public\n * {@docCategory DelayedRender}\n */\nexport class DelayedRender extends React.Component<IDelayedRenderProps, IDelayedRenderState> {\n public static defaultProps = {\n delay: 0,\n };\n\n private _timeoutId: number | undefined;\n\n constructor(props: IDelayedRenderProps) {\n super(props);\n this.state = {\n isRendered: getWindow() === undefined,\n };\n }\n\n public componentDidMount(): void {\n let { delay } = this.props;\n // eslint-disable-next-line no-restricted-globals\n this._timeoutId = window.setTimeout(() => {\n this.setState({\n isRendered: true,\n });\n }, delay);\n }\n\n public componentWillUnmount(): void {\n if (this._timeoutId) {\n clearTimeout(this._timeoutId);\n }\n }\n\n public render(): React.ReactElement<{}> | null {\n return this.state.isRendered ? (React.Children.only(this.props.children) as React.ReactElement<{}>) : null;\n }\n}\n"]}
+78
View File
@@ -0,0 +1,78 @@
/**
* @internal
*/
export interface IEventRecord {
target: any;
eventName: string;
parent: any;
callback: (args?: any) => void;
elementCallback?: (...args: any[]) => void;
objectCallback?: (args?: any) => void;
options?: boolean | AddEventListenerOptions;
}
/**
* @internal
*/
export interface IEventRecordsByName {
[eventName: string]: IEventRecordList;
}
/**
* @internal
*/
export interface IEventRecordList {
[id: string]: IEventRecord[] | number;
count: number;
}
/**
* @internal
*/
export interface IDeclaredEventsByName {
[eventName: string]: boolean;
}
/** An instance of EventGroup allows anything with a handle to it to trigger events on it.
* If the target is an HTMLElement, the event will be attached to the element and can be
* triggered as usual (like clicking for onClick).
* The event can be triggered by calling EventGroup.raise() here. If the target is an
* HTMLElement, the event gets raised and is handled by the browser. Otherwise, it gets
* handled here in EventGroup, and the handler is called in the context of the parent
* (which is passed in in the constructor).
*
* @public
* {@docCategory EventGroup}
*/
export declare class EventGroup {
private static _uniqueId;
private _parent;
private _eventRecords;
private _id;
private _isDisposed;
/** For IE8, bubbleEvent is ignored here and must be dealt with by the handler.
* Events raised here by default have bubbling set to false and cancelable set to true.
* This applies also to built-in events being raised manually here on HTMLElements,
* which may lead to unexpected behavior if it differs from the defaults.
*
*/
static raise(target: any, eventName: string, eventArgs?: any, bubbleEvent?: boolean, doc?: Document): boolean | undefined;
static isObserved(target: any, eventName: string): boolean;
/** Check to see if the target has declared support of the given event. */
static isDeclared(target: any, eventName: string): boolean;
static stopPropagation(event: any): void;
private static _isElement;
/** parent: the context in which events attached to non-HTMLElements are called */
constructor(parent: any);
dispose(): void;
/** On the target, attach a set of events, where the events object is a name to function mapping. */
onAll(target: any, events: {
[key: string]: (args?: any) => void;
}, useCapture?: boolean): void;
/**
* On the target, attach an event whose handler will be called in the context of the parent
* of this instance of EventGroup.
*/
on(target: any, eventName: string, callback: (args?: any) => void, options?: boolean | AddEventListenerOptions): void;
off(target?: any, eventName?: string, callback?: (args?: any) => void, options?: boolean | AddEventListenerOptions): void;
/** Trigger the given event in the context of this instance of EventGroup. */
raise(eventName: string, eventArgs?: any, bubbleEvent?: boolean): boolean | undefined;
/** Declare an event as being supported by this instance of EventGroup. */
declare(event: string | string[]): void;
}
+255
View File
@@ -0,0 +1,255 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventGroup = void 0;
var dom_1 = require("./dom");
var object_1 = require("./object");
/** An instance of EventGroup allows anything with a handle to it to trigger events on it.
* If the target is an HTMLElement, the event will be attached to the element and can be
* triggered as usual (like clicking for onClick).
* The event can be triggered by calling EventGroup.raise() here. If the target is an
* HTMLElement, the event gets raised and is handled by the browser. Otherwise, it gets
* handled here in EventGroup, and the handler is called in the context of the parent
* (which is passed in in the constructor).
*
* @public
* {@docCategory EventGroup}
*/
var EventGroup = /** @class */ (function () {
/** parent: the context in which events attached to non-HTMLElements are called */
function EventGroup(parent) {
this._id = EventGroup._uniqueId++;
this._parent = parent;
this._eventRecords = [];
}
/** For IE8, bubbleEvent is ignored here and must be dealt with by the handler.
* Events raised here by default have bubbling set to false and cancelable set to true.
* This applies also to built-in events being raised manually here on HTMLElements,
* which may lead to unexpected behavior if it differs from the defaults.
*
*/
EventGroup.raise = function (target, eventName, eventArgs, bubbleEvent, doc) {
var retVal;
var theDoc = doc !== null && doc !== void 0 ? doc : (0, dom_1.getDocument)();
if (EventGroup._isElement(target)) {
if (typeof theDoc !== 'undefined' && theDoc.createEvent) {
var ev = theDoc.createEvent('HTMLEvents');
// eslint-disable-next-line @typescript-eslint/no-deprecated
ev.initEvent(eventName, bubbleEvent || false, true);
(0, object_1.assign)(ev, eventArgs);
retVal = target.dispatchEvent(ev);
}
else if (typeof theDoc !== 'undefined' && theDoc.createEventObject) {
// IE8
var evObj = theDoc.createEventObject(eventArgs);
// cannot set cancelBubble on evObj, fireEvent will overwrite it
target.fireEvent('on' + eventName, evObj);
}
}
else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore -- FIXME: strictBindCallApply error - https://github.com/microsoft/fluentui/issues/17331
while (target && retVal !== false) {
var events = target.__events__;
var eventRecords = events ? events[eventName] : null;
if (eventRecords) {
for (var id in eventRecords) {
if (eventRecords.hasOwnProperty(id)) {
var eventRecordList = eventRecords[id];
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore -- FIXME: strictBindCallApply error - https://github.com/microsoft/fluentui/issues/17331
for (var listIndex = 0; retVal !== false && listIndex < eventRecordList.length; listIndex++) {
var record = eventRecordList[listIndex];
if (record.objectCallback) {
retVal = record.objectCallback.call(record.parent, eventArgs);
}
}
}
}
}
// If the target has a parent, bubble the event up.
target = bubbleEvent ? target.parent : null;
}
}
return retVal;
};
EventGroup.isObserved = function (target, eventName) {
var events = target && target.__events__;
return !!events && !!events[eventName];
};
/** Check to see if the target has declared support of the given event. */
EventGroup.isDeclared = function (target, eventName) {
var declaredEvents = target && target.__declaredEvents;
return !!declaredEvents && !!declaredEvents[eventName];
};
EventGroup.stopPropagation = function (event) {
if (event.stopPropagation) {
event.stopPropagation();
}
else {
// IE8
event.cancelBubble = true;
}
};
EventGroup._isElement = function (target) {
return (!!target && (!!target.addEventListener || (typeof HTMLElement !== 'undefined' && target instanceof HTMLElement)));
};
EventGroup.prototype.dispose = function () {
if (!this._isDisposed) {
this._isDisposed = true;
this.off();
this._parent = null;
}
};
/** On the target, attach a set of events, where the events object is a name to function mapping. */
EventGroup.prototype.onAll = function (target, events, useCapture) {
for (var eventName in events) {
if (events.hasOwnProperty(eventName)) {
this.on(target, eventName, events[eventName], useCapture);
}
}
};
/**
* On the target, attach an event whose handler will be called in the context of the parent
* of this instance of EventGroup.
*/
EventGroup.prototype.on = function (target, eventName, callback, options) {
var _this = this;
if (eventName.indexOf(',') > -1) {
var events = eventName.split(/[ ,]+/);
for (var i = 0; i < events.length; i++) {
this.on(target, events[i], callback, options);
}
}
else {
var parent_1 = this._parent;
var eventRecord = {
target: target,
eventName: eventName,
parent: parent_1,
callback: callback,
options: options,
};
// Initialize and wire up the record on the target, so that it can call the callback if the event fires.
var events = (target.__events__ = target.__events__ || {});
events[eventName] =
events[eventName] ||
{
count: 0,
};
events[eventName][this._id] = events[eventName][this._id] || [];
events[eventName][this._id].push(eventRecord);
events[eventName].count++;
if (EventGroup._isElement(target)) {
var processElementEvent = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (_this._isDisposed) {
return;
}
var result;
try {
result = callback.apply(parent_1, args);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore -- FIXME: strictBindCallApply error - https://github.com/microsoft/fluentui/issues/17331
if (result === false && args[0]) {
var e = args[0];
if (e.preventDefault) {
e.preventDefault();
}
if (e.stopPropagation) {
e.stopPropagation();
}
e.cancelBubble = true;
}
}
catch (e) {
// ignore
}
return result;
};
eventRecord.elementCallback = processElementEvent;
if (target.addEventListener) {
target.addEventListener(eventName, processElementEvent, options);
}
else if (target.attachEvent) {
// IE8
target.attachEvent('on' + eventName, processElementEvent);
}
}
else {
var processObjectEvent = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (_this._isDisposed) {
return;
}
return callback.apply(parent_1, args);
};
eventRecord.objectCallback = processObjectEvent;
}
// Remember the record locally, so that it can be removed.
this._eventRecords.push(eventRecord);
}
};
EventGroup.prototype.off = function (target, eventName, callback, options) {
for (var i = 0; i < this._eventRecords.length; i++) {
var eventRecord = this._eventRecords[i];
if ((!target || target === eventRecord.target) &&
(!eventName || eventName === eventRecord.eventName) &&
(!callback || callback === eventRecord.callback) &&
(typeof options !== 'boolean' || options === eventRecord.options)) {
var events = eventRecord.target.__events__;
var targetArrayLookup = events[eventRecord.eventName];
var targetArray = targetArrayLookup ? targetArrayLookup[this._id] : null;
// We may have already target's entries, so check for null.
if (targetArray) {
if (targetArray.length === 1 || !callback) {
targetArrayLookup.count -= targetArray.length;
delete events[eventRecord.eventName][this._id];
}
else {
targetArrayLookup.count--;
targetArray.splice(targetArray.indexOf(eventRecord), 1);
}
if (!targetArrayLookup.count) {
delete events[eventRecord.eventName];
}
}
if (eventRecord.elementCallback) {
if (eventRecord.target.removeEventListener) {
eventRecord.target.removeEventListener(eventRecord.eventName, eventRecord.elementCallback, eventRecord.options);
}
else if (eventRecord.target.detachEvent) {
// IE8
eventRecord.target.detachEvent('on' + eventRecord.eventName, eventRecord.elementCallback);
}
}
this._eventRecords.splice(i--, 1);
}
}
};
/** Trigger the given event in the context of this instance of EventGroup. */
EventGroup.prototype.raise = function (eventName, eventArgs, bubbleEvent) {
return EventGroup.raise(this._parent, eventName, eventArgs, bubbleEvent);
};
/** Declare an event as being supported by this instance of EventGroup. */
EventGroup.prototype.declare = function (event) {
var declaredEvents = (this._parent.__declaredEvents = this._parent.__declaredEvents || {});
if (typeof event === 'string') {
declaredEvents[event] = true;
}
else {
for (var i = 0; i < event.length; i++) {
declaredEvents[event[i]] = true;
}
}
};
EventGroup._uniqueId = 0;
return EventGroup;
}());
exports.EventGroup = EventGroup;
//# sourceMappingURL=EventGroup.js.map
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export {};
+206
View File
@@ -0,0 +1,206 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var EventGroup_1 = require("./EventGroup");
describe('EventGroup', function () {
it('can observe an HTML element event', function () {
var timesCalled = 0;
var sourceButton = document.createElement('button');
var parent = {
cb: function () {
timesCalled++;
},
};
var eg = new EventGroup_1.EventGroup(parent);
var ev = document.createEvent('HTMLEvents');
eg.on(sourceButton, 'click', parent.cb);
ev.initEvent('click', true, true);
sourceButton.dispatchEvent(ev);
expect(timesCalled).toEqual(1);
sourceButton.dispatchEvent(ev);
expect(timesCalled).toEqual(2);
eg.dispose();
sourceButton.dispatchEvent(ev);
expect(timesCalled).toEqual(2);
});
it('can observe an object event', function () {
var timesCalled = 0;
var sourceObject = {};
var parent = {
cb: function () {
timesCalled++;
},
};
var parentEvents = new EventGroup_1.EventGroup(parent);
var sourceEvents = new EventGroup_1.EventGroup(sourceObject);
sourceEvents.declare(['foo', 'bar']);
expect(EventGroup_1.EventGroup.isDeclared(sourceObject, 'foo')).toEqual(true);
expect(EventGroup_1.EventGroup.isDeclared(sourceObject, 'bar')).toEqual(true);
expect(EventGroup_1.EventGroup.isDeclared(sourceObject, 'baz')).toEqual(false);
parentEvents.on(sourceObject, 'foo, bar', parent.cb);
expect(EventGroup_1.EventGroup.isObserved(sourceObject, 'foo')).toEqual(true);
expect(EventGroup_1.EventGroup.isObserved(sourceObject, 'bar')).toEqual(true);
expect(EventGroup_1.EventGroup.isObserved(sourceObject, 'baz')).toEqual(false);
sourceEvents.raise('foo');
expect(timesCalled).toEqual(1);
sourceEvents.raise('bar');
expect(timesCalled).toEqual(2);
parentEvents.dispose();
sourceEvents.raise('thing');
expect(timesCalled).toEqual(2);
});
it('can bubble object events', function () {
var rootCalled = 0;
var childCalled = 0;
var grandChildCalled = 0;
var childResponse = true;
var root = {
cb: function () {
rootCalled++;
},
};
var child = {
parent: root,
cb: function () {
childCalled++;
return childResponse;
},
};
var grandChild = {
parent: child,
cb: function () {
grandChildCalled++;
},
};
var rootEvents = new EventGroup_1.EventGroup(root);
var childEvents = new EventGroup_1.EventGroup(child);
var grandChildEvents = new EventGroup_1.EventGroup(grandChild);
rootEvents.on(root, 'foo', root.cb);
childEvents.on(child, 'foo', child.cb);
grandChildEvents.on(grandChild, 'foo', grandChild.cb);
// bubble up to the root.
grandChildEvents.raise('foo', null, true);
expect(rootCalled).toEqual(1);
expect(childCalled).toEqual(1);
expect(grandChildCalled).toEqual(1);
// cancel at the child.
childResponse = false;
grandChildEvents.raise('foo', null, true);
expect(rootCalled).toEqual(1);
expect(childCalled).toEqual(2);
expect(grandChildCalled).toEqual(2);
// dispose all.
rootEvents.dispose();
childEvents.dispose();
grandChildEvents.dispose();
grandChildEvents.raise('foo', null, true);
expect(rootCalled).toEqual(1);
expect(childCalled).toEqual(2);
expect(grandChildCalled).toEqual(2);
});
it('can cancelBubble/preventDefault if false is returned on an element event callback', function () {
var rootCalled = 0;
var childCalled = 0;
var childResponse = true;
var rootDiv = document.createElement('div');
var childDiv = document.createElement('div');
var grandChildButton = document.createElement('button');
var parent = {
onRootClick: function () {
rootCalled++;
},
onChildClick: function () {
childCalled++;
return childResponse;
},
};
var parentEvents = new EventGroup_1.EventGroup(parent);
parentEvents.on(childDiv, 'click', parent.onChildClick);
parentEvents.on(rootDiv, 'click', parent.onRootClick);
document.body.appendChild(rootDiv).appendChild(childDiv).appendChild(grandChildButton);
try {
var ev = document.createEvent('HTMLEvents');
ev.initEvent('click', true, true);
grandChildButton.dispatchEvent(ev);
// verify we bubble.
expect(childCalled).toEqual(1);
expect(rootCalled).toEqual(1);
// now return false at the child, shouldn't hit root.
childResponse = false;
grandChildButton.dispatchEvent(ev);
expect(childCalled).toEqual(2);
expect(rootCalled).toEqual(1);
parentEvents.dispose();
grandChildButton.dispatchEvent(ev);
expect(childCalled).toEqual(2);
expect(rootCalled).toEqual(1);
}
finally {
document.body.removeChild(rootDiv);
}
});
it('can selectively remove event handlers', function () {
var cb1Called = 0;
var cb2Called = 0;
var sourceObject = {};
var parent = {
cb1: function () {
cb1Called++;
},
cb2: function () {
cb2Called++;
},
};
var parentEvents = new EventGroup_1.EventGroup(parent);
var sourceEvents = new EventGroup_1.EventGroup(sourceObject);
parentEvents.on(sourceObject, 'foo', parent.cb1);
parentEvents.on(sourceObject, 'foo', parent.cb2);
sourceEvents.raise('foo');
expect(cb1Called).toEqual(1);
expect(cb1Called).toEqual(1);
// remove one.
parentEvents.off(sourceObject, 'foo', parent.cb1);
sourceEvents.raise('foo');
expect(cb1Called).toEqual(1);
expect(cb2Called).toEqual(2);
// attach it again.
parentEvents.on(sourceObject, 'foo', parent.cb1);
sourceEvents.raise('foo');
expect(cb1Called).toEqual(2);
expect(cb2Called).toEqual(3);
// detatch both based on event name.
parentEvents.off(sourceObject, 'foo');
sourceEvents.raise('foo');
expect(cb1Called).toEqual(2);
expect(cb2Called).toEqual(3);
// attach it again.
parentEvents.on(sourceObject, 'foo', parent.cb1);
parentEvents.on(sourceObject, 'foo', parent.cb2);
sourceEvents.raise('foo');
expect(cb1Called).toEqual(3);
expect(cb2Called).toEqual(4);
// detach based on object.
parentEvents.off(sourceObject);
sourceEvents.raise('foo');
expect(cb1Called).toEqual(3);
expect(cb2Called).toEqual(4);
});
it('can raise custom html events', function () {
var timesCalled = 0;
var sourceButton = document.createElement('button');
var parent = {
cb: function () {
timesCalled++;
},
};
var eg = new EventGroup_1.EventGroup(parent);
eg.on(sourceButton, 'foobar', parent.cb);
EventGroup_1.EventGroup.raise(sourceButton, 'foobar');
expect(timesCalled).toEqual(1);
EventGroup_1.EventGroup.raise(sourceButton, 'foobar');
expect(timesCalled).toEqual(2);
eg.dispose();
EventGroup_1.EventGroup.raise(sourceButton, 'foobar');
expect(timesCalled).toEqual(2);
});
});
//# sourceMappingURL=EventGroup.test.js.map
File diff suppressed because one or more lines are too long
+46
View File
@@ -0,0 +1,46 @@
/**
* PerfData interface.
*
* @internal
*/
export interface IPerfData {
duration: number;
timeStamp: number;
}
/**
* PerfMeasurement interface.
*
* @internal
*/
export interface IPerfMeasurement {
totalDuration: number;
count: number;
all: IPerfData[];
}
/**
* PerfSummary interface.
*
* @internal
*/
export interface IPerfSummary {
[key: string]: IPerfMeasurement;
}
/**
* Performance helper class for measuring things.
*
* @public
* {@docCategory FabricPerformance}
*/
export declare class FabricPerformance {
static summary: IPerfSummary;
private static _timeoutId;
/**
* Measures execution time of the given syncronous function. If the same logic is executed multiple times,
* each individual measurement will be collected as well the overall numbers.
* @param name - The name of this measurement
* @param func - The logic to be measured for execution time
*/
static measure(name: string, func: () => void): void;
static reset(): void;
static setPeriodicReset(): void;
}
+56
View File
@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FabricPerformance = void 0;
var now = function () {
return typeof performance !== 'undefined' && !!performance.now ? performance.now() : Date.now();
};
var RESET_INTERVAL = 3 * 60 * 1000; // auto reset every 3 minutes
/**
* Performance helper class for measuring things.
*
* @public
* {@docCategory FabricPerformance}
*/
var FabricPerformance = /** @class */ (function () {
function FabricPerformance() {
}
/**
* Measures execution time of the given syncronous function. If the same logic is executed multiple times,
* each individual measurement will be collected as well the overall numbers.
* @param name - The name of this measurement
* @param func - The logic to be measured for execution time
*/
FabricPerformance.measure = function (name, func) {
if (FabricPerformance._timeoutId) {
FabricPerformance.setPeriodicReset();
}
var start = now();
func();
var end = now();
var measurement = FabricPerformance.summary[name] || {
totalDuration: 0,
count: 0,
all: [],
};
var duration = end - start;
measurement.totalDuration += duration;
measurement.count++;
measurement.all.push({
duration: duration,
timeStamp: end,
});
FabricPerformance.summary[name] = measurement;
};
FabricPerformance.reset = function () {
FabricPerformance.summary = {};
clearTimeout(FabricPerformance._timeoutId);
FabricPerformance._timeoutId = NaN;
};
FabricPerformance.setPeriodicReset = function () {
FabricPerformance._timeoutId = setTimeout(function () { return FabricPerformance.reset(); }, RESET_INTERVAL);
};
FabricPerformance.summary = {};
return FabricPerformance;
}());
exports.FabricPerformance = FabricPerformance;
//# sourceMappingURL=FabricPerformance.js.map
@@ -0,0 +1 @@
{"version":3,"file":"FabricPerformance.js","sourceRoot":"../src/","sources":["FabricPerformance.ts"],"names":[],"mappings":";;;AAgCA,IAAM,GAAG,GAAiB;IACxB,OAAA,OAAO,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;AAAxF,CAAwF,CAAC;AAE3F,IAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AAEnE;;;;;GAKG;AACH;IAAA;IAyCA,CAAC;IArCC;;;;;OAKG;IACW,yBAAO,GAArB,UAAsB,IAAY,EAAE,IAAgB;QAClD,IAAI,iBAAiB,CAAC,UAAU,EAAE,CAAC;YACjC,iBAAiB,CAAC,gBAAgB,EAAE,CAAC;QACvC,CAAC;QACD,IAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACpB,IAAI,EAAE,CAAC;QACP,IAAM,GAAG,GAAG,GAAG,EAAE,CAAC;QAClB,IAAM,WAAW,GAAqB,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI;YACvE,aAAa,EAAE,CAAC;YAChB,KAAK,EAAE,CAAC;YACR,GAAG,EAAE,EAAE;SACR,CAAC;QACF,IAAM,QAAQ,GAAG,GAAG,GAAG,KAAK,CAAC;QAC7B,WAAW,CAAC,aAAa,IAAI,QAAQ,CAAC;QACtC,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;YACnB,QAAQ,UAAA;YACR,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QACH,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC;IAChD,CAAC;IAEa,uBAAK,GAAnB;QACE,iBAAiB,CAAC,OAAO,GAAG,EAAE,CAAC;QAC/B,YAAY,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC3C,iBAAiB,CAAC,UAAU,GAAG,GAAG,CAAC;IACrC,CAAC;IAEa,kCAAgB,GAA9B;QACE,iBAAiB,CAAC,UAAU,GAAG,UAAU,CAAC,cAAM,OAAA,iBAAiB,CAAC,KAAK,EAAE,EAAzB,CAAyB,EAAE,cAAc,CAAC,CAAC;IAC7F,CAAC;IAvCa,yBAAO,GAAiB,EAAE,CAAC;IAwC3C,wBAAC;CAAA,AAzCD,IAyCC;AAzCY,8CAAiB","sourcesContent":["declare const setTimeout: (cb: () => void, delay: number) => number;\n\n/**\n * PerfData interface.\n *\n * @internal\n */\nexport interface IPerfData {\n duration: number;\n timeStamp: number;\n}\n\n/**\n * PerfMeasurement interface.\n *\n * @internal\n */\nexport interface IPerfMeasurement {\n totalDuration: number;\n count: number;\n all: IPerfData[];\n}\n\n/**\n * PerfSummary interface.\n *\n * @internal\n */\nexport interface IPerfSummary {\n [key: string]: IPerfMeasurement;\n}\n\nconst now: () => number = () =>\n typeof performance !== 'undefined' && !!performance.now ? performance.now() : Date.now();\n\nconst RESET_INTERVAL = 3 * 60 * 1000; // auto reset every 3 minutes\n\n/**\n * Performance helper class for measuring things.\n *\n * @public\n * {@docCategory FabricPerformance}\n */\nexport class FabricPerformance {\n public static summary: IPerfSummary = {};\n private static _timeoutId: number;\n\n /**\n * Measures execution time of the given syncronous function. If the same logic is executed multiple times,\n * each individual measurement will be collected as well the overall numbers.\n * @param name - The name of this measurement\n * @param func - The logic to be measured for execution time\n */\n public static measure(name: string, func: () => void): void {\n if (FabricPerformance._timeoutId) {\n FabricPerformance.setPeriodicReset();\n }\n const start = now();\n func();\n const end = now();\n const measurement: IPerfMeasurement = FabricPerformance.summary[name] || {\n totalDuration: 0,\n count: 0,\n all: [],\n };\n const duration = end - start;\n measurement.totalDuration += duration;\n measurement.count++;\n measurement.all.push({\n duration,\n timeStamp: end,\n });\n FabricPerformance.summary[name] = measurement;\n }\n\n public static reset(): void {\n FabricPerformance.summary = {};\n clearTimeout(FabricPerformance._timeoutId);\n FabricPerformance._timeoutId = NaN;\n }\n\n public static setPeriodicReset(): void {\n FabricPerformance._timeoutId = setTimeout(() => FabricPerformance.reset(), RESET_INTERVAL);\n }\n}\n"]}
+13
View File
@@ -0,0 +1,13 @@
import * as React from 'react';
export type FocusRectsProviderProps = {
/**
* Ref to the root element that this is providing focus rects for.
*/
providerRef: React.RefObject<HTMLElement | null>;
/**
* Indicates that this is the root of a layer, and should not inherit the providerRef from a parent context.
*/
layerRoot?: boolean;
children?: React.ReactNode;
};
export declare const FocusRectsProvider: React.FC<FocusRectsProviderProps>;
+49
View File
@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FocusRectsProvider = void 0;
var React = require("react");
var useFocusRects_1 = require("./useFocusRects");
var FocusRectsProvider = function (props) {
var providerRef = props.providerRef, layerRoot = props.layerRoot;
var registeredProviders = React.useState([])[0];
var parentContext = React.useContext(useFocusRects_1.FocusRectsContext);
// Inherit the parent context if it exists, unless this is a layer root.
// This allows the topmost provider element in the DOM tree to handle the focus events.
// Since layers are in a separate HTML tree from their parent, they shouldn't use the parent's providerRef.
var inheritParentContext = parentContext !== undefined && !layerRoot;
var context = React.useMemo(function () {
return inheritParentContext
? undefined
: {
providerRef: providerRef,
registeredProviders: registeredProviders,
registerProvider: function (ref) {
// Register this child provider with the current context, and any parent contexts
registeredProviders.push(ref);
parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerProvider(ref);
},
unregisterProvider: function (ref) {
parentContext === null || parentContext === void 0 ? void 0 : parentContext.unregisterProvider(ref);
var i = registeredProviders.indexOf(ref);
if (i >= 0) {
registeredProviders.splice(i, 1);
}
},
};
}, [providerRef, registeredProviders, parentContext, inheritParentContext]);
React.useEffect(function () {
if (context) {
context.registerProvider(context.providerRef);
return function () { return context.unregisterProvider(context.providerRef); };
}
}, [context]);
// Create a new context provider if this is not inheriting from the parent.
if (context) {
return React.createElement(useFocusRects_1.FocusRectsContext.Provider, { value: context }, props.children);
}
else {
return React.createElement(React.Fragment, null, props.children);
}
};
exports.FocusRectsProvider = FocusRectsProvider;
//# sourceMappingURL=FocusRectsProvider.js.map
@@ -0,0 +1 @@
{"version":3,"file":"FocusRectsProvider.js","sourceRoot":"../src/","sources":["FocusRectsProvider.tsx"],"names":[],"mappings":";;;AAAA,6BAA+B;AAC/B,iDAAoD;AAgB7C,IAAM,kBAAkB,GAAsC,UAAA,KAAK;IAChE,IAAA,WAAW,GAAgB,KAAK,YAArB,EAAE,SAAS,GAAK,KAAK,UAAV,CAAW;IAClC,IAAA,mBAAmB,GAAI,KAAK,CAAC,QAAQ,CAAwC,EAAE,CAAC,GAA7D,CAA8D;IACxF,IAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC,iCAAiB,CAAC,CAAC;IAE1D,wEAAwE;IACxE,uFAAuF;IACvF,2GAA2G;IAC3G,IAAM,oBAAoB,GAAG,aAAa,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC;IAEvE,IAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAC3B;QACE,OAAA,oBAAoB;YAClB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC;gBACE,WAAW,aAAA;gBACX,mBAAmB,qBAAA;gBACnB,gBAAgB,EAAE,UAAC,GAAwC;oBACzD,iFAAiF;oBACjF,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC9B,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;gBACvC,CAAC;gBACD,kBAAkB,EAAE,UAAC,GAAwC;oBAC3D,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC;oBACvC,IAAM,CAAC,GAAG,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBACX,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;aACF;IAjBL,CAiBK,EACP,CAAC,WAAW,EAAE,mBAAmB,EAAE,aAAa,EAAE,oBAAoB,CAAC,CACxE,CAAC;IAEF,KAAK,CAAC,SAAS,CAAC;QACd,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC9C,OAAO,cAAM,OAAA,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,EAA/C,CAA+C,CAAC;QAC/D,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,2EAA2E;IAC3E,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,oBAAC,iCAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,IAAG,KAAK,CAAC,QAAQ,CAA8B,CAAC;IACnG,CAAC;SAAM,CAAC;QACN,OAAO,0CAAG,KAAK,CAAC,QAAQ,CAAI,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC;AA9CW,QAAA,kBAAkB,sBA8C7B","sourcesContent":["import * as React from 'react';\nimport { FocusRectsContext } from './useFocusRects';\n\nexport type FocusRectsProviderProps = {\n /**\n * Ref to the root element that this is providing focus rects for.\n */\n providerRef: React.RefObject<HTMLElement | null>;\n\n /**\n * Indicates that this is the root of a layer, and should not inherit the providerRef from a parent context.\n */\n layerRoot?: boolean;\n\n children?: React.ReactNode;\n};\n\nexport const FocusRectsProvider: React.FC<FocusRectsProviderProps> = props => {\n const { providerRef, layerRoot } = props;\n const [registeredProviders] = React.useState<React.RefObject<HTMLElement | null>[]>([]);\n const parentContext = React.useContext(FocusRectsContext);\n\n // Inherit the parent context if it exists, unless this is a layer root.\n // This allows the topmost provider element in the DOM tree to handle the focus events.\n // Since layers are in a separate HTML tree from their parent, they shouldn't use the parent's providerRef.\n const inheritParentContext = parentContext !== undefined && !layerRoot;\n\n const context = React.useMemo(\n () =>\n inheritParentContext\n ? undefined\n : {\n providerRef,\n registeredProviders,\n registerProvider: (ref: React.RefObject<HTMLElement | null>) => {\n // Register this child provider with the current context, and any parent contexts\n registeredProviders.push(ref);\n parentContext?.registerProvider(ref);\n },\n unregisterProvider: (ref: React.RefObject<HTMLElement | null>) => {\n parentContext?.unregisterProvider(ref);\n const i = registeredProviders.indexOf(ref);\n if (i >= 0) {\n registeredProviders.splice(i, 1);\n }\n },\n },\n [providerRef, registeredProviders, parentContext, inheritParentContext],\n );\n\n React.useEffect(() => {\n if (context) {\n context.registerProvider(context.providerRef);\n return () => context.unregisterProvider(context.providerRef);\n }\n }, [context]);\n\n // Create a new context provider if this is not inheriting from the parent.\n if (context) {\n return <FocusRectsContext.Provider value={context}>{props.children}</FocusRectsContext.Provider>;\n } else {\n return <>{props.children}</>;\n }\n};\n"]}
+35
View File
@@ -0,0 +1,35 @@
/**
* Change description used for change callbacks in GlobalSettings.
*
* @public
* {@docCategory IChangeDescription}
*/
export interface IChangeDescription {
key: string;
oldValue: any;
value: any;
}
/**
* Change event callback.
*
* @public
* {@docCategory IChangeEventCallback}
*/
export interface IChangeEventCallback {
__id__?: string;
(changeDescription?: IChangeDescription): void;
}
/**
* Global settings helper, which stores settings in the global (window) namespace.
* If window is not provided, it will store settings in module scope. Provides a
* way to observe changes as well when their values change.
*
* @public
* {@docCategory GlobalSettings}
*/
export declare class GlobalSettings {
static getValue<T>(key: string, defaultValue?: T | (() => T)): T;
static setValue<T>(key: string, value: T): T;
static addChangeListener(cb: IChangeEventCallback): void;
static removeChangeListener(cb: IChangeEventCallback): void;
}
+87
View File
@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GlobalSettings = void 0;
var getWindow_1 = require("./dom/getWindow");
/**
* Storing global state in local module variables has issues when more than one copy
* if the module gets loaded on the page (due to a bundling error or simply by consuming
* a prebundled script.)
*
* This file contains helpers to deal with the getting and setting local state, and allows
* callers to get called back when it mutates.
*/
var GLOBAL_SETTINGS_PROP_NAME = '__globalSettings__';
var CALLBACK_STATE_PROP_NAME = '__callbacks__';
var _counter = 0;
/**
* Global settings helper, which stores settings in the global (window) namespace.
* If window is not provided, it will store settings in module scope. Provides a
* way to observe changes as well when their values change.
*
* @public
* {@docCategory GlobalSettings}
*/
var GlobalSettings = /** @class */ (function () {
function GlobalSettings() {
}
GlobalSettings.getValue = function (key, defaultValue) {
var globalSettings = _getGlobalSettings();
if (globalSettings[key] === undefined) {
globalSettings[key] = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
}
return globalSettings[key];
};
GlobalSettings.setValue = function (key, value) {
var globalSettings = _getGlobalSettings();
var callbacks = globalSettings[CALLBACK_STATE_PROP_NAME];
var oldValue = globalSettings[key];
if (value !== oldValue) {
globalSettings[key] = value;
var changeDescription = {
oldValue: oldValue,
value: value,
key: key,
};
for (var id in callbacks) {
if (callbacks.hasOwnProperty(id)) {
callbacks[id](changeDescription);
}
}
}
return value;
};
GlobalSettings.addChangeListener = function (cb) {
// Note: we use generated ids on the callbacks to create a map of the callbacks, which optimizes removal.
// (It's faster to delete a key than it is to look up the index of an object and splice an array.)
var id = cb.__id__;
var callbacks = _getCallbacks();
if (!id) {
id = cb.__id__ = String(_counter++);
}
callbacks[id] = cb;
};
GlobalSettings.removeChangeListener = function (cb) {
var callbacks = _getCallbacks();
delete callbacks[cb.__id__];
};
return GlobalSettings;
}());
exports.GlobalSettings = GlobalSettings;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function _getGlobalSettings() {
var _a;
var win = (0, getWindow_1.getWindow)();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var globalObj = win || {};
if (!globalObj[GLOBAL_SETTINGS_PROP_NAME]) {
globalObj[GLOBAL_SETTINGS_PROP_NAME] = (_a = {},
_a[CALLBACK_STATE_PROP_NAME] = {},
_a);
}
return globalObj[GLOBAL_SETTINGS_PROP_NAME];
}
function _getCallbacks() {
var globalSettings = _getGlobalSettings();
return globalSettings[CALLBACK_STATE_PROP_NAME];
}
//# sourceMappingURL=GlobalSettings.js.map
File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
/**
* @deprecated Use `IProcessedStyleSet` from `@fluentui/style-utilities` or `@fluentui/merge-styles` instead.
*/
export type IClassNames<T> = {
[key in keyof T]: string;
};
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IClassNames.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IClassNames.js","sourceRoot":"../src/","sources":["IClassNames.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @deprecated Use `IProcessedStyleSet` from `@fluentui/style-utilities` or `@fluentui/merge-styles` instead.\n */\nexport type IClassNames<T> = { [key in keyof T]: string };\n"]}
+17
View File
@@ -0,0 +1,17 @@
import * as React from 'react';
/**
* Properties used by render function interface for providing overrideable render callbacks.
*
* @public
* {@docCategory IComponentAsProps}
*/
export type IComponentAsProps<T> = T & {
defaultRender?: React.ComponentType<T>;
};
/**
* Render function interface for providing overrideable render callbacks.
*
* @public
* {@docCategory IComponentAs}
*/
export type IComponentAs<T> = React.ComponentType<IComponentAsProps<T>>;
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IComponentAs.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IComponentAs.js","sourceRoot":"../src/","sources":["IComponentAs.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\n\n/**\n * Properties used by render function interface for providing overrideable render callbacks.\n *\n * @public\n * {@docCategory IComponentAsProps}\n */\nexport type IComponentAsProps<T> = T & { defaultRender?: React.ComponentType<T> };\n\n/**\n * Render function interface for providing overrideable render callbacks.\n *\n * @public\n * {@docCategory IComponentAs}\n */\nexport type IComponentAs<T> = React.ComponentType<IComponentAsProps<T>>;\n"]}
+9
View File
@@ -0,0 +1,9 @@
/**
* Disposable interface.
*
* @public
* {@docCategory IDisposable}
*/
export interface IDisposable {
dispose: () => void;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IDisposable.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IDisposable.js","sourceRoot":"../src/","sources":["IDisposable.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Disposable interface.\n *\n * @public\n * {@docCategory IDisposable}\n */\nexport interface IDisposable {\n dispose: () => void;\n}\n"]}
+14
View File
@@ -0,0 +1,14 @@
/**
* Rectangle interface.
*
* @public
* {@docCategory IRectangle}
*/
export interface IRectangle {
left: number;
top: number;
width: number;
height: number;
right?: number;
bottom?: number;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IRectangle.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IRectangle.js","sourceRoot":"../src/","sources":["IRectangle.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Rectangle interface.\n *\n * @public\n * {@docCategory IRectangle}\n */\nexport interface IRectangle {\n left: number;\n top: number;\n width: number;\n height: number;\n right?: number;\n bottom?: number;\n}\n"]}
+13
View File
@@ -0,0 +1,13 @@
import type { JSXElement } from './jsx';
/**
* An interface representing a component that will not output any DOM, will just render its children and
* pass through items to modify the children.
*
* {@docCategory IRenderComponent}
*/
export interface IRenderComponent<TProps> {
/**
* JSXElement to return in this component's render() function.
*/
children: (props: TProps) => JSXElement;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IRenderComponent.js.map
@@ -0,0 +1 @@
{"version":3,"file":"IRenderComponent.js","sourceRoot":"../src/","sources":["IRenderComponent.ts"],"names":[],"mappings":"","sourcesContent":["import type { JSXElement } from './jsx';\n\n/**\n * An interface representing a component that will not output any DOM, will just render its children and\n * pass through items to modify the children.\n *\n * {@docCategory IRenderComponent}\n */\nexport interface IRenderComponent<TProps> {\n /**\n * JSXElement to return in this component's render() function.\n */\n children: (props: TProps) => JSXElement;\n}\n"]}
+7
View File
@@ -0,0 +1,7 @@
import type { JSXElement } from './jsx';
/**
* Render function interface for providing overrideable render callbacks.
*
* @public
*/
export type IRenderFunction<P> = (props?: P, defaultRender?: (props?: P) => JSXElement | null) => JSXElement | null;
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IRenderFunction.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IRenderFunction.js","sourceRoot":"../src/","sources":["IRenderFunction.ts"],"names":[],"mappings":"","sourcesContent":["import type { JSXElement } from './jsx';\n\n/**\n * Render function interface for providing overrideable render callbacks.\n *\n * @public\n */\nexport type IRenderFunction<P> = (props?: P, defaultRender?: (props?: P) => JSXElement | null) => JSXElement | null;\n"]}
+7
View File
@@ -0,0 +1,7 @@
/**
* {@docCategory ISize}
*/
export interface ISize {
width: number;
height: number;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ISize.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ISize.js","sourceRoot":"../src/","sources":["ISize.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * {@docCategory ISize}\n */\nexport interface ISize {\n width: number;\n height: number;\n}\n"]}
+1
View File
@@ -0,0 +1 @@
export type { IStyleFunction } from '@fluentui/merge-styles';
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IStyleFunction.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"IStyleFunction.js","sourceRoot":"../src/","sources":["IStyleFunction.ts"],"names":[],"mappings":"","sourcesContent":["export type { IStyleFunction } from '@fluentui/merge-styles';\n"]}
+109
View File
@@ -0,0 +1,109 @@
/**
* Simulated enum for keycodes. These will get inlined by uglify when used much like an enum
*
* @public
* {@docCategory KeyCodes}
*/
export declare const KeyCodes: {
backspace: 8;
tab: 9;
enter: 13;
shift: 16;
ctrl: 17;
alt: 18;
pauseBreak: 19;
capslock: 20;
escape: 27;
space: 32;
pageUp: 33;
pageDown: 34;
end: 35;
home: 36;
left: 37;
up: 38;
right: 39;
down: 40;
insert: 45;
del: 46;
zero: 48;
one: 49;
two: 50;
three: 51;
four: 52;
five: 53;
six: 54;
seven: 55;
eight: 56;
nine: 57;
colon: 58;
a: 65;
b: 66;
c: 67;
d: 68;
e: 69;
f: 70;
g: 71;
h: 72;
i: 73;
j: 74;
k: 75;
l: 76;
m: 77;
n: 78;
o: 79;
p: 80;
q: 81;
r: 82;
s: 83;
t: 84;
u: 85;
v: 86;
w: 87;
x: 88;
y: 89;
z: 90;
leftWindow: 91;
rightWindow: 92;
select: 93;
zero_numpad: 96;
one_numpad: 97;
two_numpad: 98;
three_numpad: 99;
four_numpad: 100;
five_numpad: 101;
six_numpad: 102;
seven_numpad: 103;
eight_numpad: 104;
nine_numpad: 105;
multiply: 106;
add: 107;
subtract: 109;
decimalPoint: 110;
divide: 111;
f1: 112;
f2: 113;
f3: 114;
f4: 115;
f5: 116;
f6: 117;
f7: 118;
f8: 119;
f9: 120;
f10: 121;
f11: 122;
f12: 123;
numlock: 144;
scrollLock: 145;
semicolon: 186;
equalSign: 187;
comma: 188;
dash: 189;
period: 190;
forwardSlash: 191;
graveAccent: 192;
openBracket: 219;
backSlash: 220;
closeBracket: 221;
singleQuote: 222;
};
export type KeyCodes = number;
+114
View File
@@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.KeyCodes = void 0;
/**
* Simulated enum for keycodes. These will get inlined by uglify when used much like an enum
*
* @public
* {@docCategory KeyCodes}
*/
exports.KeyCodes = {
backspace: 8,
tab: 9,
enter: 13,
shift: 16,
ctrl: 17,
alt: 18,
pauseBreak: 19,
capslock: 20,
escape: 27,
space: 32,
pageUp: 33,
pageDown: 34,
end: 35,
home: 36,
left: 37,
up: 38,
right: 39,
down: 40,
insert: 45,
del: 46,
zero: 48,
one: 49,
two: 50,
three: 51,
four: 52,
five: 53,
six: 54,
seven: 55,
eight: 56,
nine: 57,
colon: 58,
a: 65,
b: 66,
c: 67,
d: 68,
e: 69,
f: 70,
g: 71,
h: 72,
i: 73,
j: 74,
k: 75,
l: 76,
m: 77,
n: 78,
o: 79,
p: 80,
q: 81,
r: 82,
s: 83,
t: 84,
u: 85,
v: 86,
w: 87,
x: 88,
y: 89,
z: 90,
leftWindow: 91,
rightWindow: 92,
select: 93,
/* eslint-disable @typescript-eslint/naming-convention */
zero_numpad: 96,
one_numpad: 97,
two_numpad: 98,
three_numpad: 99,
four_numpad: 100,
five_numpad: 101,
six_numpad: 102,
seven_numpad: 103,
eight_numpad: 104,
nine_numpad: 105,
/* eslint-enable @typescript-eslint/naming-convention */
multiply: 106,
add: 107,
subtract: 109,
decimalPoint: 110,
divide: 111,
f1: 112,
f2: 113,
f3: 114,
f4: 115,
f5: 116,
f6: 117,
f7: 118,
f8: 119,
f9: 120,
f10: 121,
f11: 122,
f12: 123,
numlock: 144,
scrollLock: 145,
semicolon: 186,
equalSign: 187,
comma: 188,
dash: 189,
period: 190,
forwardSlash: 191,
graveAccent: 192,
openBracket: 219,
backSlash: 220,
closeBracket: 221,
singleQuote: 222,
};
//# sourceMappingURL=KeyCodes.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"KeyCodes.js","sourceRoot":"../src/","sources":["KeyCodes.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACU,QAAA,QAAQ,GAAG;IACtB,SAAS,EAAE,CAAM;IACjB,GAAG,EAAE,CAAM;IACX,KAAK,EAAE,EAAQ;IACf,KAAK,EAAE,EAAQ;IACf,IAAI,EAAE,EAAQ;IACd,GAAG,EAAE,EAAQ;IACb,UAAU,EAAE,EAAQ;IACpB,QAAQ,EAAE,EAAQ;IAClB,MAAM,EAAE,EAAQ;IAChB,KAAK,EAAE,EAAQ;IACf,MAAM,EAAE,EAAQ;IAChB,QAAQ,EAAE,EAAQ;IAClB,GAAG,EAAE,EAAQ;IACb,IAAI,EAAE,EAAQ;IACd,IAAI,EAAE,EAAQ;IACd,EAAE,EAAE,EAAQ;IACZ,KAAK,EAAE,EAAQ;IACf,IAAI,EAAE,EAAQ;IACd,MAAM,EAAE,EAAQ;IAChB,GAAG,EAAE,EAAQ;IACb,IAAI,EAAE,EAAQ;IACd,GAAG,EAAE,EAAQ;IACb,GAAG,EAAE,EAAQ;IACb,KAAK,EAAE,EAAQ;IACf,IAAI,EAAE,EAAQ;IACd,IAAI,EAAE,EAAQ;IACd,GAAG,EAAE,EAAQ;IACb,KAAK,EAAE,EAAQ;IACf,KAAK,EAAE,EAAQ;IACf,IAAI,EAAE,EAAQ;IACd,KAAK,EAAE,EAAQ;IACf,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,CAAC,EAAE,EAAQ;IACX,UAAU,EAAE,EAAQ;IACpB,WAAW,EAAE,EAAQ;IACrB,MAAM,EAAE,EAAQ;IAChB,yDAAyD;IACzD,WAAW,EAAE,EAAQ;IACrB,UAAU,EAAE,EAAQ;IACpB,UAAU,EAAE,EAAQ;IACpB,YAAY,EAAE,EAAQ;IACtB,WAAW,EAAE,GAAU;IACvB,WAAW,EAAE,GAAU;IACvB,UAAU,EAAE,GAAU;IACtB,YAAY,EAAE,GAAU;IACxB,YAAY,EAAE,GAAU;IACxB,WAAW,EAAE,GAAU;IACvB,wDAAwD;IACxD,QAAQ,EAAE,GAAU;IACpB,GAAG,EAAE,GAAU;IACf,QAAQ,EAAE,GAAU;IACpB,YAAY,EAAE,GAAU;IACxB,MAAM,EAAE,GAAU;IAClB,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,EAAE,EAAE,GAAU;IACd,GAAG,EAAE,GAAU;IACf,GAAG,EAAE,GAAU;IACf,GAAG,EAAE,GAAU;IACf,OAAO,EAAE,GAAU;IACnB,UAAU,EAAE,GAAU;IACtB,SAAS,EAAE,GAAU;IACrB,SAAS,EAAE,GAAU;IACrB,KAAK,EAAE,GAAU;IACjB,IAAI,EAAE,GAAU;IAChB,MAAM,EAAE,GAAU;IAClB,YAAY,EAAE,GAAU;IACxB,WAAW,EAAE,GAAU;IACvB,WAAW,EAAE,GAAU;IACvB,SAAS,EAAE,GAAU;IACrB,YAAY,EAAE,GAAU;IACxB,WAAW,EAAE,GAAU;CACxB,CAAC","sourcesContent":["/**\n * Simulated enum for keycodes. These will get inlined by uglify when used much like an enum\n *\n * @public\n * {@docCategory KeyCodes}\n */\nexport const KeyCodes = {\n backspace: 8 as 8,\n tab: 9 as 9,\n enter: 13 as 13,\n shift: 16 as 16,\n ctrl: 17 as 17,\n alt: 18 as 18,\n pauseBreak: 19 as 19,\n capslock: 20 as 20,\n escape: 27 as 27,\n space: 32 as 32,\n pageUp: 33 as 33,\n pageDown: 34 as 34,\n end: 35 as 35,\n home: 36 as 36,\n left: 37 as 37,\n up: 38 as 38,\n right: 39 as 39,\n down: 40 as 40,\n insert: 45 as 45,\n del: 46 as 46,\n zero: 48 as 48,\n one: 49 as 49,\n two: 50 as 50,\n three: 51 as 51,\n four: 52 as 52,\n five: 53 as 53,\n six: 54 as 54,\n seven: 55 as 55,\n eight: 56 as 56,\n nine: 57 as 57,\n colon: 58 as 58,\n a: 65 as 65,\n b: 66 as 66,\n c: 67 as 67,\n d: 68 as 68,\n e: 69 as 69,\n f: 70 as 70,\n g: 71 as 71,\n h: 72 as 72,\n i: 73 as 73,\n j: 74 as 74,\n k: 75 as 75,\n l: 76 as 76,\n m: 77 as 77,\n n: 78 as 78,\n o: 79 as 79,\n p: 80 as 80,\n q: 81 as 81,\n r: 82 as 82,\n s: 83 as 83,\n t: 84 as 84,\n u: 85 as 85,\n v: 86 as 86,\n w: 87 as 87,\n x: 88 as 88,\n y: 89 as 89,\n z: 90 as 90,\n leftWindow: 91 as 91,\n rightWindow: 92 as 92,\n select: 93 as 93,\n /* eslint-disable @typescript-eslint/naming-convention */\n zero_numpad: 96 as 96,\n one_numpad: 97 as 97,\n two_numpad: 98 as 98,\n three_numpad: 99 as 99,\n four_numpad: 100 as 100,\n five_numpad: 101 as 101,\n six_numpad: 102 as 102,\n seven_numpad: 103 as 103,\n eight_numpad: 104 as 104,\n nine_numpad: 105 as 105,\n /* eslint-enable @typescript-eslint/naming-convention */\n multiply: 106 as 106,\n add: 107 as 107,\n subtract: 109 as 109,\n decimalPoint: 110 as 110,\n divide: 111 as 111,\n f1: 112 as 112,\n f2: 113 as 113,\n f3: 114 as 114,\n f4: 115 as 115,\n f5: 116 as 116,\n f6: 117 as 117,\n f7: 118 as 118,\n f8: 119 as 119,\n f9: 120 as 120,\n f10: 121 as 121,\n f11: 122 as 122,\n f12: 123 as 123,\n numlock: 144 as 144,\n scrollLock: 145 as 145,\n semicolon: 186 as 186,\n equalSign: 187 as 187,\n comma: 188 as 188,\n dash: 189 as 189,\n period: 190 as 190,\n forwardSlash: 191 as 191,\n graveAccent: 192 as 192,\n openBracket: 219 as 219,\n backSlash: 220 as 220,\n closeBracket: 221 as 221,\n singleQuote: 222 as 222,\n};\nexport type KeyCodes = number;\n"]}
+23
View File
@@ -0,0 +1,23 @@
/**
* Point interface.
*
* @public
* {@docCategory Point}
*/
export interface Point {
left?: number;
top?: number;
/** @deprecated Use `left` instead */
x?: number;
/** @deprecated Use `top` instead */
y?: number;
}
/**
* Point interface.
*
* @public
* @deprecated Use `Point` instead.
* {@docCategory Point}
*/
export interface IPoint extends Point {
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=Point.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Point.js","sourceRoot":"../src/","sources":["Point.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Point interface.\n *\n * @public\n * {@docCategory Point}\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport interface Point {\n left?: number;\n top?: number;\n /** @deprecated Use `left` instead */\n x?: number;\n /** @deprecated Use `top` instead */\n y?: number;\n}\n\n/**\n * Point interface.\n *\n * @public\n * @deprecated Use `Point` instead.\n * {@docCategory Point}\n */\nexport interface IPoint extends Point {}\n"]}
+6
View File
@@ -0,0 +1,6 @@
import * as React from 'react';
export interface IReactProps<T> {
children?: React.ReactNode | undefined;
key?: React.Key | undefined;
ref?: React.Ref<T> | undefined;
}
+3
View File
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=React.types.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"React.types.js","sourceRoot":"../src/","sources":["React.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\n\n// Mirror of the removed interface React.Props<T> since React 18\nexport interface IReactProps<T> {\n children?: React.ReactNode | undefined;\n key?: React.Key | undefined;\n ref?: React.Ref<T> | undefined;\n}\n"]}
+25
View File
@@ -0,0 +1,25 @@
/**
* Rectangle helper class.
*
* @public
* {@docCategory Rectangle}
*/
export declare class Rectangle {
top: number;
bottom: number;
left: number;
right: number;
constructor(left?: number, right?: number, top?: number, bottom?: number);
/**
* Calculated automatically by subtracting the right from left
*/
get width(): number;
/**
* Calculated automatically by subtracting the bottom from top.
*/
get height(): number;
/**
* Tests if another rect is approximately equal to this rect (within 4 decimal places.)
*/
equals(rect: Rectangle): boolean;
}
+55
View File
@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Rectangle = void 0;
/**
* Rectangle helper class.
*
* @public
* {@docCategory Rectangle}
*/
var Rectangle = /** @class */ (function () {
function Rectangle(left, right, top, bottom) {
if (left === void 0) { left = 0; }
if (right === void 0) { right = 0; }
if (top === void 0) { top = 0; }
if (bottom === void 0) { bottom = 0; }
this.top = top;
this.bottom = bottom;
this.left = left;
this.right = right;
}
Object.defineProperty(Rectangle.prototype, "width", {
/**
* Calculated automatically by subtracting the right from left
*/
get: function () {
return this.right - this.left;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "height", {
/**
* Calculated automatically by subtracting the bottom from top.
*/
get: function () {
return this.bottom - this.top;
},
enumerable: false,
configurable: true
});
/**
* Tests if another rect is approximately equal to this rect (within 4 decimal places.)
*/
Rectangle.prototype.equals = function (rect) {
// Fixing to 4 decimal places because it allows enough precision and will handle cases when something
// should be rounded, like .999999 should round to 1.
return (parseFloat(this.top.toFixed(4)) === parseFloat(rect.top.toFixed(4)) &&
parseFloat(this.bottom.toFixed(4)) === parseFloat(rect.bottom.toFixed(4)) &&
parseFloat(this.left.toFixed(4)) === parseFloat(rect.left.toFixed(4)) &&
parseFloat(this.right.toFixed(4)) === parseFloat(rect.right.toFixed(4)));
};
return Rectangle;
}());
exports.Rectangle = Rectangle;
//# sourceMappingURL=Rectangle.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Rectangle.js","sourceRoot":"../src/","sources":["Rectangle.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH;IAME,mBAAY,IAAgB,EAAE,KAAiB,EAAE,GAAe,EAAE,MAAkB;QAAxE,qBAAA,EAAA,QAAgB;QAAE,sBAAA,EAAA,SAAiB;QAAE,oBAAA,EAAA,OAAe;QAAE,uBAAA,EAAA,UAAkB;QAClF,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAKD,sBAAW,4BAAK;QAHhB;;WAEG;aACH;YACE,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAChC,CAAC;;;OAAA;IAKD,sBAAW,6BAAM;QAHjB;;WAEG;aACH;YACE,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC;QAChC,CAAC;;;OAAA;IAED;;OAEG;IACI,0BAAM,GAAb,UAAc,IAAe;QAC3B,qGAAqG;QACrG,qDAAqD;QACrD,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACnE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACzE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CACxE,CAAC;IACJ,CAAC;IACH,gBAAC;AAAD,CAAC,AAxCD,IAwCC;AAxCY,8BAAS","sourcesContent":["/**\n * Rectangle helper class.\n *\n * @public\n * {@docCategory Rectangle}\n */\nexport class Rectangle {\n public top: number;\n public bottom: number;\n public left: number;\n public right: number;\n\n constructor(left: number = 0, right: number = 0, top: number = 0, bottom: number = 0) {\n this.top = top;\n this.bottom = bottom;\n this.left = left;\n this.right = right;\n }\n\n /**\n * Calculated automatically by subtracting the right from left\n */\n public get width(): number {\n return this.right - this.left;\n }\n\n /**\n * Calculated automatically by subtracting the bottom from top.\n */\n public get height(): number {\n return this.bottom - this.top;\n }\n\n /**\n * Tests if another rect is approximately equal to this rect (within 4 decimal places.)\n */\n public equals(rect: Rectangle): boolean {\n // Fixing to 4 decimal places because it allows enough precision and will handle cases when something\n // should be rounded, like .999999 should round to 1.\n return (\n parseFloat(this.top.toFixed(4)) === parseFloat(rect.top.toFixed(4)) &&\n parseFloat(this.bottom.toFixed(4)) === parseFloat(rect.bottom.toFixed(4)) &&\n parseFloat(this.left.toFixed(4)) === parseFloat(rect.left.toFixed(4)) &&\n parseFloat(this.right.toFixed(4)) === parseFloat(rect.right.toFixed(4))\n );\n }\n}\n"]}
+5
View File
@@ -0,0 +1,5 @@
/**
* Returns a single function which will call each of the given functions in the context of the
* parent.
*/
export declare function appendFunction(parent: any, ...functions: any[]): () => void;
+25
View File
@@ -0,0 +1,25 @@
"use strict";
/* eslint-disable @typescript-eslint/no-explicit-any */
Object.defineProperty(exports, "__esModule", { value: true });
exports.appendFunction = appendFunction;
/**
* Returns a single function which will call each of the given functions in the context of the
* parent.
*/
function appendFunction(parent) {
var functions = [];
for (var _i = 1; _i < arguments.length; _i++) {
functions[_i - 1] = arguments[_i];
}
if (functions.length < 2) {
return functions[0];
}
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
functions.forEach(function (f) { return f && f.apply(parent, args); });
};
}
//# sourceMappingURL=appendFunction.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"appendFunction.js","sourceRoot":"../src/","sources":["appendFunction.ts"],"names":[],"mappings":";AAAA,uDAAuD;;AAMvD,wCAQC;AAZD;;;GAGG;AACH,SAAgB,cAAc,CAAC,MAAW;IAAE,mBAAmB;SAAnB,UAAmB,EAAnB,qBAAmB,EAAnB,IAAmB;QAAnB,kCAAmB;;IAC7D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC,CAAC,CAAe,CAAC;IACpC,CAAC;IAED,OAAO;QAAC,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACpB,SAAS,CAAC,OAAO,CAAC,UAAC,CAAa,IAAK,OAAA,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,EAA1B,CAA0B,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Returns a single function which will call each of the given functions in the context of the\n * parent.\n */\nexport function appendFunction(parent: any, ...functions: any[]): () => void {\n if (functions.length < 2) {\n return functions[0] as () => void;\n }\n\n return (...args: any[]): void => {\n functions.forEach((f: () => void) => f && f.apply(parent, args));\n };\n}\n"]}
@@ -0,0 +1 @@
export {};
+40
View File
@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var appendFunction_1 = require("./appendFunction");
describe('appendFunction', function () {
it('can append 2 functions', function () {
var counter = 0;
var function1 = function () { return counter++; };
var function2 = function () { return counter++; };
var function3 = (0, appendFunction_1.appendFunction)({}, function1, function2);
function3();
expect(counter).toEqual(2);
});
it('can deal with falsey values', function () {
var counter = 0;
var function1 = function () { return counter++; };
var function2 = function () { return counter++; };
var function3 = (0, appendFunction_1.appendFunction)({}, function1, undefined, null, function2);
function3();
expect(counter).toEqual(2);
});
it('preserves the parent', function () {
function add() {
this.counter++;
}
var Foo = /** @class */ (function () {
function Foo() {
this.counter = 0;
this.add = (0, appendFunction_1.appendFunction)(this, add, this.add);
}
Foo.prototype.add = function () {
this.counter++;
};
return Foo;
}());
var foo = new Foo();
foo.add();
expect(foo.counter).toEqual(2);
});
});
//# sourceMappingURL=appendFunction.test.js.map
@@ -0,0 +1 @@
{"version":3,"file":"appendFunction.test.js","sourceRoot":"../src/","sources":["appendFunction.test.ts"],"names":[],"mappings":";;AAAA,mDAAkD;AAElD,QAAQ,CAAC,gBAAgB,EAAE;IACzB,EAAE,CAAC,wBAAwB,EAAE;QAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAM,SAAS,GAAG,cAAM,OAAA,OAAO,EAAE,EAAT,CAAS,CAAC;QAClC,IAAM,SAAS,GAAG,cAAM,OAAA,OAAO,EAAE,EAAT,CAAS,CAAC;QAClC,IAAM,SAAS,GAAG,IAAA,+BAAc,EAAC,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAE3D,SAAS,EAAE,CAAC;QACZ,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE;QAChC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAM,SAAS,GAAG,cAAM,OAAA,OAAO,EAAE,EAAT,CAAS,CAAC;QAClC,IAAM,SAAS,GAAG,cAAM,OAAA,OAAO,EAAE,EAAT,CAAS,CAAC;QAClC,IAAM,SAAS,GAAG,IAAA,+BAAc,EAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAE5E,SAAS,EAAE,CAAC;QACZ,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE;QACzB,SAAS,GAAG;YACV,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;QAED;YAGE;gBAFO,YAAO,GAAG,CAAC,CAAC;gBAGjB,IAAI,CAAC,GAAG,GAAG,IAAA,+BAAc,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACjD,CAAC;YACM,iBAAG,GAAV;gBACE,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC;YACH,UAAC;QAAD,CAAC,AATD,IASC;QAED,IAAM,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,EAAE,CAAC;QAEV,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { appendFunction } from './appendFunction';\n\ndescribe('appendFunction', () => {\n it('can append 2 functions', () => {\n let counter = 0;\n const function1 = () => counter++;\n const function2 = () => counter++;\n const function3 = appendFunction({}, function1, function2);\n\n function3();\n expect(counter).toEqual(2);\n });\n\n it('can deal with falsey values', () => {\n let counter = 0;\n const function1 = () => counter++;\n const function2 = () => counter++;\n const function3 = appendFunction({}, function1, undefined, null, function2);\n\n function3();\n expect(counter).toEqual(2);\n });\n\n it('preserves the parent', () => {\n function add(this: { counter: number }): void {\n this.counter++;\n }\n\n class Foo {\n public counter = 0;\n\n constructor() {\n this.add = appendFunction(this, add, this.add);\n }\n public add(): void {\n this.counter++;\n }\n }\n\n const foo = new Foo();\n foo.add();\n\n expect(foo.counter).toEqual(2);\n });\n});\n"]}
+7
View File
@@ -0,0 +1,7 @@
/**
* ARIA helper to concatenate attributes, returning undefined if all attributes
* are undefined. (Empty strings are not a valid ARIA attribute value.)
*
* @param ariaAttributes - ARIA attributes to merge
*/
export declare function mergeAriaAttributeValues(...ariaAttributes: (string | undefined | false)[]): string | undefined;
+21
View File
@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeAriaAttributeValues = mergeAriaAttributeValues;
/**
* ARIA helper to concatenate attributes, returning undefined if all attributes
* are undefined. (Empty strings are not a valid ARIA attribute value.)
*
* @param ariaAttributes - ARIA attributes to merge
*/
function mergeAriaAttributeValues() {
var ariaAttributes = [];
for (var _i = 0; _i < arguments.length; _i++) {
ariaAttributes[_i] = arguments[_i];
}
var mergedAttribute = ariaAttributes
.filter(function (arg) { return arg; })
.join(' ')
.trim();
return mergedAttribute === '' ? undefined : mergedAttribute;
}
//# sourceMappingURL=aria.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"aria.js","sourceRoot":"../src/","sources":["aria.ts"],"names":[],"mappings":";;AAMA,4DAMC;AAZD;;;;;GAKG;AACH,SAAgB,wBAAwB;IAAC,wBAAiD;SAAjD,UAAiD,EAAjD,qBAAiD,EAAjD,IAAiD;QAAjD,mCAAiD;;IACxF,IAAM,eAAe,GAAG,cAAc;SACnC,MAAM,CAAC,UAAC,GAA+B,IAAK,OAAA,GAAG,EAAH,CAAG,CAAC;SAChD,IAAI,CAAC,GAAG,CAAC;SACT,IAAI,EAAE,CAAC;IACV,OAAO,eAAe,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC;AAC9D,CAAC","sourcesContent":["/**\n * ARIA helper to concatenate attributes, returning undefined if all attributes\n * are undefined. (Empty strings are not a valid ARIA attribute value.)\n *\n * @param ariaAttributes - ARIA attributes to merge\n */\nexport function mergeAriaAttributeValues(...ariaAttributes: (string | undefined | false)[]): string | undefined {\n const mergedAttribute = ariaAttributes\n .filter((arg: string | undefined | false) => arg)\n .join(' ')\n .trim();\n return mergedAttribute === '' ? undefined : mergedAttribute;\n}\n"]}
+1
View File
@@ -0,0 +1 @@
export {};
+102
View File
@@ -0,0 +1,102 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var aria_1 = require("./aria");
describe('aria utils tests', function () {
describe('mergeAriaAttributeValues tests', function () {
var mergeTestCases = [
{
description: 'returns undefined when given no args',
cases: [
{
args: [],
expected: undefined,
},
],
},
{
description: 'returns undefined when given undefined and empty args',
cases: [
{
args: [undefined],
expected: undefined,
},
{
args: [undefined, undefined],
expected: undefined,
},
{
args: [''],
expected: undefined,
},
{
args: [undefined, ''],
expected: undefined,
},
],
},
{
description: 'returns arg when given one valid arg',
cases: [
{
args: ['arg1'],
expected: 'arg1',
},
{
args: ['arg1', undefined],
expected: 'arg1',
},
{
args: [undefined, 'arg1', undefined],
expected: 'arg1',
},
{
args: ['', 'arg1', ''],
expected: 'arg1',
},
],
},
{
description: 'returns merged args when given multiple valid args',
cases: [
{
args: ['arg1', 'arg2'],
expected: 'arg1 arg2',
},
{
args: ['arg1', undefined],
expected: 'arg1',
},
{
args: [undefined, 'arg1', undefined],
expected: 'arg1',
},
{
args: ['', 'arg1', ''],
expected: 'arg1',
},
{
args: ['', 'arg1', 'arg2 '],
expected: 'arg1 arg2',
},
{
args: ['', ''],
expected: undefined,
},
{
args: [' ', ' '],
expected: undefined,
},
],
},
];
mergeTestCases.forEach(function (test) {
test.cases.forEach(function (testCase, index) {
it(test.description + ', case #' + index, function () {
var merged = aria_1.mergeAriaAttributeValues.apply(void 0, testCase.args);
expect(merged).toEqual(testCase.expected);
});
});
});
});
});
//# sourceMappingURL=aria.test.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"aria.test.js","sourceRoot":"../src/","sources":["aria.test.ts"],"names":[],"mappings":";;AAAA,+BAAkD;AAYlD,QAAQ,CAAC,kBAAkB,EAAE;IAC3B,QAAQ,CAAC,gCAAgC,EAAE;QACzC,IAAM,cAAc,GAAiB;YACnC;gBACE,WAAW,EAAE,sCAAsC;gBACnD,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,EAAE;wBACR,QAAQ,EAAE,SAAS;qBACpB;iBACF;aACF;YACD;gBACE,WAAW,EAAE,uDAAuD;gBACpE,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,CAAC,SAAS,CAAC;wBACjB,QAAQ,EAAE,SAAS;qBACpB;oBACD;wBACE,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;wBAC5B,QAAQ,EAAE,SAAS;qBACpB;oBACD;wBACE,IAAI,EAAE,CAAC,EAAE,CAAC;wBACV,QAAQ,EAAE,SAAS;qBACpB;oBACD;wBACE,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC;wBACrB,QAAQ,EAAE,SAAS;qBACpB;iBACF;aACF;YACD;gBACE,WAAW,EAAE,sCAAsC;gBACnD,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,CAAC,MAAM,CAAC;wBACd,QAAQ,EAAE,MAAM;qBACjB;oBACD;wBACE,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;wBACzB,QAAQ,EAAE,MAAM;qBACjB;oBACD;wBACE,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC;wBACpC,QAAQ,EAAE,MAAM;qBACjB;oBACD;wBACE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;wBACtB,QAAQ,EAAE,MAAM;qBACjB;iBACF;aACF;YACD;gBACE,WAAW,EAAE,oDAAoD;gBACjE,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;wBACtB,QAAQ,EAAE,WAAW;qBACtB;oBACD;wBACE,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;wBACzB,QAAQ,EAAE,MAAM;qBACjB;oBACD;wBACE,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC;wBACpC,QAAQ,EAAE,MAAM;qBACjB;oBACD;wBACE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;wBACtB,QAAQ,EAAE,MAAM;qBACjB;oBACD;wBACE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC;wBAC3B,QAAQ,EAAE,WAAW;qBACtB;oBACD;wBACE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;wBACd,QAAQ,EAAE,SAAS;qBACpB;oBACD;wBACE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;wBAChB,QAAQ,EAAE,SAAS;qBACpB;iBACF;aACF;SACF,CAAC;QAEF,cAAc,CAAC,OAAO,CAAC,UAAC,IAAgB;YACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAC,QAAwB,EAAE,KAAa;gBACzD,EAAE,CAAC,IAAI,CAAC,WAAW,GAAG,UAAU,GAAG,KAAK,EAAE;oBACxC,IAAM,MAAM,GAAG,+BAAwB,eAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { mergeAriaAttributeValues } from './aria';\n\ninterface IMergeTestCase {\n args: (string | undefined)[];\n expected: string | undefined;\n}\n\ninterface IMergeTest {\n description: string;\n cases: IMergeTestCase[];\n}\n\ndescribe('aria utils tests', () => {\n describe('mergeAriaAttributeValues tests', () => {\n const mergeTestCases: IMergeTest[] = [\n {\n description: 'returns undefined when given no args',\n cases: [\n {\n args: [],\n expected: undefined,\n },\n ],\n },\n {\n description: 'returns undefined when given undefined and empty args',\n cases: [\n {\n args: [undefined],\n expected: undefined,\n },\n {\n args: [undefined, undefined],\n expected: undefined,\n },\n {\n args: [''],\n expected: undefined,\n },\n {\n args: [undefined, ''],\n expected: undefined,\n },\n ],\n },\n {\n description: 'returns arg when given one valid arg',\n cases: [\n {\n args: ['arg1'],\n expected: 'arg1',\n },\n {\n args: ['arg1', undefined],\n expected: 'arg1',\n },\n {\n args: [undefined, 'arg1', undefined],\n expected: 'arg1',\n },\n {\n args: ['', 'arg1', ''],\n expected: 'arg1',\n },\n ],\n },\n {\n description: 'returns merged args when given multiple valid args',\n cases: [\n {\n args: ['arg1', 'arg2'],\n expected: 'arg1 arg2',\n },\n {\n args: ['arg1', undefined],\n expected: 'arg1',\n },\n {\n args: [undefined, 'arg1', undefined],\n expected: 'arg1',\n },\n {\n args: ['', 'arg1', ''],\n expected: 'arg1',\n },\n {\n args: ['', 'arg1', 'arg2 '],\n expected: 'arg1 arg2',\n },\n {\n args: ['', ''],\n expected: undefined,\n },\n {\n args: [' ', ' '],\n expected: undefined,\n },\n ],\n },\n ];\n\n mergeTestCases.forEach((test: IMergeTest) => {\n test.cases.forEach((testCase: IMergeTestCase, index: number) => {\n it(test.description + ', case #' + index, () => {\n const merged = mergeAriaAttributeValues(...testCase.args);\n expect(merged).toEqual(testCase.expected);\n });\n });\n });\n });\n});\n"]}
+67
View File
@@ -0,0 +1,67 @@
/**
* Helper to find the index of an item within an array, using a callback to
* determine the match.
*
* @public
* @param array - Array to search.
* @param cb - Callback which returns true on matches.
* @param fromIndex - Optional index to start from (defaults to 0)
*/
export declare function findIndex<T>(array: T[], cb: (item: T, index: number) => boolean, fromIndex?: number): number;
/**
* Helper to find the first item within an array that satisfies the callback.
* @param array - Array to search
* @param cb - Callback which returns true on matches
*/
export declare function find<T>(array: T[], cb: (item: T, index: number) => boolean): T | undefined;
/**
* Creates an array of a given size and helper method to populate.
*
* @public
* @param size - Size of array.
* @param getItem - Callback to populate given cell index.
*/
export declare function createArray<T>(size: number, getItem: (index: number) => T): T[];
/**
* Convert the given array to a matrix with columnCount number
* of columns.
*
* @public
* @param items - The array to convert
* @param columnCount - The number of columns for the resulting matrix
* @returns A matrix of items
*/
export declare function toMatrix<T>(items: T[], columnCount: number): T[][];
/**
* Given an array, it returns a new array that does not contain the item at the given index.
* @param array - The array to operate on
* @param index - The index of the element to remove
*/
export declare function removeIndex<T>(array: T[], index: number): T[];
/**
* Given an array, this function returns a new array where the element at a given index has been replaced.
* @param array - The array to operate on
* @param newElement - The element that will be placed in the new array
* @param index - The index of the element that should be replaced
*/
export declare function replaceElement<T>(array: T[], newElement: T, index: number): T[];
/**
* Given an array, this function returns a new array where an element has been inserted at the given index.
* @param array - The array to operate on
* @param index - The index where an element should be inserted
* @param itemToAdd - The element to insert
*/
export declare function addElementAtIndex<T>(array: T[], index: number, itemToAdd: T): T[];
/**
* Given an array where each element is of type T or T[], flatten it into an array of T
* @param array - The array where each element can optionally also be an array
*/
export declare function flatten<T>(array: (T | T[])[]): T[];
/**
* Returns a boolean indicating if the two given arrays are equal in length and values.
*
* @param array1 - First array to compare
* @param array2 - Second array to compare
* @returns True if the arrays are the same length and have the same values in the same positions, false otherwise.
*/
export declare function arraysEqual<T>(array1: T[], array2: T[]): boolean;
+135
View File
@@ -0,0 +1,135 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findIndex = findIndex;
exports.find = find;
exports.createArray = createArray;
exports.toMatrix = toMatrix;
exports.removeIndex = removeIndex;
exports.replaceElement = replaceElement;
exports.addElementAtIndex = addElementAtIndex;
exports.flatten = flatten;
exports.arraysEqual = arraysEqual;
/**
* Helper to find the index of an item within an array, using a callback to
* determine the match.
*
* @public
* @param array - Array to search.
* @param cb - Callback which returns true on matches.
* @param fromIndex - Optional index to start from (defaults to 0)
*/
function findIndex(array, cb, fromIndex) {
if (fromIndex === void 0) { fromIndex = 0; }
var index = -1;
for (var i = fromIndex; array && i < array.length; i++) {
if (cb(array[i], i)) {
index = i;
break;
}
}
return index;
}
/**
* Helper to find the first item within an array that satisfies the callback.
* @param array - Array to search
* @param cb - Callback which returns true on matches
*/
function find(array, cb) {
var index = findIndex(array, cb);
if (index < 0) {
return undefined;
}
return array[index];
}
/**
* Creates an array of a given size and helper method to populate.
*
* @public
* @param size - Size of array.
* @param getItem - Callback to populate given cell index.
*/
function createArray(size, getItem) {
var array = [];
for (var i = 0; i < size; i++) {
array.push(getItem(i));
}
return array;
}
/**
* Convert the given array to a matrix with columnCount number
* of columns.
*
* @public
* @param items - The array to convert
* @param columnCount - The number of columns for the resulting matrix
* @returns A matrix of items
*/
function toMatrix(items, columnCount) {
return items.reduce(function (rows, currentValue, index) {
if (index % columnCount === 0) {
rows.push([currentValue]);
}
else {
rows[rows.length - 1].push(currentValue);
}
return rows;
}, []);
}
/**
* Given an array, it returns a new array that does not contain the item at the given index.
* @param array - The array to operate on
* @param index - The index of the element to remove
*/
function removeIndex(array, index) {
return array.filter(function (_, i) { return index !== i; });
}
/**
* Given an array, this function returns a new array where the element at a given index has been replaced.
* @param array - The array to operate on
* @param newElement - The element that will be placed in the new array
* @param index - The index of the element that should be replaced
*/
function replaceElement(array, newElement, index) {
var copy = array.slice();
copy[index] = newElement;
return copy;
}
/**
* Given an array, this function returns a new array where an element has been inserted at the given index.
* @param array - The array to operate on
* @param index - The index where an element should be inserted
* @param itemToAdd - The element to insert
*/
function addElementAtIndex(array, index, itemToAdd) {
var copy = array.slice();
copy.splice(index, 0, itemToAdd);
return copy;
}
/**
* Given an array where each element is of type T or T[], flatten it into an array of T
* @param array - The array where each element can optionally also be an array
*/
function flatten(array) {
var result = [];
array.forEach(function (item) { return (result = result.concat(item)); });
return result;
}
/**
* Returns a boolean indicating if the two given arrays are equal in length and values.
*
* @param array1 - First array to compare
* @param array2 - Second array to compare
* @returns True if the arrays are the same length and have the same values in the same positions, false otherwise.
*/
function arraysEqual(array1, array2) {
if (array1.length !== array2.length) {
return false;
}
for (var i = 0; i < array1.length; i++) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
}
//# sourceMappingURL=array.js.map
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export {};
+157
View File
@@ -0,0 +1,157 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var array_1 = require("./array");
describe('array utils tests', function () {
describe('findIndex tests', function () {
it('returns -1 when there is no match in the array', function () {
var array = [0, 1, 2];
var index = (0, array_1.findIndex)(array, function () { return false; });
expect(index).toEqual(-1);
});
it('should return the correct index when the predicate satisfies the condition', function () {
var array = [0, 1, 2];
var index = (0, array_1.findIndex)(array, function (elem) { return elem === 1; });
expect(index).toEqual(1);
});
it('should return the first index when repeated elements satisfy the predicate', function () {
var array = [0, 1, 2, 2];
var index = (0, array_1.findIndex)(array, function (elem) { return elem === 2; });
expect(index).toEqual(2);
});
});
describe('find tests', function () {
it('returns -1 when there is no match in the array', function () {
var array = [0, 1, 2];
var item = (0, array_1.find)(array, function () { return false; });
expect(item).toEqual(undefined);
});
it('should return the correct item when the predicate satisfies the condition', function () {
var array = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }];
var item = (0, array_1.find)(array, function (elem) { return elem.id === 1; });
expect(item).toEqual(array[1]);
});
it('should return the first index when repeated elements satisfy the predicate', function () {
var array = [8, 9, 10, 11];
var item = (0, array_1.find)(array, function (elem) { return elem === 10; });
expect(item).toEqual(10);
});
});
describe('createArray tests', function () {
it('creates an array while invoking the callback', function () {
var result = (0, array_1.createArray)(4, function (index) { return String.fromCharCode('a'.charCodeAt(0) + index); });
expect(result).toEqual(['a', 'b', 'c', 'd']);
});
});
describe('removeIndex tests', function () {
it('should return a new array instead of mutating the existing array', function () {
var array = [0, 1, 2];
var result = (0, array_1.removeIndex)(array, 0);
expect(result).not.toBe(array);
});
it('should remove the first element of the array', function () {
var array = [0, 1, 2];
var result = (0, array_1.removeIndex)(array, 0);
expect(result).toEqual([1, 2]);
});
it('should remove the last element of the array', function () {
var array = [0, 1, 2];
var result = (0, array_1.removeIndex)(array, 2);
expect(result).toEqual([0, 1]);
});
it('should remove the element in the middle of the array', function () {
var array = [0, 1, 2];
var result = (0, array_1.removeIndex)(array, 1);
expect(result).toEqual([0, 2]);
});
});
describe('replaceElement tests', function () {
it('should return a new array instead of mutating the existing array', function () {
var array = [1, 2, 3];
var result = (0, array_1.replaceElement)(array, 3, 1);
expect(result).toEqual([1, 3, 3]);
expect(result).not.toBe(array);
});
it('should return a new array with the replaced element in the center', function () {
var array = ['Zero', 'One', 'Two', 'Three', 'Four'];
var result = (0, array_1.replaceElement)(array, 'owT', 2);
expect(result).toEqual(['Zero', 'One', 'owT', 'Three', 'Four']);
});
it('should return a new array with the first element replaced', function () {
var array = ['Zero', 'One', 'Two', 'Three', 'Four'];
var result = (0, array_1.replaceElement)(array, 'oreZ', 0);
expect(result).toEqual(['oreZ', 'One', 'Two', 'Three', 'Four']);
});
it('should return a new array with the last element replaced', function () {
var array = ['Zero', 'One', 'Two', 'Three', 'Four'];
var result = (0, array_1.replaceElement)(array, 'ruoF', 4);
expect(result).toEqual(['Zero', 'One', 'Two', 'Three', 'ruoF']);
});
});
describe('addElementAddIndex tests', function () {
it('should add an element at the start of the array', function () {
var array = [2, 3, 4];
var result = (0, array_1.addElementAtIndex)(array, 0, 1);
expect(result).toEqual([1, 2, 3, 4]);
});
it('should add an element at the end of the array', function () {
var array = [2, 3, 4];
var result = (0, array_1.addElementAtIndex)(array, 3, 5);
expect(result).toEqual([2, 3, 4, 5]);
});
it('should add the element in the middle of the array', function () {
var array = [2, 3, 4];
var result = (0, array_1.addElementAtIndex)(array, 2, 3.5);
expect(result).toEqual([2, 3, 3.5, 4]);
});
});
describe('flatten tests', function () {
it('does nothing for an empty array', function () {
var array = [];
var result = (0, array_1.flatten)(array);
expect(result).toEqual(array);
});
it('does nothing an array with a single element', function () {
var array = [1];
var result = (0, array_1.flatten)(array);
expect(result).toEqual(array);
});
it('does nothing for an array of numbers', function () {
var array = [1, 2, 3];
var result = (0, array_1.flatten)(array);
expect(result).toEqual(array);
});
it('flattens an array of arrays', function () {
var array = [[1, 2, 3], [4, 6, 8], [20]];
var result = (0, array_1.flatten)(array);
expect(result).toEqual([1, 2, 3, 4, 6, 8, 20]);
});
it('flattens an array with numbers and arrays of numbers', function () {
var array = [[1, 2, 3], [4, 6, 8], 20, 22, [25, 26, 28]];
var result = (0, array_1.flatten)(array);
expect(result).toEqual([1, 2, 3, 4, 6, 8, 20, 22, 25, 26, 28]);
});
});
describe('arraysEqual tests', function () {
it('two empty arrays are equal', function () {
var arr1 = [];
var arr2 = [];
expect((0, array_1.arraysEqual)(arr1, arr2)).toEqual(true);
});
it('different length arrays are not equal', function () {
var arr1 = [1, 2];
var arr2 = [1];
expect((0, array_1.arraysEqual)(arr1, arr2)).toEqual(false);
});
it('different value arrays are not equal', function () {
var arr1 = [1, 2];
var arr2 = [1, 3];
expect((0, array_1.arraysEqual)(arr1, arr2)).toEqual(false);
});
it('two exact arrays are equal', function () {
var arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];
expect((0, array_1.arraysEqual)(arr1, arr2)).toEqual(true);
});
});
});
//# sourceMappingURL=array.test.js.map
File diff suppressed because one or more lines are too long
+38
View File
@@ -0,0 +1,38 @@
/**
* asAsync - a HOC for async loading components.
*
* Usage:
*
* const AsyncDialog = asAsync({
* load: () => import('Dialog').then(result => result.default),
* });
*
* React.render(domElement, <AsyncDialog asyncPlaceholder={ () => <Spinner/> } { ...dialogProps } />);
*
* Note the `asyncPlaceholder` prop will be respected when rendering the async component and it hasn't
* been loaded yet.
*/
import * as React from 'react';
export interface IAsAsyncOptions<TProps> {
/**
* Callback which returns a promise resolving an object which exports the component.
*/
load: () => Promise<React.ElementType<TProps>>;
/**
* Callback executed when async loading is complete.
*/
onLoad?: () => void;
/**
* Callback when async loading fails.
*/
onError?: (error: Error) => void;
}
/**
* Produces a component which internally loads the target component before first mount.
* The component passes all props through to the loaded component.
*
* This overload accepts a module with a default export for the component.
*/
export declare function asAsync<TProps extends {}>(options: IAsAsyncOptions<TProps>): React.ForwardRefExoticComponent<React.PropsWithoutRef<TProps & {
asyncPlaceholder?: React.ElementType | undefined;
}> & React.RefAttributes<React.ElementType<TProps>>>;
+75
View File
@@ -0,0 +1,75 @@
"use strict";
/**
* asAsync - a HOC for async loading components.
*
* Usage:
*
* const AsyncDialog = asAsync({
* load: () => import('Dialog').then(result => result.default),
* });
*
* React.render(domElement, <AsyncDialog asyncPlaceholder={ () => <Spinner/> } { ...dialogProps } />);
*
* Note the `asyncPlaceholder` prop will be respected when rendering the async component and it hasn't
* been loaded yet.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.asAsync = asAsync;
var tslib_1 = require("tslib");
var React = require("react");
/**
* If possible, use a WeakMap to maintain a cache of loaded components.
* This can be used to synchronously render components that have already been loaded,
* rather than having to wait for at least one async tick.
*/
var _syncModuleCache = typeof WeakMap !== 'undefined'
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
new WeakMap()
: undefined;
/**
* Produces a component which internally loads the target component before first mount.
* The component passes all props through to the loaded component.
*
* This overload accepts a module with a default export for the component.
*/
function asAsync(options) {
var Async = /** @class */ (function (_super) {
tslib_1.__extends(Async, _super);
function Async() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
Component: _syncModuleCache ? _syncModuleCache.get(options.load) : undefined,
};
return _this;
}
Async.prototype.render = function () {
// Typescript issue: the rest can't be pulled without the any cast, as TypeScript fails with rest on generics.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var _a = this.props, forwardedRef = _a.forwardedRef, Placeholder = _a.asyncPlaceholder, rest = tslib_1.__rest(_a, ["forwardedRef", "asyncPlaceholder"]);
var Component = this.state.Component;
return Component ? (React.createElement(Component, tslib_1.__assign(tslib_1.__assign({}, rest), { ref: forwardedRef }))) : Placeholder ? (React.createElement(Placeholder, null)) : null;
};
Async.prototype.componentDidMount = function () {
var _this = this;
var Component = this.state.Component;
if (!Component) {
options
.load()
.then(function (LoadedComponent) {
if (LoadedComponent) {
// Cache component for future reference.
_syncModuleCache && _syncModuleCache.set(options.load, LoadedComponent);
// Set state.
_this.setState({
Component: LoadedComponent,
}, options.onLoad);
}
})
.catch(options.onError);
}
};
return Async;
}(React.Component));
return React.forwardRef(function (props, ref) { return React.createElement(Async, tslib_1.__assign({}, props, { forwardedRef: ref })); });
}
//# sourceMappingURL=asAsync.js.map
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export {};
+100
View File
@@ -0,0 +1,100 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var React = require("react");
var asAsync_1 = require("./asAsync");
var react_1 = require("@testing-library/react");
describe('asAsync', function () {
it('can async load exports', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var _resolve, _loadCalled, loadThingPromise, AsyncThing, _a, container, unmount;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_resolve = function () { return undefined; };
_loadCalled = false;
loadThingPromise = new Promise(function (resolve) {
_resolve = resolve;
});
AsyncThing = (0, asAsync_1.asAsync)({
load: function () {
_loadCalled = true;
return loadThingPromise;
},
});
_a = (0, react_1.render)(React.createElement(AsyncThing, null)), container = _a.container, unmount = _a.unmount;
expect(_loadCalled).toBe(true);
expect(container).toBeEmptyDOMElement();
expect(_resolve).toBeTruthy();
return [4 /*yield*/, (0, react_1.act)(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_resolve(function () { return React.createElement("div", null, "thing"); });
// allow microtasks to flush
return [4 /*yield*/, Promise.resolve()];
case 1:
// allow microtasks to flush
_a.sent();
return [2 /*return*/];
}
});
}); })];
case 1:
_b.sent();
return [4 /*yield*/, (0, react_1.waitFor)(function () { return expect(container.firstChild).toHaveTextContent('thing'); })];
case 2:
_b.sent();
_loadCalled = false;
// Test cached case.
(0, react_1.render)(React.createElement(AsyncThing, null));
expect(_loadCalled).toBe(false);
expect(container.firstChild).toHaveTextContent('thing');
unmount();
return [2 /*return*/];
}
});
}); });
it('can async load with placeholder', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var _resolve, _loadCalled, loadThingPromise, AsyncThing, _a, container, unmount;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_resolve = function () { return undefined; };
_loadCalled = false;
loadThingPromise = new Promise(function (resolve) {
_resolve = resolve;
});
AsyncThing = (0, asAsync_1.asAsync)({
load: function () {
_loadCalled = true;
return loadThingPromise;
},
});
_a = (0, react_1.render)(React.createElement(AsyncThing, { asyncPlaceholder: function () { return React.createElement("div", null, "placeholder"); } })), container = _a.container, unmount = _a.unmount;
expect(_loadCalled).toBe(true);
expect(container).toHaveTextContent('placeholder');
expect(_resolve).toBeTruthy();
return [4 /*yield*/, (0, react_1.act)(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
_resolve(function () { return React.createElement("div", null, "thing"); });
return [4 /*yield*/, Promise.resolve()];
case 1:
_a.sent();
return [2 /*return*/];
}
});
}); })];
case 1:
_b.sent();
return [4 /*yield*/, (0, react_1.waitFor)(function () { return expect(container.firstChild).toHaveTextContent('thing'); })];
case 2:
_b.sent();
unmount();
return [2 /*return*/];
}
});
}); });
});
//# sourceMappingURL=asAsync.test.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"asAsync.test.js","sourceRoot":"../src/","sources":["asAsync.test.tsx"],"names":[],"mappings":";;;AAAA,6BAA+B;AAC/B,qCAAoC;AACpC,gDAA8D;AAE9D,QAAQ,CAAC,SAAS,EAAE;IAClB,EAAE,CAAC,wBAAwB,EAAE;;;;;oBACvB,QAAQ,GAA4C,cAAM,OAAA,SAAS,EAAT,CAAS,CAAC;oBACpE,WAAW,GAAG,KAAK,CAAC;oBAElB,gBAAgB,GAAG,IAAI,OAAO,CAAM,UAAC,OAAY;wBACrD,QAAQ,GAAG,OAAO,CAAC;oBACrB,CAAC,CAAC,CAAC;oBAEG,UAAU,GAAG,IAAA,iBAAO,EAAC;wBACzB,IAAI,EAAE;4BACJ,WAAW,GAAG,IAAI,CAAC;4BACnB,OAAO,gBAAgB,CAAC;wBAC1B,CAAC;qBACF,CAAC,CAAC;oBACG,KAAyB,IAAA,cAAM,EAAC,oBAAC,UAAU,OAAG,CAAC,EAA7C,SAAS,eAAA,EAAE,OAAO,aAAA,CAA4B;oBAEtD,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC/B,MAAM,CAAC,SAAS,CAAC,CAAC,mBAAmB,EAAE,CAAC;oBACxC,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;oBAE9B,qBAAM,IAAA,WAAG,EAAC;;;;wCACR,QAAQ,CAAC,cAAM,OAAA,yCAAgB,EAAhB,CAAgB,CAAC,CAAC;wCACjC,4BAA4B;wCAC5B,qBAAM,OAAO,CAAC,OAAO,EAAE,EAAA;;wCADvB,4BAA4B;wCAC5B,SAAuB,CAAC;;;;6BACzB,CAAC,EAAA;;oBAJF,SAIE,CAAC;oBAEH,qBAAM,IAAA,eAAO,EAAC,cAAM,OAAA,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAvD,CAAuD,CAAC,EAAA;;oBAA5E,SAA4E,CAAC;oBAC7E,WAAW,GAAG,KAAK,CAAC;oBAEpB,oBAAoB;oBACpB,IAAA,cAAM,EAAC,oBAAC,UAAU,OAAG,CAAC,CAAC;oBACvB,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAChC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;oBACxD,OAAO,EAAE,CAAC;;;;SACX,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE;;;;;oBAChC,QAAQ,GAA4C,cAAM,OAAA,SAAS,EAAT,CAAS,CAAC;oBACpE,WAAW,GAAG,KAAK,CAAC;oBAElB,gBAAgB,GAAG,IAAI,OAAO,CAAM,UAAC,OAAY;wBACrD,QAAQ,GAAG,OAAO,CAAC;oBACrB,CAAC,CAAC,CAAC;oBAEG,UAAU,GAAG,IAAA,iBAAO,EAAC;wBACzB,IAAI,EAAE;4BACJ,WAAW,GAAG,IAAI,CAAC;4BACnB,OAAO,gBAAgB,CAAC;wBAC1B,CAAC;qBACF,CAAC,CAAC;oBACG,KAAyB,IAAA,cAAM,EAAC,oBAAC,UAAU,IAAC,gBAAgB,EAAE,cAAM,OAAA,+CAAsB,EAAtB,CAAsB,GAAI,CAAC,EAA7F,SAAS,eAAA,EAAE,OAAO,aAAA,CAA4E;oBAEtG,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC/B,MAAM,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;oBACnD,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;oBAE9B,qBAAM,IAAA,WAAG,EAAC;;;;wCACR,QAAQ,CAAC,cAAM,OAAA,yCAAgB,EAAhB,CAAgB,CAAC,CAAC;wCACjC,qBAAM,OAAO,CAAC,OAAO,EAAE,EAAA;;wCAAvB,SAAuB,CAAC;;;;6BACzB,CAAC,EAAA;;oBAHF,SAGE,CAAC;oBAEH,qBAAM,IAAA,eAAO,EAAC,cAAM,OAAA,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAvD,CAAuD,CAAC,EAAA;;oBAA5E,SAA4E,CAAC;oBAC7E,OAAO,EAAE,CAAC;;;;SACX,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { asAsync } from './asAsync';\nimport { act, render, waitFor } from '@testing-library/react';\n\ndescribe('asAsync', () => {\n it('can async load exports', async () => {\n let _resolve: (result: React.ElementType<{}>) => void = () => undefined;\n let _loadCalled = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const loadThingPromise = new Promise<any>((resolve: any) => {\n _resolve = resolve;\n });\n\n const AsyncThing = asAsync({\n load: () => {\n _loadCalled = true;\n return loadThingPromise;\n },\n });\n const { container, unmount } = render(<AsyncThing />);\n\n expect(_loadCalled).toBe(true);\n expect(container).toBeEmptyDOMElement();\n expect(_resolve).toBeTruthy();\n\n await act(async () => {\n _resolve(() => <div>thing</div>);\n // allow microtasks to flush\n await Promise.resolve();\n });\n\n await waitFor(() => expect(container.firstChild).toHaveTextContent('thing'));\n _loadCalled = false;\n\n // Test cached case.\n render(<AsyncThing />);\n expect(_loadCalled).toBe(false);\n expect(container.firstChild).toHaveTextContent('thing');\n unmount();\n });\n\n it('can async load with placeholder', async () => {\n let _resolve: (result: React.ElementType<{}>) => void = () => undefined;\n let _loadCalled = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const loadThingPromise = new Promise<any>((resolve: any) => {\n _resolve = resolve;\n });\n\n const AsyncThing = asAsync({\n load: () => {\n _loadCalled = true;\n return loadThingPromise;\n },\n });\n const { container, unmount } = render(<AsyncThing asyncPlaceholder={() => <div>placeholder</div>} />);\n\n expect(_loadCalled).toBe(true);\n expect(container).toHaveTextContent('placeholder');\n expect(_resolve).toBeTruthy();\n\n await act(async () => {\n _resolve(() => <div>thing</div>);\n await Promise.resolve();\n });\n\n await waitFor(() => expect(container.firstChild).toHaveTextContent('thing'));\n unmount();\n });\n});\n"]}
+6
View File
@@ -0,0 +1,6 @@
/**
* AssertNever is a utility function that can be used for exhaustiveness checks in switch statements.
*
* @public
*/
export declare function assertNever(x: never): never;
+12
View File
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.assertNever = assertNever;
/**
* AssertNever is a utility function that can be used for exhaustiveness checks in switch statements.
*
* @public
*/
function assertNever(x) {
throw new Error('Unexpected object: ' + x);
}
//# sourceMappingURL=assertNever.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"assertNever.js","sourceRoot":"../src/","sources":["assertNever.ts"],"names":[],"mappings":";;AAKA,kCAEC;AAPD;;;;GAIG;AACH,SAAgB,WAAW,CAAC,CAAQ;IAClC,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["/**\n * AssertNever is a utility function that can be used for exhaustiveness checks in switch statements.\n *\n * @public\n */\nexport function assertNever(x: never): never {\n throw new Error('Unexpected object: ' + x);\n}\n"]}
+24
View File
@@ -0,0 +1,24 @@
import type { IStyleSetBase, IProcessedStyleSet, IStyleFunctionOrObject } from '@fluentui/merge-styles';
export interface IClassNamesFunctionOptions {
/**
* Disables class caching for scenarios where styleProp parts mutate frequently.
*/
disableCaching?: boolean;
/**
* Size of the cache. It overwrites default cache size when defined.
*/
cacheSize?: number;
/**
* Set to true if component base styles are implemented in scss instead of css-in-js.
*/
useStaticStyles?: boolean;
}
/**
* Creates a getClassNames function which calls getStyles given the props, and injects them
* into mergeStyleSets.
*
* Note that the props you pass in on every render should be in the same order and
* immutable (numbers, strings, and booleans). This will allow the results to be memoized. Violating
* these will cause extra recalcs to occur.
*/
export declare function classNamesFunction<TStyleProps extends {}, TStyleSet extends IStyleSetBase>(options?: IClassNamesFunctionOptions): (getStyles: IStyleFunctionOrObject<TStyleProps, TStyleSet> | undefined, styleProps?: TStyleProps) => IProcessedStyleSet<TStyleSet>;

Some files were not shown because too many files have changed in this diff Show More