@sequencing/design-system
Version:
Sequencing Design System
626 lines (609 loc) • 27.9 kB
TypeScript
import React, { PropsWithChildren, ButtonHTMLAttributes, ReactNode } from 'react';
type CustomLink = {
/** Link's url */
url?: string;
/** Link's label */
label: string;
/**
* The callback function for when the link is clicked.
* Note it suppress the native HTML event and only returns the set `url`
*/
onClick?: (url?: string) => void;
};
interface LinkProps {
/** Custom css class to customize the stylings */
customClass?: string;
/** The hint to be displayed when hovering over the link */
hint?: string;
/**
* The target of this link. It will be passed to the ``onClick`` handler when the user clicks on it.
* Note the ``onClick`` callback performs an event.preventDefault, so, to make it work as a regular
* HTML anchor, avoid passing an ``onClick`` handler.
*/
href?: string;
/** When set to true, it will underline the link */
selected?: boolean;
/**
* The look and feel of the link.
* Default: ``primary``
*/
variant?: "primary" | "secondary";
/** Called when a click is performed. It receives the href set on the ``href`` property.
* Use this handler to perform SPA navigation with you framework's router system.
* The returned ``href`` property is a convenient way to avoid rewriting the ``href`` property
* when navigating. Example using React Router:
* `import { useNavigate } from 'react-router';`
* `const navigate = useNavigate();`
* `return <Link href="/some-url" onClick={navigate}>Navigate</Link>`
* The second returned argument is the native click event.
*/
onClick?: (href: string, event?: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;
/**
* Called when mouse enter are performed.
* @param event: React.MouseEvent<HTMLAnchorElement>
*/
onMouseEnter?: (event: React.MouseEvent<HTMLAnchorElement>) => void;
/**
* Called when mouse leave are performed.
* @param event: React.MouseEvent<HTMLAnchorElement>
*/
onMouseLeave?: (event: React.MouseEvent<HTMLAnchorElement>) => void;
}
/**
* The Link component is used to render an anchor to navigate between pages.
* To support the different frameworks we have in our repo (React, NextJs, Gatsby),
* this component is a wrapper around an HTML anchor and provides two ways of navigation:
* - Using the ``href`` parameter: the link will behave as a native HTML anchor.
* - Using the ``onClick`` callback: the navigation is handled externally by the developer.
* Ideally, the developer should opt for either use the ``href`` param or the ``onClick`` callback,
* because the ``onClick`` execution will override the ``href`` click event.
* Passed ``children`` will be rendered inside the anchor tag.
*
*/
declare const Link: ({ hint, href, children, selected, customClass, variant, onClick, onMouseEnter, onMouseLeave, }: PropsWithChildren<LinkProps>) => React.JSX.Element;
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
/** Custom css class to customize the stylings */
customClass?: string;
/**
* Disabling a button prevents any action and will gray out the component.
*/
disabled?: boolean;
/** The hint to be displayed when hovering over the button */
hint?: string;
/** The label to be displayed inside the button */
label?: ReactNode;
/**
* Setting this flag to ``true`` will display a spinner inside the button and
* will prevent any further interaction unless the flag is set back to ``false``.
* The width will remain the same as of the rendered label.
*/
loading?: boolean;
/**
* Setting this flag to ``true`` will display the button's label alongside the spinner
* while in loading state
*/
preserveLabelWhileLoading?: boolean;
/** Controls the look and feel of the button. Default: ``primary`` */
variant?: "fancy" | "primary" | "secondary" | "outlined" | "outlinedSecondary" | "outlinedDanger" | "outlinedWarning" | "outlinedWhite" | "danger" | "warning" | "white" | "text" | "textSecondary" | "success" | "outlinedSuccess" | "yellow" | "outlinedYellow";
/** Controls the size of the button. Default: ``medium`` */
size?: "small" | "medium" | "large";
/** If present, display an icon in the button label. */
iconSrc?: string | ReactNode;
/** Determines icon position to the left or right of the label text. Default: ``left`` */
iconPosition?: "left" | "right";
/** Called when a click is performed. The HTML event will be sent to this function */
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
}
/**
* The Button component is used to trigger an action or event,
* such as submitting a form, opening a dialog, canceling an action,
* or performing a delete operation.
* Every Button that triggers an asynchronous operation should set the property ``loading`` to ``true``.
*
*/
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
interface DropdownFunctions {
/** Imperatively closes the dropdown */
close: () => void;
}
interface DropdownProps {
/**
* The start point of the dropdown content when it's open.
* Default: ``left``
*/
anchorPoint?: 'left' | 'right';
/** Custom css class to customize the stylings */
customClass?: string;
/**
* Use it if you needs to change cared icon. Use icon in down state and component will automatically rotate it
*/
customCaretDownIconSrc?: string;
/** Custom css class to customize the content rendered inside the dropdown */
customContentClass?: string;
/** Custom css class to customize the stylings of the toggle button */
customToggleButtonClass?: string;
/**
* Defines if clicking outside of the button toggle or the dropdown content
* should hide the floating container.
* Default: ``true``
*/
dismissOnClickOutside?: boolean;
/** Hides the default caret icon. It has precedence over any passed `customCaretDownIconSrc` */
hideCaret?: boolean;
/** The hint to be displayed when hovering over the toggle button */
hint?: string;
/** The icon to be used as a left adornment of the toggle button */
icon?: string;
/** The label of the toggle button */
label?: string;
/**
* The look and feel of the toggle button.
* Default: ``primary``
*/
variant?: "primary" | "outlined";
/**
* Callback to be called when toggling the dropdown content.
* It receives a boolean for the current state and the HTML event.
*/
onToggle?: (isOpen: boolean, event?: React.MouseEvent<HTMLButtonElement>) => void;
}
/**
* The Dropdown component renders its children as a floating container below its toggle button.
* It's up to the developer to define the stylings and behavior of the children.
* Initially it's set up like this to support the many different content and behaviors we have
* across our apps. This component exposes a ``React.Ref`` object as a convenient way to imperatively close
* the dropdown.
*
*/
declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & {
children?: React.ReactNode;
} & React.RefAttributes<DropdownFunctions>>;
interface TextFieldProps {
/** Custom css class to customize the stylings */
customClass?: string;
/** Placeholder when there's no text in the field */
placeholder?: string;
/** If ``true``, a small button will appear on the right side of the text field
* to clear its contents
*/
showClearButton?: boolean;
/** Text to render in the field. You can omit it if you want to have uncontrolled input */
value?: string;
/**
* The look and feel of the link.
* Default: ``primary``
*/
variant?: "primary";
/** Callback called when the text is updated */
onChange?: (value: string) => void;
/** Callback called when the input is clicked */
onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;
/** Reference to the input element. You must provide it if you want to have clear button for uncontrolled input */
inputRef?: React.RefObject<HTMLInputElement> | null;
/** Icon to display inside the text field */
icon?: string;
/** Icon position in the text field. Make sense if icon string is provided */
iconPosition?: "left" | "right";
}
/**
* The Text Field component renders a simple input field with SDS stylings applied.
*
*/
declare const TextField: ({ value, customClass, placeholder, showClearButton, variant, onChange, onClick, inputRef, icon, iconPosition, }: PropsWithChildren<TextFieldProps>) => React.JSX.Element;
interface AccordionProps {
/**
* Specifies in which side of the toggle we should render the caret icon.
* Default: ``right``
*/
caretPosition?: "left" | "right";
/** Custom css class to customize the stylings */
customClass?: string;
/** The hint to be displayed when hovering over the toggle button */
hint?: string;
/** The label of the toggle button */
label: string;
/**
* Set it to ``true`` if you want to render an open Accordion.
*/
openByDefault?: boolean;
/**
* The look and feel of the toggle button.
* Default: ``primary``
*/
variant?: "primary" | "outlined";
/**
* Callback to be called when toggling the accordion content.
* It receives a boolean for the current state and the HTML event.
*/
onToggle?: (isOpen: boolean, event: React.MouseEvent<HTMLButtonElement>) => void;
}
/**
* The Accordion is a simple yet powerful component to render collapsable sections.
* It renders a button to toggle the accordion content and the passed ``children`` as the content.
* Custom stylings can be applied by passing a ``customClass``.
* If your section is in a different place of the HTML, you can still use this component by toggling the
* visibility of the section using the ``onToggle`` callback.
*
*/
declare const Accordion: ({ hint, label, children, customClass, variant, openByDefault, caretPosition, onToggle, }: PropsWithChildren<AccordionProps>) => React.JSX.Element;
interface Tab {
label: ReactNode;
tabId: number;
chip?: ReactNode;
customClass?: string;
}
interface TabMenuProps {
/** Custom css class to customize the stylings */
customClass?: string;
/**
* Custom css class to apply to all individual tabs. For full control over individual tabs' classes, set the `customClass`
* property individually on the `tabs` array
*/
tabCustomClass?: string;
/** Custom css class to apply to any active tab */
tabCustomActiveClass?: string;
/** Custom css class to apply to any active tab */
verticalOnDesktop?: boolean;
/** This prop determines tab's 'value' for purposes of switching tabs */
tabs: Tab[];
/** Determines which tab is currently active */
activeTab: number;
/** Called when an individual tab is clicked, receives tabId of the target tab */
onClick: (tabId: number) => void;
}
/**
* The TabMenu component provides a panel with multiple Tabs to switch displayed content.
*
*/
declare const TabMenu: ({ customClass, tabCustomClass, tabCustomActiveClass, verticalOnDesktop, tabs, activeTab, onClick }: TabMenuProps) => React.JSX.Element;
interface SpinnerProps {
/** Custom css class to customize the styling */
className?: string;
/** Controls the size of the button. Default: ``16px`` any css units which supported by SVG */
size?: string | number;
/** Controls the size of the button. Default: ``white`` any css colors unit which supported by SVG */
color?: string;
}
/**
* Our default circle Spinner.
* You could specify colors and size by passing props or override styles by providing your classname or selecting .spinner class
*/
declare const Spinner: ({ size, color, className }: SpinnerProps) => React.JSX.Element;
interface ModalProps {
/**
* List of buttons or elements to be rendered at the bottom of the modal.
* On mobile they will be rendered stacked up.
*/
buttons?: JSX.Element[];
/** Css class applied to the content wrapper for custom stylings */
contentCustomClass?: string;
/** Css class applied to the overlay for custom stylings */
customClass?: string;
/**
* Can it be closed? If true, an 'x' icon will appear on the top-right corner,
* and clicking outside the modal will also close it.
* Default: ``true``.
*/
dismissable?: boolean;
/** The title of the modal */
title?: string;
/**
* Optional icon to be rendered on the left side of the title.
* It has no effect if ``title`` is undefined.
*/
titleIcon?: string;
/**
* Called when the modal is closed, either by clicking on the close button,
* or clicking outside the modal. It never fires if dismissable is ``false``.
* The modal doesn't close by itself, instead it emits this onClose event,
* so the caller can properly handle it. Note it may change in the future.
*/
onClose?: (event: React.MouseEvent<HTMLButtonElement>) => void;
}
/**
* The Modal component is used to display content above the current page.
* By default, it renders on z-index 10.
*
*/
declare const Modal: ({ buttons, children, customClass, contentCustomClass, dismissable, title, titleIcon, onClose, }: PropsWithChildren<ModalProps>) => React.JSX.Element;
interface AppBarProps {
/** Application's name */
appName: string;
/**
* Background image to be rendered instead of the default gradient.
* This string is the React path to the image and will be rendered inside CSS' `url()`
* It will take precedence over `color`.
*/
backgroundImage?: string;
/** A gradient in the form of CSS' gradient expression. Default is
* `linear-gradient(180deg, #0B193C 0%, #12306c 100%)`.
*/
backgroundGradient?: string;
/** Background color of the bar. */
backgroundColor?: string;
/** Custom css class to customize the stylings */
customClass?: string;
/**
* Application's description or any text intended to be displayed on the left side.
* On desktop it will appear side-by-side with `lastUpdated` separated by a pipe character ("|").
* On mobile it will be stacked up with `lastUpdated`.
*/
description?: ReactNode;
/** Application's icon displayed on the left side */
icon: string;
/** If `true`, display a BETA adornment at the right side of the app's title */
isBeta?: boolean;
/** Formatted date of the app's last update, it will appear after the text "Last Updated:" */
lastUpdated?: string;
/**
* If provided, will render question mark icon after "Last Updated" content, with provided tooltip content appearing on click
* TODO: Use Popover https://sequencing.atlassian.net/browse/ENGR-4876
* */
lastUpdatedTooltip?: ReactNode;
/** Custom component to render on the right side */
rightAdornment?: ReactNode;
/**
* Component to be displayed when the user clicks on the question mark icon.
* If no content is provided, the icon doesn't appear.
* TODO: Use Popover https://sequencing.atlassian.net/browse/ENGR-4876
*/
tooltipContent?: ReactNode;
/** Application's version displayed on the right side of the bar. It's hidden on mobile */
version?: string;
}
/**
* The AppBar component is designed to display information about an application, usage examples include HS, NGDS and GE.
* The component also supports custom children which will be rendered on the middle of the bar.
* For example, you can easily display tabs by rendering a `TabMenu` component as a direct child of this component.
* The background is a dark blue gradient but a custom gradient or image can be used.
* The `rightAdornment` allows custom component to be displayed on the right side
*
*/
declare const AppBar: ({ icon, isBeta, appName, version, children, customClass, lastUpdated, lastUpdatedTooltip, description, tooltipContent, rightAdornment, backgroundColor, backgroundImage, backgroundGradient, }: PropsWithChildren<AppBarProps>) => React.JSX.Element;
interface DatePickerProps {
/** Custom css class to customize the styling if input. Used TextField from SDS */
inputCustomClass?: string;
/** Format of the date to be displayed. Default: ``MMMM d, yyyy`` */
dateFormat?: string;
/** Callback called when the date is updated. Return standard JS Date object */
onDateChange?: (date: Date) => void;
/** Start date of the date picker. Use anything which could be converted to date.
* If undefined or not provided - current day will be selected.
* If null or any falsy value - field will be empty
* */
startDate?: string | number | Date | undefined;
/**
* Maximum and minimum date that can be selected. Use date object or unixtime with ms.
*/
maxDate?: Date;
/**
* Minimum and minimum date that can be selected. Use date object or unixtime with ms.
*/
minDate?: Date;
}
declare const DatePicker: (props: DatePickerProps) => React.JSX.Element;
type CustomLinkWithIcon = CustomLink & {
/**
* You can pass any React element to be rendered as an addornment. Note you'll have full control over this property,
* meaning you are responsible for placing in the page selector
*/
addornment?: ReactNode;
};
interface PageSelectorProps {
/**
* If pageLinks' length is greater than this value, only mobile views, a fly over menu will appear
* to provide easier access to all the links.
* Default: ``10``
*/
minimumLinksToDisplayFlyOverMenu?: number;
/**
* Array of `CustomLink` to work as page selectors plus an optional ReactNode
* that can be used as an addornment for the page selector
* @see {@link CustomLink}
*/
pageLinks: CustomLinkWithIcon[];
/**
* The index of the selected `pageLink`. This item will appear in a `selected` state.
* The look and feel of the item is determined by the `variant`.
* Default: ``0``
*/
selectedIndex?: number;
/**
* The look and feel of the selectors.
* Default: ``primary``
*/
variant?: 'primary' | 'secondary';
}
/**
* The Page Selector component is similar to the `TabMenu` component, but it's designed to work as a page navigator,
* unlike the TabMenu that is designed to switch between views. This component will render the given `pageLinks`
* as HTML links, triggering their `onClick` callbacks upon clicks. Use it to perform SPA or hard navigation
* based on your framework. Link labels longer than ~30 characters will be trimmed down in both the selector bar and
* the fly over menu.
*/
declare const PageSelector: ({ pageLinks, selectedIndex, variant, minimumLinksToDisplayFlyOverMenu, }: PageSelectorProps) => React.JSX.Element;
interface PopoverContentProps {
/** Title of the popover */
title?: string;
/** Content of the popover */
children: React.ReactNode;
}
/**
* PopoverContent is a component that is used to display the content of the Popover. Title and content styles are predefined.
*/
declare const PopoverContent: (props: PopoverContentProps) => React.JSX.Element;
interface PopoverProps {
/** Css class applied to the Popover for custom styling */
className?: string;
/** Element that will trigger the Popover */
children: React.ReactNode;
/**
* If `true`, the Popover will not have a maximum width. Default width and minimal width is 320px.
*/
noMaxWidth?: boolean;
/**
* Content of the Popover. It can be a string or a React component.
* Please note that by default content has limit of 320px width and base result will be with text.
* If you want to use a custom content which could be larger please add noMaxWidth prop and control width of yourself.
* If you want to have our default experiences you could use PopoverContent component.
*/
title?: React.ReactNode;
}
/**
* The Popover component is used to display content above the current page.
* It is not ready to be used everywhere, it needs to be improved.
* Position of the popover will be set automatically based on the position of the child element. By default, below the child.
* if there will not be enough space to show the popover below the child, it will be shown above the child.
* If there will not be enough space to show the popover above the child, it will be shown below the child and user
* must scroll to see the content.
* X position will be set automatically based on the position of the child element. By default, left.
* You might have problem with click if you add Popover inside label element.
*
* Why Popover not Tooltip? Tooltip is very simple and usually showing only small peas of text.
* Popover is more complex and could show more content as we do usually.
*
* Future improvements:
* 1. Open on Hover - not implemented
* 2. Reposition during scroll - not implemented
* 3. Control from outside - not implemented
*/
declare const Popover: (props: PopoverProps) => React.JSX.Element;
interface User {
name: string;
avatarImageUrl?: string;
}
interface HeaderFunctions {
closeMobileMenu: () => void;
}
interface HeaderProps {
/**
* A React node with an optional banner to be rendered above the header.
* The total header height is dynamic calculated and includes the banner's height
*/
bannerComponent?: ReactNode;
/** Custom css class to customize the stylings */
customClass?: string;
/**
* The URL of the site's home page. It will be used when the user clicks on the site's logo.
*
* PLEASE NOTE: If you want to use the SOFT navigation from your framework (React, NextJs, etc), you should
* path the `onRequestHomePage` prop and call the navigation method in the callback.
* e.g. for NextJs `onRequestHomePage={(url) => router.push(url)}`
* WARNING: Do not change or modify url argument inside your callback, because you will have undocumented behavior
* with your navigation. Your goal is only call the navigation method with the url argument.
* Without the `onRequestHomePage` prop, the component will use the default behavior of the anchor tag.
* Default: `/`.
*/
homePageUrl?: string;
/** Displays loading skeleton animation when set to `true` */
isLoading?: boolean;
/** The URL of user's account page. Default: ``/account/personal-information`` */
myAccountUrl?: string;
/** Specify number of skeleton links to display during loading. Default: 6 */
numberOfSkeletonLinks?: number;
/** Link clicks callback. Use it together with ``preventHardNavigation``
* to support different routers (Next, react-router-dom, etc.).
* NOTE: When ``preventHardNavigation`` is disabled, it has no effect.
*/
onLinkClick?: (linkUrl: string) => void;
/**
* Called when a user clicks on the site's logo, provide url argument to callback.
* Typically used to make soft navigation in your framework (React, NextJs, etc).
* e.g. for NextJs `onRequestHomePage={(url) => router.push(url)}`
* url argument is the `homePageUrl` prop value.
* NOTE: When ``preventHardNavigation`` is disabled, it has no effect and the user will be hard redirected
* to ``homePageUrl``.
*/
onRequestHomePage?: (homePageUrl: string) => void;
/**
* Called when an authenticated user clicks on the My Account link inside the main right HeaderChip.
* The url parameter is ``myAccountUrl``.
* NOTE: When ``preventHardNavigation`` is disabled, it has no effect and the user will be hard redirected
* to ``myAccountUrl``.
*/
onRequestMyAccount?: (myAccountUrl: string) => void;
/** Called when an anonymous user clicks on the Sign In button inside the auxiliary links section */
onRequestSignIn?: () => void;
/** Called when an authenticated user clicks on the Sign Out button inside the main right HeaderChip */
onRequestSignOut?: () => void;
/**
* When enabled, it avoids setting ``document.location.href`` upon link clicks and you will be
* responsible for handling the navigation through the ``onLinkClick`` function.
* This enables soft navigation for apps that want to support it.
*/
preventHardNavigation?: boolean;
/**
* A React node with the search component containing:
* - A button to toggle the visibility of the search bar
* - A div with the search bar implementation
*/
searchComponent?: ReactNode;
/**
* If the user is authenticated, pass their name and avatar image here
*/
user?: User;
}
/**
* This is the default header for Sequencing.
* It features a search component, buttons for login, logout, account access
* and two group of links. The main links are rendered on the left side of the bar,
* next to the company's logo and the auxiliary links appear on the right side.
* On the mobile view, all links appear stacked up in a slidein/slide-out menu.
* If want to use soft navigation for links, enable the ``preventHardNavigation`` flag.
* The header is rendered on z-index 5.
* When logged in, it will render a HeaderChip component with a link to the My Account page
* and a button for sign-out.
*
*/
declare const Header: React.ForwardRefExoticComponent<HeaderProps & React.RefAttributes<HeaderFunctions>>;
interface HeaderLink {
/** Absolute or relative link URL. */
pathOrUrl?: string;
/** Link label. */
label: string;
/** Custom classname. */
className?: string;
/** Custom onClick, takes priority over main onLinkClick prop. */
onClick?: (url: string) => void;
/** A list of nested link objects. */
items?: Array<{
/** Absolute or relative link URL. */
pathOrUrl?: string;
/** Link label. */
label: string;
/** Custom classname. */
className?: string;
/** Custom onClick, takes priority over main onLinkClick prop. */
onClick?: (url: string) => void;
}>;
}
interface FooterProps {
/** Optional app version to render on hover over the copyright text */
appVersion?: string;
/**
* Optional callback function to handle link clicks.
* Use it to do soft-navigation inside your framework.
*/
onLinkClick?: (url?: string) => void;
/** Links to be rendered on the right-bottom edge of the component. */
policiesLinks: CustomLink[];
/**
* The main links that will be rendered as columns. If you pass a custom `onClick` function to the link,
* it will override the top-level `onLinkClick`.
* This is useful to perform non-trivial actions (like opening the Sign In modal).
*/
linkGroups: {
title: string;
links: CustomLink[];
}[];
}
/**
* This is the default footer for Sequencing.
* It renders groups of links that give access to the main pages of the site,
* a list of certifications, social links and specific links to Sequencing's policy pages.
* Link clicks are handled externally through the `onLinkClick` callback in order
* to support different frameworks.
* Certifications and Social links are hardcoded inside the component.
*/
declare const Footer: ({ appVersion, linkGroups, onLinkClick, policiesLinks }: FooterProps) => React.JSX.Element;
export { Accordion, AccordionProps, AppBar, AppBarProps, Button, ButtonProps, DatePicker, DatePickerProps, Dropdown, DropdownFunctions, DropdownProps, Footer, Header, HeaderFunctions, HeaderLink, HeaderProps, Link, LinkProps, Modal, ModalProps, PageSelector, Popover, PopoverContent, PopoverContentProps, PopoverProps, Spinner, SpinnerProps, TabMenu, TabMenuProps, TextField, TextFieldProps };