@vitus-labs/elements
Version:
Most basic react reusable components
851 lines (785 loc) • 26.3 kB
TypeScript
import type { BreakpointKeys } from '@vitus-labs/core';
import type { ComponentType } from 'react';
import { config } from '@vitus-labs/core';
import { Context } from './context';
import { FC } from 'react';
import type { ForwardedRef } from 'react';
import type { ForwardRefExoticComponent } from 'react';
import { HTMLTags } from '@vitus-labs/core';
import type { HTMLTextTags } from '@vitus-labs/core';
import type { PropsWithoutRef } from 'react';
import { Provider } from '@vitus-labs/unistyle';
import { ReactNode } from 'react';
import type { RefAttributes } from 'react';
import { RefObject } from 'react';
import { render } from '@vitus-labs/core';
declare type Align = 'bottom' | 'top' | 'left' | 'right';
declare type Align_2 = 'bottom' | 'top' | 'left' | 'right';
export declare type AlignX = ContentAlignX | ContentAlignX[] | Partial<Record<BreakpointKeys, ContentAlignX>>;
declare type AlignX_2 = 'left' | 'center' | 'right';
declare type AlignX_3 = 'left' | 'center' | 'right';
export declare type AlignY = ContentAlignY | ContentAlignY[] | Partial<Record<BreakpointKeys, ContentAlignY>>;
declare type AlignY_2 = 'bottom' | 'top' | 'center';
declare type AlignY_3 = 'bottom' | 'top' | 'center';
export declare type Content = Parameters<typeof render>['0'];
declare type ContentAlignX = 'left' | 'center' | 'right' | 'spaceBetween' | 'spaceAround' | 'block';
declare type ContentAlignY = 'top' | 'center' | 'bottom' | 'spaceBetween' | 'spaceAround' | 'block';
export declare type ContentBoolean = boolean;
declare type ContentDirection = 'inline' | 'rows' | 'reverseInline' | 'reverseRows';
declare type ContentRenderer = (props: Partial<{
active: boolean;
showContent: () => void;
hideContent: () => void;
align: Align_2;
alignX: AlignX_3;
alignY: AlignY_3;
}>) => ReactNode;
declare type ContentSimpleValue = string | number;
declare interface Context_2 {
blocked: boolean;
setBlocked: () => void;
setUnblocked: () => void;
}
declare type Css = CssCallback | string;
declare type CssCallback = (css: typeof config.css) => ReturnType<typeof css>;
export declare type Direction = ContentDirection | ContentDirection[] | Partial<Record<BreakpointKeys, ContentDirection>>;
declare const Element_2: VLElement;
export { Element_2 as Element }
export declare type ElementProps = Partial<{
/**
* Valid HTML Tag
*/
tag: HTMLTags;
/**
* React `ref`, the prop is alternative to `ref` prop without need to wrap component to `forwardRef`
*/
innerRef: InnerRef;
/**
* Valid React `children`
*/
children: Content;
/**
* Alternative prop to React `children`
* It is recommended to pass only one of `children`, `content` or `label` props
*
* The prioritization of rendering is following: `children` → `content` → `label`
*/
content: Content;
/**
* Alternative prop to React `children`
* It is recommended to pass only one of `children`, `content` or `label` props
*
* The prioritization of rendering is following: `children` → `content` → `label`
*/
label: Content;
/**
* Valid React `children` to be rendered inside _beforeContent_ wrapper
*
* In a case, where at least one of `beforeContent` or `afterContent` is defined,
* **Element** component will render additional inner wrapper helpers to
* attach `beforeContent` **before** any of `children`, `context` or `label`
* props.
*
* Together with prop `direction` can be the **Element** component aligned
* vertically or horizontally.
*
* To attach any react node _after_, use `afterContent`
*/
beforeContent: Content;
/**
* Valid React `children` to be rendered inside _afterContent_ wrapper
*
* In a case, where at least one of `beforeContent` or `afterContent` is defined,
* **Element** component will render additional inner wrapper helpers to
* attach `afterContent` **after** any of `children`, `context` or `label`
* props.
*
* Together with prop `direction` can be the **Element** component aligned
* vertically or horizontally.
*
* To attach any react node _before_, use `beforeContent`
*/
afterContent: Content;
/**
* A boolean type to define whether **Element** should behave
* as an inline or block element (`flex` vs. `inline-flex`)
*/
block: ResponsiveBoolType;
/**
* A boolean type to define whether inner wrappers should be equal
* (have the same width or height)
*/
equalCols: ResponsiveBoolType;
/**
* Defines a `gap` spacing between inner wrappers between `beforeContent` and `children`
* and `children` and `afterContent`
*/
gap: Responsive;
/**
* Defines a `gap` spacing between inner wrappers between `beforeContent`,
* `children` and `afterContent`
*/
direction: Direction;
/**
* Defines flow of `children` elements within it's inner wrapper.
*
* Can be one of the following **flex** values `inline` | `rows` | `reverseInline` | `reverseRows`
*/
contentDirection: Direction;
/**
* Defines flow of `beforeContent` elements within it's inner wrapper.
*
* Can be one of the following **flex** values `inline` | `rows` | `reverseInline` | `reverseRows`
*/
beforeContentDirection: Direction;
/**
* Defines flow of `afterContent` elements within it's inner wrapper.
*
* Can be one of the following **flex** values `inline` | `rows` | `reverseInline` | `reverseRows`
*/
afterContentDirection: Direction;
/**
* Define alignment of `beforeContent`, `content`, and `afterContent`
* with respect to root element **horizontally**.
*
* Can be one of the following **flex** values `left` | `center` | `right` | `spaceBetween` |
* `spaceAround` | `block`
*/
alignX: AlignX;
/**
* Defines how `content` children (`children`, `content` or `label` props)
* are aligned within it's inner wrapper **horizontally**.
*
* Can be one of the following **flex** values `left` | `center` | `right` | `spaceBetween` |
* `spaceAround` | `block`
*/
contentAlignX: AlignX;
/**
* Defines how `beforeContent` children are aligned within it's inner wrapper **horizontally**.
*
* Can be one of the following **flex** values `left` | `center` | `right` | `spaceBetween` |
* `spaceAround` | `block`
*/
beforeContentAlignX: AlignX;
/**
* Defines how `afterContent` children are aligned within it's inner wrapper **horizontally**.
*
* Can be one of the following **flex** values `left` | `center` | `right` | `spaceBetween` |
* `spaceAround` | `block`
*/
afterContentAlignX: AlignX;
/**
* Define alignment of `beforeContent`, `content`, and `afterContent`
* with respect to root element **vertically**.
*
* Can be one of the following **flex** values `top` | `center` | `bottom` | `spaceBetween` |
* `spaceAround` | `block`
*/
alignY: AlignY;
/**
* Defines how `content` children (`children`, `content` or `label` props)
* are aligned within it's inner wrapper **vertically**.
*
* Can be one of the following **flex** values `top` | `center` | `bottom` | `spaceBetween` |
* `spaceAround` | `block`
*/
contentAlignY: AlignY;
/**
* Defines how `beforeContent` children are aligned within it's inner wrapper **vertically**.
*
* Can be one of the following **flex** values `top` | `center` | `bottom` | `spaceBetween` |
* `spaceAround` | `block`
*/
beforeContentAlignY: AlignY;
/**
* Defines how `afterContent` children are aligned within it's inner wrapper **vertically**.
*
* Can be one of the following **flex** values `top` | `center` | `bottom` | `spaceBetween` |
* `spaceAround` | `block`
*/
afterContentAlignY: AlignY;
/**
* React `dangerouslySetInnerHTML` prop. For more details follow the link:
*
* https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
*/
dangerouslySetInnerHTML: {
__html: string;
};
/**
* An additional prop for extending styling of the **root** wrapper element
*
* #### [A] Template literals
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [B] String
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css="text-color: red;"
* />
* )
* ```
*
* #### [C] Css Function
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* import { css } from 'styled-components'
*
* export default () => (
* <Element
* label="This is an element"
* css={css`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [D] Css Callback
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={css => css`
* text-color: red;
* `}
* />
* )
* ```
*/
css: ExtendCss;
/**
* An additional prop for extending styling of the **content** wrapper element
*
* #### [A] Template literals
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [B] String
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css="text-color: red;"
* />
* )
* ```
*
* #### [C] Css Function
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* import { css } from 'styled-components'
*
* export default () => (
* <Element
* label="This is an element"
* css={css`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [D] Css Callback
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={css => css`
* text-color: red;
* `}
* />
* )
* ```
*/
contentCss: ExtendCss;
/**
* An additional prop for extending styling of the **beforeContent** wrapper element
*
* #### [A] Template literals
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [B] String
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css="text-color: red;"
* />
* )
* ```
*
* #### [C] Css Function
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* import { css } from 'styled-components'
*
* export default () => (
* <Element
* label="This is an element"
* css={css`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [D] Css Callback
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={css => css`
* text-color: red;
* `}
* />
* )
* ```
*/
beforeContentCss: ExtendCss;
/**
* An additional prop for extending styling of the **afterContent** wrapper element
*
* #### [A] Template literals
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [B] String
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css="text-color: red;"
* />
* )
* ```
*
* #### [C] Css Function
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* import { css } from 'styled-components'
*
* export default () => (
* <Element
* label="This is an element"
* css={css`
* text-color: red;
* `}
* />
* )
* ```
*
* #### [D] Css Callback
*
* (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
*
* ```jsx
* export default () => (
* <Element
* label="This is an element"
* css={css => css`
* text-color: red;
* `}
* />
* )
* ```
*/
afterContentCss: ExtendCss;
}>;
export declare type ElementType<T extends Record<string, unknown> = any> = ComponentType<T> | ForwardRefExoticComponent<T> | HTMLTags;
export declare type ExtendCss = Css | Css[] | Partial<Record<BreakpointKeys, Css>>;
export declare type ExtendedProps = {
index: number;
first: boolean;
last: boolean;
odd: boolean;
even: boolean;
position: number;
};
declare type ExtractNullableKeys<T> = {
[P in keyof T as T[P] extends null | undefined ? never : P]: T[P];
};
declare type Id<T> = T extends infer U ? {
[K in keyof U]: U[K];
} : never;
export declare type InnerRef = ForwardedRef<any>;
export declare type IteratorProps = Partial<{
/**
* Valid React `children`
*/
children: ReactNode;
/**
* Array of data passed to `component` prop
*/
data: Array<SimpleValue | ObjectValue | MaybeNull>;
/**
* A React component to be rendered within list
*/
component: ElementType;
/**
* Defines name of the prop to be passed to the iteration component
* when **data** prop is type of `string[]`, `number[]` or combination
* of both. Otherwise ignored.
*/
valueName: string;
/**
* A React component to be rendered within list. `wrapComponent`
* wraps `component`. Therefore it can be used to enhance the behavior
* of the list component
*/
wrapComponent: ElementType;
/**
* Extension of **item** `component` props to be passed
*/
itemProps: PropsCallback;
/**
* Extension of **item** `wrapComponent` props to be passed
*/
wrapProps?: PropsCallback;
/**
* Extension of **item** `wrapComponent` props to be passed
*/
itemKey?: keyof ObjectValue | ((item: SimpleValue | Omit<ObjectValue, 'component'>, index: number) => SimpleValue);
}>;
declare type Key = string | number;
export declare const List: VLElement<ListProps>;
export declare type ListProps = MergeTypes<[IteratorProps, ListProps_2]>;
declare type ListProps_2 = {
/**
* A boolean value. When set to `false`, component returns `React.Fragment`
* When set to `true`, component returns as the **root** element `Element`
* component.
*/
rootElement?: boolean;
/**
* Label prop from `Element` component is being ignored.
*/
label: never;
/**
* Content prop from `Element` component is being ignored.
*/
content: never;
};
declare type MaybeNull = undefined | null;
declare type MergeTypes<A extends readonly [...any]> = ExtractNullableKeys<Spread<A>>;
export declare type ObjectValue = Partial<{
id: SimpleValue;
key: SimpleValue;
itemId: SimpleValue;
component: ElementType;
}> & Record<string, unknown>;
export declare const Overlay: VLComponent<OverlayProps>;
export declare type OverlayProps = {
/**
* Children to be rendered within **Overlay** component when Overlay is active.
*/
children: ContentRenderer | Content;
/**
* React component to be used as a trigger (e.g. `Button` for opening
* dropdowns). Component must acept accept `ref` or any other prop name
* defined in `triggerRefName` prop.
*/
trigger: TriggerRenderer | Content;
/**
* Defines a HTML DOM where children to be appended. Component uses JavaScript
* [`Node.appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)
*
* For more information follow [Portal](https://vitus-labs.com/docs/ui-system/elements/portal)
* component.
*/
DOMLocation?: HTMLElement;
/**
* Defines a prop name to be used for passing `ref` for **trigger**. By default,
* the value is `ref`.
*/
triggerRefName?: string;
/**
* Defines a prop name to be used for passing `ref` for **content** (passed `children`).
* By default, the value is `ref`.
*/
contentRefName?: string;
} & UseOverlayProps;
export declare const OverlayProvider: FC<Context_2 & {
children: ReactNode;
}>;
export declare const Portal: VLComponent<PortalProps>;
export declare interface PortalProps {
/**
* Defines a HTML DOM where children to be appended. Component uses JavaScript
* [`Node.appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)
*/
DOMLocation?: HTMLElement;
/**
* Children to be rendered within **Portal** component.
*/
children: ReactNode;
/**
* Valid HTML Tag
*/
tag?: string;
}
declare type Props = ElementProps & Partial<{
equalBeforeAfter: boolean;
}>;
declare interface Props_2 {
type?: 'single' | 'multi';
activeItemRequired?: boolean;
activeItems?: Key | (string | number)[];
itemProps?: Record<string, unknown> | ((props: Record<string, unknown>) => Record<string, unknown>);
}
export declare type PropsCallback = TObj | ((itemProps: Record<string, never> | Record<string, SimpleValue> | ObjectValue, extendedProps: ExtendedProps) => TObj);
export { Provider }
export declare type Responsive = ContentSimpleValue | ContentSimpleValue[] | Partial<Record<BreakpointKeys, number | string>>;
export declare type ResponsiveBoolType = ContentBoolean | ContentBoolean[] | Partial<Record<BreakpointKeys, ContentBoolean>>;
declare type SimpleHoc<P extends Record<string, unknown> = {}> = (WrappedComponent: ComponentType<P>) => ComponentType<P>;
declare type SimpleValue = string | number;
declare type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R] ? SpreadTwo<L, Spread<R>> : unknown;
declare type SpreadTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & R>;
declare const Text_2: VLForwardedComponent<TextProps> & {
isText?: true;
};
export { Text_2 as Text }
export declare type TextProps = Partial<{
/**
* Label can be used instead of children for inline syntax. But **children** prop takes a precedence
*/
label: ReactNode;
/**
* Children to be rendered within **Text** component.
*/
children: ReactNode;
/**
* Defines whether should behave as a block text element. Automatically adds **p** HTML tag
*/
paragraph: boolean;
/**
* Defines what kind of HTML tag should be rendered
*/
tag: HTMLTextTags;
/**
* If an additional styling needs to be added, it can be do so via injecting styles using this property.
*/
css: ExtendCss;
}>;
declare type TObj = Record<string, unknown>;
declare type TriggerRenderer = (props: Partial<{
active: boolean;
showContent: () => void;
hideContent: () => void;
}>) => ReactNode;
export declare const useOverlay: ({ isOpen, openOn, closeOn, type, position, align, alignX, alignY, offsetX, offsetY, throttleDelay, parentContainer, closeOnEsc, disabled, onOpen, onClose, }?: Partial<UseOverlayProps>) => {
triggerRef: RefObject<HTMLElement | null>;
contentRef: (node: HTMLElement) => void;
active: boolean;
align: Align;
alignX: "left" | "right" | "center";
alignY: "bottom" | "top" | "center";
showContent: () => void;
hideContent: () => void;
blocked: boolean;
setBlocked: () => void;
setUnblocked: () => void;
Provider: FC<Context & {
children: ReactNode;
}>;
};
export declare type UseOverlayProps = Partial<{
/**
* Defines default state whether **Overlay** component should be active.
* @defaultValue `false`
*/
isOpen: boolean;
/**
* Defines `event` when **Overlay** is supposed to be open.
*
* When `manual` is set, callbacks needs to be applied to make it working.
* @defaultValue `click`
*/
openOn: 'click' | 'hover' | 'manual';
/**
* Defines `event` when **Overlay** is supposed to be closed.
* @defaultValue `click`
*/
closeOn: 'click' | 'clickOnTrigger' | 'clickOutsideContent' | 'hover' | 'manual';
/**
* Defines what type of **Overlay** will be created. Type `modal`
* has different positioning calculations than others.
* @defaultValue `dropdown`
*/
type: 'dropdown' | 'tooltip' | 'popover' | 'modal' | 'custom';
/**
* Defines how `content` is treated regarding CSS positioning.
* @defaultValue `fixed`
*/
position: 'absolute' | 'fixed' | 'relative' | 'static';
/**
* Defines from which side is `content` aligned to `trigger` (top, left, bottom, right).
* For more specific alignment configuration can be used `alignX` and/or `alignY` prop.
* @defaultValue `bottom`
*/
align: Align;
/**
* Defines how `content` is aligned to `trigger` on axis X
* @defaultValue `left`
*/
alignX: AlignX_2;
/**
* Defines how `content` is aligned to `trigger` on axis Y
* @defaultValue `bottom`
*/
alignY: AlignY_2;
/**
* Defines `margin` from trigger on axis X.
* @defaultValue `0`
*/
offsetX: number;
/**
* Defines `margin` from trigger on axis Y.
* @defaultValue `0`
*/
offsetY: number;
/**
* Performance helper. Value defined in milliseconds for `throttling`
* recalculations
* @defaultValue `200`
*/
throttleDelay: number;
/**
* A valid HTML element. Prop can be used for ability to handle properly
* scrolling inside custom scrollable HTML element.
*/
parentContainer: HTMLElement | null;
/**
* Defines whether active **Overlay** is supposed to be closed on pressing
* `ESC` key.
* @defaultValue `true`
*/
closeOnEsc: boolean;
/**
* When set to `true`, **Overlay** is automatically closed and is blocked for
* being opened.
*/
disabled: boolean;
/**
* A callback hook to be called when **Overlay** is being opened. Does not
* accept any arguments.
*/
onOpen: () => void;
/**
* A callback hook to be called when **Overlay** is being closed. Does not
* accept any arguments.
*/
onClose: () => void;
}>;
export declare const Util: VLComponent<UtilProps>;
export declare interface UtilProps {
/**
* Children to be rendered within **Util** component.
*/
children: ReactNode;
/**
* Class name(s) to be added to children component.
*/
className?: string | string[];
/**
* Style property to extend children component inline styles
*/
style?: Record<string, unknown>;
}
declare type VLComponent<P extends Record<string, any> = {}> = FC<P> & VLStatic;
declare type VLElement<P extends Record<string, unknown> = {}> = ForwardRefExoticComponent<PropsWithoutRef<ElementProps & P> & RefAttributes<any>> & VLStatic;
declare type VLForwardedComponent<P extends Record<string, unknown> = {}> = ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<any>> & VLStatic;
declare interface VLStatic {
/**
* React displayName
*/
displayName?: string | undefined;
/**
* package name
*/
pkgName?: string;
/**
* component name
*/
VITUS_LABS__COMPONENT?: `@vitus-labs/${string}`;
}
export declare const withActiveState: SimpleHoc<Props_2>;
export declare const withEqualSizeBeforeAfter: SimpleHoc<Props>;
export { }