diff --git a/src/Alert.tsx b/src/Alert.tsx index c30064364d..fed671c99b 100644 --- a/src/Alert.tsx +++ b/src/Alert.tsx @@ -4,13 +4,12 @@ import PropTypes from 'prop-types'; import { elementType } from 'prop-types-extra'; import { useUncontrolled } from 'uncontrollable'; import useEventCallback from '@restart/hooks/useEventCallback'; -import Anchor from '@restart/ui/Anchor'; import { useBootstrapPrefix } from './ThemeProvider'; +import AlertHeading from './AlertHeading'; +import AlertLink from './AlertLink'; import Fade from './Fade'; import CloseButton, { CloseButtonVariant } from './CloseButton'; import { Variant } from './types'; -import divWithClassName from './divWithClassName'; -import createWithBsPrefix from './createWithBsPrefix'; import { TransitionType } from './helpers'; export interface AlertProps extends React.HTMLAttributes { @@ -24,17 +23,6 @@ export interface AlertProps extends React.HTMLAttributes { transition?: TransitionType; } -const DivStyledAsH4 = divWithClassName('h4'); -DivStyledAsH4.displayName = 'DivStyledAsH4'; - -const AlertHeading = createWithBsPrefix('alert-heading', { - Component: DivStyledAsH4, -}); - -const AlertLink = createWithBsPrefix('alert-link', { - Component: Anchor, -}); - const propTypes = { /** * @default 'alert' diff --git a/src/AlertHeading.tsx b/src/AlertHeading.tsx new file mode 100644 index 0000000000..7d9ae081bd --- /dev/null +++ b/src/AlertHeading.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import divWithClassName from './divWithClassName'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +const DivStyledAsH4 = divWithClassName('h4'); +DivStyledAsH4.displayName = 'DivStyledAsH4'; + +export interface AlertHeadingProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const AlertHeading: BsPrefixRefForwardingComponent<'div', AlertHeadingProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = DivStyledAsH4, ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'alert-heading'); + return ( + + ); + }, + ); + +AlertHeading.displayName = 'AlertHeading'; + +export default AlertHeading; diff --git a/src/AlertLink.tsx b/src/AlertLink.tsx new file mode 100644 index 0000000000..afe91a59f2 --- /dev/null +++ b/src/AlertLink.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import Anchor from '@restart/ui/Anchor'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface AlertLinkProps + extends BsPrefixProps, + React.AnchorHTMLAttributes {} + +const AlertLink: BsPrefixRefForwardingComponent<'a', AlertLinkProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = Anchor, ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'alert-link'); + return ( + + ); + }, + ); + +AlertLink.displayName = 'AlertLink'; + +export default AlertLink; diff --git a/src/Card.tsx b/src/Card.tsx index 966d1b053a..e0ac9fca6b 100644 --- a/src/Card.tsx +++ b/src/Card.tsx @@ -3,27 +3,18 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useBootstrapPrefix } from './ThemeProvider'; -import createWithBsPrefix from './createWithBsPrefix'; -import divWithClassName from './divWithClassName'; -import CardImg from './CardImg'; +import CardBody from './CardBody'; +import CardFooter from './CardFooter'; import CardHeader from './CardHeader'; +import CardImg from './CardImg'; +import CardImgOverlay from './CardImgOverlay'; +import CardLink from './CardLink'; +import CardSubtitle from './CardSubtitle'; +import CardText from './CardText'; +import CardTitle from './CardTitle'; import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; import { Color, Variant } from './types'; -const DivStyledAsH5 = divWithClassName('h5'); -const DivStyledAsH6 = divWithClassName('h6'); -const CardBody = createWithBsPrefix('card-body'); -const CardTitle = createWithBsPrefix('card-title', { - Component: DivStyledAsH5, -}); -const CardSubtitle = createWithBsPrefix('card-subtitle', { - Component: DivStyledAsH6, -}); -const CardLink = createWithBsPrefix('card-link', { Component: 'a' }); -const CardText = createWithBsPrefix('card-text', { Component: 'p' }); -const CardFooter = createWithBsPrefix('card-footer'); -const CardImgOverlay = createWithBsPrefix('card-img-overlay'); - export interface CardProps extends BsPrefixProps, React.HTMLAttributes { diff --git a/src/CardBody.tsx b/src/CardBody.tsx new file mode 100644 index 0000000000..258f4d43f4 --- /dev/null +++ b/src/CardBody.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface CardBodyProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardBody: BsPrefixRefForwardingComponent<'div', CardBodyProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-body'); + return ( + + ); + }, + ); + +CardBody.displayName = 'CardBody'; + +export default CardBody; diff --git a/src/CardFooter.tsx b/src/CardFooter.tsx new file mode 100644 index 0000000000..7649fee0f2 --- /dev/null +++ b/src/CardFooter.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface CardFooterProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardFooter: BsPrefixRefForwardingComponent<'div', CardFooterProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-footer'); + return ( + + ); + }, + ); + +CardFooter.displayName = 'CardFooter'; + +export default CardFooter; diff --git a/src/CardGroup.tsx b/src/CardGroup.tsx index e06092de69..109589819a 100644 --- a/src/CardGroup.tsx +++ b/src/CardGroup.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('card-group'); +export interface CardGroupProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardGroup: BsPrefixRefForwardingComponent<'div', CardGroupProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-group'); + return ( + + ); + }, + ); + +CardGroup.displayName = 'CardGroup'; + +export default CardGroup; diff --git a/src/CardImgOverlay.tsx b/src/CardImgOverlay.tsx new file mode 100644 index 0000000000..4168d57517 --- /dev/null +++ b/src/CardImgOverlay.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface CardImgOverlayProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardImgOverlay: BsPrefixRefForwardingComponent< + 'div', + CardImgOverlayProps +> = React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-img-overlay'); + return ( + + ); + }, +); + +CardImgOverlay.displayName = 'CardImgOverlay'; + +export default CardImgOverlay; diff --git a/src/CardLink.tsx b/src/CardLink.tsx new file mode 100644 index 0000000000..4063a1ecc9 --- /dev/null +++ b/src/CardLink.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface CardLinkProps + extends BsPrefixProps, + React.AnchorHTMLAttributes {} + +const CardLink: BsPrefixRefForwardingComponent<'a', CardLinkProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'a', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-link'); + return ( + + ); + }, + ); + +CardLink.displayName = 'CardLink'; + +export default CardLink; diff --git a/src/CardSubtitle.tsx b/src/CardSubtitle.tsx new file mode 100644 index 0000000000..2a0518e821 --- /dev/null +++ b/src/CardSubtitle.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; +import divWithClassName from './divWithClassName'; + +const DivStyledAsH6 = divWithClassName('h6'); + +export interface CardSubtitleProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardSubtitle: BsPrefixRefForwardingComponent<'div', CardSubtitleProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = DivStyledAsH6, ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-subtitle'); + return ( + + ); + }, + ); + +CardSubtitle.displayName = 'CardSubtitle'; + +export default CardSubtitle; diff --git a/src/CardText.tsx b/src/CardText.tsx new file mode 100644 index 0000000000..0ad455f536 --- /dev/null +++ b/src/CardText.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface CardTextProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardText: BsPrefixRefForwardingComponent<'p', CardTextProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'p', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-text'); + return ( + + ); + }, + ); + +CardText.displayName = 'CardText'; + +export default CardText; diff --git a/src/CardTitle.tsx b/src/CardTitle.tsx new file mode 100644 index 0000000000..762d701c44 --- /dev/null +++ b/src/CardTitle.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; +import divWithClassName from './divWithClassName'; + +const DivStyledAsH5 = divWithClassName('h5'); + +export interface CardTitleProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CardTitle: BsPrefixRefForwardingComponent<'div', CardTitleProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = DivStyledAsH5, ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'card-title'); + return ( + + ); + }, + ); + +CardTitle.displayName = 'CardTitle'; + +export default CardTitle; diff --git a/src/CarouselCaption.tsx b/src/CarouselCaption.tsx index 1b430e2faf..9a3dcdecb5 100644 --- a/src/CarouselCaption.tsx +++ b/src/CarouselCaption.tsx @@ -1,3 +1,28 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('carousel-caption'); +export interface CarouselCaptionProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const CarouselCaption: BsPrefixRefForwardingComponent< + 'div', + CarouselCaptionProps +> = React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'carousel-caption'); + return ( + + ); + }, +); + +CarouselCaption.displayName = 'CarouselCaption'; + +export default CarouselCaption; diff --git a/src/Dropdown.tsx b/src/Dropdown.tsx index 32fbad9033..e6b22873d4 100644 --- a/src/Dropdown.tsx +++ b/src/Dropdown.tsx @@ -9,26 +9,17 @@ import BaseDropdown, { import { useUncontrolled } from 'uncontrollable'; import useEventCallback from '@restart/hooks/useEventCallback'; import DropdownContext, { DropDirection } from './DropdownContext'; +import DropdownDivider from './DropdownDivider'; +import DropdownHeader from './DropdownHeader'; import DropdownItem from './DropdownItem'; +import DropdownItemText from './DropdownItemText'; import DropdownMenu, { getDropdownMenuPlacement } from './DropdownMenu'; import DropdownToggle from './DropdownToggle'; import InputGroupContext from './InputGroupContext'; import { useBootstrapPrefix, useIsRTL } from './ThemeProvider'; -import createWithBsPrefix from './createWithBsPrefix'; import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; import { AlignType, alignPropType } from './types'; -const DropdownHeader = createWithBsPrefix('dropdown-header', { - defaultProps: { role: 'heading' }, -}); -const DropdownDivider = createWithBsPrefix('dropdown-divider', { - Component: 'hr', - defaultProps: { role: 'separator' }, -}); -const DropdownItemText = createWithBsPrefix('dropdown-item-text', { - Component: 'span', -}); - export interface DropdownProps extends BaseDropdownProps, BsPrefixProps, diff --git a/src/DropdownDivider.tsx b/src/DropdownDivider.tsx new file mode 100644 index 0000000000..5d6cfb0a96 --- /dev/null +++ b/src/DropdownDivider.tsx @@ -0,0 +1,32 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface DropdownDividerProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const DropdownDivider: BsPrefixRefForwardingComponent< + 'hr', + DropdownDividerProps +> = React.forwardRef( + ( + { className, bsPrefix, as: Component = 'hr', role = 'separator', ...props }, + ref, + ) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'dropdown-divider'); + return ( + + ); + }, +); + +DropdownDivider.displayName = 'DropdownDivider'; + +export default DropdownDivider; diff --git a/src/DropdownHeader.tsx b/src/DropdownHeader.tsx new file mode 100644 index 0000000000..fc1ca69d50 --- /dev/null +++ b/src/DropdownHeader.tsx @@ -0,0 +1,32 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface DropdownHeaderProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const DropdownHeader: BsPrefixRefForwardingComponent< + 'div', + DropdownHeaderProps +> = React.forwardRef( + ( + { className, bsPrefix, as: Component = 'div', role = 'heading', ...props }, + ref, + ) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'dropdown-header'); + return ( + + ); + }, +); + +DropdownHeader.displayName = 'DropdownHeader'; + +export default DropdownHeader; diff --git a/src/DropdownItemText.tsx b/src/DropdownItemText.tsx new file mode 100644 index 0000000000..bc830e9cf2 --- /dev/null +++ b/src/DropdownItemText.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface DropdownItemTextProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const DropdownItemText: BsPrefixRefForwardingComponent< + 'span', + DropdownItemTextProps +> = React.forwardRef( + ({ className, bsPrefix, as: Component = 'span', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'dropdown-item-text'); + return ( + + ); + }, +); + +DropdownItemText.displayName = 'DropdownItemText'; + +export default DropdownItemText; diff --git a/src/Figure.tsx b/src/Figure.tsx index bef3507f82..0452b25e6f 100644 --- a/src/Figure.tsx +++ b/src/Figure.tsx @@ -1,10 +1,29 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; import FigureImage from './FigureImage'; import FigureCaption from './FigureCaption'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -const Figure = createWithBsPrefix('figure', { - Component: 'figure', -}); +export interface FigureProps + extends BsPrefixProps, + React.AnchorHTMLAttributes {} + +const Figure: BsPrefixRefForwardingComponent<'figure', FigureProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'figure', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'figure'); + return ( + + ); + }, + ); + +Figure.displayName = 'Figure'; export default Object.assign(Figure, { Image: FigureImage, diff --git a/src/FigureCaption.tsx b/src/FigureCaption.tsx index 3a1ab80fa5..5033f06c69 100644 --- a/src/FigureCaption.tsx +++ b/src/FigureCaption.tsx @@ -1,7 +1,28 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -const FigureCaption = createWithBsPrefix('figure-caption', { - Component: 'figcaption', -}); +export interface FigureCaptionProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const FigureCaption: BsPrefixRefForwardingComponent< + 'figcaption', + FigureCaptionProps +> = React.forwardRef( + ({ className, bsPrefix, as: Component = 'figcaption', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'figure-caption'); + return ( + + ); + }, +); + +FigureCaption.displayName = 'FigureCaption'; export default FigureCaption; diff --git a/src/FormFloating.tsx b/src/FormFloating.tsx index 1c9de06545..7809479709 100644 --- a/src/FormFloating.tsx +++ b/src/FormFloating.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('form-floating'); +export interface FormFloatingProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const FormFloating: BsPrefixRefForwardingComponent<'div', FormFloatingProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'form-floating'); + return ( + + ); + }, + ); + +FormFloating.displayName = 'FormFloating'; + +export default FormFloating; diff --git a/src/InputGroup.tsx b/src/InputGroup.tsx index 1cc9b2de1b..e4236ffa25 100644 --- a/src/InputGroup.tsx +++ b/src/InputGroup.tsx @@ -4,23 +4,19 @@ import PropTypes from 'prop-types'; import * as React from 'react'; import { useMemo } from 'react'; -import createWithBsPrefix from './createWithBsPrefix'; import { useBootstrapPrefix } from './ThemeProvider'; -import FormCheckInput from './FormCheckInput'; +import FormCheckInput, { type FormCheckInputProps } from './FormCheckInput'; import InputGroupContext from './InputGroupContext'; import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; +import InputGroupText from './InputGroupText'; -const InputGroupText = createWithBsPrefix('input-group-text', { - Component: 'span', -}); - -const InputGroupCheckbox = (props) => ( +const InputGroupCheckbox = (props: FormCheckInputProps) => ( ); -const InputGroupRadio = (props) => ( +const InputGroupRadio = (props: FormCheckInputProps) => ( diff --git a/src/InputGroupText.tsx b/src/InputGroupText.tsx new file mode 100644 index 0000000000..1f84b409f2 --- /dev/null +++ b/src/InputGroupText.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface InputGroupTextProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const InputGroupText: BsPrefixRefForwardingComponent< + 'span', + InputGroupTextProps +> = React.forwardRef( + ({ className, bsPrefix, as: Component = 'span', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'input-group-text'); + return ( + + ); + }, +); + +InputGroupText.displayName = 'InputGroupText'; + +export default InputGroupText; diff --git a/src/ModalBody.tsx b/src/ModalBody.tsx index c7b267b071..5e37d9a8a5 100644 --- a/src/ModalBody.tsx +++ b/src/ModalBody.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('modal-body'); +export interface ModalBodyProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const ModalBody: BsPrefixRefForwardingComponent<'div', ModalBodyProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'modal-body'); + return ( + + ); + }, + ); + +ModalBody.displayName = 'ModalBody'; + +export default ModalBody; diff --git a/src/ModalFooter.tsx b/src/ModalFooter.tsx index fb4daa35ad..95b2739fbe 100644 --- a/src/ModalFooter.tsx +++ b/src/ModalFooter.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('modal-footer'); +export interface ModalFooterProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const ModalFooter: BsPrefixRefForwardingComponent<'div', ModalFooterProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'modal-footer'); + return ( + + ); + }, + ); + +ModalFooter.displayName = 'ModalFooter'; + +export default ModalFooter; diff --git a/src/ModalTitle.tsx b/src/ModalTitle.tsx index 4dd13dea3a..aaa1dc49a7 100644 --- a/src/ModalTitle.tsx +++ b/src/ModalTitle.tsx @@ -1,6 +1,29 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; import divWithClassName from './divWithClassName'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; const DivStyledAsH4 = divWithClassName('h4'); -export default createWithBsPrefix('modal-title', { Component: DivStyledAsH4 }); +export interface ModalTitleProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const ModalTitle: BsPrefixRefForwardingComponent<'span', ModalTitleProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = DivStyledAsH4, ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'modal-title'); + return ( + + ); + }, + ); + +ModalTitle.displayName = 'ModalTitle'; + +export default ModalTitle; diff --git a/src/NavItem.tsx b/src/NavItem.tsx index 683d8f70ec..9a045d5604 100644 --- a/src/NavItem.tsx +++ b/src/NavItem.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('nav-item'); +export interface NavItemProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const NavItem: BsPrefixRefForwardingComponent<'div', NavItemProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'nav-item'); + return ( + + ); + }, + ); + +NavItem.displayName = 'NavItem'; + +export default NavItem; diff --git a/src/Navbar.tsx b/src/Navbar.tsx index e41c274011..ce3ae52f53 100644 --- a/src/Navbar.tsx +++ b/src/Navbar.tsx @@ -6,19 +6,15 @@ import SelectableContext from '@restart/ui/SelectableContext'; import { SelectCallback } from '@restart/ui/types'; import { useUncontrolled } from 'uncontrollable'; -import createWithBsPrefix from './createWithBsPrefix'; import NavbarBrand from './NavbarBrand'; import NavbarCollapse from './NavbarCollapse'; import NavbarToggle from './NavbarToggle'; import NavbarOffcanvas from './NavbarOffcanvas'; import { useBootstrapPrefix } from './ThemeProvider'; import NavbarContext, { NavbarContextType } from './NavbarContext'; +import NavbarText from './NavbarText'; import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -const NavbarText = createWithBsPrefix('navbar-text', { - Component: 'span', -}); - export interface NavbarProps extends BsPrefixProps, Omit, 'onSelect'> { diff --git a/src/NavbarText.tsx b/src/NavbarText.tsx new file mode 100644 index 0000000000..050e1348cc --- /dev/null +++ b/src/NavbarText.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; + +export interface NavbarTextProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const NavbarText: BsPrefixRefForwardingComponent<'span', NavbarTextProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'span', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'navbar-text'); + return ( + + ); + }, + ); + +NavbarText.displayName = 'NavbarText'; + +export default NavbarText; diff --git a/src/OffcanvasBody.tsx b/src/OffcanvasBody.tsx index 7b599bce9e..abe93b5f57 100644 --- a/src/OffcanvasBody.tsx +++ b/src/OffcanvasBody.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('offcanvas-body'); +export interface OffcanvasBodyProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const OffcanvasBody: BsPrefixRefForwardingComponent<'div', OffcanvasBodyProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas-body'); + return ( + + ); + }, + ); + +OffcanvasBody.displayName = 'OffcanvasBody'; + +export default OffcanvasBody; diff --git a/src/OffcanvasTitle.tsx b/src/OffcanvasTitle.tsx index e53f163dbd..fa208da8d7 100644 --- a/src/OffcanvasTitle.tsx +++ b/src/OffcanvasTitle.tsx @@ -1,8 +1,31 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; import divWithClassName from './divWithClassName'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; const DivStyledAsH5 = divWithClassName('h5'); -export default createWithBsPrefix('offcanvas-title', { - Component: DivStyledAsH5, -}); +export interface OffcanvasTitleProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const OffcanvasTitle: BsPrefixRefForwardingComponent< + 'div', + OffcanvasTitleProps +> = React.forwardRef( + ({ className, bsPrefix, as: Component = DivStyledAsH5, ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas-title'); + return ( + + ); + }, +); + +OffcanvasTitle.displayName = 'OffcanvasTitle'; + +export default OffcanvasTitle; diff --git a/src/PopoverBody.tsx b/src/PopoverBody.tsx index e614507fe1..d73a8a158e 100644 --- a/src/PopoverBody.tsx +++ b/src/PopoverBody.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('popover-body'); +export interface PopoverBodyProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const PopoverBody: BsPrefixRefForwardingComponent<'div', PopoverBodyProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'popover-body'); + return ( + + ); + }, + ); + +PopoverBody.displayName = 'PopoverBody'; + +export default PopoverBody; diff --git a/src/PopoverHeader.tsx b/src/PopoverHeader.tsx index 41c05e0b1e..b053e066d4 100644 --- a/src/PopoverHeader.tsx +++ b/src/PopoverHeader.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('popover-header'); +export interface PopoverHeaderProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const PopoverHeader: BsPrefixRefForwardingComponent<'div', PopoverHeaderProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'popover-header'); + return ( + + ); + }, + ); + +PopoverHeader.displayName = 'PopoverHeader'; + +export default PopoverHeader; diff --git a/src/TabContent.tsx b/src/TabContent.tsx index beb14d09fe..19842dde58 100644 --- a/src/TabContent.tsx +++ b/src/TabContent.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('tab-content'); +export interface TabContentProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const TabContent: BsPrefixRefForwardingComponent<'div', TabContentProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'tab-content'); + return ( + + ); + }, + ); + +TabContent.displayName = 'TabContent'; + +export default TabContent; diff --git a/src/ToastBody.tsx b/src/ToastBody.tsx index fa94a9a5f9..62ed554d37 100644 --- a/src/ToastBody.tsx +++ b/src/ToastBody.tsx @@ -1,3 +1,26 @@ -import createWithBsPrefix from './createWithBsPrefix'; +import * as React from 'react'; +import classNames from 'classnames'; +import { useBootstrapPrefix } from './ThemeProvider'; +import type { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers'; -export default createWithBsPrefix('toast-body'); +export interface ToastBodyProps + extends BsPrefixProps, + React.HTMLAttributes {} + +const ToastBody: BsPrefixRefForwardingComponent<'div', ToastBodyProps> = + React.forwardRef( + ({ className, bsPrefix, as: Component = 'div', ...props }, ref) => { + bsPrefix = useBootstrapPrefix(bsPrefix, 'toast-body'); + return ( + + ); + }, + ); + +ToastBody.displayName = 'ToastBody'; + +export default ToastBody; diff --git a/src/index.tsx b/src/index.tsx index ddee82372f..941c0cdcb2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -11,9 +11,21 @@ export { } from './AccordionButton'; export type { AccordionButtonProps } from './AccordionButton'; +export { default as AccordionHeader } from './AccordionHeader'; +export type { AccordionHeaderProps } from './AccordionHeader'; + +export { default as AccordionItem } from './AccordionItem'; +export type { AccordionItemProps } from './AccordionItem'; + export { default as Alert } from './Alert'; export type { AlertProps } from './Alert'; +export { default as AlertHeading } from './AlertHeading'; +export type { AlertHeadingProps } from './AlertHeading'; + +export { default as AlertLink } from './AlertLink'; +export type { AlertLinkProps } from './AlertLink'; + export { default as Anchor } from './Anchor'; export type { AnchorProps } from './Anchor'; @@ -38,13 +50,42 @@ export type { ButtonToolbarProps } from './ButtonToolbar'; export { default as Card } from './Card'; export type { CardProps } from './Card'; +export { default as CardBody } from './CardBody'; +export type { CardBodyProps } from './CardBody'; + +export { default as CardFooter } from './CardFooter'; +export type { CardFooterProps } from './CardFooter'; + +export { default as CardGroup } from './CardGroup'; +export type { CardGroupProps } from './CardGroup'; + +export { default as CardHeader } from './CardHeader'; +export type { CardHeaderProps } from './CardHeader'; + export { default as CardImg } from './CardImg'; export type { CardImgProps } from './CardImg'; -export { default as CardGroup } from './CardGroup'; +export { default as CardImgOverlay } from './CardImgOverlay'; +export type { CardImgOverlayProps } from './CardImgOverlay'; + +export { default as CardLink } from './CardLink'; +export type { CardLinkProps } from './CardLink'; + +export { default as CardSubtitle } from './CardSubtitle'; +export type { CardSubtitleProps } from './CardSubtitle'; + +export { default as CardText } from './CardText'; +export type { CardTextProps } from './CardText'; + +export { default as CardTitle } from './CardTitle'; +export type { CardTitleProps } from './CardTitle'; + export { default as Carousel } from './Carousel'; export type { CarouselProps } from './Carousel'; +export { default as CarouselCaption } from './CarouselCaption'; +export type { CarouselCaptionProps } from './CarouselCaption'; + export { default as CarouselItem } from './CarouselItem'; export type { CarouselItemProps } from './CarouselItem'; @@ -57,15 +98,44 @@ export type { ColProps } from './Col'; export { default as Collapse } from './Collapse'; export type { CollapseProps } from './Collapse'; +export { default as Container } from './Container'; +export type { ContainerProps } from './Container'; + export { default as Dropdown } from './Dropdown'; export type { DropdownProps } from './Dropdown'; export { default as DropdownButton } from './DropdownButton'; export type { DropdownButtonProps } from './DropdownButton'; +export { default as DropdownDivider } from './DropdownDivider'; +export type { DropdownDividerProps } from './DropdownDivider'; + +export { default as DropdownHeader } from './DropdownHeader'; +export type { DropdownHeaderProps } from './DropdownHeader'; + +export { default as DropdownItem } from './DropdownItem'; +export type { DropdownItemProps } from './DropdownItem'; + +export { default as DropdownItemText } from './DropdownItemText'; +export type { DropdownItemTextProps } from './DropdownItemText'; + +export { default as DropdownMenu } from './DropdownMenu'; +export type { DropdownMenuProps } from './DropdownMenu'; + +export { default as DropdownToggle } from './DropdownToggle'; +export type { DropdownToggleProps } from './DropdownToggle'; + export { default as Fade } from './Fade'; export type { FadeProps } from './Fade'; +export { default as Figure } from './Figure'; +export type { FigureProps } from './Figure'; + +export { default as FigureCaption } from './FigureCaption'; +export type { FigureCaptionProps } from './FigureCaption'; + +export { default as FigureImage } from './FigureImage'; + export { default as Form } from './Form'; export type { FormProps } from './Form'; @@ -92,13 +162,9 @@ export type { FormTextProps } from './FormText'; export { default as FormSelect } from './FormSelect'; export type { FormSelectProps } from './FormSelect'; -export { default as Container } from './Container'; -export type { ContainerProps } from './Container'; - export { default as Image } from './Image'; export type { ImageProps } from './Image'; -export { default as Figure } from './Figure'; export { default as InputGroup } from './InputGroup'; export type { InputGroupProps } from './InputGroup'; @@ -116,11 +182,15 @@ export { default as ModalBody } from './ModalBody'; export { default as ModalDialog } from './ModalDialog'; export type { ModalDialogProps } from './ModalDialog'; +export { default as ModalFooter } from './ModalFooter'; +export type { ModalFooterProps } from './ModalFooter'; + export { default as ModalHeader } from './ModalHeader'; export type { ModalHeaderProps } from './ModalHeader'; -export { default as ModalFooter } from './ModalFooter'; export { default as ModalTitle } from './ModalTitle'; +export type { ModalTitleProps } from './ModalTitle'; + export { default as Nav } from './Nav'; export type { NavProps } from './Nav'; @@ -130,20 +200,41 @@ export type { NavbarProps } from './Navbar'; export { default as NavbarBrand } from './NavbarBrand'; export type { NavbarBrandProps } from './NavbarBrand'; +export { default as NavbarCollapse } from './NavbarCollapse'; +export type { NavbarCollapseProps } from './NavbarCollapse'; + +export { default as NavbarOffcanvas } from './NavbarOffcanvas'; +export type { NavbarOffcanvasProps } from './NavbarOffcanvas'; + +export { default as NavbarText } from './NavbarText'; +export type { NavbarTextProps } from './NavbarText'; + +export { default as NavbarToggle } from './NavbarToggle'; +export type { NavbarToggleProps } from './NavbarToggle'; + export { default as NavDropdown } from './NavDropdown'; export type { NavDropdownProps } from './NavDropdown'; export { default as NavItem } from './NavItem'; +export type { NavItemProps } from './NavItem'; export { default as NavLink } from './NavLink'; export type { NavLinkProps } from './NavLink'; export { default as Offcanvas } from './Offcanvas'; export type { OffcanvasProps } from './Offcanvas'; + +export { default as OffcanvasBody } from './OffcanvasBody'; +export type { OffcanvasBodyProps } from './OffcanvasBody'; + export { default as OffcanvasHeader } from './OffcanvasHeader'; export type { OffcanvasHeaderProps } from './OffcanvasHeader'; + export { default as OffcanvasTitle } from './OffcanvasTitle'; -export { default as OffcanvasBody } from './OffcanvasBody'; +export type { OffcanvasTitleProps } from './OffcanvasTitle'; + +export { default as OffcanvasToggling } from './OffcanvasToggling'; +export type { OffcanvasTogglingProps } from './OffcanvasToggling'; export { default as Overlay } from './Overlay'; export type { OverlayProps } from './Overlay'; @@ -159,14 +250,19 @@ export type { PaginationProps } from './Pagination'; export { default as Placeholder } from './Placeholder'; export type { PlaceholderProps } from './Placeholder'; + export { default as PlaceholderButton } from './PlaceholderButton'; export type { PlaceholderButtonProps } from './PlaceholderButton'; export { default as Popover } from './Popover'; export type { PopoverProps } from './Popover'; -export { default as PopoverHeader } from './PopoverHeader'; export { default as PopoverBody } from './PopoverBody'; +export type { PopoverBodyProps } from './PopoverBody'; + +export { default as PopoverHeader } from './PopoverHeader'; +export type { PopoverHeaderProps } from './PopoverHeader'; + export { default as ProgressBar } from './ProgressBar'; export type { ProgressBarProps } from './ProgressBar'; @@ -195,6 +291,8 @@ export { default as TabContainer } from './TabContainer'; export type { TabContainerProps } from './TabContainer'; export { default as TabContent } from './TabContent'; +export type { TabContentProps } from './TabContent'; + export { default as Table } from './Table'; export type { TableProps } from './Table'; @@ -211,12 +309,14 @@ export { default as Toast } from './Toast'; export type { ToastProps } from './Toast'; export { default as ToastBody } from './ToastBody'; -export { default as ToastHeader } from './ToastHeader'; -export type { ToastHeaderProps } from './ToastHeader'; +export type { ToastBodyProps } from './ToastBody'; export { default as ToastContainer } from './ToastContainer'; export type { ToastContainerProps } from './ToastContainer'; +export { default as ToastHeader } from './ToastHeader'; +export type { ToastHeaderProps } from './ToastHeader'; + export { default as ToggleButton } from './ToggleButton'; export type { ToggleButtonProps } from './ToggleButton';