@linzjs/step-ag-grid
Version:
[](https://github.com/semantic-release/semantic-release) > Reusable [ag-grid](https://www.ag-grid.com/) component for LINZ / Toitū te whenua.
445 lines (416 loc) • 13.7 kB
text/typescript
//
// base types
// ----------------------------------------------------------------------
import { ForwardedRef, MutableRefObject } from 'react';
export type MenuState = 'opening' | 'open' | 'closing' | 'closed';
export type MenuAlign = 'start' | 'center' | 'end';
export type MenuDirection = 'left' | 'right' | 'top' | 'bottom';
export type MenuPosition = 'auto' | 'anchor' | 'initial';
export type MenuOverflow = 'auto' | 'visible' | 'hidden';
export type MenuReposition = 'auto' | 'initial';
export type MenuViewScroll = 'auto' | 'close' | 'initial';
export type MenuItemTypeProp = 'checkbox' | 'radio';
export type CloseReason = 'click' | 'cancel' | 'blur' | 'scroll';
/**
* - `'first'` focus the first item in the menu.
* - `'last'` focus the last item in the menu.
* - `number` focus item at the specific position (zero-based).
*/
export type FocusPosition = 'first' | 'last' | number;
export type ClassNameProp<M = undefined> = string | ((modifiers: M) => string);
export type RenderProp<M, R = React.ReactNode> = R | ((modifiers: M) => R);
export interface BaseProps<M = undefined> extends Omit<React.HTMLAttributes<HTMLElement>, 'className' | 'children'> {
ref?: React.Ref<any>;
/**
* Can be a string or a function which receives a modifier object and returns a CSS `class` string.
*/
className?: ClassNameProp<M>;
}
export interface BasePropsWithChildren<M = undefined> extends Omit<React.HTMLAttributes<HTMLElement>, 'className'> {
ref?: React.Ref<any>;
/**
* Can be a string or a function which receives a modifier object and returns a CSS `class` string.
*/
className?: ClassNameProp<M>;
}
export interface Event {
/**
* The `value` prop passed to the `MenuItem` being clicked.
* It's useful for identifying which menu item is clicked.
*/
value?: any;
/**
* Indicates the key if the event is triggered by keyboard. Can be 'Enter', ' '(Space) or 'Escape'.
*/
key?: string;
shiftKey?: boolean;
}
export interface MenuCloseEvent extends Event {
/**
* The reason that causes the close event.
*/
reason: CloseReason;
}
export interface MenuChangeEvent {
/**
* Indicates if the menu is open or closed.
*/
open: boolean;
}
export interface EventHandler<E> {
(event: E): void;
}
export interface RectElement {
getBoundingClientRect(): {
left: number;
right: number;
top: number;
bottom: number;
width: number;
height: number;
};
}
//
// Menu common types
// ----------------------------------------------------------------------
export type MenuModifiers = Readonly<{
/**
* Indicates the state of menu.
*/
state: MenuState;
/**
* Computed direction in which the menu expands.
*/
dir: MenuDirection;
}>;
export type MenuArrowModifiers = Readonly<{
/**
* Computed direction in which the menu expands.
*
* *Please note arrow points to the opposite direction of this value.*
*/
dir: MenuDirection;
}>;
export type TransitionFieldType =
| boolean
| {
open?: boolean;
close?: boolean;
item?: boolean;
};
export interface MenuStateOptions {
/**
* By default menu isn't mounted into DOM until it's opened for the first time.
* Setting the prop to `true` will change this behaviour,
* which also enables menu and its items to be server rendered.
*/
initialMounted?: boolean;
/**
* By default menu remains in DOM when it's closed.
* Setting the prop to `true` will change this behaviour.
*/
unmountOnClose?: boolean;
/**
* Enable or disable transition effects in `Menu`, `MenuItem`, and any descendent `SubMenu`.
*
* You can set 'open', 'close' and 'item' at the same time with one boolean value or separately with an object.
*
* *If you enable transition on menu, make sure to add your own animation styles,
* or import `'@szhsin/react-menu/dist/transitions/slide.css'`,
* otherwise menu cannot be closed or have visible delay when closed.*
*
* @example [CodeSandbox Demo](https://codesandbox.io/s/react-menu-sass-i1wxo)
*/
transition?: TransitionFieldType;
/**
* A fallback timeout in `ms` to stop transition if `onAnimationEnd` events are not fired.
*
* *Note: this value should be greater than or equal to the duration of
* transition animation applied on menu.*
*
* @default 500
*/
transitionTimeout?: number;
}
export interface Hoverable {
disabled?: boolean;
index?: number;
}
/**
* Common props for `Menu`, `SubMenu` and `ControlledMenu`
*/
interface BaseMenuProps extends Omit<BaseProps, 'style'> {
/**
* Can be a string or a function which receives a modifier object and returns a CSS `class` string.
*/
menuClassName?: ClassNameProp<MenuModifiers>;
/**
* This prop is forwarded to the `style` prop of menu DOM element.
*/
menuStyle?: React.CSSProperties;
/**
* Can be a string or a function which receives a modifier object and returns a CSS `class` string.
*/
arrowClassName?: ClassNameProp<MenuArrowModifiers>;
/**
* This prop is forwarded to the `style` prop of menu arrow DOM element.
*/
arrowStyle?: React.CSSProperties;
/**
* Set `true` to display an arrow pointing to its anchor element.
*/
arrow?: boolean;
/**
* Set the horizontal distance (in pixels) between menu and its anchor element.
* The value can be negative.
* @default 0
*/
offsetX?: number;
/**
* Set the vertical distance (in pixels) between menu and its anchor element.
* The value can be negative.
* @default 0
*/
offsetY?: number;
/**
* Set alignment of menu with anchor element.
* @default 'start'
*/
align?: MenuAlign;
/**
* Set direction in which menu expands against anchor element.
* @default 'bottom'
*/
direction?: MenuDirection;
/**
* Set the position of menu related to its anchor element:
*
* - 'auto' menu position is adjusted to have it contained within the viewport,
* even if it will be detached from the anchor element.
* This option allows to display menu in the viewport as much as possible.
*
* - 'anchor' menu position is adjusted to have it contained within the viewport,
* but it will be kept attached to the edges of anchor element.
*
* - 'initial' menu always stays at its initial position.
* @default 'auto'
*/
position?: MenuPosition;
/**
* Make the menu list scrollable or hidden when there is not enough viewport space to
* display all menu items. The prop is similar to the CSS `overflow` property.
* @default 'visible'
*/
overflow?: MenuOverflow;
/**
* Set computed overflow amount down to a child `MenuGroup`.
* The `MenuGroup` should have `takeOverflow` prop set as `true` accordingly.
*/
setDownOverflow?: boolean;
children?: React.ReactNode;
}
//
// MenuButton
// ----------------------------------------------------------------------
export type MenuButtonModifiers = Readonly<{
/**
* Indicates if the associated menu is open.
*/
open: boolean;
}>;
export interface MenuInstance {
/**
* Open menu and optionally request which menu item will be hovered.
*/
openMenu: (position?: FocusPosition, alwaysUpdate?: boolean) => void;
/**
* Close menu
*/
closeMenu: () => void;
}
/**
* Common props for `Menu` and `SubMenu`
*/
export interface UncontrolledMenuProps {
/**
* Menu component ref which can be used to programmatically open or close menu.
*/
instanceRef?: React.Ref<MenuInstance>;
/**
* Event fired after menu is open or closed.
*/
onMenuChange?: EventHandler<MenuChangeEvent>;
}
export interface RadioChangeEvent extends Event {
/**
* The `name` prop passed to the `MenuRadioGroup` when the menu item is in a radio group.
*/
name?: string;
/**
* Set this property on event object to control whether to keep menu open after menu item is activated.
* Leaving it `undefined` will behave in accordance with WAI-ARIA Authoring Practices.
*/
keepOpen?: boolean;
/**
* Setting this property on event object to `true` will skip `onItemClick` event on root menu component.
*/
stopPropagation?: boolean;
/**
* DOM event object (React synthetic event)
*/
syntheticEvent: MouseEvent | KeyboardEvent;
}
export interface ClickEvent extends RadioChangeEvent {
/**
* Indicates if the menu item is checked, only for `MenuItem` type="checkbox".
*/
checked?: boolean;
}
export type PortalFieldType =
| boolean
| {
/**
* A DOM node under which menu will be rendered.
*/
target?: Element | null;
/**
* When `target` is null, setting this value `true` prevents menu from rendering into the DOM hierarchy of its parent component.
*/
stablePosition?: boolean;
};
/**
* Common props for `Menu` and `ControlledMenu`
*/
export interface RootMenuProps extends BaseMenuProps, MenuStateOptions {
/**
* Properties of this object are spread to the root DOM element containing the menu.
*/
containerProps?: Omit<React.HTMLAttributes<HTMLElement>, 'className'>;
/**
* A ref object attached to a DOM element within which menu will be positioned.
* If not provided, the nearest ancestor which has CSS `overflow` set to a value
* other than 'visible' or the browser viewport will serve as the bounding box.
*/
boundingBoxRef?: React.RefObject<Element | RectElement>;
/**
* Specify bounding box padding in pixels. Use a syntax similar to the CSS
* `padding` property but sizing units are discarded.
* @example '10', '5 10', '1 2 4', or '2 5 3 1'
*/
boundingBoxPadding?: string;
/**
* Set the behaviour of menu and any of its descendent submenus when window is scrolling:
* - 'initial' The window scroll event is ignored and has no effect on menu.
* - 'auto' Menu will reposition itself based on the value of `position` prop when window is scrolling.
* - 'close' menu will be closed when window is scrolled.
* @default 'initial'
*/
viewScroll?: MenuViewScroll;
/**
* - If `true`, menu is rendered as a direct child of `document.body`,
* - or you can specify a target element in the DOM as menu container.
*
* Portal allows menu to visually “break out” of its container. Typical use cases may include:
* - An ancestor container is positioned and CSS `overflow` is set to a value other than `visible`.
* - You have a DOM structure that creates a complex hierarchy of stacking contexts,
* and menu is overlapped regardless of `z-index` value.
*/
portal?: PortalFieldType;
/**
* Specify when menu is repositioned:
* - 'initial' Don't automatically reposition menu. Set to this value when you want
* to explicitly reposition menu using the `repositionFlag` prop.
* - 'auto' Reposition menu whenever its size has changed, using the `ResizeObserver` API.
* @default 'auto'
*/
reposition?: MenuReposition;
/**
* Use this prop to explicitly reposition menu. Whenever the prop has a new value,
* menu position will be recalculated and updated.
* You might use a counter and increase it every time.
*
* *Warning: don't update this prop in rapid succession,
* which is inefficient and might cause infinite rendering of component.
* E.g., don't change the value of this prop in `window` scroll event.*
*/
repositionFlag?: number | string;
/**
* Set a delay in `ms` before opening a submenu when mouse moves over it.
* @default 300
*/
submenuOpenDelay?: number;
/**
* Set a delay in `ms` before closing a submenu when it's open and mouse is
* moving over other items in the parent menu list.
* @default 150
*/
submenuCloseDelay?: number;
/**
* Set a CSS `class` on the container element of menu for theming purpose.
*/
theming?: string;
/**
* Event fired when descendent menu items are clicked.
*/
onItemClick?: EventHandler<ClickEvent>;
/**
* NEW Don't shrink container if menu direction is "top"
*/
dontShrinkIfDirectionIsTop?: boolean;
}
export interface ExtraMenuProps {
isDisabled?: boolean;
ariaLabel?: string;
containerRef?: MutableRefObject<HTMLElement | undefined>;
externalRef?: ForwardedRef<HTMLUListElement>;
parentScrollingRef?: MutableRefObject<any>;
}
//
// ControlledMenu
// ----------------------------------------------------------------------
export interface ControlledMenuProps extends RootMenuProps, ExtraMenuProps {
/**
* Viewport coordinates to which context menu will be positioned.
*
* *Use this prop only for context menu*
*/
anchorPoint?: {
x: number;
y: number;
};
/**
* A ref object attached to a DOM element to which menu will be positioned.
*
* *Don't set this prop for context menu*
*/
anchorRef?: React.RefObject<Element>;
skipOpen?: React.MutableRefObject<boolean>;
/**
* If `true`, the menu list element will gain focus after menu is open.
* @default true
*/
captureFocus?: boolean;
/**
* Controls the state of menu. When the prop is `undefined`, menu will be unmounted from DOM.
*/
state?: MenuState;
/**
* Sets which menu item receives focus (hover) when menu opens.
* You will usually set this prop when the menu is opened by keyboard events.
*
* *Note: If you don't intend to update focus (hover) position,
* it's important to keep this prop's identity stable when your component re-renders.*
*/
menuItemFocus?: {
position?: FocusPosition;
alwaysUpdate?: boolean;
};
/**
* Set the return value of `useMenuState` to this prop.
*/
endTransition?: () => void;
/**
* Event fired when menu is about to close.
*/
onClose?: EventHandler<MenuCloseEvent>;
}