@sheetxl/utils-react
Version:
Utils React - Utilities for React capabilities needed for all SheetXL components.
1,425 lines (1,311 loc) • 71.8 kB
TypeScript
import { CellCoords } from '@sheetxl/utils';
import { default as default_2 } from 'react';
import { DefaultNotifier } from '@sheetxl/utils';
import { DependencyList } from 'react';
import { Direction } from '@sheetxl/utils';
import { EditModeHandler } from '@sheetxl/utils';
import { INotifier } from '@sheetxl/utils';
import { JSX } from 'react/jsx-runtime';
import { NotifierOptions } from '@sheetxl/utils';
import { ReactNode } from 'react';
import { ReferenceableClipboard } from '@sheetxl/utils';
import { RemoveListener } from '@sheetxl/utils';
import { Size } from '@sheetxl/utils';
import { TopLeft } from '@sheetxl/utils';
import { UndoManager } from '@sheetxl/utils';
declare type BaseGlyph = {
tags?: string[];
rtlMirror?: boolean;
};
declare function boundPixel(cssPoint: number, _increase?: boolean, _absOffset?: number): number;
export declare type CellFinder = (activeCoords: CellCoords, isContentfulCell: IsContentfulCell | undefined, hiddenAt: HiddenHeadersAt | undefined, direction: Direction, first: boolean, limit: number) => number;
export declare type ClickOrFocusAwayListener = (event: globalThis.MouseEvent | globalThis.KeyboardEvent) => void;
export declare interface ClickOrFocusAwayOptions {
mouseEvents?: boolean;
focusEvents?: boolean;
}
/**
* A default implementation of ICommand
*/
export declare class Command<STATE extends any = void, CONTEXT extends any = void> implements ICommand<STATE, CONTEXT> {
protected _key: string;
protected _target: ICommand.ITarget | (() => ICommand.ITarget);
protected _label: ICommand.DynamicValue<string, CONTEXT>;
protected _scopedLabels?: Record<string, ICommand.DynamicValue<string, CONTEXT>>;
protected _description?: ICommand.DynamicValue<string, CONTEXT>;
protected _icon: ICommand.DynamicValue<React.ReactElement | string, CONTEXT>;
protected _tags: ICommand.DynamicValue<string[], CONTEXT>;
protected _shortcut: ICommand.DynamicValue<IKeyStroke | IKeyStroke[] | null, CONTEXT>;
protected _disabled: ICommand.DynamicValue<boolean, CONTEXT>;
protected _state: STATE;
protected _context: CONTEXT;
protected _callback: ICommand.Callback<STATE>;
protected _listenersProperties: Set<ICommand.PropertyListener<STATE, CONTEXT>>;
protected _listenersExecute: Set<ICommand.Hook<STATE, CONTEXT>>;
constructor(key: string, target: ICommand.ITarget | (() => ICommand.ITarget) | null, props?: ICommand.Properties<STATE, CONTEXT>, callback?: ICommand.Callback<STATE>);
/** @inheritdoc ICommand.getKey */
getKey(): string;
protected _resolve<T = any>(value: ICommand.DynamicValue<T, CONTEXT>, scopedContext?: CONTEXT | (() => CONTEXT)): T;
/** @inheritdoc ICommand.getTarget */
getTarget(): ICommand.ITarget;
/** @inheritdoc ICommand.getLabel */
getLabel(scope?: string, scopedContext?: CONTEXT): string;
/** @inheritdoc ICommand.getDescription */
getDescription(context?: ICommand.DynamicContext<CONTEXT>): string;
/** @inheritdoc ICommand.getTags */
getTags(context?: ICommand.DynamicContext<CONTEXT>): string[];
/** @inheritdoc ICommand.getIcon */
getIcon(context?: ICommand.DynamicContext<CONTEXT>): React.ReactElement | string;
/** @inheritdoc ICommand.getShortcut */
getShortcut(): IKeyStroke | readonly IKeyStroke[];
/** @inheritdoc ICommand.disabled */
disabled(): boolean;
/** @inheritdoc ICommand.getState */
getState(): STATE;
/** @inheritdoc ICommand.getContext */
getContext(): CONTEXT;
/** @inheritdoc ICommand.execute */
execute(args: STATE, hook?: ICommand.Hook<STATE, CONTEXT>): Promise<boolean>;
/** @inheritdoc ICommand.addPropertyListener */
addPropertyListener(listener: ICommand.PropertyListener<STATE, CONTEXT>, fireOnListen?: boolean): RemoveListener;
/** @inheritdoc ICommand.addExecuteListener */
addExecuteListener(listener: ICommand.Hook<STATE, CONTEXT>): RemoveListener;
protected _notifyExecute(args: STATE): void;
protected _notifyError(error: any, args: STATE): void;
/** @inheritdoc ICommand.updateCallback */
updateCallback(callback: ICommand.Callback<STATE>): ICommand<STATE, CONTEXT>;
/** @inheritdoc ICommand.update */
update(props: ICommand.Properties<STATE, CONTEXT>): ICommand<STATE, CONTEXT>;
protected _notifyPropertyChange(props: ICommand.Properties<STATE, CONTEXT>): void;
protected _applyProps(props: ICommand.Properties<STATE, CONTEXT>): ICommand.Properties<STATE, CONTEXT>;
}
export declare interface CommandButtonOptions<STATE = any, CONTEXT = any> extends Omit<React.HTMLAttributes<HTMLElement>, "color" | "label"> {
/**
* Allow for listeners against a specific buttons execute rather then the command.
* Useful when knowing the specific button that executed a command is required.
* (For example when closing menus or restoring focus)
*/
commandHook?: ICommand.Hook<STATE, CONTEXT>;
/**
* Optional string to enable the command label to be configured based on the scope of how it is being used.
*/
scope?: string;
icon?: React.ReactNode | ((command: ICommand) => React.ReactNode);
label?: React.ReactNode | ((command: ICommand) => React.ReactNode);
/**
* The shortcut to display.
*
* @remarks
* This is display only and doesn't actually track the shortcut.
* Override the display for the shortcut on the command (if available).
*/
shortcut?: IKeyStroke | IKeyStroke[];
selected?: boolean;
disabled?: boolean;
disableHover?: boolean;
/**
* Tooltip properties. If this is specified then the tooltips are used.
* Do not provide a child as this component will be the child.
*/
propsTooltip?: any;
/**
* How the button will be styles.
* @defaultValue CommandButtonType.Toolbar
*/
variant?: CommandButtonType;
/**
* Optional state for this specific command button.
* @defaultValue to undefined
*/
commandState?: STATE;
context?: CONTEXT;
}
export declare interface CommandButtonProps<STATE = any, CONTEXT = any> extends CommandButtonOptions {
command: ICommand<STATE, CONTEXT>;
}
export declare type CommandButtonRefAttribute = {
ref?: React.Ref<HTMLDivElement>;
};
/**
* Follow useCommandsButtons. pattern createCommandButtonSet
*
* Use ProviderContext or just set a singleton. (research why/which)
*
* Register icon, label, description
* { commandManager.createButton( commands.getCommand('formatAlignLeftToggle'), CommandButtonType.TOOLBAR ) }
*
* Register factory for each type of Command
* Register configuration for each key
*
* When registering to a component also
*
*/
export declare const CommandButtonType: {
/**
* Suitable for toolbars. Click to open, click to close, generally disabled as icon
*/
readonly Toolbar: "toolbar";
/**
* Suitable for menus. HoverIn to open, hover leave to close, generally disabled as icon and text
*/
readonly Menuitem: "menuitem";
};
export declare type CommandButtonType = typeof CommandButtonType[keyof typeof CommandButtonType];
/**
* Default implementation of `ICommands.IGroup`.
*/
export declare class CommandGroup implements ICommands.IGroup {
protected _target: ICommand.ITarget | (() => ICommand.ITarget);
protected _groupKey: string;
protected _root: CommandGroup | null;
protected _parent: CommandGroup | null;
protected _focused: CommandGroup;
protected _nodes: Map<string, CommandGroup>;
protected _uuid: string;
protected _children: Map<string, ICommands.IGroup>;
protected _commandsByKey: Map<string, ICommand<any, any>>;
protected _commandsByShortcut: Map<string, string>;
protected _listeners: Set<ICommands.IListener>;
protected _listenersByKey: Map<string, Set<ICommands.IListener> | null>;
protected _unListenersByCommand: Map<ICommand, RemoveListener>;
protected _commandsPropertyListener: ICommand.PropertyListener<any, any>;
constructor(target: ICommand.ITarget | (() => ICommand.ITarget), groupKey?: string);
private _getCommand;
/** {@inheritDoc ICommands.IGroup.getCommand} */
getCommand(key: string, _ignoreActive?: boolean): ICommand<any, any>;
/** {@inheritDoc ICommands.IGroup.createChildGroup} */
createChildGroup(target: ICommand.ITarget | (() => ICommand.ITarget), when: string, replace?: boolean): ICommands.IGroup;
/** {@inheritDoc ICommands.IGroup.getKey} */
getKey(): string;
/** {@inheritDoc ICommands.IGroup.getGroup} */
getGroup(key: string): ICommands.IGroup | null;
protected _addCommands(commands: readonly ICommand<any, any>[], replace?: boolean): void;
/** {@inheritDoc ICommands.IGroup.removeFromParent} */
removeFromParent(): void;
/** {@inheritDoc ICommands.IGroup.addCommands} */
addCommands(commands: readonly ICommand<any, any>[], replace?: boolean): void;
/** {@inheritDoc ICommands.IGroup.getActive} */
getActive(): ICommands.IGroup;
/** {@inheritDoc ICommands.IGroup.activate} */
activate(groupKey?: string): void;
/** {@inheritDoc ICommands.IGroup.findCommandByEvent} */
findCommandByEvent(e: React.KeyboardEvent): ICommand | null;
/** {@inheritDoc ICommands.IGroup.dispatchToFocusedCommand} */
dispatchToFocusedCommand(e: React.KeyboardEvent): boolean;
/** {@inheritDoc ICommands.IGroup.getRoot} */
getRoot(): ICommands.IGroup;
/** {@inheritDoc ICommands.IGroup.getParent} */
getParent(): ICommands.IGroup | null;
/** {@inheritDoc ICommands.IGroup.addListener} */
addListener(listener: ICommands.IListener, options?: ICommands.IListenerOptions): RemoveListener;
protected _notifyCommands(listeners: Set<ICommands.IListener>, key: keyof ICommands.IListener, args?: any): void;
protected _notify(key: keyof ICommands.IListener, args?: any): void;
/** {@inheritDoc ICommands.IGroup.getAllCommands} */
getAllCommands(): {
command: ICommand<any, any>;
groupKey: string;
}[];
}
export declare interface CopyPasteProps {
source: ReferenceableClipboard.Source;
target?: ReferenceableClipboard.Target;
commands?: ICommands.IGroup;
/**
* Called when the clipboard is updated.
* @param reference If `null` then the clipboard was cleared.
*/
onClipboardUpdate?: (reference: ReferenceableClipboard.ReferenceItem | null) => void;
/**
* Called after paste has been called.
*/
onPaste?: (reference: ReferenceableClipboard.ReferenceItem, args: ReferenceableClipboard.PasteOptions) => void;
}
export declare interface CopyPasteResults {
copy: (args?: ReferenceableClipboard.CopyOptions) => void;
paste: (args?: ReferenceableClipboard.PasteOptions) => void;
/**
* The clipboard used. Generally the `InternalClipboard.Global`.
*/
clipboard: ReferenceableClipboard;
}
export declare function createDynamicIconService(): {
register: (key: IconPackKey, packOrLoader: IconPack | IconPackInput | PackLoader) => void;
prefetch: (keys?: IconPackKey | IconPackKey[]) => Promise<void>;
setActive: (packKey: IconPackKey) => void;
getActive: () => IconPackKey;
resolve: (key: IconGlyphKey, o?: ResolveOptions) => Promise<IconGlyphPackPair | null>;
registerAlias: (packKey: IconPackKey, fromKey: IconGlyphKey, toKey: IconGlyphKey) => void;
has: (key: IconGlyphKey, o?: ResolveOptions) => boolean;
getPack: (packKey?: IconPackKey) => IconPack;
hasPack: (packKey: IconPackKey) => boolean;
listPacks: () => IconPackKey[];
listIcons: (packKey: IconPackKey) => string[];
addActiveListener: (cb: (key: IconPackKey) => void) => RemoveListener;
};
/**
* Creates a React synthetic event from a native DOM event.
*
* @remarks
* This helper creates a synthetic event wrapper that mimics React's SyntheticEvent behavior,
* including proper type inference for specific event types (PointerEvent, MouseEvent, etc.).
*
* @template T - The element type (extends Element)
* @template E - The native event type (extends Event)
*
* @param event - The native DOM event to wrap
* @param currentTarget - Optional override for currentTarget (useful for portals/delegated events)
*
* @returns A React synthetic event with all standard properties and methods
*
* @example
* ```typescript
* // Basic usage
* const syntheticEvent = createSyntheticEvent<HTMLDivElement, PointerEvent>(nativePointerEvent);
*
* // With custom currentTarget (for portals)
* const syntheticEvent = createSyntheticEvent<HTMLDivElement, PointerEvent>(
* nativePointerEvent,
* portalElement
* );
* ```
*/
declare const createSyntheticEvent: <T extends Element, E extends Event, R extends React.SyntheticEvent<T, E>>(event: E, currentTarget?: EventTarget & T) => R;
export declare const defaultCreateScrollCorner: (size: Size) => JSX.Element;
/**
* TODO - implement styling support similar to other scroll buttons. Currently hardcoded
*/
export declare const defaultCreateScrollEdgeButton: (props: ScrollButtonProps) => default_2.ReactElement;
/**
* Relies on external styling. Follows the styling of scrollbars pattern.
* @see https://css-tricks.com/custom-scrollbars-in-webkit/
* class of scrollbar-button, vertical or horizontal, end
*/
export declare const defaultCreateScrollEndButton: (props: ScrollButtonProps) => default_2.ReactElement;
/**
* Relies on external styling. Follows the styling of scrollbars pattern. @see https://css-tricks.com/custom-scrollbars-in-webkit/
* class of scrollbar-button, vertical or horizontal, end
*/
export declare const defaultCreateScrollStartButton: (props: ScrollButtonProps) => default_2.ReactElement;
export declare const DefaultDynamicIconService: {
register: (key: IconPackKey, packOrLoader: IconPack | IconPackInput | PackLoader) => void;
prefetch: (keys?: IconPackKey | IconPackKey[]) => Promise<void>;
setActive: (packKey: IconPackKey) => void;
getActive: () => IconPackKey;
resolve: (key: IconGlyphKey, o?: ResolveOptions) => Promise<IconGlyphPackPair | null>;
registerAlias: (packKey: IconPackKey, fromKey: IconGlyphKey, toKey: IconGlyphKey) => void;
has: (key: IconGlyphKey, o?: ResolveOptions) => boolean;
getPack: (packKey?: IconPackKey) => IconPack;
hasPack: (packKey: IconPackKey) => boolean;
listPacks: () => IconPackKey[];
listIcons: (packKey: IconPackKey) => string[];
addActiveListener: (cb: (key: IconPackKey) => void) => RemoveListener;
};
export declare class DefaultReactNotifier extends DefaultNotifier implements IReactNotifier {
/** @inheritdoc IReactNotifier.setOverrides */
setOverrides(overrides: Partial<IReactNotifier> | null): void;
/** @inheritdoc IReactNotifier.getDelegate */
getDelegate(): Partial<IReactNotifier> | null;
/** @inheritdoc IReactNotifier.showMessage */
showMessage(message: string | default_2.ReactNode, options?: EnqueueNotifierOptions): void;
/** @inheritdoc IReactNotifier.showBusy */
showBusy(message: string | default_2.ReactNode, options?: ShowBusyOptions): (Promise<() => void>) | (() => void);
/** @inheritdoc IReactNotifier.showWindow */
showWindow(type: string, options?: ShowWindowOptions): Promise<HTMLElement>;
/** @inheritdoc IReactNotifier.showError */
showError(error: any): void;
/** @inheritdoc IReactNotifier.showOptions */
showOptions(options: ShowOptionsOptions): Promise<string>;
/** @inheritdoc IReactNotifier.showInput */
showInput(options: ShowInputOptions): Promise<InputResults>;
}
declare const defaultRenderScrollbar: (props: ScrollbarProps) => JSX.Element;
/**
* Re-export detectIt.
*
* @returns The `detect-it` library.
*/
declare function detectIt(): {
supportsPassiveEvents: boolean;
supportsPointerEvents: boolean;
supportsTouchEvents: boolean;
deviceType: 'mouseOnly' | 'touchOnly' | 'hybrid';
primaryInput: 'mouse' | 'touch';
};
export declare interface DevicePixelRatioOptions {
/**
* Default DPR to use if browser does not support the `devicePixelRatio`
* property, or when rendering on server
*
* @defaultValue `1`
*/
defaultDpr?: number;
/**
* Whether or not to round the number down to the closest integer
*
* @defaultValue `true`
*/
round?: boolean;
/**
* Maximum DPR to return (set to `2` to only generate 1 and 2)
*
* @defaultValue `3`
*/
maxDpr?: number;
}
export declare const DynamicIcon: default_2.MemoExoticComponent<(props: DynamicIconProps) => JSX.Element>;
export declare interface DynamicIconProps extends default_2.HTMLAttributes<HTMLElement> {
iconKey?: IconGlyphKey;
packKey?: IconPackKey;
className?: string;
style?: default_2.CSSProperties;
/** Sets wrapper font-size; children scale to 1em */
size?: string | number;
title?: string;
role?: 'img' | 'presentation' | string;
ariaHidden?: boolean;
/** Extra props forwarded to React glyphs (if the glyph is of type `react`) */
propsSource?: unknown;
}
export declare type EmojiGlyph = BaseGlyph & {
emoji: string | {
text: string;
};
};
export declare type EmojiInput = {
text: string;
} | string;
declare const EmptyCssProperties: React.CSSProperties;
/**
* Configuration for non-blocking notifications.
*/
export declare interface EnqueueNotifierOptions extends NotifierOptions {
/**
* A hint for decorations of the message.
*/
type?: NotifierType;
/**
* Passed directly to the Snackbar component.
*/
enqueueProps?: Record<string, any>;
}
/**
* Props for an Error Panel
*/
export declare interface ErrorPanelProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* The error to show
*/
error: any;
/**
* Ref to the element.
*/
ref?: React.Ref<HTMLDivElement>;
}
/**
* Simple panel to trigger various error scenarios for testing error boundaries and logging.
*/
export declare const ErrorTestPanel: () => JSX.Element;
declare const focusableNodeNames: Set<string>;
/**
* Wrap around a div to allow. This will navigate through enabled divs with tabindex (but only one level deep)
* It uses the current layout to determine navigation
* TODO - we need to find an
* tab/shift-tab navigation
* arrow key navigation
*
* another option is to use rowindex/columnIndex attributes?
*
* default direction (for tab)
*/
export declare const FocusKeyNavigation: default_2.FC<FocusKeyNavigationProps>;
export declare interface FocusKeyNavigationProps extends default_2.HTMLAttributes<HTMLDivElement> {
refFocusStart?: default_2.RefObject<HTMLElement>;
/**
* If tab and all tabIndices are the same which direction should the tab scan. Note - shift tab will go the opposite direction
*/
tabForward?: Direction;
}
export declare interface FocusWindowOptions extends FocusOptions {
/**
* Allows for a specific component to be selected.
*
* @remarks
* If a string is provided this will be used as a querySelector to find the initial focusable component.
*/
selection?: string;
}
export declare interface FullscreenPortalRoot {
getPortalContainer: () => Element;
isFullscreen: boolean;
}
/**
* Returns the current device pixel ratio (DPR) given the passed options
*
* @param options
* @returns current device pixel ratio
*/
export declare function getDevicePixelRatio(options?: DevicePixelRatioOptions): number;
/**
* scan all elements until we find one in the given direction
* Note - only horizontal at the moment
*/
declare const getScrollTo: (currentLocation: number, boundary: number, children: any, isLeft: boolean, defaultValue?: number) => number;
export declare interface HiddenHeadersAt {
/**
* A called back to traverse hidden headers
*/
(index: number, reverse?: boolean): number;
}
export declare const HorizontalAlignment: {
/**
* Aligned based on the data value.
* Text data is left-aligned. Numbers, dates, and times are right-aligned. Boolean types are centered.
*/
readonly General: "general";
readonly Left: "left";
readonly Right: "right";
readonly Center: "center";
readonly Justify: "justify";
readonly Fill: "fill";
/** Not Supported */
readonly Distributed: "distributed";
/** Not Supported */
readonly CenterContinuous: "centerContinuous";
};
export declare type HorizontalAlignment = typeof HorizontalAlignment[keyof typeof HorizontalAlignment];
export declare interface ICellLayout {
/**
* Returns the offset given an index.
*/
getColOffset: ItemSizer;
/**
* Returns the index given an offset.
*/
getColIndex: ItemSizer;
/**
* Returns the offset given an index.
*/
getRowOffset: ItemSizer;
/**
* Returns the index given an offset.
*/
getRowIndex: ItemSizer;
}
export declare interface ICommand<STATE extends any = any, CONTEXT extends any = void> {
/**
* A unique key for the command. This is how the command is identified
* within the CommandTree
*
* @remarks
* Immutable
*/
getKey(): string;
/**
* The target that the command operates on.
*/
getTarget(): ICommand.ITarget;
/**
* Indicates if the command is disabled.
*/
disabled(): boolean;
/**
* Called to execute the command.
*
* @param args Optional arguments for the command.
*/
execute(args?: STATE, hook?: ICommand.Hook<STATE, CONTEXT>): Promise<boolean>;
/**
* Represents the model state.
*/
getState(): STATE;
/**
* The current view context associated with the command.
*/
getContext(): CONTEXT;
/**
* Additional information that may be needed to render or make decisions about setting state.
*/
update(props: ICommand.Properties<STATE, CONTEXT>): ICommand<STATE, CONTEXT>;
/**
* Update the callback function for the command.
* @param callback
*/
updateCallback(callback: ICommand.Callback<STATE>): ICommand<STATE, CONTEXT>;
/**
* Add a listener that will be called when command properties have changed
*/
addPropertyListener(listener: ICommand.PropertyListener<STATE, CONTEXT>, fireOnListen?: boolean): RemoveListener;
/**
* Add a listener that will be called when the command is executed
* @param listener
*/
addExecuteListener(listener: ICommand.Hook<STATE, CONTEXT>): RemoveListener;
/**
* Get the shortcut(s) associated with the command.
*/
getShortcut(): IKeyStroke | readonly IKeyStroke[];
/**
* Get the label associated with the command.
*/
getLabel(scope?: string, context?: ICommand.DynamicContext<CONTEXT>): string;
/**
* Get the tags associated with the command.
*/
getTags(context?: ICommand.DynamicContext<CONTEXT>): string[];
/**
* Get the description associated with the command.
*/
getDescription(context?: ICommand.DynamicContext<CONTEXT>): string;
/**
* Get the icon associated with the command.
*/
getIcon(context?: ICommand.DynamicContext<CONTEXT>): React.ReactElement | string;
}
/**
* @see
* ### **Interface**
*
* {@link ICommand}
*/
export declare namespace ICommand {
/**
* Used to interactive with a dom element.
*
* @remarks
* * When dispatching keystrokes the target is used to determine if the keystroke
* can be consumed by the element.
* * Many commands will refocus the target after they have completed. The target focus will be called.
*/
export interface ITarget {
/**
* Used to determine if a dom element is contained with the group.
*
* @param element
*
* @remarks
* This is used for validating keystrokes and focus traversal.
*/
contains(element: Node | null): boolean;
/**
* Called after a command is executed.
*/
focus(): void;
}
/**
* The callback function for a command.
*
* @remarks
* When
*/
export interface Callback<STATE extends any = void> {
(args?: STATE, command?: ICommand<STATE, unknown>): void | boolean | Promise<boolean> | Promise<void>;
}
export type DynamicContext<CONTEXT> = CONTEXT | (() => CONTEXT);
export type DynamicValue<T, CONTEXT> = T | ((context?: DynamicContext<CONTEXT>) => T);
/**
* Properties that can be updated on a command.
*/
export interface Properties<STATE extends any = void, CONTEXT extends any = void> {
disabled?: boolean | (() => boolean);
/**
* Values associated with the command model.
*/
state?: STATE;
/**
* View specific context values
*/
context?: DynamicContext<CONTEXT>;
shortcut?: IKeyStroke | IKeyStroke[] | (() => IKeyStroke);
label?: DynamicValue<string, CONTEXT>;
tags?: DynamicValue<string[], CONTEXT>;
/**
* The ability to override labels for specific context. Useful for content menus
* For example 'Rename Sheet' command might only want to be displayed as 'Rename' in the content menu.
*/
scopedLabels?: Record<string, DynamicValue<string, CONTEXT>>;
description?: DynamicValue<string, CONTEXT>;
icon?: DynamicValue<React.ReactNode, CONTEXT>;
}
export interface PropertyListener<STATE extends any, CONTEXT extends any> {
/**
* Called when command properties have changed.
*/
(props: ICommand.Properties<STATE, CONTEXT>, command: ICommand<STATE, CONTEXT>): void;
}
/**
* A hook that can be passed to a command execute function.
*/
export interface Hook<STATE extends any, CONTEXT extends any = void> {
/**
* If implemented will be called when execute is called. If a promise is return if will wait until
* this is completed.
*
* @param command
* @param args
*/
beforeExecute?(command: ICommand<STATE, CONTEXT>, args: STATE): Promise<boolean | void> | boolean | void;
/**
* Called when a command has been executed successful.
*/
onExecute?(command: ICommand<STATE, CONTEXT>, args: STATE): void;
/**
* Called when a command failed to executed successfully.
*/
onError?(command: ICommand<STATE, CONTEXT>, error: any, args: STATE): void;
}
}
export declare interface ICommandListener<STATE extends any, CONTEXT extends any = void> extends ICommand.Hook<STATE, CONTEXT> {
onChange?(command: ICommand<STATE, CONTEXT>): void;
}
export declare interface ICommandListenerOptions {
fireOnCommandChange: boolean;
}
/**
* The ICommands namespace contains interfaces for managing collections of commands and
* dispatching keystrokes to the most specific command.
*
* @remarks
* This is done by creating a hierarchy of command groups and tracking the 'most focused' group.
* All keystrokes will walk up the commands groups until a command is found.
*
*/
export declare namespace ICommands {
export interface IListener {
/**
* Called when the active group has changed.
* @param source
*/
onActiveChange?(source: ICommands.IGroup): void;
/**
* Called when a command has changed.
* @param source
* @param command
*
* @remarks
* For this to be enabled the keys must be provided in the {@link ICommands.IListenerOptions}.
*/
onCommandChange?(source: ICommands.IGroup, command: ICommand): void;
/**
* Called when any change to the resolvable commands has occurred.
*
* @remarks
* This can be either due to changed the active or commands were added
*/
onGroupChange?(source: ICommands.IGroup): void;
}
export interface IListenerOptions {
/**
* If provided then the onCommandChange will be called when the command changes.
*/
keys?: string[];
}
/**
* Contains commands and child command maps.
*/
export interface ILookup {
/**
* Return a command that matches the key.
*
* @remarks
* Search both the current and any child commands groups that are actives.
*/
getCommand(key: string): ICommand<any, any>;
}
/**
* A command group is a collection of commands and child command groups.
*/
export interface IGroup extends ICommands.ILookup {
/**
* Create a new map to add Commands.
*
* @param target {@link ICommand.ITarget}.
* @param groupKey String description describing the reason for the group. This is presented to the user in the shortcut UI.
* @param replace If `true` replace the existing commands. If `false` ignores duplicates. If unspecified a warning will be logged for duplicates.
*/
createChildGroup(target: ICommand.ITarget | (() => ICommand.ITarget), groupKey: string, replace?: boolean): ICommands.IGroup;
/**
* Returns the keys associated with the group
*/
getKey(): string;
/**
* Remove the command group from the parent.
* @remarks
* If this is the root this operation will have no effect
*/
removeFromParent(): void;
/**
* Returns a group for the given when string.
*/
getGroup(key: string): ICommands.IGroup | null;
/**
* Add a collection of commands to the group.
* @param commands The commands to add.
* @param replace If `true` replace the existing commands. If `false` ignores duplicates. If unspecified a warning will be logged for duplicates.
* @remarks
* Set the commands for the current node.
*/
addCommands(commands: readonly ICommand<any, any>[], replace?: boolean): void;
/**
* Set the command group to the 'focused group.
* @param key The key of the group to activate. If not provided then the current group is activated.
*/
activate(key?: string): void;
/**
* Return the active group.
*
* @remarks
* This is the group that the dispatch will start from.
*/
getActive(): ICommands.IGroup;
/**
*
* @param e The keyboard event to dispatch
*/
dispatchToFocusedCommand(e: React.KeyboardEvent): boolean;
/**
* Returns the top most commands group.
*
* @remarks
* If root then will return return itself.
*/
getRoot(): ICommands.IGroup;
/**
* Returns the parent command group.
*
* @remarks
* If root then will return return itself.
*/
getParent(): ICommands.IGroup | null;
/**
* Add listener.
*/
addListener(listener: ICommands.IListener, options?: ICommands.IListenerOptions): RemoveListener;
/**
* Returns a list of all commands in the group and all children commands.
* @remarks
* This does not return parent commands.
*/
getAllCommands(): {
command: ICommand<any, any>;
groupKey: string;
}[];
/**
* Return a command that matched the keyboard event or `null` if no command was found.
*
* @param e The keyboard event.
*/
findCommandByEvent(e: React.KeyboardEvent): ICommand | null;
}
}
export declare interface ICommandsListeners<STATE extends any, CONTEXT extends any = void> extends ICommand.Hook<STATE, CONTEXT> {
/**
* Called when either the command group is updated or if keys are provided then the commands as well.
*
* @param commands
*/
onChange?(commands: ICommands.IGroup): void;
}
export declare type IconGlyph = SvgGlyph | UrlGlyph | EmojiGlyph | ReactGlyph;
export declare type IconGlyphInput = ({
svg: SvgSourceInput;
}) | ({
url: UrlInput;
} & BaseGlyph) | ({
emoji: EmojiInput;
} & BaseGlyph) | ({
react: ReactInput;
} & BaseGlyph);
export declare type IconGlyphKey = string;
export declare interface IconGlyphPackPair {
glyph: IconGlyph;
pack: IconPack;
packKey: string;
}
export declare interface IconPack {
icons: Readonly<Record<IconGlyphKey, IconGlyph>>;
meta: IconPackMeta;
}
export declare interface IconPackInput {
icons: IconsInputRecord;
meta?: Partial<IconPackMeta>;
overrides?: Record<IconPackKey, IconsInputRecord>;
}
export declare type IconPackKey = string;
export declare interface IconPackMeta {
label: string;
version: string;
license: string;
defaultViewBox: string;
extends: IconPackKey[];
}
export declare type IconPath = {
d: string;
className?: string;
fill?: string;
stroke?: string;
opacity?: number | string;
fillRule?: "nonzero" | "evenodd";
clipRule?: "nonzero" | "evenodd";
};
export declare type IconsInputRecord = Readonly<Record<IconGlyphKey, IconGlyphInput>>;
export declare interface IKeyStroke {
readonly key: string;
readonly modifiers?: KeyModifiers[];
}
/** In-memory state (default fallback / SSR-safe) */
export declare class InMemoryStore implements PersistenceStore {
private store;
/** {@inheritDoc PersistenceStore.getItem} */
getItem(k: string): Promise<string>;
/** {@inheritDoc PersistenceStore.setItem} */
setItem(k: string, v: string): Promise<void>;
/** {@inheritDoc PersistenceStore.removeItem} */
removeItem(k: string): Promise<void>;
}
export declare interface InputResults {
input: string;
option: string;
}
export declare interface InputValidationResults {
valid: boolean;
message?: string;
}
/**
* Interface that provides popups for the user.
*/
export declare interface IReactNotifier extends INotifier {
/**
* Useful when informing the user of something but are not expecting a response.
*/
showMessage: (message: string | default_2.ReactNode, options?: EnqueueNotifierOptions) => void;
/**
* Should return error object exception.
*
* @param error The error to show
*/
showError: (error: Error | string) => void;
/**
* Useful when performing a long running operation and you want to inform the user.
*
* A return type of a handler will be returned to allow for hideBusy.
* If multiple calls are made the consumer should continue to indicated blocked
* until all calls have been hideBusy.
*/
showBusy: (message: string | default_2.ReactNode, options?: ShowBusyOptions) => (Promise<() => void>) | (() => void);
/**
* Show a dialog for a given type.
*
* @param type
* @param options
*/
showWindow: (type: string, options?: ShowWindowOptions) => Promise<HTMLElement>;
/**
* Provide a user with a list of options to choose from.
* @param options
*/
showOptions: (options: ShowOptionsOptions) => Promise<string>;
/**
* Provider a user with a way to enter a text input.
* @param options
*/
showInput: (options: ShowInputOptions) => Promise<InputResults>;
}
export declare interface IsContentfulCell {
(coords: CellCoords): boolean;
}
export declare interface IScrollbarAttributes extends HTMLDivElement {
isScrollbar: () => true;
}
export declare interface IScrollbarElement extends IScrollbarAttributes, HTMLDivElement {
}
export declare interface IScrollPaneAttributes {
isScrollPane: () => true;
}
export declare interface IScrollPaneElement extends HTMLDivElement, IScrollPaneAttributes {
}
export declare interface IShowToolTipProperties {
/**
* The anchor for the tooltip. x,y are required
* but width and height can also be provided.
*/
anchor: {
x: number;
y: number;
width?: number;
height?: number;
};
/**
* The value to display. This is either a string or a react element
*/
display?: string | default_2.ReactElement;
/**
* Purely suggestion only
* If not specified then the consumer will determine
*/
placement?: ToolTipPlacement;
}
export declare interface ISplitPaneElement extends HTMLDivElement, SplitPaneAttributes {
}
export declare type ItemSizer = (index: number) => number;
export declare const KeyCodes: {
readonly BackSpace: 8;
readonly Tab: 9;
readonly Clear: 12;
readonly Enter: 13;
readonly Shift: 16;
readonly Control: 17;
readonly Alt: 18;
readonly Pause: 19;
readonly CapsLock: 20;
readonly Escape: 27;
readonly Space: 32;
readonly PageUp: 33;
readonly PageDown: 34;
readonly End: 35;
readonly Home: 36;
readonly Left: 37;
readonly Up: 38;
readonly Right: 39;
readonly Down: 40;
readonly Insert: 45;
readonly Delete: 46;
readonly Digit_8: 56;
readonly Y: 89;
readonly Z: 90;
readonly Meta: 91;
readonly F1: 112;
readonly F2: 113;
readonly F3: 114;
readonly F4: 115;
readonly F5: 116;
readonly F6: 117;
readonly F7: 118;
readonly F8: 119;
readonly F9: 120;
readonly F10: 121;
readonly F11: 122;
readonly F12: 123;
readonly NumLock: 144;
readonly ScrollLock: 145;
readonly BackSlash: 220;
readonly Slash: 191;
readonly BracketRight: 221;
readonly BracketLeft: 219;
/** Android/IME composition key - used when virtual keyboards send composite input */
readonly Composition: 229;
};
export declare type KeyCodes = typeof KeyCodes[keyof typeof KeyCodes];
export declare const KeyModifiers: {
readonly Shift: "shift";
readonly Alt: "alt";
readonly Ctrl: "ctrl";
readonly Meta: "meta";
};
export declare type KeyModifiers = typeof KeyModifiers[keyof typeof KeyModifiers];
/**
* Props for LoadingPanel
*/
export declare interface LoadingPanelProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* A delay for showing the loading panel.
*
* @remarks
* This helps prevent flicker if loading is very fast.
*/
transitionDelay?: string;
/**
* Whether the background should be transparent.
*
* @defaultValue false
*/
transparentBackground?: boolean;
/**
* Optional callback when mounted
*/
onMount?: () => void;
/**
* Optional callback when unmounted
*/
onUnmount?: () => void;
/**
* Ref to the element.
*/
ref?: React.Ref<HTMLDivElement>;
}
/** LocalStorage state with cross-tab sync */
export declare class LocalStorageStore implements PersistenceStore {
private storage;
constructor(storage?: Storage);
/** {@inheritDoc PersistenceStore.getItem} */
getItem(k: string): Promise<string>;
/** {@inheritDoc PersistenceStore.setItem} */
setItem(k: string, v: string): Promise<void>;
/** {@inheritDoc PersistenceStore.removeItem} */
removeItem(k: string): Promise<void>;
/** {@inheritDoc PersistenceStore.subscribe} */
subscribe?(onExternalChange: (changedKey: string) => void): () => void;
}
export declare const MouseButtonCodes: {
readonly Left: 1;
readonly Middle: 2;
readonly Right: 3;
};
export declare type MouseButtonCodes = typeof MouseButtonCodes[keyof typeof MouseButtonCodes];
export declare const NotifierProvider: default_2.FC<NotifierProviderProps>;
/**
* Context provider for notifications. Allows custom notification implementations
* to be provided to components within the provider tree.
*
* @example
* ```tsx
* const customNotifier = {
* showMessage: (message) => toast(message),
* showError: (error) => toast.error(error),
* // ... other methods
* };
*
* <NotifierProvider notifier={customNotifier}>
* <App />
* </NotifierProvider>
* ```
*/
export declare interface NotifierProviderProps {
children: ReactNode;
notifier: IReactNotifier;
}
/**
* Indicates the type of notification.
*/
export declare const NotifierType: {
readonly Default: "default";
readonly Error: "error";
readonly Success: "success";
readonly Warning: "warning";
readonly Info: "info";
};
export declare type NotifierType = typeof NotifierType[keyof typeof NotifierType];
export declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
declare type PackLoader = () => Promise<IconPack | IconPackInput | PackModule>;
declare type PackModule = {
readonly default: IconPack | IconPackInput;
} & Record<string, unknown>;
export declare type PersistenceProviderProps = {
/**
* Storage backend to use
*/
store: PersistenceStore;
/**
* Namespace prefix for all keys
*
* @defaultValue none
*/
namespace?: string;
serializer?: PersistenceSerializer;
debounceMs?: number;
crossTabSync?: boolean;
/**
* Children elements that will have access to the persistence context.
*
* @remarks
* Required for provider
*/
children: React.ReactNode;
};
export declare type PersistenceSerializer<T = any> = {
parse: (raw: string | null) => T;
stringify: (val: T) => string;
};
export declare type PersistenceStateOptions<T = any> = {
/**
* Convert the value to/from a string for storage
*
* @defaultValue JSON
*/
serializer?: PersistenceSerializer<T>;
version?: number;
migrate?: (oldValue: unknown, oldVersion: number | undefined) => T;
lazy?: boolean;
};
export declare function PersistenceStateProvider(props: PersistenceProviderProps): JSX.Element;
export declare type PersistenceStateSetter<T> = (next: T | ((prev: T) => T)) => void;
/**
* Primary interface for storing retrieving key/value pairs
*/
export declare interface PersistenceStore {
/**
* Retrieves the value associated with the given key.
*
* @param key The key to retrieve.
*/
getItem(key: string): Promise<string | null>;
/**
* Sets the value for the given key.
*
* @param key The key to set.
* @param value The value to associate with the key.
*/
setItem(key: string, value: string): Promise<void>;
/**
* Removes the value associated with the given key.
*
* @param key The key to remove.
*/
removeItem(key: string): Promise<void>;
/**
* Subscribes to external changes for cross-tab synchronization.
*
* @param onExternalChange Callback invoked when a key changes externally.
*
* @remarks
* Not all state implementations support cross-tab subscription (may no-op)
*/
subscribe?(onExternalChange: (changedKey: string) => void): () => void;
}
/**
* If returns false don't setup the other listeners
*/
export declare type PointerDownListener = (event: default_2.PointerEvent<Element>) => void;
export declare interface PointerHandlerOptions<T extends Element = Element> {
/**
* If returns false then other events will not be fired
*/
onPointerDown: (event: default_2.PointerEvent<T>, modifiers: PointerModifiers) => boolean | void;
/**
* If the Pointer has moved or it the Pointer was held for a period of timerContinuous.
*/
onPointerMoveOrWait?: (event: default_2.PointerEvent<T>, modifiers: PointerModifiers, originalEvent: default_2.PointerEvent<T>) => void;
/**
* Called when Pointer is released. This is different than the regular
* Pointer up in that it will be called even if the Pointer is released
* when outside the component.
*/
onPointerUp?: (event: default_2.PointerEvent<T>, modifiers: PointerModifiers, originalEvent: default_2.PointerEvent<T>) => void;
timerInitial?: number;
timerContinuous?: number;
/**
* If this is being used for a touch device then this should be true. This will
* prevent the default touch events from being fired (by calling defaultPrevent during the capture phase).
* @default false
*/
processTouch?: boolean;
/**
* If true the touch events will be consumed and not propagated.
* @default true
*/
consumeTouch?: boolean;
}
/**
* The pointer modifiers are used because pointer events and keyboard events
* both have modifiers but pointer events are not updated with a keyboard event
* is pressed.
*/
export declare interface PointerModifiers {
ctrlKey: boolean;
shiftKey: boolean;
altKey: boolean;
metaKey: boolean;
}
export declare const ReactErrorBoundary: default_2.FC<{
children: ReactNode;
}>;
export declare type ReactGlyph<P extends ReactIconProps = ReactIconProps> = BaseGlyph & {
react: ReactInput<P>;
};
export declare interface ReactIconProps extends React.HTMLAttributes<HTMLElement> {
}
export declare type ReactInput<P extends ReactIconProps = ReactIconProps> = (props: P) => React.ReactNode;
export declare namespace ReactUtils {
export {
detectIt,
boundPixel,
focusableNodeNames,
EmptyCssProperties,
toPrettyKeyCode,
createSyntheticEvent
}
}
export declare interface RepeatClickOptions {
timerInitial?: number;
timerContinuous?: number;
}
export declare interface ResolveOptions {
packKey?: IconPackKey;
}
export declare const RoundedTab: default_2.FC<RoundedTabProps>;
export declare interface RoundedTabProps extends default_2.HTMLAttributes<HTMLElement> {
radius?: number;
strokeWidth?: number;
strokeColor?: string;
}
export declare type ScrollableViewport = {
left: number;
top: number;
width: number;
height: number;
totalWidth: number;
totalHeight: number;
};
export declare const Scrollbar: default_2.NamedExoticComponent<Omit<ScrollbarProps, "ref"> & default_2.RefAttributes<IScrollbarElement>>;
export declare const ScrollbarOrientation: {
readonly Horizontal: "horizontal";
readonly Vertical: "vertical";
};
export declare type ScrollbarOrientation = typeof ScrollbarOrientation[keyof typeof ScrollbarOrientation];
export declare interface ScrollbarProps extends default_2.HTMLAttributes<HTMLElement> {
offset: number;
viewportSize: number;
totalSize: number;
orientation: ScrollbarOrientation;
onScrollOffset: (offset: number, viewportSize: number, totalSize: number) => void;
/**
* Add custom scrollButtons.
* This should only be set to true if you have used css styling to hide the default scrollButtons
* using:
::-webkit-scrollbar-button: {
display: 'none'
}
*
* @defaultValue false
*/
showCustomScrollButtons?: boolean;
/**
* The minimum size of the thumb in pixels.
*
* @defaultValue 24
*/
minThumbSize?: number;
/**
* The maximum size of the thumb in pixels.
*
* @defaultValue undefined (no maximum size)
*/
maxThumbSize?: number;
/**
* The amount to increment the scroll position when the scroll button is clicked.
* This can be a fixed number or a function that takes the current offset, viewport size,
* and total size and returns the increment amount.
*/
scrollButtonIncrement?: number | ((offset: number, viewport: number, totalSize: number) => number);
scrollButtonInitialRepeatDelay?: number;
scrollButtonAdditionalRepeatDelay?: number;
renderScrollButtonStart?: (props: ScrollButtonProps) => default_2.ReactElement;
renderScrollButtonEnd?: (props: ScrollButtonProps) => default_2.ReactElement;
propsTouchThumb?: Partial<TouchThumbHandleProps>;
propsThumb?: default_2.HTMLAttributes<HTMLElement>;
/**
* Reference to the underling element
*/
ref?: default_2.Ref<IScrollbarElement>;
}
export declare interface ScrollButtonProps extends default_2.HTMLAttributes<any> {
orientation?: ScrollbarOrientation;
disabled?: boolean;
onMouseUp: (e: default_2.MouseEvent<any>) => void;
onMouseLeave: (e: default_2.MouseEvent<any>) => void;
onMouseDown: (e: default_2.MouseEvent<any>) => void;
onClick?: (e: default_2.MouseEvent<any>) => void;
ref?: default_2.Ref<any>;
}
export declare const ScrollPane: default_2.NamedExoticComponent<Omit<ScrollPaneProps, "ref"> & default_2.RefAttributes<IScrollPaneElement>>;
/**
* Properties fo