@uiloos/core
Version:
The core of the uiloos headless UI
1,622 lines (1,618 loc) • 256 kB
TypeScript
/**
* A function which when called will unsubscribe from the observable.
*
* @since 1.0.0
*/
type UnsubscribeFunction = () => void;
/**
* The interface each component of uiloos/core implements so it
* can be subscribed to.
*
* Note: there is no reason to ever implement the `Observable`
* interface yourself. It is only exposed so bindings to frameworks
* can use the type.
*
* @since 1.4.0
*/
interface Observable<T, E> {
/**
* Subscribe to changes of the Observable. The function you provide
* will get called whenever changes occur in the Observable.
*
* Returns an unsubscribe function which when called will
* unsubscribe from the Observable.
*
* @param {Subscriber<T, E>} subscriber The subscriber which responds to changes in the Observable.
* @returns {UnsubscribeFunction} A function which when called will unsubscribe from the Observable.
*
* @since 1.4.0
*/
subscribe(subscriber: Subscriber<T, E>): UnsubscribeFunction;
}
/**
* A function which when called will subscribe to the observable.
*
* @since 1.4.0
*/
type Subscriber<T, E> = (observerable: T, event: E) => void;
/**
* Checks / validates the license for "uiloos".
*
* Note: you are not supposed to use this class directly. Use the
* variable `licenseChecker` instead.
*
* @since 1.0.0
*/
declare class _LicenseChecker {
private _licenseKey;
private _logOnSuccess;
private _success;
/**
* With `activateLicense` you can set activate your license key for
* uiloos. Make sure that you set your license key before using any
* functionality that uiloos provides.
*
* You can purchase a license at https://www.uiloos.dev.
*
* @param {string} licenseKey The license key of uiloos you want to activate.
* @param {ActivateLicenseOptions} options The optional options for the `activateLicense` function, can be used to suppress the "license activated" message.
* @since 1.0.0
*/
activateLicense(licenseKey: string, options?: ActivateLicenseOptions): void;
/**
* Checks the current license to see if it is valid.
*
* Note: this method is for internal use inside uiloos only.
*
* @since 1.0.0
*/
_checkLicense(): void;
}
/**
* The sole instance (a singleton) of the `_LicenseChecker` class.
*
* Use this instance of `_LicenseChecker` to call `activateLicense` to
* activate your license.
*
* @see _LicenseChecker
* @since 1.0.0
*
* @example
*
* Activating license
*
* You activate the license by calling "activateLicense" on the
* "licenseChecker" instance.
*
* ```js
* import { licenseChecker } from '@uiloos/core';
* licenseChecker.activateLicense("{LICENSE-HERE}");
* ```
*/
declare let licenseChecker: _LicenseChecker;
/**
* The options for the `activateLicense` functions. Can be used
* to silence the "license activated" message.
*
* @since 1.0.0
*/
type ActivateLicenseOptions = {
/**
* Whether or not to silence the "license activated" message
* when the license is valid.
*
* @since 1.0.0
*/
logLicenseActivated: boolean;
};
/**
* Configures the initial state of the `ActiveList`
*
* @since 1.0.0
*/
type ActiveListConfig<T> = {
/**
* The contents which you want to display, can be an array of anything
* you want.
*
* Note: the `ActiveList` will wrap each item in the `contents` array
* inside of a `ActiveListContent` item.
*
* Defaults to `[]` meaning there is no content.
*
* @since 1.0.0
*/
contents?: T[];
/**
* How many items can be active at the same time.
*
* When the value of `limit` is `false` there is no limit to the
* number of active items.
*
* Defaults to `1`.
*
* @since 1.0.0
*/
maxActivationLimit?: number | false;
/**
* How the limit is enforced. In other words what the behavior
* should be when the limit is surpassed.
*
* The modes are strings which can be the following values:
*
* 1. 'circular': the first item which was added will be removed so
* the last item can be added without violating the limit. This
* basically means that the first one in is the first one out.
*
* 2. 'error': An error is thrown whenever the limit is surpassed,
* the error is called the `ActiveListActivationLimitReachedError`.
*
* 3. 'ignore': Nothing happens when an item is added and the limit
* is reached. The item is simply not added, but no error is
* thrown.
*
* Defaults to 'circular'.
*
* @since 1.0.0
*/
maxActivationLimitBehavior?: ActiveListMaxActivationLimitBehavior;
/**
* Which item or items in the content array are currently active.
*
* When the `active` is an array each item in the array is activated
* from left to right one at a time.
*
* Note: "active" is chosen over the "activeIndexes" property.
*
* Defaults to `[]` meaning no content is active.
*
* @since 1.0.0
*/
active?: T | T[];
/**
* Which index or indexes of the content array are currently active.
*
* When the `activeIndexes` is an array each index in the array
* is activated from left to right one at a time.
*
* Note: "active" is chosen over the "activeIndexes" property.
*
* Defaults to `[]` meaning no content is active.
*
* @since 1.0.0
*/
activeIndexes?: number | number[];
/**
* Whether or not the content starts back at the beginning when
* the end of the content is reached, and whether the content should
* go to the end when moving left of the start.
*
* Defaults to `true`.
*
* @since 1.0.0
*/
isCircular?: boolean;
/**
* Whether or not `autoPlay` is enabled. When `autoPlay` is enabled
* it will automatically move to the next content, based on the
* `duration`.
*
* When `isCircular` is `true` content will move to the right
* indefinitely. When `isCircular` is `false` it will stop autoPlay
* at the end of the content.
*
* Note: autoPlay will only start when one or more contents are
* currently active. The reason for this is that the `duration`, is
* based on the `ActiveList` `lastActivatedContent` property.
* Whenever there are no more items to activate the autoPlay will
* stop.
*
* Defaults to no autoPlay.
*
* @since 1.0.0
*/
autoPlay?: ActiveListAutoPlayConfig<T>;
/**
* Describes which strings should be associated with what
* direction, will be the value of the `ActiveList` property
* `direction`.
*
* So when setting the direction `next` to "up"` and the content
* moves up, the `ActiveList.direction` will be "up". Useful when
* wanting to apply CSS classes based on the direction.
*
* Defaults to `{ next: 'right', previous: 'left' }`.
*
* @since 1.0.0
*/
directions?: ActiveListDirection;
/**
* For how many items the `history` may contain in the `ActiveList`.
*
* Defaults to `0` meaning that it will not track history.
*
* @since 1.0.0
*/
keepHistoryFor?: number;
/**
* The `cooldown` is the number of milliseconds before another
* activation / deactivation is allowed. For example if the
* `cooldown` is `5000` the `ActiveList` will not allow
* transitions until after 5 seconds have passed. Any activation /
* deactivation in that period will simply be ignored.
*
* This can be useful when you have an animation which should be
* finished before allowing user interaction again.
*
* This global `cooldown` is the same for all transitions you might trigger.
* If you want a `cooldown` that differs per button use the `cooldown`
* in the `ActiveListActivationOptions` instead.
*
* Note that the `cooldown` options with the `ActiveListActivationOptions` takes
* precedence over this more global cooldown.
*
* IMPORTANT: `cooldown` is only ran when `isUserInteraction` within
* the `ActiveListActivationOptions` is `true`. This means that `autoPlay`, which
* is not a user interaction, ignores the `cooldown`.
*
* @since 1.0.0
*/
cooldown?: ActiveListCooldownConfig<T>;
};
/**
* Describes all the behaviors for when the limit of the ActiveList
* is surpassed.
*
* 1. 'circular': the first item which was added will be removed so
* the last item can be added without violating the limit. This
* basically means that the first one in is the first one out.
*
* 2. 'error': An error is thrown whenever the limit is surpassed,
* the error is called the `ActiveListActivationLimitReachedError`.
*
* 3. 'ignore': Nothing happens when an item is added and the limit
* is reached. The item is simply not added, but no error is
* thrown.
*
* @since 1.0.0
*/
type ActiveListMaxActivationLimitBehavior = 'circular' | 'ignore' | 'error';
/**
* Represents options for activation / deactivation methods.
*
* @since 1.0.0
*/
type ActiveListActivationOptions<T> = {
/**
* Whether or not the action was taken by a user / human. This
* affects the `autoPlay` when `stopsOnUserInteraction` is `true`,
* the `autoPlay` stops, when `false` the autoPlay is debounced.
*
* Also affects the `cooldown` when `isUserInteraction` is `true`,
* the `cooldown` is checked, otherwise when `false`
* the `cooldown` is ignored.
*
* Defaults to `true`.
*
* @since 1.0.0
*/
isUserInteraction?: boolean;
/**
* The `cooldown` is the number of milliseconds before another
* activation / deactivation is allowed. For example if the
* `cooldown` is `5000` the `ActiveList` will not allow
* transitions until after 5 seconds have passed. Any activation /
* deactivation in that period will simply be ignored.
*
* This can be useful when you have an animation which should be
* finished before allowing user interaction again.
*
* The benefit of this `cooldown` over the `cooldown` in the
* `Config`, is that this `cooldown` can be different for different
* actions. For example: it allows you to create two buttons each
* with a different cooldown.
*
* Note that the `cooldown` options within the `ActiveListActivationOptions`
* takes precedence over the `cooldown` in the `Config`.
*
* IMPORTANT: `cooldown` is only ran when `isUserInteraction` within
* the `ActiveListActivationOptions` is `true`. This means that
* `autoPlay`, which is not a user interaction, ignores the
* `cooldown`.
*
* @since 1.0.0
*/
cooldown?: ActiveListCooldownConfig<T>;
};
/**
* The subscriber which is informed of all state changes the
* ActiveList goes through.
*
* @param {ActiveList<T>} activeList The ActiveList which had changes.
* @param {ActiveListEvent<T>} event The event that occurred.
*
* @since 1.0.0
*/
type ActiveListSubscriber<T> = (activeList: ActiveList<T>, event: ActiveListEvent<T>) => void;
/**
* Represents a bundle of data which is given as the first parameter
* to the ContentPredicate function. Based on this data the
* ContentPredicate must either return `true` or `false`.
*
* @since 1.0.0
*/
type ActiveListContentPredicateData<T> = {
/**
* The value the ActiveListContent wraps.
*
* @since 1.0.0
*/
value: T;
/**
* The index the ActiveListContent has within the ActiveList
*
* @since 1.0.0
*/
index: number;
/**
* A reference to the ActiveListContent which wraps the value.
*
* @since 1.0.0
*/
content: ActiveListContent<T>;
/**
* A reference to the ActiveList itself.
*
* @since 1.0.0
*/
activeList: ActiveList<T>;
};
/**
* Represents a callback which is given all relevant data for the
* action, and expects either `true` or `false` to be returned. If
* `true` is returned will perform the action.
*
* @param {ActiveListContentPredicateData<T>} data The data for which this predicate will determine if the action needs to be performed.
* @returns {boolean} Whether or not to perform the action associated with the predicate based on the given item and index.
*
* @since 1.0.0
*/
type ActiveListContentPredicate<T> = (data: ActiveListContentPredicateData<T>) => boolean;
/**
* Represents a bundle of data which is given whenever the
* AutoPlayDurationCallbackData function must determine the number
* of milliseconds the content should be active for.
*
* @since 1.0.0
*/
type ActiveListAutoPlayDurationCallbackData<T> = {
/**
* The value which is currently asking which autoPlay duration it should have.
*
* @since 1.0.0
*/
value: T;
/**
* The index the value has within the ActiveList
*
* @since 1.0.0
*/
index: number;
/**
* A reference to the ActiveListContent which wraps the value.
*
* @since 1.0.0
*/
content: ActiveListContent<T>;
/**
* A reference to the ActiveList itself.
*
* @since 1.0.0
*/
activeList: ActiveList<T>;
};
/**
* Represents a callback function which is given all relevant autoPlay
* duration data, and expects to be given back the number of
* milliseconds the content should be active before autoPlay moves on.
*
* @param {ActiveListAutoPlayDurationCallbackData<T>} data An object containing all relevant duration data for which the callback function must determine the number of milliseconds the content is active for.
* @returns {number} The time in milliseconds the content is active for the given AutoPlayDurationCallbackData.
*
* @since 1.0.0
*/
type ActiveListAutoPlayDurationCallback<T> = (config: ActiveListAutoPlayDurationCallbackData<T>) => number;
/**
* Represents the configuration for AutoPlay. AutoPlay means
* that the ActiveList will move to the next content by itself
* after a duration.
*
* @since 1.0.0
*/
type ActiveListAutoPlayConfig<T> = {
/**
* The time in milliseconds the ActiveListContent should remain active, before
* moving to the next ActiveListContent.
*
* @since 1.0.0
*/
duration: ActiveListAutoPlayDurationCallback<T> | number;
/**
* Whether or not the user interacting with the component should
* stop the autoPlay.
*
* When `true` any activation / deactivation method called on
* the `ActiveList` will stop the autoPlay. When `false` it will
* debounce the autoPlay instead by the duration.
*
* Defaults to `false`.
*
* @since 1.0.0
*/
stopsOnUserInteraction?: boolean;
};
/**
* AutoPlay means that the ActiveList will move to the next content by
* itself after a duration.
*
* Contains whether or not the autoPlay is playing via `isPlaying` and
* the current duration via `duration`.
*
* @since 1.0.0
*/
type ActiveListAutoPlay = {
/**
* Whether or not the ActiveList is playing. In other words whether
* or not the ActiveList is going to cycle through the content
* automatically.
*
* @since 1.0.0
*/
isPlaying: boolean;
/**
* The amount of milliseconds the item should remain active before
* jumping to the next item.
*
* This duration is the duration for the current item which is
* playing. It is not affected by calling pause, meaning that
* when the duration is set to 200ms and you pause after 100ms,
* the duration will still be 200ms.
*
* When calling `stop`, or when `stop` is called when the autoPlay
* reaches the end, the duration will be set to zero.
*
* @since 1.0.0
*/
duration: number;
/**
* Whether or not the ActiveList had the autoPlay stopped at one
* point before.
*
* Use case: say you are making a carousel which should stop on
* any user interaction, so you set `stopsOnUserInteraction` to
* `true`. Say you also have another feature: a pause whenever
* the user hovers over the carousel. These two features would cause
* a conflict:
*
* Whenever the mouse over happens you call `play()`, which negates
* the `stopsOnUserInteraction`, causing the carousel to play again.
*
* To fix this problem you should on the mouse over not call
* `play()` whenever `hasBeenStoppedBefore` is `true`.
*
* @since 1.1.0
*/
hasBeenStoppedBefore: boolean;
};
/**
* Represents the configuration of the cooldown.
*
* Can be two possible things:
*
* 1. A callback function which receives the relevant cooldown data,
* and which is required to return the duration in milliseconds.
* Useful for providing a different cooldown for different items.
*
* 2. A number in milliseconds. When it is a number all items will
* have the same cooldown.
*
* @since 1.0.0
*/
type ActiveListCooldownConfig<T> = ActiveListCooldownDurationCallback<T> | number;
/**
* Represents a bundle of data which is given whenever the
* CooldownDurationCallback function must determine what the number of
* milliseconds the content should be in a cooldown state.
*
* @since 1.0.0
*/
type ActiveListCooldownDurationCallbackData<T> = {
/**
* The value which is currently asking which cooldown it should have.
*
* @since 1.0.0
*/
value: T;
/**
* The index the value has within the ActiveList
*
* @since 1.0.0
*/
index: number;
/**
* A reference to the ActiveListContent which wraps the value.
*
* @since 1.0.0
*/
content: ActiveListContent<T>;
/**
* A reference to the ActiveList itself.
*
* @since 1.0.0
*/
activeList: ActiveList<T>;
};
/**
* Represents a callback function which is given all relevant cooldown
* duration data, and expects to be given back the number of
* milliseconds the content should be cooled down before it responds
* to user interaction again.
*
* WARNING: do not return a negative number or zero in this callback
* as this results in a `ActiveListCooldownDurationError`. The action
* will still occur however, this means that the ActiveList is invalid
* when this happens.
*
* @param {ActiveListCooldownDurationCallbackData<T>} data An object containing all relevant cooldown data for which the callback function must determine the cooldown duration in number of milliseconds.
* @returns {number} The time in milliseconds of the duration of the cooldown for the given CooldownCallbackData.
*
* @since 1.0.0
*/
type ActiveListCooldownDurationCallback<T> = (data: ActiveListCooldownDurationCallbackData<T>) => number;
/**
* A Cooldown is a time period in which all user made activations
* and deactivations are prevented / ignored. Activations and
* deactivations where the `isUserInteraction` is set to `false`
* always bypass the cooldown.
*
* The use-case is a cooldown can guarantees that animations are
* completed, before another is triggered.
*
* Contains whether or not the cooldown is active via `isActive` and
* the current duration via `duration`.
*
* @since 1.0.0
*/
type ActiveListCooldown = {
/**
* Whether or not the ActiveList is currently in the cooldown state.
* When in cooldown all activations and deactivations are ignored.
*
* @since 1.0.0
*/
isActive: boolean;
/**
* The amount of milliseconds the ActiveList should remain in
* the cooldown state.
*
* @since 1.0.0
*/
duration: number;
};
/**
* Describes which strings should be associated with what
* direction. For example it could be "right" and "left",
* or "down" and "up".
*
* Will be the value of the `ActiveList` property `direction`.
*
* Useful for when animations have a certain direction and you
* name your animation CSS classes `left-animation` and
* `right-animation`.
*
* @since 1.0.0
*/
type ActiveListDirection = {
/**
* The name of the direction when moving to the next item of the
* `ActiveList`.
*
* Could for example be "right" or "down".
*
* @since 1.0.0
*/
next: string;
/**
* The name of the direction when moving to the previous item of the
* `ActiveList`.
*
* Could for example be "left" or "up".
*
* @since 1.0.0
*/
previous: string;
};
/**
* Represents whether the `ActiveListEvent` was inserted, removed, activated
* swapped, etc etc.
*
* @since 1.0.0
*/
type ActiveListEventType = 'INITIALIZED' | 'INSERTED' | 'REMOVED' | 'REMOVED_MULTIPLE' | 'ACTIVATED' | 'ACTIVATED_MULTIPLE' | 'SWAPPED' | 'MOVED' | 'DEACTIVATED' | 'DEACTIVATED_MULTIPLE' | 'AUTO_PLAY_PLAYING' | 'AUTO_PLAY_PAUSED' | 'AUTO_PLAY_STOPPED' | 'COOLDOWN_STARTED' | 'COOLDOWN_ENDED';
/**
* Represents an event which happened in the ActiveList. Based
* on the `type` you can determine which event occurred.
*
* @since 1.0.0
*/
type ActiveListBaseEvent = {
/**
* Which event occurred
*
* @since 1.0.0
*/
type: ActiveListEventType;
/**
* The time the event occurred on as a Date object.
*
* @since 1.0.0
*/
time: Date;
};
/**
* Represents the initialization of the ActiveList
*
* @since 1.0.0
*/
type ActiveListInitializedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'INITIALIZED';
/**
* The values which were active upon initialization.
*
* Note: these are the values at the time of the initialization, they might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
values: T[];
/**
* The indexes of the values which were active upon initialization.
*
* Note: these are the indexes at the time of the initialization, it might
* no longer be accurate.
*
* @since 1.0.0
*/
indexes: number[];
};
/**
* Represents an insertion into the ActiveList.
*
* @since 1.0.0
*/
type ActiveListInsertedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'INSERTED';
/**
* The value which was inserted.
*
* Note: this was the value at the time of insertion, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
value: T;
/**
* The index of the insertion.
*
* Note: this was the index at the time of the insertion, it might
* no longer be accurate.
*
* @since 1.0.0
*/
index: number;
};
/**
* Represents an removal of an item of the ActiveList.
*
* @since 1.0.0
*/
type ActiveListRemovedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'REMOVED';
/**
* The value which was removed.
*
* Note: this was the value at the time of removal, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
value: T;
/**
* The index of removed item.
*
* Note: this was the index at the time of the removal, it might
* no longer be accurate.
*
* @since 1.0.0
*/
index: number;
};
/**
* Represents multiple removals of items in the ActiveList.
*
* @since 1.0.0
*/
type ActiveListRemovedMultipleEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'REMOVED_MULTIPLE';
/**
* The values which were removed
*
* Note: these are the values at the time of removal, they might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
values: T[];
/**
* The indexes of the removed items.
*
* Note: these are the indexes at the time of the removal, it might
* no longer be accurate.
*
* @since 1.0.0
*/
indexes: number[];
};
/**
* Represents an activation of an ActiveList.
*
* @since 1.0.0
*/
type ActiveListActivatedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'ACTIVATED';
/**
* The value which was activated.
*
* Note: this was the value at the time of activation, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
value: T;
/**
* The index of the activated item.
*
* Note: this was the index at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
index: number;
/**
* The value which was deactivated, will be `null` when no value
* was deactivated as part of the activation.
*
* A deactivation will only happen as part of an activation when
* `maxActivationLimit` is set to a `number` and
* `maxActivationLimitBehavior` is set to `circular`.
*
* Note: these are the values at the time of deactivation, they might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.5.0
*/
deactivatedValue: T | null;
/**
* The index of the deactivated item, will be `-1` when no index
* was deactivated as part of the activation.
*
* A deactivation will only happen as part of an activation when
* `maxActivationLimit` is set to a `number` and
* `maxActivationLimitBehavior` is set to `circular`.
*
* Note: this was the index at the time of the deactivation, it might
* no longer be accurate.
*
* @since 1.5.0
*/
deactivatedIndex: number;
};
/**
* Represents multiple activations happening at the same time in an
* ActiveList.
*
* @since 1.0.0
*/
type ActiveListActivatedMultipleEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'ACTIVATED_MULTIPLE';
/**
* The values which were activated.
*
* Note: these are the values at the time of activation, they might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
values: T[];
/**
* The indexes of the activated items.
*
* Note: these are the indexes at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
indexes: number[];
/**
* The values which were deactivated.
*
* A deactivation will only happen as part of an activation when
* `maxActivationLimit` is set to a `number` and
* `maxActivationLimitBehavior` is set to `circular`.
*
* Note: these are the values at the time of deactivation, they might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.5.0
*/
deactivatedValues: T[];
/**
* The indexes of the deactivated items.
*
* A deactivation will only happen as part of an activation when
* `maxActivationLimit` is set to a `number` and
* `maxActivationLimitBehavior` is set to `circular`.
*
* Note: these are the indexes at the time of the deactivation, it might
* no longer be accurate.
*
* @since 1.5.0
*/
deactivatedIndexes: number[];
};
/**
* Represents a deactivation of an ActiveList.
*
* IMPORTANT: this event is only fired as a result of a direct
* deactivation call. So not when activating an item also deactivated
* an item due to a `maxActivationLimit` being set.
*
* @since 1.0.0
*/
type ActiveListDeactivatedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'DEACTIVATED';
/**
* The value which was deactivated.
*
* Note: this was the value at the time of deactivation, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
value: T;
/**
* The index of the deactivated item.
*
* Note: this was the index at the time of the deactivation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
index: number;
};
/**
* Represents multiple deactivations happening at the same time in an
* ActiveList.
*
* IMPORTANT: this event is only fired as a result of a direct
* deactivation call. So not when activating an item also deactivated
* an item due to a `maxActivationLimit` being set.
*
*
* @since 1.0.0
*/
type ActiveListDeactivatedMultipleEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'DEACTIVATED_MULTIPLE';
/**
* The values which were deactivated.
*
* Note: these are the values at the time of deactivation, they might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
values: T[];
/**
* The indexes of the deactivated items.
*
* Note: these are the indexes at the time of the deactivation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
indexes: number[];
};
/**
* Represents an activation of an ActiveList.
*
* @since 1.0.0
*/
type ActiveListSwappedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'SWAPPED';
/**
* An object containing the value of the items which were swapped.
*
* @since 1.0.0
*/
value: {
/**
* The value of the first item which was swapped.
*
* Note: this was the value at the time of the swap, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
a: T;
/**
* The value of the second item which was swapped.
*
* Note: this was the value at the time of the swap, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
b: T;
};
/**
* An object containing the indexes of the items which were swapped.
*
* @since 1.0.0
*/
index: {
/**
* The index of the first item before it was swapped.
*
* Note: this was the index at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
a: number;
/**
* The index of the second item before it was swapped.
*
* Note: this was the index at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
b: number;
};
};
/**
* Represents an activation of an ActiveList.
*
* @since 1.0.0
*/
type ActiveListMovedEvent<T> = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'MOVED';
/**
* The value which was moved.
*
* Note: this was the value at the time of the move, it might
* no longer be accurate. Keep in mind that when the `value` is
* an object or an array, they can still be mutated, because no
* copy is made.
*
* @since 1.0.0
*/
value: T;
/**
* An object containing the "from" and "to" index of the item which
* were moved.
*
* Note: this was the index at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
index: {
/**
* The index of the "from" item before it was moved.
*
* Note: this was the index at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
from: number;
/**
* The index of the "to" item before it was moved.
*
* Note: this was the index at the time of the activation, it might
* no longer be accurate.
*
* @since 1.0.0
*/
to: number;
};
};
/**
* Represents an ActiveList autoPlay being restarted again when it was
* stopped or paused.
*
* Note: this event is not fired when a ActiveList is initialized
* even though this does start the autoPlay.
*
* @since 1.0.0
*/
type ActiveListAutoPlayPlayingEvent = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'AUTO_PLAY_PLAYING';
};
/**
* Represents an ActiveList autoPlay being paused.
*
* @since 1.0.0
*/
type ActiveListAutoPlayPausedEvent = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'AUTO_PLAY_PAUSED';
};
/**
* Represents an ActiveList autoPlay being stopped.
*
* Can be fired for four reasons:
*
* 1. The `stop` method on the `ActiveList` is called.
*
* 2. The autoPlay reached the last of the items, which can only
* happen when `isCircular` is `false`.
*
* 3. When all content items are removed when the autoPlay is playing.
* It will then stop automatically since there are no more items.
*
* 4. When no more items are left active, in this case the autoPlay
* will stop as well.
*
* Note: due to reasons 3 and 4 this event can be fired right before
* a 'REMOVED', 'REMOVED_MULTIPLE', 'DEACTIVATED' and
* 'DEACTIVATED_MULTIPLE' event.
*
* @since 1.0.0
*/
type ActiveListAutoPlayStoppedEvent = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'AUTO_PLAY_STOPPED';
};
/**
* Represents an ActiveList being in a cooldown state, meaning no
* activations or deactivations can occur.
*
* @since 1.0.0
*/
type ActiveListCooldownStartedEvent = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'COOLDOWN_STARTED';
};
/**
* Represents an ActiveList moving out of the cooldown state, meaning
* all activation and deactivations can occur again.
*
* @since 1.0.0
*/
type ActiveListCooldownEndedEvent = ActiveListBaseEvent & {
/**
* Which type occurred
*
* @since 1.0.0
*/
type: 'COOLDOWN_ENDED';
};
/**
* A ActiveListEvent represents an event happened in the ActiveList.
* For example the insertion, removal, or activation of a
* ActiveListContent<T>.
*
* @since 1.0.0
*/
type ActiveListEvent<T> = ActiveListInitializedEvent<T> | ActiveListInsertedEvent<T> | ActiveListRemovedEvent<T> | ActiveListRemovedMultipleEvent<T> | ActiveListActivatedEvent<T> | ActiveListActivatedMultipleEvent<T> | ActiveListSwappedEvent<T> | ActiveListMovedEvent<T> | ActiveListDeactivatedEvent<T> | ActiveListDeactivatedMultipleEvent<T> | ActiveListAutoPlayPlayingEvent | ActiveListAutoPlayPausedEvent | ActiveListAutoPlayStoppedEvent | ActiveListCooldownStartedEvent | ActiveListCooldownEndedEvent;
/**
* Represents where the action needs to take place for when a
* predicate is provided.
*
* 1. When the mode is 'at', the `ActiveListContent` is inserted to the
* position where the predicate matches. This is the `default`
* mode.
*
* 2. When the mode is 'after', the `ActiveListContent` is inserted to after
* the position where the predicate matches.
*
* 3. When the mode is 'before', the `ActiveListContent` is inserted to
* before the position where the predicate matches.
*
* @since 1.0.0
*/
type ActiveListPredicateMode = 'at' | 'before' | 'after';
/**
* Represents options for methods which require predicates.
*
* @since 1.0.0
*/
type ActiveListPredicateOptions = {
/**
* Represents where the action needs to take place for when a
* predicate is provided.
*
* Represents where the action needs to take place for when a
* predicate is provided.
*
* 1. When the mode is 'at', the `ActiveListContent` is inserted to the
* position where the predicate matches. This is the `default`
* mode.
*
* 2. When the mode is 'after', the `ActiveListContent` is inserted to after
* the position where the predicate matches.
*
* 3. When the mode is 'before', the `ActiveListContent` is inserted to
* before the position where the predicate matches.
*
* @since 1.0.0
*/
mode: ActiveListPredicateMode;
};
/**
* Represents a piece of content in the `contents` array of the `ActiveList`.
*
* The purpose of the ActiveListContent is to act as a wrapper around the
* value which is actually in the contents array. It knows things like
* whether the item is active or not.
*
* It also contains methods to activate, remove, swap and move itself
* within the ActiveList.
*
* @since 1.0.0
*/
declare class ActiveListContent<T> {
/**
* Reference to the ActiveList is it a part of.
*
* @since 1.0.0
*/
activeList: ActiveList<T>;
/**
* The index of the `ActiveListContent` which it has within the `contents`.
*
* @since 1.0.0
*/
index: number;
/**
* The actual `value` of the `ActiveListContent` it can be whatever the
* developer wants it to be.
*
* @since 1.0.0
*/
value: T;
/**
* Whether or not the `ActiveListContent` is currently active.
*
* @since 1.0.0
*/
isActive: boolean;
/**
* Whether or not the `ActiveListContent` has been active at least once
* in the past.
*
* @since 1.0.0
*/
hasBeenActiveBefore: boolean;
/**
* Whether or not the `ActiveListContent` is considered to be the first
* item in the `contents`.
*
* @since 1.0.0
*/
isFirst: boolean;
/**
* Whether or not the `ActiveListContent` is considered to be the last
* item in the `contents`.
*
* @since 1.0.0
*/
isLast: boolean;
/**
* Whether this `ActiveListContent` has at least one other `ActiveListContent` coming
* after it in the `contents`
*
* @since 1.0.0
*/
hasNext: boolean;
/**
* Whether this `ActiveListContent` has at least one other `ActiveListContent` coming
* before it in the `contents`.
*
* @since 1.0.0
*/
hasPrevious: boolean;
/**
* Whether this `ActiveListContent` comes directly after the `ActiveListContent`, in the
* `contents` array, which is currently the `lastActiveList`.
*
* @since 1.0.0
*/
isNext: boolean;
/**
* Whether this `ActiveListContent` comes directly before the `ActiveListContent`, in the
* `contents` array, which is currently the `lastActiveList`.
*
* @since 1.0.0
*/
isPrevious: boolean;
/**
* Creates an ActiveListContent which belongs to the given ActiveList.
*
* Note: you should never create instances of ActiveListContent yourself. You
* are supposed to let ActiveList do this for you.
*
* @param {ActiveList<T>} activeList The ActiveList this ActiveListContent belongs to.
* @param {number} index The index of this ActiveListContent within the ActiveList.
* @param {T} value The value this ActiveListContent wraps.
*
* @since 1.0.0
*/
constructor(activeList: ActiveList<T>, index: number, value: T);
/**
* When calling `activate` it will make this `ActiveListContent` active.
*
* @param {ActiveListActivationOptions<T>} [activationOptions] The activation options @see ActiveListActivationOptions<T>
*
* @since 1.0.0
*/
activate(activationOptions?: ActiveListActivationOptions<T>): void;
/**
* When calling `deactivate` it will make this `ActiveListContent` inactive.
*
* @param {ActiveListActivationOptions<T>} [activationOptions] The activation options @see ActiveListActivationOptions<T>
*
* @since 1.0.0
*/
deactivate(activationOptions?: ActiveListActivationOptions<T>): void;
/**
* When calling `toggle` it will flip the this `ActiveListContent`
* `isActive` state.
*
* So when `isActive` is `true` and `toggle` is called, `isActive`
* will become `false`. When `isActive` is `false` and `toggle` is
* called, `isActive` will become `true`.
*
* With the `activationOptions` you can determine the effects
* on `cooldown` and `autoPlay`.
*
* @param {ActiveListActivationOptions<T>} [activationOptions] The activation options @see ActiveListActivationOptions<T>
*
* @since 1.0.0
*/
toggle(activationOptions?: ActiveListActivationOptions<T>): void;
/**
* When calling `remove` it will remove this `ActiveListContent`, and return
* the `value` the ActiveListContent held.
*
* @returns {T} The removed value
*
* @since 1.0.0
*/
remove(): T;
/**
* Swaps the `ActiveListContent` with the `ActiveListContent` at the given index.
*
* Note: if the active `ActiveListContent` is swapped, it will stay active,
* it will only get a new position.
*
* @param {number} index The index to swap the current `ActiveListContent` with.
* @throws {ActiveListItemNotFoundError} Item not found error
*
* @since 1.0.0
*/
swapWith(item: T): void;
/**
* Swaps the `ActiveListContent` with the `ActiveListContent` at the given index.
*
* Note: if the active `ActiveListContent` is swapped, it will stay active,
* it will only get a new position.
*
* @param {number} index] The index to swap the current `ActiveListContent` with.
* @throws {ActiveListIndexOutOfBoundsError} Index out of bounds error.
*
* @since 1.0.0
*/
swapWithByIndex(index: number): void;
/**
* Swaps the `ActiveListContent` with the next `ActiveListContent` in the sequence.
*
* If `isCircular` of the `ActiveList` is `true` swapping whilst on
* the last index will make this `ActiveListContent` swap with the
* first index. If `isCircular` is `false` it will do nothing,
* and keep the `ActiveListContent` on the last index.
*
* Note: if the active `ActiveListContent` is swapped, it will stay active,
* it will only get a new position.
*
* @since 1.0.0
*/
swapWithNext(): void;
/**
* Swaps the `ActiveListContent` with the previous `ActiveListContent` in the sequence.
*
* If `isCircular` of the `ActiveList` is `true` swapping whilst on
* the first index will make this `ActiveListContent` swap with the
* last index. If `isCircular` is `false` it will do nothing,
* and keep the `ActiveListContent` on the first index.
*
* Note: if the active `ActiveListContent` is swapped, it will stay active,
* it will only get a new position.
*
* @since 1.0.0
*/
swapWithPrevious(): void;
/**
* Moves the `ActiveListContent` to the position at index "to".
*
* It is possible to move the `ActiveListContent` to the last place by making
* the "to" index the length of the `contents` array.
*
* Note: if the active `ActiveListContent` is moved it will stay active,
* meaning that the activeIndex will get updated.
*
* @param {number} to The location the `from` needs to move "to".
* @throws {ActiveListIndexOutOfBoundsError} Index out of bounds error.
*
* @since 1.0.0
*/
moveToIndex(to: number): void;
/**
* Moves the `ActiveListContent` to the position of the item for which
* the predicate returns `true`.
*
* If no item matches the predicate nothing is moved.
*
* The position to where the `ActiveListContent` is inserted can be altered by
* providing a mode:
*
* 1. When the mode is 'at', the `ActiveListContent` is inserted to the
* position where the predicate matches. This is the `default`
* mode.
*
* 2. When the mode is 'after', the `ActiveListContent` is inserted to after
* the position where the predicate matches.
*
* 3. When the mode is 'before', the `ActiveListContent` is inserted to
* before the position where the predicate matches.
*
* @param {ActiveListContentPredicate<T>} predicate The predicate function which when `true` is returned moves the item to after that position.
* @param {ActiveListPredicateOptions} options The options for the predicate, when no options are provided the mode will default to "at".
*
* @since 1.0.0
*/
moveToPredicate(predicate: ActiveListContentPredicate<T>, options?: ActiveListPredicateOptions): void;
/**
* Moves the `ActiveListContent` to the first position in the contents array.
*
* Note: if the active `ActiveListContent` is moved it will stay active,
* meaning that the activeIndex will get updated.
*
* @since 1.0.0
*/
moveToFirst(): void;
/**
* Moves the `ActiveListContent` to the last position in the contents array.
*
* Note: if the active `ActiveListContent` is moved it will stay active,
* meaning that the activeIndex will get updated.
*
* @since 1.0.0
*/
moveToLast(): void;
}
/**
* ActiveList is a class which represents visual elements which
* have multiple pieces of content which can be active or inactive.
*
* The `ActiveList` can be used to implement multiple types of
* components:
*
* 1. A tabs component for which one tab can be active at a time.
*
* 2. A carrousel component: the user sees single slide, which will
* autoPlay to the next slide automatically.
*
* 3. A dropdown menu with one active menu item.
*
* 4. A accordion component from which the user can open multiple
* items at once.
*
* 5. A list the user can sort and move around.
*
* 6. Etc etc
*
* Another way of defining the ActiveList is that it is an array
* / list like data structure, because it supports things like
* insertion and removal.
*
* ActiveList will make sure that when content is inserted, that
* the active content is not affected.
*
* @since 1.0.0
*/
declare class ActiveList<T> implements Observable<ActiveList<T>, ActiveListEvent<T>> {
/**
* Whether or not to inform subscribers of changes / record history.
* Used in the `initialize` to temporarily stop subscriptions running
* the initial activation, and altering the history.
*/
private _isInitializing;
/**
* The `ActiveListContent` instances which the `ActiveList` holds.
*
* @since 1.0.0
*/
readonly contents: ActiveListContent<T>[];
/**
* How many items can be active at the same time.
*
* When the value of `limit` is `false` there is no limit to the
* number of active items.
*
* Defaults to 1.
*
* @since 1.0.0
*/
maxActivationLimit: number | false;
/**
* How the `maxActivationLimit` is enforced. In other words what the
* behavior should be when the limit is surpassed.
*
* The modes are strings which can be the following values:
*
* 1. 'circular': the first item which was added will be removed so
* the last item can be added without violating the limit. This
* basically means that the first one in is the first one out.
*
* 2. 'error': An error is thrown whenever the limit is surpassed,
* the error is called the `ActiveListActivationLimitReachedError`.
*
* 3. 'ignore': Nothing happens when an item is added and the limit
* is reached. The item is simply not added, but no error is
* thrown.
*
* Defaults to 'circular'.
*
* @since 1.0.0
*/
maxActivationLimitBehavior: ActiveListMaxActivationLimitBehavior;
/**
* All `value` of the content which are currently considered active.
*
* @since 1.0.0
*/
readonly active: T[];
/**
* All `ActiveListContent` which are currently considered active.
*
* @since 1.0.0
*/
readonly activeContents: ActiveListContent<T>[];
/**
* All indexes of which are currently considered active.
*
* @since 1.0.0
*/
readonly activeIndexes: number[];
/**
* Which `value` from within an `ActiveListContent` was the last
* value which was activated.
*
* In other words: of all active values which value was activated
* the last chronologically.
*
* When nothing is activated in the `ActiveList` the value of
* `lastActivated` will be `null`.
*
* @since 1.0.0
*/
lastActivated: T | null;
/**
* Which `ActiveListContent` is the last ActiveListContent which
* was activated.
*
* In other words: of all active contents which content