UNPKG

@sequencing/design-system

Version:
626 lines (609 loc) 27.9 kB
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 };