UNPKG

@sheetxl/utils-react

Version:

Utils React - Utilities for React capabilities needed for all SheetXL components.

1,361 lines (1,241 loc) 49.1 kB
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 { }