@sheetxl/utils-react
Version:
Utils React - Utilities for React capabilities needed for all SheetXL components.
1,361 lines (1,241 loc) • 49.1 kB
TypeScript
import { CellCoords } from '@sheetxl/utils';
import { default as default_2 } from 'react';
import { DependencyList } from 'react';
import { Dimensions } from '@sheetxl/utils';
import { Direction } from '@sheetxl/utils';
import { EditModeHandler } from '@sheetxl/utils';
import { JSX } from 'react/jsx-runtime';
import { ReferenceableClipboard } from '@sheetxl/utils';
import { RemoveListener } from '@sheetxl/utils';
import { TopLeft } from '@sheetxl/utils';
import { UndoManager } from '@sheetxl/utils';
declare function boundPixel(pixel: number, _increase?: boolean, _absOffset?: number): number;
export declare interface BusyNotificationOptions {
icon?: React.ReactNode;
}
export declare type CellFinder = (activeCoords: CellCoords, isContentfulCell: IsContentfulCell | undefined, hiddenAt: HiddenHeadersAt | undefined, direction: Direction, first: boolean, limit: number) => number;
export declare interface CellLayout {
/**
* 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 type ClickOrFocusAwayListener = (event: globalThis.MouseEvent | globalThis.KeyboardEvent) => void;
export declare interface ClickOrFocusAwayOptions {
mouseEvents?: boolean;
focusEvents?: boolean;
}
export declare class Command<STATE extends any = void, CONTEXT extends any = void> implements ICommand<STATE, CONTEXT> {
protected _key: string;
protected _target: ICommands.ITarget | (() => ICommands.ITarget);
protected _label: DynamicValue<string, CONTEXT>;
protected _scopedLabels?: Record<string, DynamicValue<string, CONTEXT>>;
protected _description?: DynamicValue<string, CONTEXT>;
protected _icon: DynamicValue<React.ReactNode, CONTEXT>;
protected _tags: DynamicValue<string[], CONTEXT>;
protected _shortcut: DynamicValue<IKeyStroke | IKeyStroke[] | null, CONTEXT>;
protected _disabled: DynamicValue<boolean, CONTEXT>;
protected _state: STATE;
protected _context: CONTEXT;
protected _callback: ICommandCallback<STATE>;
protected _listenersProperties: Set<ICommandPropertyListener<STATE, CONTEXT>>;
protected _listenersExecute: Set<ICommandHook<STATE, CONTEXT>>;
constructor(key: string, target: ICommands.ITarget | (() => ICommands.ITarget), props?: ICommandProperties<STATE, CONTEXT>, callback?: ICommandCallback<STATE>);
key(): string;
protected _resolve<T = any>(value: DynamicValue<T, CONTEXT>, scopedContext?: CONTEXT | (() => CONTEXT)): T;
target(): ICommands.ITarget;
label(scope?: string, scopedContext?: CONTEXT): string;
description(context?: DynamicContext<CONTEXT>): string;
tags(context?: DynamicContext<CONTEXT>): string[];
icon(context?: DynamicContext<CONTEXT>): React.ReactNode;
shortcut(): IKeyStroke | IKeyStroke[];
disabled(): boolean;
state(): STATE;
context(): any;
execute(args: STATE, hook?: ICommandHook<STATE, CONTEXT>): Promise<boolean>;
/**
* This is call when any command properties are changed but not when the callback is changed
*/
addPropertyListener(listener: ICommandPropertyListener<STATE, CONTEXT>, fireOnListen?: boolean): RemoveListener;
addExecuteListener(listener: ICommandHook<STATE, CONTEXT>): RemoveListener;
protected _notifyExecute(args: STATE): void;
protected _notifyError(error: any, args: STATE): void;
updateCallback(callback: ICommandCallback<STATE>): ICommand<STATE, CONTEXT>;
update(props: ICommandProperties<STATE, CONTEXT>): ICommand<STATE, CONTEXT>;
protected _notifyPropertyChange(props: ICommandProperties<STATE, CONTEXT>): void;
protected _applyProps(props: ICommandProperties<STATE, CONTEXT>): ICommandProperties<STATE, CONTEXT>;
}
export declare interface CommandButtonCreator {
}
export declare interface CommandButtonMeta {
}
export declare interface CommandButtonRegistry {
}
/**
* 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: ICommands.ITarget | (() => ICommands.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: ICommandPropertyListener<any, any>;
constructor(target: ICommands.ITarget | (() => ICommands.ITarget), groupKey?: string);
private _getCommand;
/** {@inheritDoc ICommands.IGroup.getCommand} */
getCommand(key: string, _ignoreActive?: boolean): ICommand<any, any>;
/** {@inheritDoc ICommands.IGroup.createChildGroup} */
createChildGroup(target: ICommands.ITarget | (() => ICommands.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;
/**
* A notifier to provide for warnings and errors.
*/
notifier?: Notifier;
}
export declare interface CopyPasteResults {
copy: (args?: ReferenceableClipboard.CopyOptions) => void;
paste: (args?: ReferenceableClipboard.PasteOptions) => void;
/**
* The clipboard used. Generally the `InternalClipboard.Global`.
*/
clipboard: ReferenceableClipboard;
}
declare const createSyntheticEvent: <T extends Element, E extends Event>(event: E) => React.SyntheticEvent<T, E>;
export declare const defaultCreateScrollbar: (props: ScrollbarRefProps) => JSX.Element;
export declare const defaultCreateScrollCorner: ({ width, height }: {
width: any;
height: any;
}) => 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 DefaultNotifier: Notifier;
/**
* 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;
}
declare type DynamicContext<CONTEXT> = CONTEXT | (() => CONTEXT);
declare type DynamicValue<T, CONTEXT> = T | ((context?: DynamicContext<CONTEXT>) => T);
declare const EmptyCssProperties: React.CSSProperties;
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 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 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
*/
key(): string;
target(): ICommands.ITarget;
disabled(): boolean;
execute(args?: STATE, hook?: ICommandHook<STATE, CONTEXT>): Promise<boolean>;
/**
* Represents the current state of the value that can also be set
*/
state(): STATE;
context(): CONTEXT;
/**
* Additional information that may be needed to render or make decisions about setting state.
*/
update(props: ICommandProperties<STATE, CONTEXT>): ICommand<STATE, CONTEXT>;
updateCallback(callback: ICommandCallback<STATE>): ICommand<STATE, CONTEXT>;
/**
* This is call when any command properties are changed but not when the callback is changed
*/
addPropertyListener(listener: ICommandPropertyListener<STATE, CONTEXT>, fireOnListen?: boolean): RemoveListener;
addExecuteListener(listener: ICommandHook<STATE, CONTEXT>): RemoveListener;
shortcut(): IKeyStroke | IKeyStroke[];
label(scope?: string, context?: DynamicContext<CONTEXT>): string;
tags(context?: DynamicContext<CONTEXT>): string[];
description(context?: DynamicContext<CONTEXT>): string;
icon(context?: DynamicContext<CONTEXT>): React.ReactNode;
}
export declare interface ICommandCallback<STATE extends any = void> {
(args?: STATE, command?: ICommand<STATE, unknown>): void | boolean | Promise<boolean> | Promise<void>;
}
/**
* A hook that can be passed to a command execute function.
*/
export declare interface ICommandHook<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 ICommandHook<STATE, CONTEXT> {
onChange?(command: ICommand<STATE, CONTEXT>): void;
}
export declare interface ICommandListenerOptions {
fireOnCommandChange: boolean;
}
export declare interface ICommandProperties<STATE extends any = void, CONTEXT extends any = void> {
disabled?: boolean | (() => boolean);
state?: STATE;
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 declare interface ICommandPropertyListener<STATE extends any, CONTEXT extends any> {
/**
* Called when command properties have changed.
*/
(props: ICommandProperties<STATE, CONTEXT>, command: ICommand<STATE, CONTEXT>): void;
}
/**
* 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[];
}
/**
* 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;
}
/**
* 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 ICommands.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: ICommands.ITarget | (() => ICommands.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 ICommandHook<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 interface IKeyStroke {
readonly key: string;
readonly modifiers?: KeyModifiers[];
}
export declare interface InputOptionsNotificationOptions extends OptionsNotificationOptions {
initialValue?: string;
/**
* Css style for input
*/
inputProps?: React.HTMLAttributes<HTMLInputElement | HTMLTextAreaElement>;
inputLabel?: string;
inputType?: 'text' | 'password' | 'email' | 'number' | 'search' | 'tel' | 'url';
inputPlaceHolder?: string;
onInputOption?: (input?: string, option?: string) => void;
/**
* Call when an option is selected. If false is returned, the the
* dialog will not close. Notification is not provided but can
* be supplied via the textFieldProps helperText property.
* @remarks
* Optional the textProps can be updated via the textFieldProps argument
*/
onValidateInputOption?: (input?: string, option?: string) => InputValidationResults | Promise<InputValidationResults>;
}
export declare interface InputResults {
input: string;
option: string;
}
export declare interface InputValidationResults {
valid: boolean;
message?: string;
}
export declare interface IsContentfulCell {
(coords: CellCoords): boolean;
}
export declare interface IScrollPaneElement extends HTMLDivElement, ScrollPaneAttributes {
}
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;
};
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];
export declare const MouseButtonCodes: {
readonly Left: 1;
readonly Middle: 2;
readonly Right: 3;
};
export declare type MouseButtonCodes = typeof MouseButtonCodes[keyof typeof MouseButtonCodes];
/**
* Configuration for non-blocking notifications.
*/
declare interface NotificationOptions_2 {
/**
* A hint for decorations of the message.
*/
type?: NotificationType;
/**
* Setting this to true will leave the notification on the screen unless it is dismissed (programmatically or through user interaction).
* If `false` will be removed after a period of time.
*
* @defaultValue false
*/
persist?: boolean;
/**
* Ignores displaying multiple snackBars with the same `message`.
*
* @defaultValue false
*/
preventDuplicate?: boolean;
/**
* If provided then then notification provider should not notify if the same id is used again.
*/
onceKey?: string;
/**
* Passed directly to the Snackbar component.
*/
enqueueProps?: Record<string, any>;
}
export { NotificationOptions_2 as NotificationOptions }
/**
* Indicates the type of notification.
*/
export declare const NotificationType: {
readonly Default: "default";
readonly Error: "error";
readonly Success: "success";
readonly Warning: "warning";
readonly Info: "info";
};
export declare type NotificationType = typeof NotificationType[keyof typeof NotificationType];
/**
* Interface that provides popups for the user.
*/
export declare interface Notifier {
/**
* Useful when informing the user of something but are not expecting a response.
*/
showMessage?: (message: string | React.ReactNode, options?: NotificationOptions_2) => 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 | React.ReactNode, options?: BusyNotificationOptions) => (Promise<() => void>) | (() => void);
/**
* Show a dialog for a given type.
* @param type
* @param props
* @param options
*/
showWindow?: (type: string, props?: any, options?: {
disableAutoDestroy?: boolean;
}) => Promise<HTMLElement>;
/**
* Should return error object exception.
*
* @param error
*/
showError?: (error: Error | string) => void;
/**
* Provide a user with a list of options to choose from.
* @param options
*/
showOptions?: (options: OptionsNotificationOptions) => Promise<string>;
/**
* Provider a user with a way to enter a text input.
* @param options
*/
showInputOptions?: (options: InputOptionsNotificationOptions) => Promise<InputResults>;
}
export declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
/**
* Configuration for an options dialog.
*/
export declare interface OptionsNotificationOptions extends React.HTMLAttributes<HTMLDivElement> {
/**
* The options as a list of strings
*/
options?: string[];
/**
* The title of the options panel
*/
title?: string;
/**
* Display text information for the user to make a decision.
*/
description?: string;
/**
* Display an icon next to the description for additional context
*
* @remarks
* Not yet implemented
*/
icon?: React.ReactNode;
/**
* Allows for the option will be the default selected option and the enter key trigger.
* @defaultValue The first option
*/
defaultOption?: string;
/**
* Allows for the cancel option to be specified. Allow for special styling.
* @defaultValue 'Cancel'
*/
cancelOption?: string;
/**
* Call when an option is selected.
* @remarks
* It is possible that the option can be both a cancel and a default option.
*/
onOption?: (option: string, isCancel: boolean, isDefault: boolean) => void;
/**
* Hook for create custom options buttons
* @param props
*
* @remarks
* The option is passed as the `children` prop and as the second argument
*/
createOptionsButton?: (option: string, props: React.HTMLAttributes<HTMLButtonElement> & React.Attributes, isDefaultOption: boolean) => React.ReactNode;
/**
* Call when an option is selected. If false is returned, the the
* dialog will not close. Notification is not provided but can
* be supplied via the textFieldProps helperText property.
*/
onValidateOption?: (option?: string) => boolean | Promise<boolean>;
}
/**
* If returns false don't setup the other listeners
*/
export declare type PointerDownListener = (event: default_2.PointerEvent<Element>) => void;
export declare interface PointerHandlerOptions {
/**
* If returns false then other events will not be fired
*/
onPointerDown: (event: default_2.PointerEvent<Element>, modifiers: PointerModifiers) => boolean | void;
/**
* If the Pointer has moved or it the Pointer was held for a period of timerContinuous.
*/
onPointerMoveOrWait?: (event: globalThis.PointerEvent, modifiers: PointerModifiers, originalEvent: default_2.PointerEvent<Element>) => 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: globalThis.PointerEvent, modifiers: PointerModifiers, originalEvent: default_2.PointerEvent<Element>) => 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 namespace ReactUtils {
export {
detectIt,
boundPixel,
focusableNodeNames,
EmptyCssProperties,
toPrettyKeyCode,
createSyntheticEvent
}
}
export declare interface RepeatClickOptions {
timerInitial?: number;
timerContinuous?: number;
}
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<ScrollbarProps & default_2.RefAttributes<HTMLDivElement>>;
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;
totalSize: number;
viewportSize: 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;
scrollButtonIncrement?: number;
scrollButtonInitialRepeatDelay?: number;
scrollButtonAdditionalRepeatDelay?: number;
createScrollStartButton?: (props: ScrollButtonProps) => default_2.ReactElement;
createScrollEndButton?: (props: ScrollButtonProps) => default_2.ReactElement;
}
export declare interface ScrollbarRefProps extends ScrollbarProps {
ref?: React.Ref<HTMLDivElement>;
}
export declare interface ScrollButtonProps {
style?: default_2.CSSProperties;
orientation?: ScrollbarOrientation;
disabled: boolean;
onMouseUp: (e: default_2.MouseEvent<HTMLElement>) => void;
onMouseLeave: (e: default_2.MouseEvent<HTMLElement>) => void;
onMouseDown: (e: default_2.MouseEvent<HTMLElement>) => void;
onClick?: (e: default_2.MouseEvent<HTMLElement>) => void;
}
export declare const ScrollPane: default_2.FC<ScrollPaneProps & {
ref?: default_2.Ref<IScrollPaneElement>;
}>;
export declare interface ScrollPaneAttributes {
isScrollPane: () => true;
}
export declare interface ScrollPaneProps extends React.HTMLAttributes<HTMLDivElement> {
viewport: ScrollableViewport;
onScrollViewport?: (scrollPoint: Partial<TopLeft>) => void;
showHorizontalScrollbar?: boolean;
showVerticalScrollbar?: boolean;
createScrollCorner?: (dims: Dimensions) => React.ReactNode;
createHorizontalScrollbar?: (props: ScrollbarRefProps) => React.ReactNode;
createVerticalScrollbar?: (props: ScrollbarRefProps) => React.ReactNode;
/**
* By default the ScrollPane will listen for events on all of the children of the ScrollPane but this
* allows for a custom element to be specified. Useful when the ScrollPane has some elements
* that should not be touch enabled (for example headers)
*/
touchElement?: HTMLElement;
/**
* If touch is disabled.
* @defaultValue false unless no touch events are detected
*/
disableTouch?: boolean;
}
export declare interface ScrollState extends TopLeft {
horizontalScrollDirection: Direction | null;
verticalScrollDirection: Direction | null;
}
export declare namespace ScrollUtils {
export {
getScrollTo
}
}
export declare class SimpleCommand extends Command<void, void> {
}
/**
* SplitPane
* A component can have two children and will add a resizer between the two.
* @remarks
*
* Because this component measures the elements (both panes and the resizer) it is important
* that none of these have margins or paddings. If these are required then use a nested element.
*/
export declare const SplitPane: default_2.FC<SplitPaneProps & {
ref?: default_2.Ref<ISplitPaneElement>;
}>;
export declare interface SplitPaneAttributes {
/**
* Programmatic api to set the position. Can be either a string with px or %.
* If it is a number it will be interpreted based on whether there is a fixed pane or not.
* @param position - Pixels as `string` or a percent as a `number`.
*/
setPosition: (position: string | number) => void;
isSplitPane: () => true;
}
export declare interface SplitPaneProps extends default_2.HTMLAttributes<HTMLDivElement> {
/**
* The elementBefore the divider.
*/
elementBefore?: default_2.ReactElement<any>;
/**
* The element after the divider.
*/
elementAfter?: default_2.ReactElement<any>;
/**
* If the fixedPane is set resizing will keep one the sizes.
*
* @remarks
* When set the default position to be interpreted as pixels.
*/
fixedPane?: 'before' | 'after' | null;
/**
* The position. Can be either a string with px or %.
* If it is a number it will be interpreted based on whether there is a fixed pane or not.
*/
position?: number | string;
/**
* The minimum size. Can be either a string with px or %.
* If it is a number it will be interpreted based on whether there is a fixed pane or not.
*/
minBefore?: number | string;
/**
* The minimum size. Can be either a string with px or %.
* If it is a number it will be interpreted based on whether there is a fixed pane or not.
*/
maxBefore?: number | string;
/**
* The minimum size. Can be either a string with px or %.
* If it is a number it will be interpreted based on whether there is a fixed pane or not.
*/
minAfter?: number | string;
/**
* The minimum size. Can be either a string with px or %.
* If it is a number it will be interpreted based on whether there is a fixed pane or not.
*/
maxAfter?: number | string;
/**
* When the position has been changed.
* @remarks This is not fired during drag.
* @param position
*/
onPositionChange?: (position: {
pixels: number;
percent: number;
}) => void;
/**
* Determine the direction of the scrollPane
*/
splitDirection?: 'row' | 'column';
disabled?: boolean;
resizerProps?: SplitPaneResizerProps;
paneProps?: default_2.HTMLAttributes<HTMLElement>;
paneBeforeProps?: default_2.HTMLAttributes<HTMLElement>;
paneAfterProps?: default_2.HTMLAttributes<HTMLElement>;
onDragStart?: () => void;
onDragResize?: (position: number) => void;
onDragFinish?: (position: number) => void;
createResizer?: (props: SplitPaneResizerProps & default_2.Attributes & {
ref?: default_2.Ref<HTMLDivElement>;
}) => default_2.ReactElement;
}
export declare const SplitPaneResizer: (props: SplitPaneResizerProps & default_2.Attributes & {
ref?: default_2.Ref<HTMLDivElement>;
}) => default_2.ReactElement;
export declare interface SplitPaneResizerProps extends default_2.HTMLAttributes<HTMLDivElement> {
splitDirection?: 'row' | 'column';
disabled?: boolean;
paddingBefore?: number;
paddingAfter?: number;
hitAreaProps?: default_2.HTMLAttributes<HTMLDivElement>;
}
export declare interface Style {
stroke?: string;
strokeLeftColor?: string;
strokeTopColor?: string;
strokeRightColor?: string;
strokeBottomColor?: string;
strokeWidth?: number;
strokeTopWidth?: number;
strokeRightWidth?: number;
strokeBottomWidth?: number;
strokeLeftWidth?: number;
strokeStyle?: string;
}
export declare interface TextSelectionRange {
start: number;
end: number;
direction?: 'forward' | 'backward' | 'none';
}
export declare const ToolTipPlacement: {
readonly BottomEnd: "bottom-end";
readonly BottomStart: "bottom-start";
readonly Bottom: "bottom";
readonly LeftEnd: "left-end";
readonly LeftStart: "left-start";
readonly Left: "left";
readonly RightEnd: "right-end";
readonly RightStart: "right-start";
readonly Right: "right";
readonly TopEnd: "top-end";
readonly TopStart: "top-start";
readonly Top: "top";
};
export declare type ToolTipPlacement = typeof ToolTipPlacement[keyof typeof ToolTipPlacement];
declare const toPrettyKeyCode: (key: string) => string;
export declare const toShortcutString: (keyStroke: IKeyStroke, modifierSymbol?: boolean) => string;
export declare interface UndoContext {
readonly undoManager: UndoManager;
}
export declare interface UndoManagerProps {
manager: UndoManager;
/**
* Not allow to invoke undo/redo
* Interesting.... Because this is sharable and not scoped to an object it's not clear the best
* way to disable/protect a sheet. Excel clears the undo stack!
*/
disabled?: boolean;
notifier?: Notifier;
commands?: ICommands.IGroup;
}
export declare interface UndoManagerResults {
/**
* Call undo manager via command
*/
undo: (count?: number) => void;
/**
* Call undo manager via command
*/
redo: (count?: number) => void;
}
/**
* This is a callback hook that is similar to useCallback except in
* one important way. When it's dependencies change it does
* NOT update the callback handler itself. Useful
* in the instance where you want to pass a callback and
* want to avoid have stale values do to closure but don't
* want a re-render to occur.
*/
export declare const useCallbackRef: <T extends (...args: any[]) => any>(callback: T, deps: DependencyList) => T;
/**
* Useful for capture command changes. This can be used with an @see ICommandHook or without.
* If used with then will call the function. If not then a change will force a re-render.
* @param command
* @param listener
*/
export declare function useCommand<STATE = any, CONTEXT = any>(command: ICommand<STATE, CONTEXT> | ICommand<STATE, CONTEXT>[], listener?: ICommandListener<STATE, CONTEXT>): number;
/**
* Useful for capture command changes. This can be used with an @see ICommandHook or without.
* If used with then will call the function. If not then a change will force a re-render.
*
* @param commands
* @param keys
* @param listener
* @param deps Optional dependencies to trigger a re-render
*
* @remarks
* A change to the commands, keys, or listeners will not trigger a rerender. The deps argument can be used.
*/
export declare function useCommands<STATE extends any, CONTEXT extends any = void>(commands: ICommands.IGroup, keys?: string[], listener?: ICommandsListeners<STATE, CONTEXT>, deps?: React.DependencyList): ICommand<STATE, CONTEXT>[];
/**
* Copy paste hook.
*/
export declare const useCopyPaste: (props: CopyPasteProps) => CopyPasteResults;
/**
* Get the device pixel ratio, potentially rounded and capped.
* Will emit new values if it changes.
*
* @param options
* @returns The current device pixel ratio, or the default if none can be resolved
*/
export declare function useDevicePixelRatio(options?: DevicePixelRatioOptions): number;
export declare const useEditMode: () => EditModeHandler;
export declare function useFullscreenPortal(): FullscreenPortalRoot;
export declare const useGlobalClipboard: any;
/**
* Uses React 18's built-in `useId()` when available, or falls back to a
* slightly less performant (requiring a double render) implementation for
* earlier React versions.
*
* @see {@link https://movable-ui.com/docs/useId}
*/
export declare const useId: any;
export declare function useImperativeElement<R extends T, A = any, T = HTMLElement & A>(refForwarded: React.Ref<R>, attributeFn?: () => Partial<A>, deps?: DependencyList): React.RefObject<R>;
/**
* Simple hook that calls onMouseDown at intervals until mouse is up.
*
* @remarks
* Fires the original mouse down event so preventDefault should be ignored or treated accordingly.
*/
export declare function useMouseDownAndHoldListener(onPointerDown: (event: default_2.PointerEvent<Element>) => boolean | void, options?: RepeatClickOptions): (event: default_2.PointerEvent<Element>) => void;
export declare function useOnClickOrFocusAway(ref: default_2.RefObject<any>, listenerArg: ClickOrFocusAwayListener, options?: ClickOrFocusAwayOptions): void;
/**
* This hook will respond on Pointer down and then continue to fire events
* until the Pointer is released.
*
* Returns PointerDownListener that should be added to the
* source component's onPointerDown event handler.
*/
export declare function useSynchronizedPointerHandler(options: PointerHandlerOptions): PointerDownListener;
export declare function useTraceUpdate(props: any, enabled?: boolean): void;
/**
* Undo manager hook
*/
export declare const useUndoManager: ({ manager, commands: commandsParent, disabled: propDisabled, notifier }: UndoManagerProps) => UndoManagerResults;
/**
* The virtual scrollbar is for very large scroll area.
* Browsers have issues with more than divs more than 6m pixels width/height (which by most account is reasonable).
*
* This virtualScrollbar also has an elastic component that allows the scrollbar to shrink to its minSize
* for easier scrolling for large virtual areas with small content areas. (Similar to excel desktop)
*
* Note -
* Because of the virtual nature of the scrollbar the onScroll method is disabled
* and onScrollOffset must be used.
*/
export declare const VirtualScrollbar: default_2.NamedExoticComponent<VirtualScrollbarProps & default_2.RefAttributes<HTMLDivElement>>;
export declare interface VirtualScrollbarProps extends Omit<ScrollbarProps, "onScroll"> {
/**
* Amount of scrollbar between minSize and totalSize. This is mean to show that there is more scroll area.
* @defaultValue 100
*/
endGap?: number;
/**
* If this is the minimum scrollbar size.
* By default this is the bottom of the viewport but can be extended.
* @defaultValue 0
*/
minSize?: number;
/**
* Determines the increment amount when the scrollbar has been dragged to the end but is not scrolled to total size.
* @defaultValue 100;
*/
endScrollIncrement?: number;
/**
* The max size of the area before scaling is implemented.
* @defaultValue 1000000
*/
scaleLimit?: number;
/**
* The factor amount for physical scaling
* @defaultValue 100
*/
scaleFactor?: number;
/**
* The default precision. This is a factor of the scale factor.
* @defaultValue 50
*/
precisionFactor?: number;
}
export { }