@newskit-render/shared-components
v4.37.1
Published
Newskit Render Shared Components
Downloads
2,749
Readme
@newskit-render/shared-components
sharedTheme
Based on the Newskit Light Theme, the Shared Theme can be used as a base for every Newskit Solutions application. It overrides the brand color, adds custom presets and/or componentDefaults to some of the components in shared-components
. You can extend it in the same way it extends Newskit Light theme.
Back Button
The Back Button is a Next.js's next/link
wrapper for a Newskit Button or link. It enables native Next.js routing.
- Props:
interface BackButtonProps {
backButton?: TBackButton
backButtonOverrides?: BackButtonOverrides
}
interface TBackButton {
text: string
href: string
'aria-label': string
}
export interface BackButtonOverrides {
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
marginBlockEnd?: MQ<string>
iconSize?: MQ<string>
size?: 'small' | 'medium' | 'large'
asLink?: boolean
}
ButtonGroup
The group is a component that combines a standard group of Primary and Secondary button. The group can also contain a flag, marking a secure operation. The ButtonGroup can have only one button, (either Primery or Secondary), or both buttons. Each button is a separate component with the following props:
type ButtonProps = Omit<NewkitButtonProps, 'children' | 'size'> & {
ariaLabel?: string
text?: string
href?: string
onClick?: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
size?: ButtonSize
}
Each button is styled independetly and has its own componentDefaults in the theme. You can override those by passing your own size
and overrides
props to each button via the context.
The ButtonGroup also has it's own stylePreset, that is used as a componentDefault in the theme. The ButtonGroup component takes the following:
- Props:
type ButtonGroupProps = {
loading?: boolean
secureFlag?: boolean
secureFlagOverrides?: SecureFlagProps
primaryButton?: ButtonProps
secondaryButton?: ButtonProps
stylePreset?: MQ<string>
keepFixed?: boolean
breakPoint?: BreakpointKeys
}
The stylePreset
is used to override the default stylePreset of the ButtonGroup.
The primaryButton
and secondaryButton
are used to pass context (props) to the <PrimaryButton />
and <SecondaryButton />
:
The keepFixed
property is used to tell the group if it should be kept at a fixed position at the bottom of the screen on mobile / smaller screens.
The secureFlag
property is used to tell the group if it should display the flag, that indicates secure operations. The SecureFlag
is it's own component, exported from shared-components
. go to SecureFlag
Calendar
This component is based on the Airbnb's react-dates calendar picker, enhanced with the ablity to be customized by using newskit design tokens. The end user can select a range of dates. The components accepts the following arguments:
- overrides?: CalendarStylesProps | optional. If not passed, the Calendar will use the default values. This prop is used to override the style of the calendar and has the following shape:
interface CalendarStylesProps {
calendar: {
typographyPreset: string // sets the global typography preset for the component
borders: {
stylePreset: string //defines the border style for the calendar; this border surrounds both/all months
}
transitionContainer: {
borders: {
stylePreset: string //this container comes from 'react-dates' and the same style preset as above is needed here
}
}
day: { // defines the styles for the individual days and the different states they can be in.
color: string
backgroundColor: string
typographyPreset: string
hover: {
backgroundColor: string
}
selected: {
color: string
backgroundColor: string
active: {
hover: {
color: string
backgroundColor: string
}
}
}
blocked: {
color: string
outOfRange: {
color: string
}
}
span: { //when we have selected dates and reopen the calendar, these styles apply for the days
color: string
backgroundColor: string
selected: {
active: {
hover: {
color: string
backgroundColor: string
}
}
}
hover: {
color: string
backgroundColor: string
active: {
backgroundColor: string
}
}
}
}
week: {
headers: { //styles for the names of the days of the week
typographyPreset: string
}
}
month: {
headers: { // style the names of the months and the arrows and buttons that serve as navigation between months
typographyPreset: string
color: string
}
navigation: {
default: {
stylePreset: string
}
vertical: {
buttons: {
next: string
}
}
icons: {
stylePreset: string
svg: {
left: {
fill: string
}
vertical: {
width: string
height: string
fill: string
}
}
}
}
}
inputs: { // sets the syles for the input fields that are used for the start and end dates
typographyPreset: string
colors: {
color: string
fill: string
backgroundColor: string
}
spacing: {
marginLeft: string
marginRight: string
padding: string
}
sizing: {
width: string
}
borders: {
stylePreset: string
}
}
}
}
- startDate: Date | null | mandatory. Passed by a parent component or a hook, in order to be accessible for further use.
- endDate: Date | null | mandatory. Passed by a parent component or a hook, in order to be accessible for further use.
- setDates: (start: null | Date, end: null | Date) => void | mandatory. Passed by a parent component or a hook, in order to set the two dates above. This is most likely to be a setState() hook, but any function that manages state and returns void is valid.
ContentListView
This component is a highly flexible wrapper around the Newskit's StructuredList component
. The content in each list item looks like a table structure, can have multiple cells, can contain buttons, links. The component is used in my-account
package to display the sections in Personal details, Subscription and billing and Newsletters and alerts pages, as well as the Holiday stops page.
The ContentListView component takes the following
- Props:
interface ContentListViewProps {
children: React.ReactNode
introductionProps?: IntroductionProps & {
extendTitleOverrides: TitleOverrides
extendDescriptionOverrides: DescriptionOverrides
}
link?: boolean
ariaLabel?: string
marginBlockEnd?: MQ<string>
stylePreset?: MQ<string>
showDividerByBreakpoint?: boolean
}
ContentListView
uses some components internally and exports 3 additional components: ListItem
, DateItemButtons
and DateItemStatus
.
filterListItems
This function filters a list of items based on specified criteria. It accepts two arguments:
- ListItems: Array with list items
- data: The data which will be used for filtering
List items contains filter object that contains two attributes:
- dataPath - The path to the field in the data object used for filtering the items.
- showOnTrue - Set to true if you want the item to be included in the filtered list when the dataPath returns true. Set to false if you want the item to be excluded from the filtered list.
The function will return an item if filter is not provided, or the provided data path does not exist in the data object.
ListItem
This is the regular list item. It is used in my-account
main pages and takes the following
- Props:
interface ListItemComponentProps {
item: ListItemType
listCellProps?: ListCellProps
listItemProps: ListItemProps
}
DateItemButtons
This is used when the list item must contain a date and a button. It is used in the Holiday Stops page, when displaying the list of upcoming holiday stops. It takes the following
- Props:
interface DateItemComponentProps {
item: DateItemType
listItemProps: ListItemProps
listCellProps?: Partial<ListCellProps> & {
statusOverrides?: {
typographyPreset?: MQ<string>
stylePreset?: MQ<string>
}
}
redirectUrl?: string
onCancel?: () => void
children?: React.FunctionComponent
}
DateItemStatus
This is used in the holiday stops list, when displaying the current or past holiday stops - the list item displays a date but instad of an edit button, it only displays the status of the holiday stop. The component takes the type of props as the DateItemButtons.
The difference is made by the item's status, which is part of the DateItemType itself and has the following shape:
interface DateItemType {
id: string
startDate: string
endDate: string
status: string | null
}
CorePackageContent
This component is used to display the core content of a 'subscription package'. It is meant to display the title of the package, an image, a list of benefits for that package, description, payment details. price, promotions etc. It takes the following
- Props:
interface CorePackageContentProps {
titleBar?: TitleBarProps
image?:
| (ImageProps & {
marginBlockEnd?: MQ<string>
})
| false
benifitList?: Omit<UnorderedListProps, 'children'> & {
marginBlockEnd?: MQ<string>
icon?: NewsKitIcon
}
benifitItems?: string[]
divider?: {
marginBlockEnd?: MQ<string>
}
promo?: string
promoOverrides?: Omit<TextBlockProps, 'children'> & {
marginBlockEnd?: MQ<string>
}
paymentKey?: string
paymentValue?: string
paymentOverrides?: Omit<TextBlockProps, 'children'> & {
marginBlockEnd?: MQ<string>
}
description?: string
descriptionOverrides?: Omit<TextBlockProps, 'children'> & {
marginBlockEnd?: MQ<string>
}
billingDetails?: string
billingDetailsOverrides?: Omit<TextBlockProps, 'children'> & {
marginBlockEnd?: MQ<string>
}
backgroundColor?: string
padding?: string
}
ExpandSection
This component is used when we need to partially hide a part of some text, that is too long to display at once. It contains a button that allows the contend to be expanded and collaped as needed. It's initial state, the text of the buttons, and the styling of the content can be controlled using the following
- Props:
interface ExpandSectionProps {
data: {
textList: string[]
moreInfo: {
text: string
textList: string[]
}
}
expanded?: boolean
expandButton?: { expand: string; collapse: string }
unorderedListOverrides?: {
content?: {
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
}
marginBlockEnd?: MQ<string>
}
textOverrides?: {
typographyPreset?: MQ<string>
stylePreset?: MQ<string>
marginBlockEnd?: MQ<string>
}
buttonOverrides?: {
stylePreset?: MQ<string>
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
minHeight?: MQ<string>
minWidth?: MQ<string>
width?: MQ<string>
}
}
FormComponent
This component is a wrapper around the Newskit's Form component and is used to display the forms that edit Name, Display Name and email in my-account
. It takes the following
- Props:
interface FormProps extends FormWrapperProps {
validation?: Record<string, any>
validationSchemaKey?: string
fields: EditFieldType[]
disable?: boolean
handleError?: (
type: string,
errorMessage?: ErrorMessage,
genericErrorMessage?: GenericErrorMessage,
message?: string
) => void
handleLoading?: (
type: string,
errorMessage?: ErrorMessage,
genericErrorMessage?: GenericErrorMessage
) => void
handleSuccess?: () => void
baseUrl?: string
errorMessages?: ErrorMessage
genericErrorMessage?: GenericErrorMessage
onSubmit?: (
e: {
[x: string]: any
},
validationSchemaKey: string | unknown,
router?: any,
handleError?: ((overrideMessage?: string) => void) | undefined,
handleSuccess?: (() => void) | undefined,
redirectUrl?: string | undefined
) => Promise<Response>
}
The form is based on react-hook-form
and uses yup validation.
Header
This component is used to form the upper part of the page, below the navigation header. It contains the title of the page's cpntent, and other elements that might be used as the page's heading.
- Props:
type HeaderProps = IntroductionProps & {
backButton?: TBackButton
backButtonOverrides?: BackButtonOverrides
image?: EnhancedImageProps | false
marginBlockEnd?: MQ<string>
showDivider?: boolean
fullWidthTitle?: boolean
imageCell?: GridLayoutItemProps
introductionCell?: GridLayoutItemProps
backButtonCell?: GridLayoutItemProps
}
Image
The image component is a wrapper around next/image
.
- Props:
type ImageProps = {
aspectRatio?: string | number
href?: string
width?: number
} & NextImageProps
Introduction
This component is used to display the headline and description of the page or modal. It is used in both Header
and Modal
components.
- Props:
interface IntroductionProps {
title?: string
titleOverrides?: TitleOverrides
description?: string | string[]
descriptionOverrides?: DescriptionOverrides
overline?: string
overlineOverrides?: OverlineOverrides
center?: boolean
innerHTML?: string
makeBoldTextRegEx?: string
makeBoldTextRegExFlags?: string
}
Link
The eventContext interface is not exported
- Props:
interface EventContext {
event_navigation_action: string
event_navigation_name: string
event_navigation_browsing_method: EventTrigger
event_navigation_label?: string
}
interface LinkProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
href: string
type: 'standalone' | 'inline'
eventContext?: EventContext
external?: boolean
overrides?: {
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
spaceInline?: MQ<string>
externalIcon?: {
size?: string
}
}
}
Modal
This component is a wrapper around the Newskit's Modal. The modal content can contain other components from shared-components
:
Image, Introduction, CorePackageContent and ButtonGroup
- Props:
interface ModalProps
extends Omit<MKModalProps, 'children'>,
ModalContentProps {
closePosition?: 'left' | 'right' | 'none'
onOpen?: () => void
}
interface ModalContentProps {
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
image?: ImageProps & {
marginBlockEnd?: MQ<string>
}
introduction?: IntroductionProps
inlineMessage?: Omit<InlineMessageProps, 'children'> & {
message?: string
marginBlockEnd?: MQ<string>
}
corePackageContent?: CorePackageContentProps
buttonGroup?: ButtonGroupProps & {
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
}
centeredButton?: ButtonProps & {
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
}
modalLink?: ModalLinkProps
}
interface ModalLinkProps {
links?: Array<LinkProps & { text: string }> | (LinkProps & { text: string })
introduction?: IntroductionProps
}
NavigationFooter
- Props:
interface FooterProps {
footer: FooterContext
footerOverrides: FooterContextOverrides
margin?: {
xsMargin?: string
smMargin?: string
mdMargin?: string
lgMargin?: string
}
gutter?: {
xsColumnGutter?: string
smColumnGutter?: string
mdColumnGutter?: string
lgColumnGutter?: string
}
}
interface FooterContext {
helpChat?: React.ComponentType<{
chatHelpOverrides?: Record<string, unknown>
}>
menuItemArray: {
text: string
href: string
id: string | number
}[]
legalText: string
}
interface FooterContextOverrides {
ariaLabel?: string
menuItemOverrides?: {
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
}
menuOverrides?: {
marginBlockEnd?: MQ<string>
backgroundColor?: string
borderColorTop?: string
borderColorBottom?: string
padding?: {
xs: string
md: string
}
}
legalTextOverrides?: {
marginBlockEnd?: MQ<string>
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
padding?: {
xs: string
md: string
}
}
chatHelpOverrides?: Record<string, unknown>
}
NavigationPrimary
This component is a wrapper around a <header>
tag and contains the primary navigation, the logo, and can also display additional item, depending on the route. For example /account route displays the word Account next to the logo and the navigation lead to either the main page or logout. The / route displays links to index pages and only displays Account link and icon if the visitor is loggged in.
The component takes the following
- Props:
interface NavigationPrimaryProps extends NavigationPrimaryThemeProps {
children?: React.ReactNode
nav?: NavigationPrimaryInterface[] | false
title?: string
titleHref?: string
titleOverrides?: {
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
}
logoSrc?: string
logoWidth?: string
logoHeight?: string
loggedInUser?: boolean
gridOverrides?: {
width?: MQ<string>
minWidth?: MQ<string>
maxWidth?: MQ<string>
height?: MQ<string>
minHeight?: MQ<string>
maxHeight?: MQ<string>
} & {
marginInlineStart?: MQ<string>
marginInlineEnd?: MQ<string>
marginInline?: MQ<string>
marginBlockStart?: MQ<string>
marginBlockEnd?: MQ<string>
marginBlock?: MQ<string>
}
}
and uses the following interfaces:
interface NavigationPrimaryInterface {
text: string
link: string
icon: React.ReactElement<NewsKitIconProps> | null
ariaLabel?: string
}
interface NavigationPrimaryThemeProps {
customTheme?: UncompiledTheme
}
type Logo =
| {
src?: string
width?: string
height?: string
top?: string
}
| undefined
PastDueBanner, PastDueBannerExternal and pastDuebannerDefaultContext
PastDueBanner is the component, used to display the notification message when a user's subscription is no longer active or soon to be deactivated. There are several different states of deactivation, each one represented by a slightly different banner. The differences are passed to the component through a context object. In both PastDueBanner and PastDueBannerExternal the context is passed through the pastDueBanner
prop. The components's props are as follows:
- PastDueBanner props:
type PastDueBannerProps = {
className?: string
pastDueBanner: PastDueBannerType
userData: Partial<UserData>
url: string
}
- PastDueBannerExternal props:
type PastDueBannerExternalProps = {
className?: string
pastDueBanner?: PastDueBannerType
user: UserData
wrapper?: React.ComponentType
theme?: UncompiledTheme
}
If no context is passed to the components, a default context (called pastDueBannerDefaultContext) is used:
- the context type is as follows:
interface PastDueBannerType {
firstNotice: Notice
secondNotice: Notice
terminated: Notice
toBeCancelled: Notice
toBeCancelledWithRefund: Notice
cancelled: Notice
treshold: PastDueBannerTreshold
}
type Notice = {
title: string
text: string
dismissDays?: number
phoneNumber?: string
button?: string
link?: {
linkLocation: string
linkText: string
}
}
In this context object parts of the banner's message are placeholders. The placeholders are dynamically replaced with an actual value. To add a hyperlink to the banner's message, pass a link prop to the banner in the context. The link prop has this shape :
link: {
linkLocation: string, // example: 'https://someurl.com'
linkText: string, // example: 'click here'
},
In the text prop, add a ##LINK## placeholder where the hyperlink should be.
The pastDueBannerDefaultContext
contains an example of this in its "terminated" banner:
terminated: {
title: 'Your subscription has been terminated',
phoneNumber: 'XXXX-XXX-XXXX',
text:
'We didn’t receive payment for your subscription. To reactivate it, please call ##PHONE_NUMBER##. Or click ##LINK##.',
dismissDays: 7,
link: {
linkLocation: 'http://localhost:3000/account',
linkText: 'here',
},
},
RadioForm
The RadioForm component combines several Newskit components in a single choice form, including validation. The validation is based on react-hook-form
. A textarea field can be added to one or more of the radio buttons in the form, in case some extra information needs to be provided with the choice. The form takes the following:
- Props:
interface RadioFormProps {
onSubmit: (response: RadioFormResponse) => void
introductionProps?: Omit<IntroductionProps, 'title' | 'titleOverrides'>
radioInputList: RadioFormInput[]
radioInputName?: string
size?: 'small' | 'medium' | 'large'
resolver: Resolver
radioInputListOverrides?: Overrides
errorOverrides?: Overrides
inputTextAreaOverrides?: Omit<Overrides, 'marginBlockEnd'> & {
marginBlockStart?: MQ<string>
}
inputAssistiveTextOverrides?: Overrides
characterCountOverrides?: Overrides
marginBlockEnd?: MQ<string>
buttonGroupProps?: ButtonGroupProps
introductionInlineMessage?: string
introductionInlineMessageOverrides?: Omit<InlineMessageProps, 'children'> & {
marginBlockEnd?: MQ<string>
}
gridProps?: {
xsMargin: string
xsColumnGutter: string
xsRowGutter: string
}
}
SecureFlag
SecureFlag is a simple component, used to mark a payment operation as secure. It takes the following:
- Props:
const props: SecureFlagProps = {
size,
overrides,
iconOverrides,
icon,
}
interface SecureFlagProps extends FlagProps {
iconOverrides?: {
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
spaceInline?: MQ<string>
size?: MQ<string>
stylePreset?: MQ<string>
}
icon?: ReactElement<NewsKitIcon>
}
The component has a default styling in the theme, consisting of size
, overrides
and iconOverrides
:
const secureFlagDefaultOverrides = {
stylePreset: 'secureFlagStylePresets',
typographyPreset: 'utilityLabel010',
paddingInline: 'space000',
paddingBlock: 'space000',
spaceInline: 'space020',
}
const secureFlagIconDefaultOverrides = {
paddingInline: 'space000',
paddingBlock: 'space000',
spaceInline: 'space020',
size: 'iconSize020',
}
const secureFlagComponentDefaults: SecureFlagProps = {
size: 'small',
overrides: secureFlagDefaultOverrides,
iconOverrides: secureFlagIconDefaultOverrides,
}
These are going to be used if no values are passed from the context.
Seo
The Seo component is a wrapper around the Next.js native Head component, used to build the <head>
section of the document. It is used to gurantee a certain minimal level of SEO and takes the following:
- Props:
const seoProps: SEOProps = {
title,
description,
url,
siteHost,
hrefLang = 'en',
maxImagePreview = 'large',
gscId,
fbTitle,
fbType,
fbImageUrl,
twUsername,
twTitle,
twDescription,
twImageUrl,
twImageAlt,
}
type SEOProps {
title: string
description: string
url: string
siteHost: string
hrefLang?: string
maxImagePreview?: 'none' | 'standard' | 'large'
gscId?: string
fbTitle?: string
fbType: string
fbImageUrl: string
twUsername?: string
twTitle?: string
twDescription?: string
twImageUrl?: string
twImageAlt?: string
}
SkipToContent
A small component, used for accesibility purposes. Allows the page's visitor to use the Tab bitton to skip to the content of the page, and move around it.
SubscriptionDetails
The component is a small wrapper around the Newskit'a banner.It's maent to display the name and price of a user's subscription, as well as a button, which reveals the full details on click. The component is used in the mobile/smaller screens view in the payment-details page of the checkout
package.
- Props:
interface SubscriptionDetailsProps {
banner?: {
buttonText: string
message: string
title: string
onClick?: () => void
}
bannerOverrides?: {
stylePreset: MQ<string>
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
maxWidth: string
minHeight: MQ<string>
content: {
title: {
stylePreset: MQ<string>
}
message: {
typographyPreset: MQ<string>
stylePreset: MQ<string>
}
}
}
containerOverrides?: {
stylePreset: MQ<string>
marginBlockEnd: MQ<string>
}
margin?: {
xsMargin?: string
smMargin?: string
mdMargin?: string
lgMargin?: string
}
gutter?: {
xsColumnGutter?: string
smColumnGutter?: string
mdColumnGutter?: string
lgColumnGutter?: string
}
}
SubscriptionDrawer
This component uses the Newskit's Drawer component and the CorePackageContent to display the full details of a user's subscription on a mobile screen. This is the component that is displayed if the button in SubscriptionDetails is clicked. It takes the following
- Props:
interface SubscriptionDrawerProps
extends CorePackageContentProps,
Omit<DrawerProps, 'children'> {
size?: string
}
TitleBar
This component displays the title of the CorePackageContent and takes the following
- Props:
interface TitleBarProps
extends Omit<NKTitleBarProps, 'children' | 'actionItem'> {
text: string
marginBlockEnd?: MQ<string>
link?: {
text: string
href: string
'aria-label'?: string
}
linkOverriders?: {
stylePreset?: MQ<string>
typographyPreset?: MQ<string>
paddingInline?: MQ<string>
paddingBlock?: MQ<string>
marginBlockEnd?: MQ<string>
iconSize?: MQ<string>
}
}