first commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
|
||||
export default function OLTagIcon() {
|
||||
return <MaterialIcon type="sell" />
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
import Badge from '@/features/ui/components/bootstrap-5/badge'
|
||||
|
||||
function OLBadge(props: React.ComponentProps<typeof Badge>) {
|
||||
let { bg, text, ...rest } = props
|
||||
|
||||
// For warning badges, use a light background by default. We still want the
|
||||
// Bootstrap warning colour to be dark for text though, so make an
|
||||
// adjustment here
|
||||
if (bg === 'warning') {
|
||||
bg = 'warning-light-bg'
|
||||
text = 'warning'
|
||||
}
|
||||
|
||||
return <Badge bg={bg} text={text} {...rest} />
|
||||
}
|
||||
|
||||
export default OLBadge
|
@@ -0,0 +1,7 @@
|
||||
import { ButtonGroup, ButtonGroupProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLButtonGroup({ as, ...rest }: ButtonGroupProps) {
|
||||
return <ButtonGroup {...rest} as={as} />
|
||||
}
|
||||
|
||||
export default OLButtonGroup
|
@@ -0,0 +1,7 @@
|
||||
import { ButtonToolbar, ButtonToolbarProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLButtonToolbar(props: ButtonToolbarProps) {
|
||||
return <ButtonToolbar {...props} />
|
||||
}
|
||||
|
||||
export default OLButtonToolbar
|
@@ -0,0 +1,13 @@
|
||||
import { forwardRef } from 'react'
|
||||
import type { ButtonProps } from '@/features/ui/components/types/button-props'
|
||||
import Button from '../bootstrap-5/button'
|
||||
|
||||
export type OLButtonProps = ButtonProps
|
||||
|
||||
const OLButton = forwardRef<HTMLButtonElement, OLButtonProps>((props, ref) => {
|
||||
return <Button {...props} ref={ref} />
|
||||
})
|
||||
|
||||
OLButton.displayName = 'OLButton'
|
||||
|
||||
export default OLButton
|
@@ -0,0 +1,12 @@
|
||||
import { Card } from 'react-bootstrap-5'
|
||||
import { FC } from 'react'
|
||||
|
||||
const OLCard: FC<{ className?: string }> = ({ children, className }) => {
|
||||
return (
|
||||
<Card className={className}>
|
||||
<Card.Body>{children}</Card.Body>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLCard
|
@@ -0,0 +1,15 @@
|
||||
import { CloseButton, CloseButtonProps } from 'react-bootstrap-5'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
const OLCloseButton = forwardRef<HTMLButtonElement, CloseButtonProps>(
|
||||
(props, ref) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return <CloseButton ref={ref} aria-label={t('close')} {...props} />
|
||||
}
|
||||
)
|
||||
|
||||
OLCloseButton.displayName = 'OLCloseButton'
|
||||
|
||||
export default OLCloseButton
|
@@ -0,0 +1,7 @@
|
||||
import { Col } from 'react-bootstrap-5'
|
||||
|
||||
function OLCol(props: React.ComponentProps<typeof Col>) {
|
||||
return <Col {...props} />
|
||||
}
|
||||
|
||||
export default OLCol
|
@@ -0,0 +1,14 @@
|
||||
import { DropdownItem } from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
||||
import { DropdownItemProps } from '@/features/ui/components/types/dropdown-menu-props'
|
||||
import DropdownListItem from '@/features/ui/components/bootstrap-5/dropdown-list-item'
|
||||
|
||||
// This represents a menu item. It wraps the item within an <li> element.
|
||||
function OLDropdownMenuItem(props: DropdownItemProps) {
|
||||
return (
|
||||
<DropdownListItem>
|
||||
<DropdownItem {...props} />
|
||||
</DropdownListItem>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLDropdownMenuItem
|
@@ -0,0 +1,42 @@
|
||||
import { Form, FormCheckProps } from 'react-bootstrap-5'
|
||||
import { MergeAndOverride } from '../../../../../../types/utils'
|
||||
import FormText from '../bootstrap-5/form/form-text'
|
||||
|
||||
type OLFormCheckboxProps = MergeAndOverride<
|
||||
FormCheckProps,
|
||||
{
|
||||
inputRef?: React.MutableRefObject<HTMLInputElement | null>
|
||||
} & (
|
||||
| { description: string; id: string }
|
||||
| { description?: undefined; id?: string }
|
||||
)
|
||||
>
|
||||
|
||||
function OLFormCheckbox(props: OLFormCheckboxProps) {
|
||||
const { inputRef, ...rest } = props
|
||||
|
||||
return rest.type === 'radio' ? (
|
||||
<Form.Check
|
||||
ref={inputRef}
|
||||
aria-describedby={rest.description ? `${rest.id}-description` : undefined}
|
||||
{...rest}
|
||||
label={
|
||||
<>
|
||||
{rest.label}
|
||||
{rest.description && (
|
||||
<FormText
|
||||
id={`${rest.id}-description`}
|
||||
className="form-check-label-description"
|
||||
>
|
||||
{rest.description}
|
||||
</FormText>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Form.Check ref={inputRef} {...rest} />
|
||||
)
|
||||
}
|
||||
|
||||
export default OLFormCheckbox
|
@@ -0,0 +1,30 @@
|
||||
import { forwardRef } from 'react'
|
||||
import FormControl, {
|
||||
type OLBS5FormControlProps,
|
||||
} from '@/features/ui/components/bootstrap-5/form/form-control'
|
||||
import OLSpinner from '@/features/ui/components/ol/ol-spinner'
|
||||
import type { BsPrefixRefForwardingComponent } from 'react-bootstrap-5/helpers'
|
||||
|
||||
type OLFormControlProps = OLBS5FormControlProps & {
|
||||
'data-ol-dirty'?: unknown
|
||||
'main-field'?: any // For the CM6's benefit in the editor search panel
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
const OLFormControl: BsPrefixRefForwardingComponent<
|
||||
'input',
|
||||
OLFormControlProps
|
||||
> = forwardRef<HTMLInputElement, OLFormControlProps>((props, ref) => {
|
||||
const { append, ...rest } = props
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
ref={ref}
|
||||
{...rest}
|
||||
append={rest.loading ? <OLSpinner size="sm" /> : append}
|
||||
/>
|
||||
)
|
||||
})
|
||||
OLFormControl.displayName = 'OLFormControl'
|
||||
|
||||
export default OLFormControl
|
@@ -0,0 +1,14 @@
|
||||
import { Form } from 'react-bootstrap-5'
|
||||
import { ComponentProps } from 'react'
|
||||
import FormFeedback from '@/features/ui/components/bootstrap-5/form/form-feedback'
|
||||
|
||||
type OLFormFeedbackProps = Pick<
|
||||
ComponentProps<typeof Form.Control.Feedback>,
|
||||
'type' | 'className' | 'children'
|
||||
>
|
||||
|
||||
function OLFormFeedback(props: OLFormFeedbackProps) {
|
||||
return <FormFeedback {...props} />
|
||||
}
|
||||
|
||||
export default OLFormFeedback
|
@@ -0,0 +1,8 @@
|
||||
import { FormGroupProps } from 'react-bootstrap-5'
|
||||
import FormGroup from '@/features/ui/components/bootstrap-5/form/form-group'
|
||||
|
||||
function OLFormGroup(props: FormGroupProps) {
|
||||
return <FormGroup {...props} />
|
||||
}
|
||||
|
||||
export default OLFormGroup
|
@@ -0,0 +1,7 @@
|
||||
import { Form } from 'react-bootstrap-5'
|
||||
|
||||
function OLFormLabel(props: React.ComponentProps<(typeof Form)['Label']>) {
|
||||
return <Form.Label {...props} />
|
||||
}
|
||||
|
||||
export default OLFormLabel
|
@@ -0,0 +1,11 @@
|
||||
import { forwardRef } from 'react'
|
||||
import { Form, FormSelectProps } from 'react-bootstrap-5'
|
||||
|
||||
const OLFormSelect = forwardRef<HTMLSelectElement, FormSelectProps>(
|
||||
(props, ref) => {
|
||||
return <Form.Select ref={ref} {...props} />
|
||||
}
|
||||
)
|
||||
OLFormSelect.displayName = 'OLFormSelect'
|
||||
|
||||
export default OLFormSelect
|
@@ -0,0 +1,20 @@
|
||||
import { FormCheck, FormCheckProps, FormLabel } from 'react-bootstrap-5'
|
||||
|
||||
type OLFormSwitchProps = FormCheckProps & {
|
||||
inputRef?: React.MutableRefObject<HTMLInputElement | null>
|
||||
}
|
||||
|
||||
function OLFormSwitch(props: OLFormSwitchProps) {
|
||||
const { inputRef, label, id, ...rest } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormCheck type="switch" ref={inputRef} id={id} {...rest} />
|
||||
<FormLabel htmlFor={id} visuallyHidden>
|
||||
{label}
|
||||
</FormLabel>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLFormSwitch
|
@@ -0,0 +1,9 @@
|
||||
import FormText, {
|
||||
FormTextProps,
|
||||
} from '@/features/ui/components/bootstrap-5/form/form-text'
|
||||
|
||||
function OLFormText({ as = 'div', ...rest }: FormTextProps) {
|
||||
return <FormText {...rest} as={as} />
|
||||
}
|
||||
|
||||
export default OLFormText
|
@@ -0,0 +1,8 @@
|
||||
import { Form } from 'react-bootstrap-5'
|
||||
import { ComponentProps } from 'react'
|
||||
|
||||
function OLForm(props: ComponentProps<typeof Form>) {
|
||||
return <Form {...props} />
|
||||
}
|
||||
|
||||
export default OLForm
|
@@ -0,0 +1,15 @@
|
||||
import { forwardRef } from 'react'
|
||||
import type { IconButtonProps } from '@/features/ui/components/types/icon-button-props'
|
||||
import IconButton from '../bootstrap-5/icon-button'
|
||||
|
||||
export type OLIconButtonProps = IconButtonProps
|
||||
|
||||
const OLIconButton = forwardRef<HTMLButtonElement, OLIconButtonProps>(
|
||||
(props, ref) => {
|
||||
// BS5 tooltip relies on the ref
|
||||
return <IconButton {...props} ref={ref} />
|
||||
}
|
||||
)
|
||||
OLIconButton.displayName = 'OLIconButton'
|
||||
|
||||
export default OLIconButton
|
@@ -0,0 +1,15 @@
|
||||
import { ListGroupItem, ListGroupItemProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLListGroupItem(props: ListGroupItemProps) {
|
||||
const as = props.as ?? 'button'
|
||||
|
||||
return (
|
||||
<ListGroupItem
|
||||
{...props}
|
||||
as={as}
|
||||
type={as === 'button' ? 'button' : undefined}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLListGroupItem
|
@@ -0,0 +1,9 @@
|
||||
import { ListGroup, ListGroupProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLListGroup(props: ListGroupProps) {
|
||||
const as = props.as ?? 'div'
|
||||
|
||||
return <ListGroup {...props} as={as} />
|
||||
}
|
||||
|
||||
export default OLListGroup
|
@@ -0,0 +1,37 @@
|
||||
import {
|
||||
Modal,
|
||||
ModalProps,
|
||||
ModalHeaderProps,
|
||||
ModalTitleProps,
|
||||
ModalFooterProps,
|
||||
} from 'react-bootstrap-5'
|
||||
import { ModalBodyProps } from 'react-bootstrap-5/ModalBody'
|
||||
|
||||
type OLModalProps = ModalProps & {
|
||||
size?: 'sm' | 'lg'
|
||||
onHide: () => void
|
||||
}
|
||||
|
||||
export default function OLModal({ children, ...props }: OLModalProps) {
|
||||
return <Modal {...props}>{children}</Modal>
|
||||
}
|
||||
|
||||
export function OLModalHeader({ children, ...props }: ModalHeaderProps) {
|
||||
return <Modal.Header {...props}>{children}</Modal.Header>
|
||||
}
|
||||
|
||||
export function OLModalTitle({ children, ...props }: ModalTitleProps) {
|
||||
return (
|
||||
<Modal.Title as="h2" {...props}>
|
||||
{children}
|
||||
</Modal.Title>
|
||||
)
|
||||
}
|
||||
|
||||
export function OLModalBody({ children, ...props }: ModalBodyProps) {
|
||||
return <Modal.Body {...props}>{children}</Modal.Body>
|
||||
}
|
||||
|
||||
export function OLModalFooter({ children, ...props }: ModalFooterProps) {
|
||||
return <Modal.Footer {...props}>{children}</Modal.Footer>
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
import Notification from '@/shared/components/notification'
|
||||
|
||||
function OLNotification(props: React.ComponentProps<typeof Notification>) {
|
||||
return (
|
||||
<div className="notification-list">
|
||||
<Notification {...props} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLNotification
|
@@ -0,0 +1,7 @@
|
||||
import { Overlay, OverlayProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLOverlay(props: OverlayProps) {
|
||||
return <Overlay {...props} />
|
||||
}
|
||||
|
||||
export default OLOverlay
|
@@ -0,0 +1,19 @@
|
||||
import { Card, CardBody } from 'react-bootstrap-5'
|
||||
import { FC } from 'react'
|
||||
import classNames from 'classnames'
|
||||
|
||||
// This wraps the Bootstrap 5 Card component but is restricted to the very
|
||||
// basic way we're using it, which is as a container for page content. The
|
||||
// Bootstrap 3 equivalent previously in our codebase is a div with class "card"
|
||||
const OLPageContentCard: FC<{ className?: string }> = ({
|
||||
children,
|
||||
className,
|
||||
}) => {
|
||||
return (
|
||||
<Card className={classNames('page-content-card', className)}>
|
||||
<CardBody>{children}</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLPageContentCard
|
@@ -0,0 +1,20 @@
|
||||
import { forwardRef } from 'react'
|
||||
import { Popover, PopoverProps } from 'react-bootstrap-5'
|
||||
|
||||
type OLPopoverProps = Omit<PopoverProps, 'title'> & {
|
||||
title?: React.ReactNode
|
||||
}
|
||||
|
||||
const OLPopover = forwardRef<HTMLDivElement, OLPopoverProps>((props, ref) => {
|
||||
const { title, children, ...bs5Props } = props
|
||||
|
||||
return (
|
||||
<Popover {...bs5Props} ref={ref}>
|
||||
{title && <Popover.Header>{title}</Popover.Header>}
|
||||
<Popover.Body>{children}</Popover.Body>
|
||||
</Popover>
|
||||
)
|
||||
})
|
||||
OLPopover.displayName = 'OLPopover'
|
||||
|
||||
export default OLPopover
|
@@ -0,0 +1,7 @@
|
||||
import { Row } from 'react-bootstrap-5'
|
||||
|
||||
function OLRow(props: React.ComponentProps<typeof Row>) {
|
||||
return <Row {...props} />
|
||||
}
|
||||
|
||||
export default OLRow
|
@@ -0,0 +1,16 @@
|
||||
import { Spinner } from 'react-bootstrap-5'
|
||||
|
||||
export type OLSpinnerSize = 'sm' | 'lg'
|
||||
|
||||
function OLSpinner({ size = 'sm' }: { size: OLSpinnerSize }) {
|
||||
return (
|
||||
<Spinner
|
||||
size={size === 'sm' ? 'sm' : undefined}
|
||||
animation="border"
|
||||
aria-hidden="true"
|
||||
role="status"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default OLSpinner
|
@@ -0,0 +1,7 @@
|
||||
import Table from '@/features/ui/components/bootstrap-5/table'
|
||||
|
||||
function OLTable(props: React.ComponentProps<typeof Table>) {
|
||||
return <Table {...props} />
|
||||
}
|
||||
|
||||
export default OLTable
|
@@ -0,0 +1,12 @@
|
||||
import Tag from '@/features/ui/components/bootstrap-5/tag'
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
type OLTagProps = React.ComponentProps<typeof Tag>
|
||||
|
||||
const OLTag = forwardRef<HTMLElement, OLTagProps>((props: OLTagProps, ref) => {
|
||||
return <Tag ref={ref} {...props} />
|
||||
})
|
||||
|
||||
OLTag.displayName = 'OLTag'
|
||||
|
||||
export default OLTag
|
@@ -0,0 +1,19 @@
|
||||
import { CSSProperties, FC } from 'react'
|
||||
import { ToastContainer as BS5ToastContainer } from 'react-bootstrap-5'
|
||||
|
||||
type OLToastContainerProps = {
|
||||
style?: CSSProperties
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const OLToastContainer: FC<OLToastContainerProps> = ({
|
||||
children,
|
||||
className,
|
||||
style,
|
||||
}) => {
|
||||
return (
|
||||
<BS5ToastContainer className={className} style={style}>
|
||||
{children}
|
||||
</BS5ToastContainer>
|
||||
)
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
import classNames from 'classnames'
|
||||
import { Toast as BS5Toast } from 'react-bootstrap-5'
|
||||
import {
|
||||
NotificationIcon,
|
||||
NotificationType,
|
||||
} from '../../../../shared/components/notification'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import MaterialIcon from '../../../../shared/components/material-icon'
|
||||
import { ReactNode, useCallback, useState } from 'react'
|
||||
|
||||
export type OLToastProps = {
|
||||
type: NotificationType
|
||||
className?: string
|
||||
title?: string
|
||||
content: string | ReactNode
|
||||
isDismissible?: boolean
|
||||
onDismiss?: () => void
|
||||
autoHide?: boolean
|
||||
delay?: number
|
||||
}
|
||||
|
||||
export const OLToast = ({
|
||||
type = 'info',
|
||||
className = '',
|
||||
content,
|
||||
title,
|
||||
isDismissible,
|
||||
onDismiss,
|
||||
autoHide,
|
||||
delay,
|
||||
}: OLToastProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [show, setShow] = useState(true)
|
||||
|
||||
const toastClassName = classNames(
|
||||
'notification',
|
||||
`notification-type-${type}`,
|
||||
className,
|
||||
'toast-content'
|
||||
)
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
setShow(false)
|
||||
}, [])
|
||||
|
||||
const handleOnHidden = useCallback(() => {
|
||||
if (onDismiss) onDismiss()
|
||||
}, [onDismiss])
|
||||
|
||||
const toastElement = (
|
||||
<div className={toastClassName}>
|
||||
<NotificationIcon notificationType={type} />
|
||||
|
||||
<div className="notification-content-and-cta">
|
||||
<div className="notification-content">
|
||||
{title && (
|
||||
<p>
|
||||
<b>{title}</b>
|
||||
</p>
|
||||
)}
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isDismissible && (
|
||||
<div className="notification-close-btn">
|
||||
<button
|
||||
aria-label={t('close')}
|
||||
data-bs-dismiss="toast"
|
||||
onClick={handleClose}
|
||||
>
|
||||
<MaterialIcon type="close" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
return (
|
||||
<BS5Toast
|
||||
onClose={handleClose}
|
||||
autohide={autoHide}
|
||||
onExited={handleOnHidden}
|
||||
delay={delay}
|
||||
show={show}
|
||||
>
|
||||
{toastElement}
|
||||
</BS5Toast>
|
||||
)
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
import { ToggleButtonGroup, ToggleButtonGroupProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLToggleButtonGroup<T>(props: ToggleButtonGroupProps<T>) {
|
||||
return <ToggleButtonGroup {...props} />
|
||||
}
|
||||
|
||||
export default OLToggleButtonGroup
|
@@ -0,0 +1,7 @@
|
||||
import { ToggleButton, ToggleButtonProps } from 'react-bootstrap-5'
|
||||
|
||||
function OLToggleButton(props: ToggleButtonProps) {
|
||||
return <ToggleButton {...props} />
|
||||
}
|
||||
|
||||
export default OLToggleButton
|
@@ -0,0 +1,7 @@
|
||||
import Tooltip from '@/features/ui/components/bootstrap-5/tooltip'
|
||||
|
||||
function OLTooltip(props: React.ComponentProps<typeof Tooltip>) {
|
||||
return <Tooltip {...props} />
|
||||
}
|
||||
|
||||
export default OLTooltip
|
Reference in New Issue
Block a user