UNPKG

@legendarymediatv/bootstrap

Version:

additional Bootstrap-based React components for extending functionality to react-bootstrap and gatsby

948 lines (739 loc) 57.6 kB
# LegendaryMediaTV Bootstrap This is a Node.js package for extending [React Bootstrap](https://react-bootstrap.github.io) (which is based on [Bootstrap 5](https://getbootstrap.com/)) and [Gatsby 3 or 4](https://www.gatsbyjs.com). It also has components for class-based icons (i.e., [FontAwesome](https://fontawesome.com), [Bootstrap icons](https://icons.getbootstrap.com), etc.). ## Recent changes - **v4.1.0** - updated the peer dependency for Gatsby to include `5.x` - **v4.0.0** - upgrated to FontAwesome 6 for the default icon names - updated FontAwesome reference to `6.1.1` - updated Bootstrap Icons CSS reference to `1.8.2` - **v3.5** - updated the peer dependency for React to `17.x` or `18.x` - **v3.4** - added a new `<Feature>` component with `title` and `subtitle` properties - added `<Alert>` with `title`/`subtitle` to the `<Demo>` - made `<ScrollToTop>` component not print - bugfix for `<ListGroup.Item>` component not showing `subitem` when `subactions` property is set - **v3.3** - added an `<Alert>` component with `title`, `subtitle`, and `error` properties - made the `<Demo>` utilize the new `<Alert>` component - **v3.2** - added a `<ListGroup.Item>` component with `subitem` and `subactions` properties - added a `sleep()` function - **v3.1** - added a `<Pagination>` component that uses our Gatsby-friendly `<Link>` component - made the `<Demo>` component more robust - added a `title` property to the `<Spinner>` component - bugfix for `<Link>` opening internal links in a new tab when requested - bugfix for the `<ListGroup>` default italics class on `displaySubClassName` - updated the peer dependency for React Bootstrap to `2.x`, since 2.0 stable released - updated the peer dependency for Gatsby to `3.x` or `4.x` - updated Bootstrap CSS reference to `5.1.3` For more information, check out the [release notes](https://github.com/LegendaryMediaTV/LMTV-Bootstrap/releases) and the [changelog](https://github.com/LegendaryMediaTV/LMTV-Bootstrap/commits/main). ## Getting started ### Installation Install peer dependencies (if they aren't already). ```JavaScript npm install react react-dom react-bootstrap gatsby ``` Optionally, install [React Helmet](https://github.com/nfl/react-helmet) (useful for linking Bootstrap resources). ```JavaScript npm install react-helmet ``` Install this package. ```JavaScript npm install @legendarymediatv/bootstrap ``` > _NOTE: if you are still using Bootstrap 4.6.x and React Bootstrap 1.6.x, then you can use [version 2.13.1 of this package](https://www.npmjs.com/package/@legendarymediatv/bootstrap/v/2.13.1), however, it is not continuing to be maintained_ ### Preparation [Modify the Babel loader](https://www.gatsbyjs.com/docs/how-to/custom-configuration/add-custom-webpack-config/#modifying-the-babel-loader) to transpile JSX for this package. > _NOTE: not configuring this will result in the following error when running `gatsby build`: ERROR #98123 WEBPACK – Generating development JavaScript bundle failed: Unexpected token_ **Sample `/gatsby-node.js`** ```JavaScript exports.onCreateWebpackConfig = ({ actions, loaders, getConfig }) => { const config = getConfig(); config.module.rules = [ // omit the default rule where test === '\.jsx?$' ...config.module.rules.filter( (rule) => String(rule.test) !== String(/\.jsx?$/) ), // re-create it with custom exclude filter { // apply required Babel presets/plugins and merge in your configuration from `babel.config.js`. ...loaders.js(), test: /\.jsx?$/, // exclude all node_modules from transpilation, except for this plugin // NOTE: their pattern has "\/" but this has "[\\\/]" to support all OS path separators exclude: (modulePath) => /node_modules/.test(modulePath) && !/node_modules[\\\/]@legendarymediatv[\\\/]bootstrap/.test(modulePath), }, ]; // replace the webpack config with the modified object. actions.replaceWebpackConfig(config); }; ``` Either import Bootstrap CSS or link Bootstrap into your layout or app file. **Sample `/src/components/Layout.js` (link, with FontAwesome)** ```JavaScript import React from "react"; import { Helmet } from "react-helmet"; import Container from "react-bootstrap/Container"; const Layout = (props) => { return ( <> <Helmet htmlAttributes={{ lang: "en" }}> <title>{props.title}</title> <meta name="description" content={props.description} /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> </Helmet> <Container className="py-4"> <h1 className="display-1">{props.title}</h1> {props.children} </Container> </> ); }; export default Layout; ``` Finally, import the components as needed into your app/components. **Sample `/src/pages/index.js`** ```JavaScript // dependencies import React from "react"; // page layout template import Layout from "../components/Layout"; // sample LegendaryMediaTV component import Icon from "@legendarymediatv/bootstrap/Icon"; const SamplePage = () => { return ( <Layout title="Page Title" description="Page Description"> <Icon name="fa-solid fa-camera" /> </Layout> ); }; export default SamplePage; ``` ## Components > _NOTE: components can be imported at the package level or at the component level_ ```JavaScript // package-level import { Demo } from '@legendarymediatv/bootstrap'; // component level (preferred) import Demo from '@legendarymediatv/bootstrap/Demo'; ``` ### `<Alert>` An extension of [React Bootstrap’s `<Alert>`](https://react-bootstrap.github.io/components/alerts/) component, but with the ability to set a title, subtitle, and/or error. It provides `<Alert.Heading>` as is, but converts their `<Alert.Link>` to our Gatsby-friendly `<Link>` component. ```JavaScript import Alert from '@legendarymediatv/bootstrap/Alert'; … <Alert title="Alert Title" subtitle="Alert subtitle" variant="info" onClose={() => { alert("Insert dismiss logic here"); }} dismissible > Some text with a <Alert.Link to="/sample">link</Alert.Link> </Alert> <Alert error={{ error: "Request failed with status code 401", url: "/", method: "GET", }} onRetry={() => { alert("Insert retry logic here"); }} /> <Alert error={["Field 1 is required", "Field 2 is required"]} /> ``` In addition to the properties provided by [React Bootstrap’s `<Alert>`](https://react-bootstrap.github.io/components/alerts/) component, the following additional properties are available: | Name | Type | Default | Description | | :--------- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------- | | `error` | JSX \| object | | either a JSX component or an object containing keys for `error`/`message` and optionally `url` and/or `method` | | `onRetry` | function | | when defined, a retry `<Button>` is rendered with this as its `onClick` | | `subtitle` | JSX | if `error` is an array, then `'Please fix the following error(s):'`; if `error` is not an array, then `'The server has encountered a situation it doesn’t know how to handle'`; otherwise, blank | content that goes inside a `<p>` tag styled with a `lead` class | | `title` | JSX | if `error` is an array, then `'Submission Error'`; if `error` is not an array, then `'Process Error'`; otherwise, blank | content that goes inside an `<Alert.Heading>` styled as a `<div>` with an `h3` class | | `variant` | string | `'danger'` if `error` is defined, otherwise `'primary'` (inherited) | Bootstrap theme color name | ### `<BackgroundImage>` Set a background image so that it covers the whole screen without distorting and stays in place, regardless of scrolling. ```JavaScript import BackgroundImage from '@legendarymediatv/bootstrap/BackgroundImage'; … <BackgroundImage src="/images/sample.jpg" /> ``` | Name | Type | Default | Description | | :--------------- | :----- | :------- | :----------------------------------- | | `imageClassName` | string | | `className` property for the `<img>` | | `imageStyle` | object | | `style` property for the `<img>` | | `src` | string | required | path to the image file | ### `<Blockquote>` Quote blocks of content using [Bootstrap’s Blockquote](https://getbootstrap.com/docs/5.1/content/typography/#blockquotes). ```JavaScript import Blockquote from '@legendarymediatv/bootstrap/Blockquote'; … <Blockquote> <p className="mb-0"> A well-known quote, contained in a blockquote element. </p> </Blockquote> <Blockquote> <p> Success, meaningful success, begins when we take ownership and actively take responsibility for our part in the shortcomings of our life. </p> <Blockquote.Footer> Dr Eric Thomas,{" "} <cite>Greatness Is Upon You: Laying the Foundation</cite> </Blockquote.Footer> </Blockquote> ``` ### `<Breakpoint>` Quickly see what the current breakpoint is (e.g., “md”). ```JavaScript import Breakpoint from '@legendarymediatv/bootstrap/Breakpoint'; … <Breakpoint /> ``` > _NOTE: This component is intended to be used for development purposes and probably should be removed before deploying your app_ | Name | Type | Default | Description | | :-------- | :----- | :------- | :------------------------- | | `variant` | string | `'info'` | Bootstrap theme color name | ### `<DatePicker>` Allow someone to select a date using a calendar popover. ```JavaScript import DatePicker from '@legendarymediatv/bootstrap/DatePicker'; … // use React state to track selected date const [componentState, setComponentState] = React.useState(null); … // select a new date function dateHandler(selected) => { setComponentState(selected); }; … <DatePicker title="Contact Date" value={componentState} onChange={dateHandler} /> ``` > _TIP: You could make your date change handler set the value for a hidden form element in addition to setting the state so that the date is submitted with the other form values_ | Name | Type | Default | Description | | :-------- | :---------- | :------------ | :------------------------------------------------------- | | `title` | JSX | `Date Picker` | popover title | | `titleAs` | elementType | `<h3>` | `as` property for the popover title | | `variant` | string | `light` | Bootstrap theme color name applied to the display button | ### `<Demo>` This component is intended to be used for development purposes (e.g., testing your custom Bootstrap theme) by having everything all one one page! ### `<Display>` Bootstrap’s display heading typography classes. - `<Display.Heading1>` - `<Display.Heading2>` - `<Display.Heading3>` - `<Display.Heading4>` - `<Display.Heading5>` - `<Display.Heading6>` ```JavaScript import Display from '@legendarymediatv/bootstrap/Display'; … <Display.Heading1>Display Heading 1</Display.Heading1> <Display.Heading2>Display Heading 2</Display.Heading2> <Display.Heading3>Display Heading 3</Display.Heading3> <Display.Heading4>Display Heading 4</Display.Heading4> <Display.Heading5>Display Heading 5</Display.Heading5> <Display.Heading6>Display Heading 6</Display.Heading6> ``` | Name | Type | Default | Description | | :--- | :---------- | :------------------------------- | :------------------- | | `as` | elementType | `<h#>` corresponding to the size | changes the HTML tag | ### `<Feature>` Quickly create a stylized hero link or button that uses scaling and shadows to grow on hover and appear as depressed when clicked. > _TIP: use in conjunction with grid layout components to have a wall effect_ > _TIP: since this component uses scaling, to prevent horizontal scrollbars on smaller displays, you may want to wrap your content in a `<Feature.Container>` component or otherwise add `overflow: hidden;` styling to a fluid container, your `<body>` tag, etc._ ```JavaScript import Feature from '@legendarymediatv/bootstrap/Feature'; … <Feature title="Featured Content" subtitle="content to be featured" to="/sample" variant="info" textShadow wrapperClassName="rounded-pill mb-3" className="text-white py-5" /> <Row className="text-white"> <Col sm className="p-0"> <Feature title="Sample 1" to="/sample-1" variant="dark" className="py-3" /> </Col> <Col sm className="p-0"> <Feature title="Sample 2" to="/sample-2" variant="success" className="py-3" /> </Col> <Col sm className="p-0"> <Feature title="Sample 3" onClick={() => { alert("danger!"); }} variant="danger" className="py-3" /> </Col> </Row> ``` > _NOTE: This component is intended to be used for development purposes and probably should be removed before deploying your app_ | Name | Type | Default | Description | | :----------------- | :------ | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `href` \| `to` | string | | URL or anchor target, making the feature item our Gatsby-friendly `<Link>` when set, otherwise it renders as a `<button>` and probably should have the `onClick` set | | `id` | string | | applied to the wrapper `<div>` | | `subtitle` | JSX | | content that goes inside a `<div>` tag styled with `lead fst-italic` between the `title` and `children` | | `title` | JSX | | content that goes inside an `<h2>` tag styled with `display-4 mb-0` above the `subtitle` and/or `children` | | `textShadow` | boolean | `false` | add a slight shadow to the feature’s text | | `variant` | string | | Bootstrap theme color, if one is not provided, you should probably add background color and/or image using the provided `id` (images are set to `center` and `cover`) | | `wrapperClassName` | string | | `className` property for the wrapper `<div>` | | `wrapperStyle` | object | | `style` property for the wrapper `<div>` | ### `<Flipper>` Flashcard-like component that can flip horizontally or vertically using a 3D effect either on hover or via an event. ```JavaScript import Flipper from '@legendarymediatv/bootstrap/Flipper'; … <Flipper front={<h3>auto-flipper front content</h3>} frontClassName="bg-primary text-light p-2" back={<h3>auto-flipper back content</h3>} backClassName="bg-secondary text-light p-2" /> … // use React state to track flipped state const [componentState, setComponentState] = React.useState(false); … function flipHandler(event) => { // un-click the button event.preventDefault(); // toggle flip state setComponentState(!componentState); }; … <Flipper front={ <Button onClick={flipHandler} className="w-100" > click to flip to the back </Button> } frontClassName="d-flex align-items-stretch" back={ <Button onClick={flipHandler} variant="secondary" className="w-100" > click to flip to the front </Button> } backClassName="d-flex align-items-stretch" className="text-center" height="10rem" flipped={componentState} horizontal /> ``` | Name | Type | Default | Description | | :--------------- | :------ | :------ | :-------------------------------------------------------------------------------------------------------------------------------- | | `back` | JSX | | flipper back side content | | `backClassName` | string | | `className` property for the back side of the flipper | | `backStyle` | object | | `style` property for the back side of the flipper | | `front` | JSX | | flipper front side content | | `frontClassName` | string | | `className` property for the front side of the flipper | | `frontStyle` | object | | `style` property for the front side of the flipper | | `flipped` | boolean | `null` | determines whether the card should display as flipped over (i.e., tie events to this property), if `null`, then it flips on hover | | `height` | string | `15rem` | `height` property to apply to the `style` for the flipper and both sides | | `horizontal` | boolean | `false` | flip the card horizontally instead of vertically | > _NOTE: if `flipped` is `null`, then doesn’t toggle `aria-label` for the flipper sides, because it flips on an untracked hover action rather than an event_ ### `<FormGroup>` An extension of [React Bootstrap’s `<Form.Group>`](https://react-bootstrap.github.io/components/forms/#form-group-props), which automatically contains a React Bootstrap [`<Form.Label>`](https://react-bootstrap.github.io/components/forms/#form-label-props). The label then optionally includes a `<InfoIcon>` when the `info` property is set. ```JavaScript import FormGroup from '@legendarymediatv/bootstrap/FormGroup'; … <FormGroup title="Sample textbox" info={<p>Things, <i>stuff</i>, <b>content</b>!</p>} > <Form.Control name="sample" maxLength="80" defaultValue="eleventeen" /> </FormGroup> ``` | Name | Type | Default | Description | | :--------------- | :-------------------------- | :--------------- | :----------------------------------------------- | | `ref` | ReactRef | inherited | `ref` property for the `<Form.Group>` | | `as` | elementType | inherited | `as` property for the `<Form.Group>` | | `controlId` | string | inherited | `controlId` property for the `<Form.Group>` | | `info` | JSX | | popover content for the `<InfoIcon>` | | `infoAlt` | string | inherited | `alt` property for the `<InfoIcon>` | | `infoClassName` | string | | `className` property for the `<InfoIcon>` | | `infoStyle` | object | | `style` property for the `<InfoIcon>` | | `infoName` | string | inherited | `name` property for the `<InfoIcon>` | | `infoTitle` | JSX | `title` property | `title` property for the `<InfoIcon>` | | `infoTitleAs` | elementType | inherited | `titleAs` property for the `<InfoIcon>` | | `infoVariant` | string | inherited | `variant` property for the `<InfoIcon>` | | `iconClassName` | string | | `className` property for the `<InfoIcon>` | | `iconStyle` | object | | `style` property for the `<InfoIcon>` | | `title` | JSX | | content for the `<Form.Label>` | | `labelRef` | ReactRef | inherited | `ref` property for the `<Form.Label>` | | `labelAs` | elementType | inherited | `as` property for the `<Form.Label>` | | `column` | boolean \| `'sm'` \| `'lg'` | inherited | `column` property for the `<Form.Label>` | | `htmlFor` | string | inherited | `htmlFor` property for the `<Form.Label>` | | `visuallyHidden` | boolean | inherited | `visuallyHidden` property for the `<Form.Label>` | | `labelClassName` | string | | `className` property for the `<Form.Label>` | | `labelStyle` | object | | `style` property for the `<Form.Label>` | ### `<FullPage>` Make your page always use at least the full height of the browser window using flexbox instead of fixed/sticky styling. Plus, it has a footer component that will display at the bottom of the page without forcing a scrollbar! This component set doesn't have any special properties, but it is made up of three parts: - `<FullPage>` – the wrapper (should only contain the other FullPage components below) - `<FullPage.Content>` (**required**) – page content (should contain your `<Navbar>` and page copy components such as `<article>`) - `<FullPage.Footer>` (optional) – page footer (can be styled directly or given an `id` and styled elsewhere) ```JavaScript import FullPage from '@legendarymediatv/bootstrap/FullPage'; … <FullPage> <FullPage.Content>Page Content</FullPage.Content> <FullPage.Footer>Footer Content</FullPage.Footer> </FullPage> ``` **Containerized example:** ```JavaScript <div className="bg-dark"> <Container className="bg-light p-0"> <FullPage> <FullPage.Content> <Navbar bg="primary" variant="dark"> <Navbar.Brand>LegendaryMediaTV</Navbar.Brand> </Navbar> <article className="py-4 px-2"> <h1>Title or whatever</h1> <p>Things, stuff, content!</p> </article> </FullPage.Content> <FullPage.Footer className="bg-secondary py-2 text-center text-white"> Footer Content </FullPage.Footer> </FullPage> </Container> </div> ``` > _NOTE: if using [React Helmet](https://github.com/nfl/react-helmet), you can use its `bodyAttributes` property instead of a `<div>` wrapper to set the main background color: `<Helmet bodyAttributes={{ class: "bg-dark" }}>`_ ### `<Icon>` Class-based icon (`<i>` tag) that can automatically add an [ARIA label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) based on the icon name. ```JavaScript import Icon from '@legendarymediatv/bootstrap/Icon'; … <Icon name="fa-solid fa-camera" /> <Icon name="fa-solid fa-camera" alt="DSLR" variant="success" className="ms-3" style={{ fontSize: '2rem' }} /> ``` | Name | Type | Default | Description | | :-------- | :----- | :------------------------------------- | :-------------------------------------------------------------------------------------------------------------- | | `alt` | string | variation of `name` (e.g., `'camera'`) | [alternate text](https://accessibility.psu.edu/images/imageshtml/) for the icon (i.e., ends up in `aria-label`) | | `name` | string | required | icon class name (e.g., `'fa-solid fa-camera'`) | | `variant` | string | | Bootstrap theme color name (e.g., `'primary'`) | ### `<InfoIcon>` An extension of [React Bootstrap’s `<Popover>`](https://react-bootstrap.netlify.app/components/overlays/#popovers) (with `rootClose` set to auto-close when it loses focus) that contains an `<Icon>`. ```JavaScript import InfoIcon from '@legendarymediatv/bootstrap/InfoIcon'; … <InfoIcon title="Info Title">Info Content</InfoIcon> <InfoIcon title="Info Title" name="bi bi-info-circle-fill" alt="help me!" variant="danger" iconStyle={{ fontSize: "2rem" }} > Things, <i>stuff</i>, <b>content</b>! </InfoIcon> ``` | Name | Type | Default | Description | | :-------------- | :---------- | :------------------------------------- | :------------------------------------------------------------------------------------------------------------------ | | children | JSX | | popover content | | `alt` | string | variation of `name` (e.g., `'camera'`) | [alternate text](https://accessibility.psu.edu/images/imageshtml/) for the `<Icon>` (i.e., ends up in `aria-label`) | | `iconClassName` | string | | `className` property for the `<Icon>` (i.e., `className` is applied to the toggler button) | | `iconStyle` | object | | `style` property for the the `<Icon>` (i.e., `style` is applied to the toggler button) | | `name` | string | `'fa-solid fa-circle-info'` | icon class name | | `title` | JSX | | popover title | | `titleAs` | elementType | `<h3>` | `as` property for the popover title | | `variant` | string | `info` | Bootstrap theme color name applied to the icon | ### `<Link>` A combination of an HTML `<a>` tag and Gatsby’s [`<Link>`](https://www.gatsbyjs.com/docs/linking-between-pages/). It mostly uses the normal `<a>` tag properties, but accepting either `href` or `to` in order to set the URL, so that you can simply swith the import of Gatsby’s `<Link>` to this one instead, plus you can set the `as` property for any React Bootstrap to be this component so that links work properly in Gatsby. If `href` property begins with `#` (i.e., anchor), a protocol (e.g., `https://` or `mailto:`), or ends with a file extension (e.g., `sample.jpg`), or `external` is set, then it uses an `<a>` tag. Otherwise, it uses Gatsby’s `<Link>` tag, so that it doesn’t force a page reload. ```JavaScript import Link from '@legendarymediatv/bootstrap/Link'; … <Link href="/">Gatsby link</Link> <Link href="#link">HTML link</Link> <Link href="https://www.legendarymediatv.com">auto-external HTML link</Link> <Link href="/external-somehow" externalIcon="bi bi-box-arrow-up-right" externalVariant="danger" > HTML link with custom external icon and color </Link> <Navbar.Brand as={Link} to='/'>LegendaryMediaTV</Navbar.Brand> <Nav.Link as={Link} to='/'>Home</Nav.Link> ``` | Name | Type | Default | Description | | :------------------ | :-------------- | :------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | | `href` \| `to` | URL | required | URL or anchor target | | `external` | boolean | `true` if the URL starts with `http:` or `https:` or `externalIcon` is set | explicitly (un-)flag an external link icon (also forces an `<a>` tag when enabled), which goes inside its own `<small>` tag | | `externalNewTab` | boolean | `false` | set `newTab` to `true` when `external` is `true` | | `externalIcon` | icon class name | `'fa-solid fa-arrow-up-right-from-square'` | external icon class name | | `externalVariant` | string | `info` | Bootstrap theme color name (e.g., `'primary'`) applied to the icon | | `externalClassName` | string | `'small ps-1 align-text-top'` | `className` property for the `<Icon>` (i.e., `className` is applied to the toggler button) | | `externalStyle` | object | | `style` property for the the `<Icon>` (i.e., `style` is applied to the toggler button) | | `newTab` | boolean | `false` | force the link to open in a new tab (sets `target="_blank" rel="noopener"`) | ### `<ListGroup>` An extension of [React Bootstrap’s `<ListGroup>`](https://react-bootstrap.netlify.app/components/list-group/) that has a title, accepting arrays of URL strings and arrays of obects as items. If the item has a URL, then it is rendered as our Gatsby-friendly `<Link>` component, otherwise it is rendered as our `<ListGroup.Item>` instead. ```JavaScript import ListGroup from '@legendarymediatv/bootstrap/ListGroup'; … const linkArray = [ '/test', '/sample' ]; … <ListGroup title="Array of Links" items={linkArray} /> … const linkObjects = [ { title: 'Test Link', url: '/test' }, { title: 'Sample Link', subtitle: "additional information in a subtitle", url: '/sample' } ]; … <ListGroup title="Array of Objects with Links" items={linkObjects} /> … function sampleHandler(itemSelected) { alert(JSON.stringify(itemSelected, null, 4)); } … const objectArray = [ { id: 1, title: 'Test Non-Link' }, { id: 2, title: 'Sample Non-Link' } ]; … <ListGroup title="Array of Objects with Click Handler" titleVariant="success" items={objectArray} click={sampleHandler} className="mt-3" /> ``` | Name | Type | Default | Description | | :-------------------- | :--------------------------------------------- | :---------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- | | `activeKey` | unknown | inherited | `activeKey` property | | `as` | elementType | inherited | `as` property for the list group | | `defaultActiveKey` | unknown | inherited | `defaultActiveKey` property | | `horizontal` | `true` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` | inherited | `horizontal` property | | `onSelect` | function | inherited | when `items` is an array of objects, this is the `onClick` callback function that passes the clicked item as an argument | | `variant` | 'flush' | inherited | `variant` property | | `displayField` | string | `'title'` | when `items` is an array of objects, this is the object field to display | | `displaySubField` | string | `'subtitle'` | when `items` is an array of objects, this is the object field to subtly display below the `displayField` | | `displaySubClassName` | string | `fst-italic small text-muted` | when `items` is an array of objects, this is the `className` property for the `displaySubField` | | `items` | string[] or object[] | required | array of URL strings or an array of objects | | `itemsAs` | elementType | inherited | `as` property for the list group items | | `keyField` | string | `'id'` | when `items` is an array of objects, this is the object field to use as the React list key; otherwise it just uses the array index as the key | | `title` | string | | list group title | | `titleAs` | elementType | `<h3>` | `as` property for the list group title | | `titleVariant` | string | `'primary'` | Bootstrap theme color name for the list group title | | `titleClassName` | string | | `className` property for the list group title | | `titleStyle` | object | | `style` property for the list group title | | `urlField` | string | `'url'` | when `items` is an array of objects, this is the object field to use as the link URL | ### `<ListGroup.Item>` An extension of [React Bootstrap’s `<ListGroup.Item>`](https://react-bootstrap.netlify.app/components/list-group/) that adds support for sub-items, sub-actions, auto-conversion to a Gatsby-friendly `<Link>` when a URL is provided, and auto-conversion to an action when a URL or click handler are defined. The `subactions` property should be an array of objects corresponding containing `<ListGroup.Item>` properties. ```JavaScript import ListGroup from '@legendarymediatv/bootstrap/ListGroup'; … <ListGroup title="ListGroup with items" titleVariant="info" > <ListGroup.Item subitem="sample sub-item"> ListGroup.Item with a sub-item below </ListGroup.Item> <ListGroup.Item to="/sample"> ListGroup.Item auto-converted to a link/action </ListGroup.Item> <ListGroup.Item onClick={() => { alert("clicked"); }} > ListGroup.Item auto-converted to a button </ListGroup.Item> <ListGroup.Item to="#list-group" subactions={[ { to: "/sample", variant: "info", children: <Icon name="fa-solid fa-camera" />, }, { onClick: () => { alert("deleted!"); }, variant: "danger", children: <Icon name="fa-solid fa-trash-can" />, }, ]} > ListGroup.Item with a URL and sub-actions </ListGroup.Item> </ListGroup.Item> ``` | Name | Type | Default | Description | | :----------------- | :--------------- | :------------------------------ | :--------------------------------------------------------------------------------------------------------- | | `action` | boolean | inherited / `true` | marks the item as actionable; will be set to `true` when `href` / `to` / `onClick` are defined | | `active` | boolean | inherited | marks the item as active | | `as` | elementType | inherited / `Link` | `as` property for the item; becomes our Gatsby-friendly `Link` when the `href` or `to` property is defined | | `children` | JSX | | content for the main list item (will be nested if `subactions` property is set) | | `disabled` | boolean | inherited | marks the item as disabled | | `eventKey` | string \| number | inherited | unique identifier for when using events | | `href` \| `to` | URL | | URL or anchor target for the `<Link>` | | `onClick` | function | | fired when the item is clicked | | `subitem` | JSX | | to subtly display below the `children` | | `subitemClassName` | string | `'fst-italic small text-muted'` | `className` property for the `subitem` | | `variant` | string | | Bootstrap theme color name (e.g., `'primary'`) | ### `<Pagination>` Basically a rebuild of React Bootstrap’s `<Pagination>` and `<PageItem>` components, but based off of our `<Link>` component (in order to be Gatsby-friendly). Sub-components include: - `<Pagination.Item>` – creates a pagination item containing a `<Link>` or `<button>` (native), depending on if a URL is provided in the `href`/`to` property - `<Pagination.First>` – `<Pagination.Item>` with the content as an ARIA-friendly `«` by default - `<Pagination.Last>` – `<Pagination.Item>` with the content as an ARIA-friendly `»` by default - `<Pagination.Prev>` – `<Pagination.Item>` with the content as an ARIA-friendly `‹` by default - `<Pagination.Next>` – `<Pagination.Item>` with the content as an ARIA-friendly `›` by default - `<Pagination.Ellipsis>` – `<Pagination.Item>` with the content as an ARIA-friendly `…` by default > _TIP: if you prefer to use icons, you can override the default content of any of the above by making the child an_ `<Icon>` ```JavaScript import Pagination from '@legendarymediatv/bootstrap/Pagination'; … <Pagination> <Pagination.First /> <Pagination.Prev /> <Pagination.Ellipsis /> <Pagination.Item>1</Pagination.Item> <Pagination.Item to="/sample">2</Pagination.Item> <Pagination.Item onClick={sampleHandler.bind(this, 3)}>3</Pagination.Item> <Pagination.Item active>4</Pagination.Item> <Pagination.Item disabled>5</Pagination.Item> <Pagination.Ellipsis /> <Pagination.Next /> <Pagination.Last /> </Pagination> … <Pagination size="sm"> <Pagination.First> <Icon name="fa-solid fa-angles-left" alt="first" /> </Pagination.First> <Pagination.Prev> <Icon name="fa-solid fa-angle-left" alt="previous" /> </Pagination.Prev> <Pagination.Ellipsis> <Icon name="fa-solid fa-ellipsis" alt="more" /> </Pagination.Ellipsis> <Pagination.Next> <Icon name="fa-solid fa-angle-right" alt="next" /> </Pagination.Next> <Pagination.Last> <Icon name="fa-solid fa-angles-right" alt="last" /> </Pagination.Last> </Pagination> ``` #### `<Pagination>` properties | Name | Type | Default | Description | | :----- | :--------------- | :------ | :--------------------------------------- | | `size` | `'sm'` \| `'lg'` | | sets the sizing for the whole pagination | #### `<Pagination.*>` properties | Name | Type | Default | Description | | :------------- | :------- | :---------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `active` | boolean | `false` | sets the pagination item as `active` and appends the children with a `<VisuallyHidden>` tag containing the `activeLabel` | | `activeLabel` | string | `(current)` | content of the `<VisuallyHidden>` tag when flagged as `active` | | `disabled` | boolean | `false` | sets the pagination item as disabled | | `href` \| `to` | URL | | URL or anchor target for the `<Link>`; if blank, then a `<button>` is rendered and probably should have an `onClick` defined | | `onClick` | function | | callback function for when the component is clicked; _TIP: as in the example above, use_ `bind()` _when assigning the property in order to tell which pagination item is clicked_ | ### `<ScrollToTop>` Customizable icon that automatically appears in the bottom-right corner when you’re scrolled down the page a bit and smoothly scrolls to the top of the page when clicked. ```JavaScript import ScrollToTop from '@legendarymediatv/bootstrap/ScrollToTop'; … <ScrollToTop /> <ScrollToTop name="fa-solid fa-square-caret-up" variant="success" /> ``` > _NOTE: the `scrollToTop()` handler function can be exported as well; see below for details_ | Name | Type | Default | Description | | :-------------- | :----- | :-------------------------------- | :-------------------------------------------------------------------------------------------------------------- | | `alt` | string | `'up arrow'` | [alternate text](https://accessibility.psu.edu/images/imageshtml/) for the icon (i.e., ends up in `aria-label`) | | `name` | string | `'fa-solid fa-circle-chevron-up'` | icon class name | | `variant` | string | `'dark'` | Bootstrap theme color name | | `iconClassName` | string | | `className` property for the `<Icon>` | | `iconStyle` | object | | `style` property for the `<Icon>` | ### `<Spinner>` An extension of [React Bootstrap’s `<Spinner>`](https://react-bootstrap.github.io/components/spinners/) that automatically selects the `border` animation and adds the screen reader and ARIA role, so it can be self-closing and easily [ensure the maximum accessibility](https://react-bootstrap.github.io/components/spinners/#accessibility). ```JavaScript import Spinner from '@legendarymediatv/bootstrap/Spinner'; … <Spinner /> <Spinner animation="grow" variant="success" /> <Spinner alert /> <Spinner title="Reticulating splines …" variant="primary" /> ``` | Name | Type | Default | Description | | :---------- | :--------------------- | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | children | JSX | `'loading…'` | content for `<VisuallyHidden>` child component | | `animation` | `'border'` \| `'grow'` | `'border'` | changes the animation style of the spinner