diff --git a/LICENSES/OFL-1.1.txt b/LICENSES/OFL-1.1.txt deleted file mode 100644 index 0da42f86b..000000000 --- a/LICENSES/OFL-1.1.txt +++ /dev/null @@ -1,84 +0,0 @@ -SIL OPEN FONT LICENSE - -Version 1.1 - 26 February 2007 - -PREAMBLE - -The goals of the Open Font License (OFL) are to stimulate worldwide development -of collaborative font projects, to support the font creation efforts of academic -and linguistic communities, and to provide a free and open framework in which -fonts may be shared and improved in partnership with others. - -The OFL allows the licensed fonts to be used, studied, modified and redistributed -freely as long as they are not sold by themselves. The fonts, including any -derivative works, can be bundled, embedded, redistributed and/or sold with -any software provided that any reserved names are not used by derivative works. -The fonts and derivatives, however, cannot be released under any other type -of license. The requirement for fonts to remain under this license does not -apply to any document created using the fonts or their derivatives. - -DEFINITIONS - -"Font Software" refers to the set of files released by the Copyright Holder(s) -under this license and clearly marked as such. This may include source files, -build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the copyright -statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, or -substituting — in part or in whole — any of the components of the Original -Version, by changing formats or by porting the Font Software to a new environment. - -"Author" refers to any designer, engineer, programmer, technical writer or -other person who contributed to the Font Software. - -PERMISSION & CONDITIONS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of the Font Software, to use, study, copy, merge, embed, modify, redistribute, -and sell modified and unmodified copies of the Font Software, subject to the -following conditions: - -1) Neither the Font Software nor any of its individual components, in Original -or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, redistributed -and/or sold with any software, provided that each copy contains the above -copyright notice and this license. These can be included either as stand-alone -text files, human-readable headers or in the appropriate machine-readable -metadata fields within text or binary files as long as those fields can be -easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font Name(s) -unless explicit written permission is granted by the corresponding Copyright -Holder. This restriction only applies to the primary font name as presented -to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software -shall not be used to promote, endorse or advertise any Modified Version, except -to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) -or with their explicit written permission. - -5) The Font Software, modified or unmodified, in part or in whole, must be -distributed entirely under this license, and must not be distributed under -any other license. The requirement for fonts to remain under this license -does not apply to any document created using the Font Software. - -TERMINATION - -This license becomes null and void if any of the above conditions are not met. - -DISCLAIMER - -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, -TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE -FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, -INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT -SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/content/interface/toolbar.md b/docs/content/interface/toolbar.md index 3d6c327ac..9ae2c07fd 100644 --- a/docs/content/interface/toolbar.md +++ b/docs/content/interface/toolbar.md @@ -88,7 +88,7 @@ If some text is selected it will either put that as the link, if it thinks that inserting `name=$YourName`, a time by inserting `time=$time` or a color by inserting `color=#FFFFFF` in the `[]`. Please note that you can only specify one of those per `[]`, but you can use multiple `[]`. 5. **Emoji Picker** - This button opens the emoji picker, where you can choose an emoji or a fork awesome icon to insert into your note. + This button opens the emoji picker, where you can choose an emoji to insert into your note. ![Emoji Picker](../images/interface/toolbar/emoji.png) ## Settings diff --git a/docs/content/references/hfm.md b/docs/content/references/hfm.md index 379fe0ef8..12f321375 100644 --- a/docs/content/references/hfm.md +++ b/docs/content/references/hfm.md @@ -1,13 +1,12 @@ # HedgeDoc Flavored Markdown -HedgeDoc has its own markdown dialect which supports many features from [CommonMark][commonmark] and [Github Flavored Markdown][gfm]. It also adds some new extensions and is missing some. +HedgeDoc has its own markdown dialect which supports many features from [CommonMark][commonmark] +and [Github Flavored Markdown][gfm]. It also adds some new extensions and is missing some. These tables tell you what exactly we support in HedgeDoc 1.x (HFM 1) and HedgeDoc 2 (HFM 2). - ## Typography - | Feature | HFM 1 | HFM 2 | CommonMark | GFM | | ------------- | :---: | :---: | :---------------: | :---------------: | | bold | ☑️ | ☑️ | ☑️ | ☑️ | @@ -36,7 +35,8 @@ These tables tell you what exactly we support in HedgeDoc 1.x (HFM 1) and HedgeD | task list | ☑️ | ☑️ | | ☑️ | | defition list | ☑️ | ☑️ | | | | emoji | [Unicode 6.1][unicode-6] | [Unicode 13][unicode-13] | | | -| [ForkAwesome][fa] | ☑️ with `` | ☑️ with shortcodes | | | +| [ForkAwesome][fa] | ☑️ with `` | removed | | | +| [Bootstrap Icons][bootstrap-icons] | | ☑️ with shortcodes | | | | LaTeX | ☑️[^mj] | ☑️[^kt] | | | [^highlight]: Code blocks with a given language are rendered using syntax highlighting. @@ -59,7 +59,6 @@ These tables tell you what exactly we support in HedgeDoc 1.x (HFM 1) and HedgeD | image with given size | ☑️ | ☑️ | (☑️ with ``) | (☑️ with ``) | | table of contents | ☑️ | ☑️ | | | - ## Structural elements | Feature | HFM 1 | HFM 2 | CommonMark | GFM | @@ -70,7 +69,9 @@ These tables tell you what exactly we support in HedgeDoc 1.x (HFM 1) and HedgeD | Alerts | ☑️ | ☑️ | | | ## Embeddings -HFM 1 includes support for certain embeddings of external content by using the `{%keyword parameter %}` syntax. To increase the readability of the markdown code we decided that HFM 2 should just use plain links if possible. + +HFM 1 includes support for certain embeddings of external content by using the `{%keyword parameter %}` syntax. To +increase the readability of the markdown code we decided that HFM 2 should just use plain links if possible. | Feature | HFM 1 | HFM 2 | CommonMark | GFM | | --------------------------------------------------- | :---: | :---------------------: | :--------: | :---: | @@ -81,10 +82,13 @@ HFM 1 includes support for certain embeddings of external content by using the ` | [Speakerdeck][speakerdeck] (`{%speakerdeck ... %}`) | ☑️ | removed | | | | [GitHub Gist][gist] (`{%gist ... %}`) | ☑️ | with plain link[^embed] | | | -[^embed]: The special syntax from HFM 1 is deprecated, but will still work in HFM 2. However, a plain link to the content should be used. +[^embed]: The special syntax from HFM 1 is deprecated, but will still work in HFM 2. However, a plain link to the +content should be used. ## HTML -Besides the basic HTML typography elements (`

`, ``, ``, ``, ``) the following more special HTML elements are supported by some specification. + +Besides the basic HTML typography elements (`

`, ``, ``, ``, ``) the following more special HTML +elements are supported by some specification. | Feature | HedgeDocMark 1 | HedgeDocMark 2 | CommonMark | GFM | | :-----------: | :------------: | :------------: | :--------: | :---: | @@ -99,14 +103,27 @@ Besides the basic HTML typography elements (`

`, ``, ``, ``, ` | `

` | | ☑️ | ☑️ | | [fa]: https://forkaweso.me/ + +[bootstrap-icons]: https://icons.getbootstrap.com/ + [youtube]: https://www.youtube.com/ + [vimeo]: https://vimeo.com/ + [slideshare]: https://www.slideshare.net/ + [speakerdeck]: https://speakerdeck.com/ + [gist]: https://gist.github.com/ + [mathjax]: https://www.mathjax.org/ + [katex]: https://katex.org/ + [gfm]: https://github.github.com/gfm/ + [commonmark]: https://spec.commonmark.org/ + [unicode-6]: https://unicode.org/versions/Unicode6.1.0/ + [unicode-13]: https://unicode.org/versions/Unicode13.0.0/ diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index ea831ff45..68c7e1a6c 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -19,7 +19,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 - `{%pdf https://example.org/example-pdf.pdf %}` -> Embedding removed - The use of `sequence` as code block language ([Why?](https://github.com/hedgedoc/react-client/issues/488#issuecomment-683262875)) - Comma-separated definition of tags in the yaml-frontmatter -- Fork Awesome Icons will be removed in a future release ### Removed @@ -43,6 +42,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 - F9 shortcut to sort lines - Highlight.JS language support for `1c` was removed. - Support for tag definitions in headings +- Fork Awesome has been replaced with [Bootstrap Icons](https://icons.getbootstrap.com/) ### Added @@ -54,9 +54,9 @@ SPDX-License-Identifier: CC-BY-SA-4.0 - HedgeDoc instances can be branded either with a '@ \<custom string\>' or '@ \<custom logo\>' after the HedgeDoc logo and text - Images will be loaded via proxy if an image proxy is configured in the backend - Asciinema videos may be embedded by pasting the URL of one video into a single line -- The toolbar includes an emoji and fork-awesome icon picker. +- The toolbar includes an emoji picker. - Collapsible blocks can be added via a toolbar button or via autocompletion of "<details" -- Added shortcodes for [fork-awesome icons](https://forkaweso.me/Fork-Awesome/icons/) (e.g. `:fa-picture-o:`) +- Added shortcodes for icons (e.g. `:bi-picture:`) - The code button now adds code fences even if the user selected nothing beforehand - Code blocks with 'csv' as language render as tables. - All images can be clicked to show them in full screen. diff --git a/frontend/global-styles/index.scss b/frontend/global-styles/index.scss index 394c92bef..2eb5ddd00 100644 --- a/frontend/global-styles/index.scss +++ b/frontend/global-styles/index.scss @@ -10,7 +10,6 @@ @import '~react-bootstrap-typeahead/css/Typeahead'; @import "~@fontsource/source-sans-pro/index.css"; @import "~twemoji-colr-font/twemoji"; -@import '~fork-awesome/css/fork-awesome.min.css'; @import '~firacode/distr/fira_code'; @import "typeahead"; @import "./button-inside"; @@ -79,16 +78,6 @@ body { cursor: zoom-out; } -.faded-fa { - .fa, &::after { - opacity: 0.5; - } - - &:hover .fa, &:hover::after { - opacity: 1; - } -} - .dropup .dropdown-toggle, .dropdown-toggle { &.no-arrow::after { content: initial; diff --git a/frontend/jest.config.ts b/frontend/jest.config.ts index efa91431f..3265e9c8c 100644 --- a/frontend/jest.config.ts +++ b/frontend/jest.config.ts @@ -23,6 +23,16 @@ const customJestConfig = { testEnvironment: 'jsdom', testPathIgnorePatterns: ['/node_modules/', '/cypress/'] } - // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async -module.exports = createJestConfig(customJestConfig) +module.exports = async () => { + const nextJestConfig = await createJestConfig(customJestConfig)() + return { + ...nextJestConfig, + moduleNameMapper: { + ...nextJestConfig.moduleNameMapper, + '^.+\\.(svg)$': '<rootDir>/src/test-utils/svg-mock.tsx', + '^react-bootstrap-icons$': '<rootDir>/src/test-utils/bootstrap-icon-mocks.tsx', + '^react-bootstrap-icons/dist/icons/.*$': '<rootDir>/src/test-utils/svg-mock.tsx' + } + } +} diff --git a/frontend/locales/en.json b/frontend/locales/en.json index 311f15797..610026c02 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -223,7 +223,7 @@ "shortcode": "The {{shortcode}} short-code is deprecated and will be removed in a future release. Use a single line URL instead.", "frontmatter": "The yaml-metadata is invalid.", "frontmatter-tags": "The comma-separated definition of tags in the yaml-metadata is deprecated. Use a yaml-array instead.", - "fork-awesome": "Fork Awesome is deprecated and will be removed in a future release. Please use bootstrap icons instead. See {{link}} for more information." + "fork-awesome": "The usage of Fork Awesome is deprecated and has been removed. Please use bootstrap icons instead. See {{link}} for more information." }, "upload": { "uploadFile": { diff --git a/frontend/next.config.js b/frontend/next.config.js index 9db1b1f3a..546c5a13d 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -31,29 +31,33 @@ if (isMockMode) { `) } +/** @type {import('@svgr/webpack').LoaderOptions} */ +const svgrConfig = { + svgoConfig: { + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + removeViewBox: false + } + } + } + ] + } +} + /** @type {import('next').NextConfig} */ const rawNextConfig = { webpack: (config) => { + config.module.rules.push({ test: /\.svg$/i, issuer: /\.[jt]sx?$/, use: [ { loader: '@svgr/webpack', - options: { - svgoConfig: { - plugins: [ - { - name: 'preset-default', - params: { - overrides: { - removeViewBox: false - } - } - } - ] - } - } + options: svgrConfig } ] }) diff --git a/frontend/package.json b/frontend/package.json index f0c333707..20d453701 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -74,7 +74,6 @@ "fast-deep-equal": "3.1.3", "firacode": "6.2.0", "flowchart.js": "1.17.1", - "fork-awesome": "1.2.0", "highlight.js": "11.7.0", "htmlparser2": "8.0.1", "i18next": "22.4.10", @@ -102,6 +101,7 @@ "next": "13.1.6", "react": "18.2.0", "react-bootstrap": "2.7.2", + "react-bootstrap-icons": "1.10.2", "react-bootstrap-typeahead": "6.0.0", "react-diff-viewer": "3.1.1", "react-dom": "18.2.0", diff --git a/frontend/src/components/application-loader/loading-screen/animations.module.scss b/frontend/src/components/application-loader/loading-screen/animations.module.scss index a3fac7966..424ba6403 100644 --- a/frontend/src/components/application-loader/loading-screen/animations.module.scss +++ b/frontend/src/components/application-loader/loading-screen/animations.module.scss @@ -43,8 +43,8 @@ z-index: 1000; position: relative; font-size: 3em; - height: 240px; - width: 203px; + height: 5em; + width: 5em; color: #ffffff; text-shadow: 4px 4px 0 #3b4045; @@ -55,10 +55,11 @@ animation: fill 6s infinite; width: 100%; - &, :global(.fa) { + & > * { position: absolute; bottom: 0; left: 0; + z-index: 1001; } } } diff --git a/frontend/src/components/application-loader/loading-screen/loading-animation.tsx b/frontend/src/components/application-loader/loading-screen/loading-animation.tsx index bfe0ba9af..8843de19f 100644 --- a/frontend/src/components/application-loader/loading-screen/loading-animation.tsx +++ b/frontend/src/components/application-loader/loading-screen/loading-animation.tsx @@ -3,11 +3,13 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { createNumberRangeArray } from '../../common/number-range/number-range' import styles from './animations.module.scss' import { IconRow } from './icon-row' import React, { useMemo } from 'react' +import { Pencil as IconPencil } from 'react-bootstrap-icons' +import { PencilFill as IconPencilFill } from 'react-bootstrap-icons' export interface HedgeDocLogoProps { error: boolean @@ -25,10 +27,10 @@ export const LoadingAnimation: React.FC<HedgeDocLogoProps> = ({ error }) => { <div className={`position-relative ${error ? styles.error : ''}`}> <div className={styles.logo}> <div> - <ForkAwesomeIcon icon={'pencil'} className={styles.background} size={'5x'}></ForkAwesomeIcon> + <UiIcon icon={IconPencilFill} className={styles.background} size={5} /> </div> <div className={`${styles.overlay}`}> - <ForkAwesomeIcon icon={'pencil'} size={'5x'}></ForkAwesomeIcon> + <UiIcon icon={IconPencil} size={5} /> </div> </div> <div className={styles.pulse}></div> diff --git a/frontend/src/components/application-loader/loading-screen/random-icon.tsx b/frontend/src/components/application-loader/loading-screen/random-icon.tsx index ed342e59f..bd1bd97d0 100644 --- a/frontend/src/components/application-loader/loading-screen/random-icon.tsx +++ b/frontend/src/components/application-loader/loading-screen/random-icon.tsx @@ -3,28 +3,39 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../common/fork-awesome/types' import styles from './animations.module.scss' -import React, { useEffect, useState } from 'react' +import React, { Fragment, useEffect, useState } from 'react' +import type { Icon } from 'react-bootstrap-icons' +import { FileText as IconFileText } from 'react-bootstrap-icons' +import { File as IconFile } from 'react-bootstrap-icons' +import { Fonts as IconFonts } from 'react-bootstrap-icons' +import { Gear as IconGear } from 'react-bootstrap-icons' +import { KeyboardFill as IconKeyboardFill } from 'react-bootstrap-icons' +import { ListCheck as IconListCheck } from 'react-bootstrap-icons' +import { Markdown as IconMarkdown } from 'react-bootstrap-icons' +import { Pencil as IconPencil } from 'react-bootstrap-icons' +import { Person as IconPerson } from 'react-bootstrap-icons' +import { Tag as IconTag } from 'react-bootstrap-icons' +import { TypeBold as IconTypeBold } from 'react-bootstrap-icons' +import { TypeItalic as IconTypeItalic } from 'react-bootstrap-icons' -const elements: IconName[] = [ - 'file-text', - 'markdown', - 'pencil', - 'bold', - 'italic', - 'align-justify', - 'tag', - 'user', - 'file', - 'keyboard-o', - 'cog', - 'font' +const elements: Icon[] = [ + IconFileText, + IconMarkdown, + IconPencil, + IconTypeBold, + IconTypeItalic, + IconListCheck, + IconTag, + IconPerson, + IconFile, + IconKeyboardFill, + IconGear, + IconFonts ] /** - * Chooses a random fork awesome icon from a predefined set and renders it. + * Chooses a random icon from a predefined set and renders it. * * The component uses a static icon in the first rendering and will choose the random icon after that. * This is done because if the loading screen is prepared using SSR and then hydrated in the client, the rendered css class isn't the expected one from the SSR. (It's random. d'uh). @@ -33,13 +44,12 @@ const elements: IconName[] = [ * See https://nextjs.org/docs/messages/react-hydration-error */ export const RandomIcon: React.FC = () => { - const [icon, setIcon] = useState<number | undefined>() + const [icon, setIcon] = useState<JSX.Element | undefined>() useEffect(() => { - setIcon(Math.floor(Math.random() * elements.length)) + const index = Math.floor(Math.random() * elements.length) + setIcon(React.createElement(elements[index], { className: styles.particle })) }, []) - return icon === undefined ? null : ( - <ForkAwesomeIcon icon={elements[icon]} className={styles.particle}></ForkAwesomeIcon> - ) + return <Fragment>{icon}</Fragment> } diff --git a/frontend/src/components/common/async-loading-boundary/__snapshots__/async-loading-boundary.test.tsx.snap b/frontend/src/components/common/async-loading-boundary/__snapshots__/async-loading-boundary.test.tsx.snap index 8079c47b1..60c2ace27 100644 --- a/frontend/src/components/common/async-loading-boundary/__snapshots__/async-loading-boundary.test.tsx.snap +++ b/frontend/src/components/common/async-loading-boundary/__snapshots__/async-loading-boundary.test.tsx.snap @@ -5,9 +5,7 @@ exports[`Async loading boundary shows a waiting spinner if loading 1`] = ` <div class="m-3 d-flex align-items-center justify-content-center" > - <i - class="fa fa-spinner fa-spin " - /> + BootstrapIconMock_ArrowRepeat </div> </div> `; diff --git a/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.test.tsx.snap b/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.test.tsx.snap index 04d88a7a4..12f2e8282 100644 --- a/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.test.tsx.snap +++ b/frontend/src/components/common/copyable/copy-to-clipboard-button/__snapshots__/copy-to-clipboard-button.test.tsx.snap @@ -7,9 +7,7 @@ exports[`Copy to clipboard button show an error text if clipboard api isn't avai title="renderer.highlightCode.copyCode" type="button" > - <i - class="fa fa-files-o " - /> + BootstrapIconMock_Files </button> </div> `; @@ -22,9 +20,7 @@ exports[`Copy to clipboard button show an error text if clipboard api isn't avai title="renderer.highlightCode.copyCode" type="button" > - <i - class="fa fa-files-o " - /> + BootstrapIconMock_Files </button> </div> `; @@ -36,9 +32,7 @@ exports[`Copy to clipboard button shows an error text if writing failed 1`] = ` title="renderer.highlightCode.copyCode" type="button" > - <i - class="fa fa-files-o " - /> + BootstrapIconMock_Files </button> </div> `; @@ -51,9 +45,7 @@ exports[`Copy to clipboard button shows an error text if writing failed 2`] = ` title="renderer.highlightCode.copyCode" type="button" > - <i - class="fa fa-files-o " - /> + BootstrapIconMock_Files </button> </div> `; @@ -65,9 +57,7 @@ exports[`Copy to clipboard button shows an success text if writing succeeded 1`] title="renderer.highlightCode.copyCode" type="button" > - <i - class="fa fa-files-o " - /> + BootstrapIconMock_Files </button> </div> `; @@ -80,9 +70,7 @@ exports[`Copy to clipboard button shows an success text if writing succeeded 2`] title="renderer.highlightCode.copyCode" type="button" > - <i - class="fa fa-files-o " - /> + BootstrapIconMock_Files </button> </div> `; diff --git a/frontend/src/components/common/copyable/copy-to-clipboard-button/copy-to-clipboard-button.tsx b/frontend/src/components/common/copyable/copy-to-clipboard-button/copy-to-clipboard-button.tsx index 7d4a785bc..c055f3182 100644 --- a/frontend/src/components/common/copyable/copy-to-clipboard-button/copy-to-clipboard-button.tsx +++ b/frontend/src/components/common/copyable/copy-to-clipboard-button/copy-to-clipboard-button.tsx @@ -5,10 +5,11 @@ */ import type { PropsWithDataCypressId } from '../../../../utils/cypress-attribute' import { cypressId } from '../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../icons/ui-icon' import { useCopyOverlay } from '../hooks/use-copy-overlay' import React, { Fragment, useRef } from 'react' import { Button } from 'react-bootstrap' +import { Files as IconFiles } from 'react-bootstrap-icons' import type { Variant } from 'react-bootstrap/types' import { useTranslation } from 'react-i18next' @@ -46,7 +47,7 @@ export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({ title={t('renderer.highlightCode.copyCode') ?? undefined} onClick={copyToClipboard} {...cypressId(props)}> - <ForkAwesomeIcon icon='files-o' /> + <UiIcon icon={IconFiles} /> </Button> {overlayElement} </Fragment> diff --git a/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx b/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx index cf0487b89..b6852dd7b 100644 --- a/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx +++ b/frontend/src/components/common/copyable/copyable-field/copyable-field.tsx @@ -5,11 +5,12 @@ */ import { isClientSideRendering } from '../../../../utils/is-client-side-rendering' import { Logger } from '../../../../utils/logger' -import { ForkAwesomeIcon } from '../../fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../icons/ui-icon' import { ShowIf } from '../../show-if/show-if' import { CopyToClipboardButton } from '../copy-to-clipboard-button/copy-to-clipboard-button' import React, { useCallback, useMemo } from 'react' import { Button, FormControl, InputGroup } from 'react-bootstrap' +import { Share as IconShare } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface CopyableFieldProps { @@ -57,7 +58,7 @@ export const CopyableField: React.FC<CopyableFieldProps> = ({ content, shareOrig <ShowIf condition={sharingSupported}> <InputGroup.Text> <Button variant='secondary' title={'Share'} onClick={doShareAction}> - <ForkAwesomeIcon icon='share-alt' /> + <UiIcon icon={IconShare} /> </Button> </InputGroup.Text> </ShowIf> diff --git a/frontend/src/components/common/fork-awesome/__snapshots__/fork-awesome-icon.test.tsx.snap b/frontend/src/components/common/fork-awesome/__snapshots__/fork-awesome-icon.test.tsx.snap deleted file mode 100644 index 238394832..000000000 --- a/frontend/src/components/common/fork-awesome/__snapshots__/fork-awesome-icon.test.tsx.snap +++ /dev/null @@ -1,65 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` 1`] = ` -<div> - <i - class="fa fa-heart fa-stack-1x" - /> -</div> -`; - -exports[`ForkAwesomeIcon renders a heart correctly 1`] = ` -<div> - <i - class="fa fa-heart " - /> -</div> -`; - -exports[`ForkAwesomeIcon renders in size 2x 1`] = ` -<div> - <i - class="fa fa-heart fa-2x" - /> -</div> -`; - -exports[`ForkAwesomeIcon renders in size 3x 1`] = ` -<div> - <i - class="fa fa-heart fa-3x" - /> -</div> -`; - -exports[`ForkAwesomeIcon renders in size 4x 1`] = ` -<div> - <i - class="fa fa-heart fa-4x" - /> -</div> -`; - -exports[`ForkAwesomeIcon renders in size 5x 1`] = ` -<div> - <i - class="fa fa-heart fa-5x" - /> -</div> -`; - -exports[`ForkAwesomeIcon renders with additional className 1`] = ` -<div> - <i - class="fa fa-heart testClass " - /> -</div> -`; - -exports[`ForkAwesomeIcon renders with fixed width icon 1`] = ` -<div> - <i - class="fa fa-fw fa-heart " - /> -</div> -`; diff --git a/frontend/src/components/common/fork-awesome/__snapshots__/fork-awesome-stack.test.tsx.snap b/frontend/src/components/common/fork-awesome/__snapshots__/fork-awesome-stack.test.tsx.snap deleted file mode 100644 index 96f4a77fd..000000000 --- a/frontend/src/components/common/fork-awesome/__snapshots__/fork-awesome-stack.test.tsx.snap +++ /dev/null @@ -1,76 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ForkAwesomeStack renders a heart and a download icon stack 1`] = ` -<div> - <span - class="fa-stack " - > - <i - class="fa fa-heart fa-stack-1x" - /> - <i - class="fa fa-download fa-stack-1x" - /> - </span> -</div> -`; - -exports[`ForkAwesomeStack renders in size 2x 1`] = ` -<div> - <span - class="fa-stack fa-2x" - > - <i - class="fa fa-heart fa-stack-1x" - /> - <i - class="fa fa-download fa-stack-1x" - /> - </span> -</div> -`; - -exports[`ForkAwesomeStack renders in size 3x 1`] = ` -<div> - <span - class="fa-stack fa-3x" - > - <i - class="fa fa-heart fa-stack-1x" - /> - <i - class="fa fa-download fa-stack-1x" - /> - </span> -</div> -`; - -exports[`ForkAwesomeStack renders in size 4x 1`] = ` -<div> - <span - class="fa-stack fa-4x" - > - <i - class="fa fa-heart fa-stack-1x" - /> - <i - class="fa fa-download fa-stack-1x" - /> - </span> -</div> -`; - -exports[`ForkAwesomeStack renders in size 5x 1`] = ` -<div> - <span - class="fa-stack fa-5x" - > - <i - class="fa fa-heart fa-stack-1x" - /> - <i - class="fa fa-download fa-stack-1x" - /> - </span> -</div> -`; diff --git a/frontend/src/components/common/fork-awesome/fork-awesome-icon.test.tsx b/frontend/src/components/common/fork-awesome/fork-awesome-icon.test.tsx deleted file mode 100644 index cb123a4db..000000000 --- a/frontend/src/components/common/fork-awesome/fork-awesome-icon.test.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import { ForkAwesomeIcon } from './fork-awesome-icon' -import type { IconName } from './types' -import { render } from '@testing-library/react' - -describe('ForkAwesomeIcon', () => { - const icon: IconName = 'heart' - it('renders a heart correctly', () => { - const view = render(<ForkAwesomeIcon icon={icon} />) - expect(view.container).toMatchSnapshot() - }) - it('renders with fixed width icon', () => { - const view = render(<ForkAwesomeIcon icon={icon} fixedWidth={true} />) - expect(view.container).toMatchSnapshot() - }) - it('renders with additional className', () => { - const view = render(<ForkAwesomeIcon icon={icon} className={'testClass'} />) - expect(view.container).toMatchSnapshot() - }) - describe('renders in size', () => { - it('2x', () => { - const view = render(<ForkAwesomeIcon icon={icon} size={'2x'} />) - expect(view.container).toMatchSnapshot() - }) - it('3x', () => { - const view = render(<ForkAwesomeIcon icon={icon} size={'3x'} />) - expect(view.container).toMatchSnapshot() - }) - it('4x', () => { - const view = render(<ForkAwesomeIcon icon={icon} size={'4x'} />) - expect(view.container).toMatchSnapshot() - }) - it('5x', () => { - const view = render(<ForkAwesomeIcon icon={icon} size={'5x'} />) - expect(view.container).toMatchSnapshot() - }) - }) - describe('renders in stack', () => { - const view = render(<ForkAwesomeIcon icon={icon} stacked={true} />) - expect(view.container).toMatchSnapshot() - }) -}) diff --git a/frontend/src/components/common/fork-awesome/fork-awesome-icon.tsx b/frontend/src/components/common/fork-awesome/fork-awesome-icon.tsx deleted file mode 100644 index ff3747576..000000000 --- a/frontend/src/components/common/fork-awesome/fork-awesome-icon.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import type { IconName, IconSize } from './types' -import React from 'react' - -export interface ForkAwesomeIconProps { - icon: IconName - className?: string - fixedWidth?: boolean - size?: IconSize - stacked?: boolean -} - -/** - * Renders a fork awesome icon. - * - * @param icon The icon that should be rendered. - * @param fixedWidth If the icon should be rendered with a fixed width. - * @param size The size class the icon should be rendered in. - * @param className Additional classes the icon should get. - * @param stacked If the icon is part of a {@link ForkAwesomeStack stack}. - * @see https://forkaweso.me - */ -export const ForkAwesomeIcon: React.FC<ForkAwesomeIconProps> = ({ - icon, - fixedWidth = false, - size, - className, - stacked = false -}) => { - const fixedWithClass = fixedWidth ? 'fa-fw' : '' - const sizeClass = size ? `-${size}` : stacked ? '-1x' : '' - const stackClass = stacked ? '-stack' : '' - const extraClasses = `${className ?? ''} ${sizeClass || stackClass ? `fa${stackClass}${sizeClass}` : ''}` - return <i className={`fa ${fixedWithClass} fa-${icon} ${extraClasses}`} /> -} diff --git a/frontend/src/components/common/fork-awesome/fork-awesome-icons.ts b/frontend/src/components/common/fork-awesome/fork-awesome-icons.ts deleted file mode 100644 index c5a9a9eb6..000000000 --- a/frontend/src/components/common/fork-awesome/fork-awesome-icons.ts +++ /dev/null @@ -1,804 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export const ForkAwesomeIcons = [ - '500px', - 'activitypub', - 'address-book-o', - 'address-book', - 'address-card-o', - 'address-card', - 'adjust', - 'adn', - 'align-center', - 'align-justify', - 'align-left', - 'align-right', - 'amazon', - 'ambulance', - 'american-sign-language-interpreting', - 'anchor', - 'android', - 'angellist', - 'angle-double-down', - 'angle-double-left', - 'angle-double-right', - 'angle-double-up', - 'angle-down', - 'angle-left', - 'angle-right', - 'angle-up', - 'apple', - 'archive-org', - 'archive', - 'archlinux', - 'area-chart', - 'arrow-circle-down', - 'arrow-circle-left', - 'arrow-circle-o-down', - 'arrow-circle-o-left', - 'arrow-circle-o-right', - 'arrow-circle-o-up', - 'arrow-circle-right', - 'arrow-circle-up', - 'arrow-down', - 'arrow-left', - 'arrow-right', - 'arrows-alt', - 'arrows-h', - 'arrows', - 'arrows-v', - 'arrow-up', - 'artstation', - 'askfm', - 'assistive-listening-systems', - 'asterisk', - 'at', - 'att', - 'audio-description', - 'backward', - 'balance-scale', - 'bandcamp', - 'ban', - 'bar-chart', - 'barcode', - 'bars', - 'bath', - 'battery-empty', - 'battery-full', - 'battery-half', - 'battery-quarter', - 'battery-three-quarters', - 'bed', - 'beer', - 'behance-square', - 'behance', - 'bell-o', - 'bell-rigning-o', - 'bell-ringing', - 'bell-slash-o', - 'bell-slash', - 'bell', - 'bicycle', - 'binoculars', - 'biometric', - 'birthday-cake', - 'bitbucket-square', - 'bitbucket', - 'black-tie', - 'blind', - 'blockstack', - 'bluetooth-b', - 'bluetooth', - 'boardgamegeek', - 'bold', - 'bolt', - 'bomb', - 'bookmark-o', - 'bookmark', - 'book', - 'bootstrap', - 'braille', - 'briefcase', - 'btc', - 'bug', - 'building-o', - 'building', - 'bullhorn', - 'bullseye', - 'bunny', - 'bus', - 'buymeacoffee', - 'buysellads', - 'calculator', - 'calendar-check-o', - 'calendar-minus-o', - 'calendar-o', - 'calendar-plus-o', - 'calendar', - 'calendar-times-o', - 'camera-retro', - 'camera', - 'caret-down', - 'caret-left', - 'caret-right', - 'caret-square-o-down', - 'caret-square-o-left', - 'caret-square-o-right', - 'caret-square-o-up', - 'caret-up', - 'car', - 'cart-arrow-down', - 'cart-plus', - 'cc-amex', - 'cc-by', - 'cc-cc', - 'cc-diners-club', - 'cc-discover', - 'cc-jcb', - 'cc-mastercard', - 'cc-nc-eu', - 'cc-nc-jp', - 'cc-nc', - 'cc-nd', - 'cc-paypal', - 'cc-pd', - 'cc-remix', - 'cc-sa', - 'cc-share', - 'cc-stripe', - 'cc', - 'cc-visa', - 'cc-zero', - 'certificate', - 'chain-broken', - 'check-circle-o', - 'check-circle', - 'check-square-o', - 'check-square', - 'check', - 'chevron-circle-down', - 'chevron-circle-left', - 'chevron-circle-right', - 'chevron-circle-up', - 'chevron-down', - 'chevron-left', - 'chevron-right', - 'chevron-up', - 'child', - 'chrome', - 'circle-o-notch', - 'circle-o', - 'circle', - 'circle-thin', - 'classicpress-circle', - 'classicpress', - 'clipboard', - 'clock-o', - 'clone', - 'cloud-download', - 'cloud', - 'cloud-upload', - 'code-fork', - 'codepen', - 'code', - 'codiepie', - 'coffee', - 'cogs', - 'cog', - 'columns', - 'commenting-o', - 'commenting', - 'comment-o', - 'comments-o', - 'comments', - 'comment', - 'compass', - 'compress', - 'connectdevelop', - 'contao', - 'conway-glider', - 'copyright', - 'creative-commons', - 'credit-card-alt', - 'credit-card', - 'crop', - 'crosshairs', - 'csharp', - 'css3', - 'c', - 'cubes', - 'cube', - 'cutlery', - 'dashcube', - 'database', - 'deaf', - 'debian', - 'delicious', - 'desktop', - 'deviantart', - 'dev-to', - 'diamond', - 'diaspora', - 'digg', - 'digitalocean', - 'discord-alt', - 'discord', - 'dogmazic', - 'dot-circle-o', - 'download', - 'dribbble', - 'dropbox', - 'drupal', - 'edge', - 'eercast', - 'eject', - 'ellipsis-h', - 'ellipsis-v', - 'email-bulk-o', - 'email-bulk', - 'emby', - 'empire', - 'envelope-open-o', - 'envelope-open', - 'envelope-o', - 'envelope-square', - 'envelope', - 'envira', - 'eraser', - 'ethereum', - 'etsy', - 'eur', - 'exchange', - 'exclamation-circle', - 'exclamation', - 'exclamation-triangle', - 'expand', - 'expeditedssl', - 'external-link-square', - 'external-link', - 'eyedropper', - 'eye-slash', - 'eye', - 'facebook-messenger', - 'facebook-official', - 'facebook-square', - 'facebook', - 'fast-backward', - 'fast-forward', - 'fax', - 'f-droid', - 'female', - 'ffmpeg', - 'fighter-jet', - 'file-archive-o', - 'file-audio-o', - 'file-code-o', - 'file-epub', - 'file-excel-o', - 'file-image-o', - 'file-o', - 'file-pdf-o', - 'file-powerpoint-o', - 'files-o', - 'file', - 'file-text-o', - 'file-text', - 'file-video-o', - 'file-word-o', - 'film', - 'filter', - 'fire-extinguisher', - 'firefox', - 'fire', - 'first-order', - 'flag-checkered', - 'flag-o', - 'flag', - 'flask', - 'flickr', - 'floppy-o', - 'folder-open-o', - 'folder-open', - 'folder-o', - 'folder', - 'font-awesome', - 'fonticons', - 'font', - 'fork-awesome', - 'fort-awesome', - 'forumbee', - 'forward', - 'foursquare', - 'free-code-camp', - 'freedombox', - 'friendica', - 'frown-o', - 'funkwhale', - 'futbol-o', - 'gamepad', - 'gavel', - 'gbp', - 'genderless', - 'get-pocket', - 'gg-circle', - 'gg', - 'gift', - 'gimp', - 'gitea', - 'github-alt', - 'github-square', - 'github', - 'gitlab', - 'git-square', - 'git', - 'glass', - 'glide-g', - 'glide', - 'globe-e', - 'globe', - 'globe-w', - 'gnupg', - 'gnu-social', - 'gnu', - 'google-play', - 'google-plus-official', - 'google-plus-square', - 'google-plus', - 'google', - 'google-wallet', - 'graduation-cap', - 'gratipay', - 'grav', - 'hackaday', - 'hacker-news', - 'hackster', - 'hal', - 'hand-lizard-o', - 'hand-o-down', - 'hand-o-left', - 'hand-o-right', - 'hand-o-up', - 'hand-paper-o', - 'hand-peace-o', - 'hand-pointer-o', - 'hand-rock-o', - 'hand-scissors-o', - 'handshake-o', - 'hand-spock-o', - 'hashnode', - 'hashtag', - 'hdd-o', - 'header', - 'headphones', - 'heartbeat', - 'heart-o', - 'heart', - 'heroku', - 'history', - 'home-assistant', - 'home', - 'hospital-o', - 'hourglass-end', - 'hourglass-half', - 'hourglass-o', - 'hourglass-start', - 'hourglass', - 'houzz', - 'h-square', - 'html5', - 'hubzilla', - 'i-cursor', - 'id-badge', - 'id-card-o', - 'id-card', - 'ils', - 'imdb', - 'inbox', - 'indent', - 'industry', - 'info-circle', - 'info', - 'inkscape', - 'inr', - 'instagram', - 'internet-explorer', - 'ioxhost', - 'italic', - 'java', - 'jirafeau', - 'joomla', - 'joplin', - 'jpy', - 'jsfiddle', - 'julia', - 'jupyter', - 'keybase', - 'keyboard-o', - 'key-modern', - 'key', - 'krw', - 'language', - 'laptop', - 'laravel', - 'lastfm-square', - 'lastfm', - 'leaf', - 'leanpub', - 'lemon-o', - 'level-down', - 'level-up', - 'liberapay-square', - 'liberapay', - 'life-ring', - 'lightbulb-o', - 'line-chart', - 'linkedin-square', - 'linkedin', - 'link', - 'linode', - 'linux', - 'list-alt', - 'list-ol', - 'list', - 'list-ul', - 'location-arrow', - 'lock', - 'long-arrow-down', - 'long-arrow-left', - 'long-arrow-right', - 'long-arrow-up', - 'low-vision', - 'magic', - 'magnet', - 'male', - 'map-marker', - 'map-o', - 'map-pin', - 'map-signs', - 'map', - 'mariadb', - 'markdown', - 'mars-double', - 'mars-stroke-h', - 'mars-stroke', - 'mars-stroke-v', - 'mars', - 'mastodon-alt', - 'mastodon-square', - 'mastodon', - 'matrix-org', - 'maxcdn', - 'meanpath', - 'medium-square', - 'medium', - 'medkit', - 'meetup', - 'meh-o', - 'mercury', - 'microchip', - 'microphone-slash', - 'microphone', - 'minus-circle', - 'minus-square-o', - 'minus-square', - 'minus', - 'mixcloud', - 'mobile', - 'modx', - 'money', - 'moon-o', - 'moon', - 'motorcycle', - 'mouse-pointer', - 'music', - 'mysql', - 'neuter', - 'newspaper-o', - 'nextcloud-square', - 'nextcloud', - 'nodejs', - 'nordcast', - 'object-group', - 'object-ungroup', - 'odnoklassniki-square', - 'odnoklassniki', - 'opencart', - 'open-collective', - 'openid', - 'opera', - 'optin-monster', - 'orcid', - 'outdent', - 'pagelines', - 'paint-brush', - 'paperclip', - 'paper-plane-o', - 'paper-plane', - 'paragraph', - 'patreon', - 'pause-circle-o', - 'pause-circle', - 'pause', - 'paw', - 'paypal', - 'peertube', - 'pencil-square-o', - 'pencil-square', - 'pencil', - 'percent', - 'phone-square', - 'phone', - 'php', - 'picture-o', - 'pie-chart', - 'pinterest-p', - 'pinterest-square', - 'pinterest', - 'pixelfed', - 'plane', - 'play-circle-o', - 'play-circle', - 'play', - 'pleroma', - 'plug', - 'plume', - 'plus-circle', - 'plus-square-o', - 'plus-square', - 'plus', - 'podcast', - 'postgresql', - 'power-off', - 'print', - 'product-hunt', - 'puzzle-piece', - 'python', - 'qq', - 'qrcode', - 'question-circle-o', - 'question-circle', - 'question', - 'quora', - 'quote-left', - 'quote-right', - 'random', - 'ravelry', - 'react', - 'rebel', - 'recycle', - 'reddit-alien', - 'reddit-square', - 'reddit', - 'refresh', - 'registered', - 'renren', - 'repeat', - 'reply-all', - 'reply', - 'researchgate', - 'retweet', - 'road', - 'rocket', - 'rss-square', - 'rss', - 'rub', - 'safari', - 'sass-alt', - 'sass', - 'scissors', - 'scribd', - 'scuttlebutt', - 'search-minus', - 'search-plus', - 'search', - 'sellsy', - 'server', - 'shaarli-o', - 'shaarli', - 'share-alt-square', - 'share-alt', - 'share-square-o', - 'share-square', - 'share', - 'shield', - 'ship', - 'shirtsinbulk', - 'shopping-bag', - 'shopping-basket', - 'shopping-cart', - 'shower', - 'signalapp', - 'signal', - 'sign-in', - 'sign-language', - 'sign-out', - 'simplybuilt', - 'sitemap', - 'skate', - 'sketchfab', - 'skyatlas', - 'skype', - 'slack', - 'sliders', - 'slideshare', - 'smile-o', - 'snapchat-ghost', - 'snapchat-square', - 'snapchat', - 'snowdrift', - 'snowflake-o', - 'social-home', - 'sort-alpha-asc', - 'sort-alpha-desc', - 'sort-amount-asc', - 'sort-amount-desc', - 'sort-asc', - 'sort-desc', - 'sort-numeric-asc', - 'sort-numeric-desc', - 'sort', - 'soundcloud', - 'space-shuttle', - 'spell-check', - 'spinner', - 'spoon', - 'spotify', - 'square-o', - 'square', - 'stack-exchange', - 'stack-overflow', - 'star-half-o', - 'star-half', - 'star-o', - 'star', - 'steam-square', - 'steam', - 'step-backward', - 'step-forward', - 'stethoscope', - 'sticky-note-o', - 'sticky-note', - 'stop-circle-o', - 'stop-circle', - 'stop', - 'street-view', - 'strikethrough', - 'stumbleupon-circle', - 'stumbleupon', - 'subscript', - 'subway', - 'suitcase', - 'sun-o', - 'sun', - 'superpowers', - 'superscript', - 'syncthing', - 'table', - 'tablet', - 'tachometer', - 'tags', - 'tag', - 'tasks', - 'taxi', - 'telegram', - 'television', - 'tencent-weibo', - 'terminal', - 'tex', - 'text-height', - 'textpattern', - 'text-width', - 'themeisle', - 'thermometer-empty', - 'thermometer-full', - 'thermometer-half', - 'thermometer-quarter', - 'thermometer-three-quarters', - 'th-large', - 'th-list', - 'th', - 'thumbs-down', - 'thumbs-o-down', - 'thumbs-o-up', - 'thumbs-up', - 'thumb-tack', - 'ticket', - 'times-circle-o', - 'times-circle', - 'times', - 'tint', - 'tipeee', - 'toggle-off', - 'toggle-on', - 'tor-onion', - 'trademark', - 'train', - 'transgender-alt', - 'transgender', - 'trash-o', - 'trash', - 'tree', - 'trello', - 'tripadvisor', - 'trophy', - 'truck', - 'try', - 'tty', - 'tumblr-square', - 'tumblr', - 'twitch', - 'twitter-square', - 'twitter', - 'umbrella', - 'underline', - 'undo', - 'unity', - 'universal-access', - 'university', - 'unlock-alt', - 'unlock', - 'unslpash', - 'upload', - 'usb', - 'usd', - 'user-circle-o', - 'user-circle', - 'user-md', - 'user-o', - 'user-plus', - 'user-secret', - 'users', - 'user', - 'user-times', - 'venus-double', - 'venus-mars', - 'venus', - 'viacoin', - 'viadeo-square', - 'viadeo', - 'video-camera', - 'vimeo-square', - 'vimeo', - 'vine', - 'vk', - 'volume-control-phone', - 'volume-down', - 'volume-mute', - 'volume-off', - 'volume-up', - 'weibo', - 'weixin', - 'whatsapp', - 'wheelchair-alt', - 'wheelchair', - 'wifi', - 'wikidata', - 'wikipedia-w', - 'window-close-o', - 'window-close', - 'window-maximize', - 'window-minimize', - 'window-restore', - 'windows', - 'wire', - 'wordpress', - 'wpbeginner', - 'wpexplorer', - 'wpforms', - 'wrench', - 'xing-square', - 'xing', - 'xmpp', - 'yahoo', - 'y-combinator', - 'yelp', - 'yoast', - 'youtube-play', - 'youtube-square', - 'youtube', - 'zotero' -] as const diff --git a/frontend/src/components/common/fork-awesome/fork-awesome-stack.test.tsx b/frontend/src/components/common/fork-awesome/fork-awesome-stack.test.tsx deleted file mode 100644 index 4718e814a..000000000 --- a/frontend/src/components/common/fork-awesome/fork-awesome-stack.test.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import type { ForkAwesomeIconProps } from './fork-awesome-icon' -import { ForkAwesomeIcon } from './fork-awesome-icon' -import { ForkAwesomeStack } from './fork-awesome-stack' -import { render } from '@testing-library/react' -import type { ReactElement } from 'react' - -describe('ForkAwesomeStack', () => { - const stack: Array<ReactElement<ForkAwesomeIconProps>> = [ - <ForkAwesomeIcon icon={'heart'} key={'heart'} />, - <ForkAwesomeIcon icon={'download'} key={'download'} /> - ] - it('renders a heart and a download icon stack', () => { - const view = render(<ForkAwesomeStack>{stack}</ForkAwesomeStack>) - expect(view.container).toMatchSnapshot() - }) - describe('renders in size', () => { - it('2x', () => { - const view = render(<ForkAwesomeStack size={'2x'}>{stack}</ForkAwesomeStack>) - expect(view.container).toMatchSnapshot() - }) - it('3x', () => { - const view = render(<ForkAwesomeStack size={'3x'}>{stack}</ForkAwesomeStack>) - expect(view.container).toMatchSnapshot() - }) - it('4x', () => { - const view = render(<ForkAwesomeStack size={'4x'}>{stack}</ForkAwesomeStack>) - expect(view.container).toMatchSnapshot() - }) - it('5x', () => { - const view = render(<ForkAwesomeStack size={'5x'}>{stack}</ForkAwesomeStack>) - expect(view.container).toMatchSnapshot() - }) - }) -}) diff --git a/frontend/src/components/common/fork-awesome/fork-awesome-stack.tsx b/frontend/src/components/common/fork-awesome/fork-awesome-stack.tsx deleted file mode 100644 index 5982be39c..000000000 --- a/frontend/src/components/common/fork-awesome/fork-awesome-stack.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import type { ForkAwesomeIconProps } from './fork-awesome-icon' -import { ForkAwesomeIcon } from './fork-awesome-icon' -import type { IconSize } from './types' -import type { ReactElement } from 'react' -import React from 'react' - -export interface ForkAwesomeStackProps { - size?: IconSize - children: ReactElement<ForkAwesomeIconProps> | Array<ReactElement<ForkAwesomeIconProps>> -} - -/** - * A stack of {@link ForkAwesomeIcon ForkAwesomeIcons}. - * - * @param size Which size the stack should have. - * @param children One or more {@link ForkAwesomeIcon ForkAwesomeIcons} to be stacked. - */ -export const ForkAwesomeStack: React.FC<ForkAwesomeStackProps> = ({ size, children }) => { - return ( - <span className={`fa-stack ${size ? 'fa-' : ''}${size ?? ''}`}> - {React.Children.map(children, (child) => { - if (!React.isValidElement<ForkAwesomeIconProps>(child)) { - return null - } - return <ForkAwesomeIcon {...child.props} stacked={true} /> - })} - </span> - ) -} diff --git a/frontend/src/components/common/fork-awesome/types.d.ts b/frontend/src/components/common/fork-awesome/types.d.ts deleted file mode 100644 index 93f7a8479..000000000 --- a/frontend/src/components/common/fork-awesome/types.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import type { ForkAwesomeIcons } from './fork-awesome-icons' - -export type IconName = (typeof ForkAwesomeIcons)[number] -export type IconSize = '2x' | '3x' | '4x' | '5x' diff --git a/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-with-text.tsx b/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-with-text.tsx index 6e01b87ee..844c41ec4 100644 --- a/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-with-text.tsx +++ b/frontend/src/components/common/hedge-doc-logo/hedge-doc-logo-with-text.tsx @@ -6,8 +6,7 @@ import LogoBwHorizontal from './logo_text_bw_horizontal.svg' import LogoColorVertical from './logo_text_color_vertical.svg' import LogoWbHorizontal from './logo_text_wb_horizontal.svg' -import React, { useMemo } from 'react' -import { useTranslation } from 'react-i18next' +import React from 'react' export enum HedgeDocLogoSize { SMALL = 32, @@ -33,17 +32,13 @@ export enum HedgeDocLogoType { * @param logoType The logo type to be used. */ export const HedgeDocLogoWithText: React.FC<HedgeDocLogoProps> = ({ size = HedgeDocLogoSize.MEDIUM, logoType }) => { - const { t } = useTranslation() - const altText = useMemo(() => t('app.icon'), [t]) - const style = useMemo(() => ({ height: size }), [size]) - switch (logoType) { case HedgeDocLogoType.COLOR_VERTICAL: - return <LogoColorVertical className={'w-auto'} title={altText} style={style} /> + return <LogoColorVertical className={'w-auto'} height={`${size}px`} width={'auto'} /> case HedgeDocLogoType.BW_HORIZONTAL: - return <LogoBwHorizontal className={'w-auto'} title={altText} style={style} /> + return <LogoBwHorizontal className={'w-auto'} height={`${size}px`} width={'auto'} /> case HedgeDocLogoType.WB_HORIZONTAL: - return <LogoWbHorizontal className={'w-auto'} title={altText} style={style} /> + return <LogoWbHorizontal className={'w-auto'} height={`${size}px`} width={'auto'} /> default: return null } diff --git a/frontend/src/components/common/icon-button/__snapshots__/icon-button.test.tsx.snap b/frontend/src/components/common/icon-button/__snapshots__/icon-button.test.tsx.snap index 1d1c9096c..b480d4475 100644 --- a/frontend/src/components/common/icon-button/__snapshots__/icon-button.test.tsx.snap +++ b/frontend/src/components/common/icon-button/__snapshots__/icon-button.test.tsx.snap @@ -10,9 +10,7 @@ exports[`IconButton correctly uses the onClick callback 1`] = ` <span class="icon-part d-flex align-items-center" > - <i - class="fa fa-heart icon " - /> + BootstrapIconMock_Heart </span> <span class="text-part d-flex align-items-center" @@ -33,9 +31,7 @@ exports[`IconButton renders heart icon 1`] = ` <span class="icon-part d-flex align-items-center" > - <i - class="fa fa-heart icon " - /> + BootstrapIconMock_Heart </span> <span class="text-part d-flex align-items-center" @@ -56,9 +52,7 @@ exports[`IconButton renders with additional className 1`] = ` <span class="icon-part d-flex align-items-center" > - <i - class="fa fa-heart icon " - /> + BootstrapIconMock_Heart </span> <span class="text-part d-flex align-items-center" @@ -79,9 +73,7 @@ exports[`IconButton renders with border 1`] = ` <span class="icon-part d-flex align-items-center" > - <i - class="fa fa-heart icon " - /> + BootstrapIconMock_Heart </span> <span class="text-part d-flex align-items-center" @@ -91,26 +83,3 @@ exports[`IconButton renders with border 1`] = ` </button> </div> `; - -exports[`IconButton renders with fixed width icon 1`] = ` -<div> - <button - class="btn-icon p-0 d-inline-flex align-items-stretch btn btn-primary" - data-testid="icon-button" - type="button" - > - <span - class="icon-part d-flex align-items-center" - > - <i - class="fa fa-fw fa-heart icon " - /> - </span> - <span - class="text-part d-flex align-items-center" - > - test with fixed with icon - </span> - </button> -</div> -`; diff --git a/frontend/src/components/common/icon-button/icon-button.test.tsx b/frontend/src/components/common/icon-button/icon-button.test.tsx index 435becb68..21e3b3b79 100644 --- a/frontend/src/components/common/icon-button/icon-button.test.tsx +++ b/frontend/src/components/common/icon-button/icon-button.test.tsx @@ -3,35 +3,26 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { IconName } from '../fork-awesome/types' import { IconButton } from './icon-button' import { fireEvent, render, screen } from '@testing-library/react' +import { Heart as IconHeart } from 'react-bootstrap-icons' describe('IconButton', () => { - const icon: IconName = 'heart' it('renders heart icon', () => { - const view = render(<IconButton icon={icon}>test</IconButton>) + const view = render(<IconButton icon={IconHeart}>test</IconButton>) expect(view.container).toMatchSnapshot() }) it('renders with border', () => { const view = render( - <IconButton icon={icon} border={true}> + <IconButton icon={IconHeart} border={true}> test with border </IconButton> ) expect(view.container).toMatchSnapshot() }) - it('renders with fixed width icon', () => { - const view = render( - <IconButton icon={icon} iconFixedWidth={true}> - test with fixed with icon - </IconButton> - ) - expect(view.container).toMatchSnapshot() - }) it('renders with additional className', () => { const view = render( - <IconButton icon={icon} className={'testClass'}> + <IconButton icon={IconHeart} className={'testClass'}> test with additional className </IconButton> ) @@ -40,7 +31,7 @@ describe('IconButton', () => { it('correctly uses the onClick callback', async () => { const onClick = jest.fn() const view = render( - <IconButton icon={icon} onClick={onClick}> + <IconButton icon={IconHeart} onClick={onClick}> test with onClick </IconButton> ) diff --git a/frontend/src/components/common/icon-button/icon-button.tsx b/frontend/src/components/common/icon-button/icon-button.tsx index 6c9bea858..b4ebf8df2 100644 --- a/frontend/src/components/common/icon-button/icon-button.tsx +++ b/frontend/src/components/common/icon-button/icon-button.tsx @@ -5,37 +5,38 @@ */ import type { PropsWithDataTestId } from '../../../utils/test-id' import { testId } from '../../../utils/test-id' -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' -import type { IconName } from '../fork-awesome/types' +import { UiIcon } from '../icons/ui-icon' import { ShowIf } from '../show-if/show-if' import styles from './icon-button.module.scss' import React from 'react' import type { ButtonProps } from 'react-bootstrap' import { Button } from 'react-bootstrap' +import type { Icon } from 'react-bootstrap-icons' export interface IconButtonProps extends ButtonProps, PropsWithDataTestId { - icon: IconName + icon: Icon onClick?: () => void border?: boolean - iconFixedWidth?: boolean + iconSize?: number | string } /** - * A generic {@link Button button} with an {@link ForkAwesomeIcon icon} in it. + * A generic {@link Button button} with an icon in it. * * @param icon Which icon should be used * @param children The children that will be added as the content of the button. * @param iconFixedWidth If the icon should be of fixed width. * @param border Should the button have a border. * @param className Additional class names added to the button. + * @param iconSize Size of the icon * @param props Additional props for the button. */ export const IconButton: React.FC<IconButtonProps> = ({ icon, children, - iconFixedWidth = false, border = false, className, + iconSize, ...props }) => { return ( @@ -46,7 +47,7 @@ export const IconButton: React.FC<IconButtonProps> = ({ }`} {...testId('icon-button')}> <span className={`${styles['icon-part']} d-flex align-items-center`}> - <ForkAwesomeIcon icon={icon} fixedWidth={iconFixedWidth} className={'icon'} /> + <UiIcon size={iconSize} icon={icon} className={'icon'} /> </span> <ShowIf condition={!!children}> <span className={`${styles['text-part']} d-flex align-items-center`}>{children}</span> diff --git a/frontend/src/components/common/icons/bootstrap-icons.tsx b/frontend/src/components/common/icons/bootstrap-icons.tsx new file mode 100644 index 000000000..8153b136f --- /dev/null +++ b/frontend/src/components/common/icons/bootstrap-icons.tsx @@ -0,0 +1,1994 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import React from 'react' + +export type BootstrapIconName = keyof typeof BootstrapLazyIcons + +export const isBootstrapIconName = (name: string): name is BootstrapIconName => { + return name in BootstrapLazyIcons +} + +export const BootstrapLazyIcons = { + '0-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/0-circle-fill')), + '0-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/0-circle')), + '0-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/0-square-fill')), + '0-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/0-square')), + '1-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/1-circle-fill')), + '1-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/1-circle')), + '1-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/1-square-fill')), + '1-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/1-square')), + '123': React.lazy(() => import('react-bootstrap-icons/dist/icons/123')), + '2-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/2-circle-fill')), + '2-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/2-circle')), + '2-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/2-square-fill')), + '2-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/2-square')), + '3-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/3-circle-fill')), + '3-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/3-circle')), + '3-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/3-square-fill')), + '3-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/3-square')), + '4-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/4-circle-fill')), + '4-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/4-circle')), + '4-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/4-square-fill')), + '4-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/4-square')), + '5-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/5-circle-fill')), + '5-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/5-circle')), + '5-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/5-square-fill')), + '5-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/5-square')), + '6-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/6-circle-fill')), + '6-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/6-circle')), + '6-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/6-square-fill')), + '6-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/6-square')), + '7-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/7-circle-fill')), + '7-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/7-circle')), + '7-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/7-square-fill')), + '7-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/7-square')), + '8-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/8-circle-fill')), + '8-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/8-circle')), + '8-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/8-square-fill')), + '8-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/8-square')), + '9-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/9-circle-fill')), + '9-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/9-circle')), + '9-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/9-square-fill')), + '9-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/9-square')), + activity: React.lazy(() => import('react-bootstrap-icons/dist/icons/activity')), + 'airplane-engines-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/airplane-engines-fill')), + 'airplane-engines': React.lazy(() => import('react-bootstrap-icons/dist/icons/airplane-engines')), + 'airplane-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/airplane-fill')), + airplane: React.lazy(() => import('react-bootstrap-icons/dist/icons/airplane')), + 'alarm-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/alarm-fill')), + alarm: React.lazy(() => import('react-bootstrap-icons/dist/icons/alarm')), + alexa: React.lazy(() => import('react-bootstrap-icons/dist/icons/alexa')), + 'align-bottom': React.lazy(() => import('react-bootstrap-icons/dist/icons/align-bottom')), + 'align-center': React.lazy(() => import('react-bootstrap-icons/dist/icons/align-center')), + 'align-end': React.lazy(() => import('react-bootstrap-icons/dist/icons/align-end')), + 'align-middle': React.lazy(() => import('react-bootstrap-icons/dist/icons/align-middle')), + 'align-start': React.lazy(() => import('react-bootstrap-icons/dist/icons/align-start')), + 'align-top': React.lazy(() => import('react-bootstrap-icons/dist/icons/align-top')), + alipay: React.lazy(() => import('react-bootstrap-icons/dist/icons/alipay')), + alt: React.lazy(() => import('react-bootstrap-icons/dist/icons/alt')), + amd: React.lazy(() => import('react-bootstrap-icons/dist/icons/amd')), + android: React.lazy(() => import('react-bootstrap-icons/dist/icons/android')), + android2: React.lazy(() => import('react-bootstrap-icons/dist/icons/android2')), + 'app-indicator': React.lazy(() => import('react-bootstrap-icons/dist/icons/app-indicator')), + app: React.lazy(() => import('react-bootstrap-icons/dist/icons/app')), + apple: React.lazy(() => import('react-bootstrap-icons/dist/icons/apple')), + 'archive-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/archive-fill')), + archive: React.lazy(() => import('react-bootstrap-icons/dist/icons/archive')), + 'arrow-90deg-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-90deg-down')), + 'arrow-90deg-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-90deg-left')), + 'arrow-90deg-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-90deg-right')), + 'arrow-90deg-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-90deg-up')), + 'arrow-bar-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-bar-down')), + 'arrow-bar-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-bar-left')), + 'arrow-bar-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-bar-right')), + 'arrow-bar-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-bar-up')), + 'arrow-clockwise': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-clockwise')), + 'arrow-counterclockwise': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-counterclockwise')), + 'arrow-down-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-circle-fill')), + 'arrow-down-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-circle')), + 'arrow-down-left-circle-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/arrow-down-left-circle-fill') + ), + 'arrow-down-left-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-left-circle')), + 'arrow-down-left-square-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/arrow-down-left-square-fill') + ), + 'arrow-down-left-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-left-square')), + 'arrow-down-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-left')), + 'arrow-down-right-circle-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/arrow-down-right-circle-fill') + ), + 'arrow-down-right-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-right-circle')), + 'arrow-down-right-square-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/arrow-down-right-square-fill') + ), + 'arrow-down-right-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-right-square')), + 'arrow-down-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-right')), + 'arrow-down-short': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-short')), + 'arrow-down-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-square-fill')), + 'arrow-down-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-square')), + 'arrow-down-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down-up')), + 'arrow-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-down')), + 'arrow-left-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left-circle-fill')), + 'arrow-left-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left-circle')), + 'arrow-left-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left-right')), + 'arrow-left-short': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left-short')), + 'arrow-left-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left-square-fill')), + 'arrow-left-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left-square')), + 'arrow-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-left')), + 'arrow-repeat': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-repeat')), + 'arrow-return-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-return-left')), + 'arrow-return-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-return-right')), + 'arrow-right-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-right-circle-fill')), + 'arrow-right-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-right-circle')), + 'arrow-right-short': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-right-short')), + 'arrow-right-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-right-square-fill')), + 'arrow-right-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-right-square')), + 'arrow-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-right')), + 'arrow-through-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-through-heart-fill')), + 'arrow-through-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-through-heart')), + 'arrow-up-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-circle-fill')), + 'arrow-up-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-circle')), + 'arrow-up-left-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-left-circle-fill')), + 'arrow-up-left-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-left-circle')), + 'arrow-up-left-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-left-square-fill')), + 'arrow-up-left-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-left-square')), + 'arrow-up-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-left')), + 'arrow-up-right-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-right-circle-fill')), + 'arrow-up-right-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-right-circle')), + 'arrow-up-right-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-right-square-fill')), + 'arrow-up-right-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-right-square')), + 'arrow-up-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-right')), + 'arrow-up-short': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-short')), + 'arrow-up-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-square-fill')), + 'arrow-up-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up-square')), + 'arrow-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrow-up')), + 'arrows-angle-contract': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrows-angle-contract')), + 'arrows-angle-expand': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrows-angle-expand')), + 'arrows-collapse': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrows-collapse')), + 'arrows-expand': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrows-expand')), + 'arrows-fullscreen': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrows-fullscreen')), + 'arrows-move': React.lazy(() => import('react-bootstrap-icons/dist/icons/arrows-move')), + 'aspect-ratio-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/aspect-ratio-fill')), + 'aspect-ratio': React.lazy(() => import('react-bootstrap-icons/dist/icons/aspect-ratio')), + asterisk: React.lazy(() => import('react-bootstrap-icons/dist/icons/asterisk')), + at: React.lazy(() => import('react-bootstrap-icons/dist/icons/at')), + 'award-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/award-fill')), + award: React.lazy(() => import('react-bootstrap-icons/dist/icons/award')), + back: React.lazy(() => import('react-bootstrap-icons/dist/icons/back')), + 'backspace-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/backspace-fill')), + 'backspace-reverse-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/backspace-reverse-fill')), + 'backspace-reverse': React.lazy(() => import('react-bootstrap-icons/dist/icons/backspace-reverse')), + backspace: React.lazy(() => import('react-bootstrap-icons/dist/icons/backspace')), + 'badge-3d-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-3d-fill')), + 'badge-3d': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-3d')), + 'badge-4k-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-4k-fill')), + 'badge-4k': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-4k')), + 'badge-8k-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-8k-fill')), + 'badge-8k': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-8k')), + 'badge-ad-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-ad-fill')), + 'badge-ad': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-ad')), + 'badge-ar-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-ar-fill')), + 'badge-ar': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-ar')), + 'badge-cc-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-cc-fill')), + 'badge-cc': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-cc')), + 'badge-hd-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-hd-fill')), + 'badge-hd': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-hd')), + 'badge-sd-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-sd-fill')), + 'badge-sd': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-sd')), + 'badge-tm-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-tm-fill')), + 'badge-tm': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-tm')), + 'badge-vo-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-vo-fill')), + 'badge-vo': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-vo')), + 'badge-vr-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-vr-fill')), + 'badge-vr': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-vr')), + 'badge-wc-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-wc-fill')), + 'badge-wc': React.lazy(() => import('react-bootstrap-icons/dist/icons/badge-wc')), + 'bag-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-check-fill')), + 'bag-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-check')), + 'bag-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-dash-fill')), + 'bag-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-dash')), + 'bag-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-fill')), + 'bag-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-heart-fill')), + 'bag-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-heart')), + 'bag-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-plus-fill')), + 'bag-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-plus')), + 'bag-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-x-fill')), + 'bag-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/bag-x')), + bag: React.lazy(() => import('react-bootstrap-icons/dist/icons/bag')), + 'balloon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/balloon-fill')), + 'balloon-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/balloon-heart-fill')), + 'balloon-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/balloon-heart')), + balloon: React.lazy(() => import('react-bootstrap-icons/dist/icons/balloon')), + 'bandaid-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bandaid-fill')), + bandaid: React.lazy(() => import('react-bootstrap-icons/dist/icons/bandaid')), + bank: React.lazy(() => import('react-bootstrap-icons/dist/icons/bank')), + bank2: React.lazy(() => import('react-bootstrap-icons/dist/icons/bank2')), + 'bar-chart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bar-chart-fill')), + 'bar-chart-line-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bar-chart-line-fill')), + 'bar-chart-line': React.lazy(() => import('react-bootstrap-icons/dist/icons/bar-chart-line')), + 'bar-chart-steps': React.lazy(() => import('react-bootstrap-icons/dist/icons/bar-chart-steps')), + 'bar-chart': React.lazy(() => import('react-bootstrap-icons/dist/icons/bar-chart')), + 'basket-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/basket-fill')), + basket: React.lazy(() => import('react-bootstrap-icons/dist/icons/basket')), + 'basket2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/basket2-fill')), + basket2: React.lazy(() => import('react-bootstrap-icons/dist/icons/basket2')), + 'basket3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/basket3-fill')), + basket3: React.lazy(() => import('react-bootstrap-icons/dist/icons/basket3')), + 'battery-charging': React.lazy(() => import('react-bootstrap-icons/dist/icons/battery-charging')), + 'battery-full': React.lazy(() => import('react-bootstrap-icons/dist/icons/battery-full')), + 'battery-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/battery-half')), + battery: React.lazy(() => import('react-bootstrap-icons/dist/icons/battery')), + behance: React.lazy(() => import('react-bootstrap-icons/dist/icons/behance')), + 'bell-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bell-fill')), + 'bell-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bell-slash-fill')), + 'bell-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/bell-slash')), + bell: React.lazy(() => import('react-bootstrap-icons/dist/icons/bell')), + bezier: React.lazy(() => import('react-bootstrap-icons/dist/icons/bezier')), + bezier2: React.lazy(() => import('react-bootstrap-icons/dist/icons/bezier2')), + bicycle: React.lazy(() => import('react-bootstrap-icons/dist/icons/bicycle')), + 'binoculars-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/binoculars-fill')), + binoculars: React.lazy(() => import('react-bootstrap-icons/dist/icons/binoculars')), + 'blockquote-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/blockquote-left')), + 'blockquote-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/blockquote-right')), + bluetooth: React.lazy(() => import('react-bootstrap-icons/dist/icons/bluetooth')), + 'body-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/body-text')), + 'book-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/book-fill')), + 'book-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/book-half')), + book: React.lazy(() => import('react-bootstrap-icons/dist/icons/book')), + 'bookmark-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-check-fill')), + 'bookmark-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-check')), + 'bookmark-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-dash-fill')), + 'bookmark-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-dash')), + 'bookmark-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-fill')), + 'bookmark-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-heart-fill')), + 'bookmark-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-heart')), + 'bookmark-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-plus-fill')), + 'bookmark-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-plus')), + 'bookmark-star-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-star-fill')), + 'bookmark-star': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-star')), + 'bookmark-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-x-fill')), + 'bookmark-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark-x')), + bookmark: React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmark')), + 'bookmarks-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmarks-fill')), + bookmarks: React.lazy(() => import('react-bootstrap-icons/dist/icons/bookmarks')), + bookshelf: React.lazy(() => import('react-bootstrap-icons/dist/icons/bookshelf')), + 'boombox-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/boombox-fill')), + boombox: React.lazy(() => import('react-bootstrap-icons/dist/icons/boombox')), + 'bootstrap-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bootstrap-fill')), + 'bootstrap-reboot': React.lazy(() => import('react-bootstrap-icons/dist/icons/bootstrap-reboot')), + bootstrap: React.lazy(() => import('react-bootstrap-icons/dist/icons/bootstrap')), + 'border-all': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-all')), + 'border-bottom': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-bottom')), + 'border-center': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-center')), + 'border-inner': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-inner')), + 'border-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-left')), + 'border-middle': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-middle')), + 'border-outer': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-outer')), + 'border-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-right')), + 'border-style': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-style')), + 'border-top': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-top')), + 'border-width': React.lazy(() => import('react-bootstrap-icons/dist/icons/border-width')), + border: React.lazy(() => import('react-bootstrap-icons/dist/icons/border')), + 'bounding-box-circles': React.lazy(() => import('react-bootstrap-icons/dist/icons/bounding-box-circles')), + 'bounding-box': React.lazy(() => import('react-bootstrap-icons/dist/icons/bounding-box')), + 'box-arrow-down-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-down-left')), + 'box-arrow-down-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-down-right')), + 'box-arrow-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-down')), + 'box-arrow-in-down-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-down-left')), + 'box-arrow-in-down-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-down-right')), + 'box-arrow-in-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-down')), + 'box-arrow-in-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-left')), + 'box-arrow-in-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-right')), + 'box-arrow-in-up-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-up-left')), + 'box-arrow-in-up-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-up-right')), + 'box-arrow-in-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-in-up')), + 'box-arrow-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-left')), + 'box-arrow-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-right')), + 'box-arrow-up-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-up-left')), + 'box-arrow-up-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-up-right')), + 'box-arrow-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-arrow-up')), + 'box-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-fill')), + 'box-seam-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-seam-fill')), + 'box-seam': React.lazy(() => import('react-bootstrap-icons/dist/icons/box-seam')), + box: React.lazy(() => import('react-bootstrap-icons/dist/icons/box')), + 'box2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/box2-fill')), + 'box2-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/box2-heart-fill')), + 'box2-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/box2-heart')), + box2: React.lazy(() => import('react-bootstrap-icons/dist/icons/box2')), + boxes: React.lazy(() => import('react-bootstrap-icons/dist/icons/boxes')), + 'braces-asterisk': React.lazy(() => import('react-bootstrap-icons/dist/icons/braces-asterisk')), + braces: React.lazy(() => import('react-bootstrap-icons/dist/icons/braces')), + bricks: React.lazy(() => import('react-bootstrap-icons/dist/icons/bricks')), + 'briefcase-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/briefcase-fill')), + briefcase: React.lazy(() => import('react-bootstrap-icons/dist/icons/briefcase')), + 'brightness-alt-high-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-alt-high-fill')), + 'brightness-alt-high': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-alt-high')), + 'brightness-alt-low-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-alt-low-fill')), + 'brightness-alt-low': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-alt-low')), + 'brightness-high-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-high-fill')), + 'brightness-high': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-high')), + 'brightness-low-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-low-fill')), + 'brightness-low': React.lazy(() => import('react-bootstrap-icons/dist/icons/brightness-low')), + 'broadcast-pin': React.lazy(() => import('react-bootstrap-icons/dist/icons/broadcast-pin')), + broadcast: React.lazy(() => import('react-bootstrap-icons/dist/icons/broadcast')), + 'browser-chrome': React.lazy(() => import('react-bootstrap-icons/dist/icons/browser-chrome')), + 'browser-edge': React.lazy(() => import('react-bootstrap-icons/dist/icons/browser-edge')), + 'browser-firefox': React.lazy(() => import('react-bootstrap-icons/dist/icons/browser-firefox')), + 'browser-safari': React.lazy(() => import('react-bootstrap-icons/dist/icons/browser-safari')), + 'brush-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/brush-fill')), + brush: React.lazy(() => import('react-bootstrap-icons/dist/icons/brush')), + 'bucket-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bucket-fill')), + bucket: React.lazy(() => import('react-bootstrap-icons/dist/icons/bucket')), + 'bug-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bug-fill')), + bug: React.lazy(() => import('react-bootstrap-icons/dist/icons/bug')), + 'building-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-add')), + 'building-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-check')), + 'building-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-dash')), + 'building-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-down')), + 'building-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-exclamation')), + 'building-fill-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-add')), + 'building-fill-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-check')), + 'building-fill-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-dash')), + 'building-fill-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-down')), + 'building-fill-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-exclamation')), + 'building-fill-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-gear')), + 'building-fill-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-lock')), + 'building-fill-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-slash')), + 'building-fill-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-up')), + 'building-fill-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill-x')), + 'building-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-fill')), + 'building-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-gear')), + 'building-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-lock')), + 'building-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-slash')), + 'building-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-up')), + 'building-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/building-x')), + building: React.lazy(() => import('react-bootstrap-icons/dist/icons/building')), + 'buildings-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/buildings-fill')), + buildings: React.lazy(() => import('react-bootstrap-icons/dist/icons/buildings')), + bullseye: React.lazy(() => import('react-bootstrap-icons/dist/icons/bullseye')), + 'bus-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/bus-front-fill')), + 'bus-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/bus-front')), + 'c-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/c-circle-fill')), + 'c-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/c-circle')), + 'c-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/c-square-fill')), + 'c-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/c-square')), + 'calculator-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calculator-fill')), + calculator: React.lazy(() => import('react-bootstrap-icons/dist/icons/calculator')), + 'calendar-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-check-fill')), + 'calendar-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-check')), + 'calendar-date-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-date-fill')), + 'calendar-date': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-date')), + 'calendar-day-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-day-fill')), + 'calendar-day': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-day')), + 'calendar-event-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-event-fill')), + 'calendar-event': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-event')), + 'calendar-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-fill')), + 'calendar-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-heart-fill')), + 'calendar-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-heart')), + 'calendar-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-minus-fill')), + 'calendar-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-minus')), + 'calendar-month-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-month-fill')), + 'calendar-month': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-month')), + 'calendar-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-plus-fill')), + 'calendar-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-plus')), + 'calendar-range-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-range-fill')), + 'calendar-range': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-range')), + 'calendar-week-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-week-fill')), + 'calendar-week': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-week')), + 'calendar-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-x-fill')), + 'calendar-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar-x')), + calendar: React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar')), + 'calendar2-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-check-fill')), + 'calendar2-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-check')), + 'calendar2-date-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-date-fill')), + 'calendar2-date': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-date')), + 'calendar2-day-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-day-fill')), + 'calendar2-day': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-day')), + 'calendar2-event-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-event-fill')), + 'calendar2-event': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-event')), + 'calendar2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-fill')), + 'calendar2-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-heart-fill')), + 'calendar2-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-heart')), + 'calendar2-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-minus-fill')), + 'calendar2-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-minus')), + 'calendar2-month-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-month-fill')), + 'calendar2-month': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-month')), + 'calendar2-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-plus-fill')), + 'calendar2-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-plus')), + 'calendar2-range-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-range-fill')), + 'calendar2-range': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-range')), + 'calendar2-week-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-week-fill')), + 'calendar2-week': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-week')), + 'calendar2-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-x-fill')), + 'calendar2-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2-x')), + calendar2: React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar2')), + 'calendar3-event-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-event-fill')), + 'calendar3-event': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-event')), + 'calendar3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-fill')), + 'calendar3-range-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-range-fill')), + 'calendar3-range': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-range')), + 'calendar3-week-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-week-fill')), + 'calendar3-week': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3-week')), + calendar3: React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar3')), + 'calendar4-event': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar4-event')), + 'calendar4-range': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar4-range')), + 'calendar4-week': React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar4-week')), + calendar4: React.lazy(() => import('react-bootstrap-icons/dist/icons/calendar4')), + 'camera-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-fill')), + 'camera-reels-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-reels-fill')), + 'camera-reels': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-reels')), + 'camera-video-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-video-fill')), + 'camera-video-off-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-video-off-fill')), + 'camera-video-off': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-video-off')), + 'camera-video': React.lazy(() => import('react-bootstrap-icons/dist/icons/camera-video')), + camera: React.lazy(() => import('react-bootstrap-icons/dist/icons/camera')), + camera2: React.lazy(() => import('react-bootstrap-icons/dist/icons/camera2')), + 'capslock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/capslock-fill')), + capslock: React.lazy(() => import('react-bootstrap-icons/dist/icons/capslock')), + 'capsule-pill': React.lazy(() => import('react-bootstrap-icons/dist/icons/capsule-pill')), + capsule: React.lazy(() => import('react-bootstrap-icons/dist/icons/capsule')), + 'car-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/car-front-fill')), + 'car-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/car-front')), + 'card-checklist': React.lazy(() => import('react-bootstrap-icons/dist/icons/card-checklist')), + 'card-heading': React.lazy(() => import('react-bootstrap-icons/dist/icons/card-heading')), + 'card-image': React.lazy(() => import('react-bootstrap-icons/dist/icons/card-image')), + 'card-list': React.lazy(() => import('react-bootstrap-icons/dist/icons/card-list')), + 'card-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/card-text')), + 'caret-down-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-down-fill')), + 'caret-down-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-down-square-fill')), + 'caret-down-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-down-square')), + 'caret-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-down')), + 'caret-left-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-left-fill')), + 'caret-left-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-left-square-fill')), + 'caret-left-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-left-square')), + 'caret-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-left')), + 'caret-right-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-right-fill')), + 'caret-right-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-right-square-fill')), + 'caret-right-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-right-square')), + 'caret-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-right')), + 'caret-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-up-fill')), + 'caret-up-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-up-square-fill')), + 'caret-up-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-up-square')), + 'caret-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/caret-up')), + 'cart-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-check-fill')), + 'cart-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-check')), + 'cart-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-dash-fill')), + 'cart-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-dash')), + 'cart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-fill')), + 'cart-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-plus-fill')), + 'cart-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-plus')), + 'cart-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-x-fill')), + 'cart-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/cart-x')), + cart: React.lazy(() => import('react-bootstrap-icons/dist/icons/cart')), + cart2: React.lazy(() => import('react-bootstrap-icons/dist/icons/cart2')), + cart3: React.lazy(() => import('react-bootstrap-icons/dist/icons/cart3')), + cart4: React.lazy(() => import('react-bootstrap-icons/dist/icons/cart4')), + 'cash-coin': React.lazy(() => import('react-bootstrap-icons/dist/icons/cash-coin')), + 'cash-stack': React.lazy(() => import('react-bootstrap-icons/dist/icons/cash-stack')), + cash: React.lazy(() => import('react-bootstrap-icons/dist/icons/cash')), + 'cassette-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cassette-fill')), + cassette: React.lazy(() => import('react-bootstrap-icons/dist/icons/cassette')), + cast: React.lazy(() => import('react-bootstrap-icons/dist/icons/cast')), + 'cc-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cc-circle-fill')), + 'cc-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/cc-circle')), + 'cc-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cc-square-fill')), + 'cc-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/cc-square')), + 'chat-dots-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-dots-fill')), + 'chat-dots': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-dots')), + 'chat-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-fill')), + 'chat-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-heart-fill')), + 'chat-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-heart')), + 'chat-left-dots-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-dots-fill')), + 'chat-left-dots': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-dots')), + 'chat-left-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-fill')), + 'chat-left-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-heart-fill')), + 'chat-left-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-heart')), + 'chat-left-quote-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-quote-fill')), + 'chat-left-quote': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-quote')), + 'chat-left-text-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-text-fill')), + 'chat-left-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left-text')), + 'chat-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-left')), + 'chat-quote-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-quote-fill')), + 'chat-quote': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-quote')), + 'chat-right-dots-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-dots-fill')), + 'chat-right-dots': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-dots')), + 'chat-right-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-fill')), + 'chat-right-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-heart-fill')), + 'chat-right-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-heart')), + 'chat-right-quote-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-quote-fill')), + 'chat-right-quote': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-quote')), + 'chat-right-text-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-text-fill')), + 'chat-right-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right-text')), + 'chat-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-right')), + 'chat-square-dots-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-dots-fill')), + 'chat-square-dots': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-dots')), + 'chat-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-fill')), + 'chat-square-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-heart-fill')), + 'chat-square-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-heart')), + 'chat-square-quote-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-quote-fill')), + 'chat-square-quote': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-quote')), + 'chat-square-text-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-text-fill')), + 'chat-square-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square-text')), + 'chat-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-square')), + 'chat-text-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-text-fill')), + 'chat-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/chat-text')), + chat: React.lazy(() => import('react-bootstrap-icons/dist/icons/chat')), + 'check-all': React.lazy(() => import('react-bootstrap-icons/dist/icons/check-all')), + 'check-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/check-circle-fill')), + 'check-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/check-circle')), + 'check-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/check-lg')), + 'check-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/check-square-fill')), + 'check-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/check-square')), + check: React.lazy(() => import('react-bootstrap-icons/dist/icons/check')), + 'check2-all': React.lazy(() => import('react-bootstrap-icons/dist/icons/check2-all')), + 'check2-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/check2-circle')), + 'check2-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/check2-square')), + check2: React.lazy(() => import('react-bootstrap-icons/dist/icons/check2')), + 'chevron-bar-contract': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-bar-contract')), + 'chevron-bar-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-bar-down')), + 'chevron-bar-expand': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-bar-expand')), + 'chevron-bar-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-bar-left')), + 'chevron-bar-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-bar-right')), + 'chevron-bar-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-bar-up')), + 'chevron-compact-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-compact-down')), + 'chevron-compact-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-compact-left')), + 'chevron-compact-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-compact-right')), + 'chevron-compact-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-compact-up')), + 'chevron-contract': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-contract')), + 'chevron-double-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-double-down')), + 'chevron-double-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-double-left')), + 'chevron-double-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-double-right')), + 'chevron-double-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-double-up')), + 'chevron-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-down')), + 'chevron-expand': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-expand')), + 'chevron-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-left')), + 'chevron-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-right')), + 'chevron-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/chevron-up')), + 'circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/circle-fill')), + 'circle-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/circle-half')), + 'circle-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/circle-square')), + circle: React.lazy(() => import('react-bootstrap-icons/dist/icons/circle')), + 'clipboard-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-check-fill')), + 'clipboard-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-check')), + 'clipboard-data-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-data-fill')), + 'clipboard-data': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-data')), + 'clipboard-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-fill')), + 'clipboard-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-heart-fill')), + 'clipboard-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-heart')), + 'clipboard-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-minus-fill')), + 'clipboard-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-minus')), + 'clipboard-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-plus-fill')), + 'clipboard-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-plus')), + 'clipboard-pulse': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-pulse')), + 'clipboard-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-x-fill')), + 'clipboard-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard-x')), + clipboard: React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard')), + 'clipboard2-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-check-fill')), + 'clipboard2-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-check')), + 'clipboard2-data-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-data-fill')), + 'clipboard2-data': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-data')), + 'clipboard2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-fill')), + 'clipboard2-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-heart-fill')), + 'clipboard2-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-heart')), + 'clipboard2-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-minus-fill')), + 'clipboard2-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-minus')), + 'clipboard2-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-plus-fill')), + 'clipboard2-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-plus')), + 'clipboard2-pulse-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-pulse-fill')), + 'clipboard2-pulse': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-pulse')), + 'clipboard2-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-x-fill')), + 'clipboard2-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2-x')), + clipboard2: React.lazy(() => import('react-bootstrap-icons/dist/icons/clipboard2')), + 'clock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clock-fill')), + 'clock-history': React.lazy(() => import('react-bootstrap-icons/dist/icons/clock-history')), + clock: React.lazy(() => import('react-bootstrap-icons/dist/icons/clock')), + 'cloud-arrow-down-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-arrow-down-fill')), + 'cloud-arrow-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-arrow-down')), + 'cloud-arrow-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-arrow-up-fill')), + 'cloud-arrow-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-arrow-up')), + 'cloud-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-check-fill')), + 'cloud-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-check')), + 'cloud-download-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-download-fill')), + 'cloud-download': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-download')), + 'cloud-drizzle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-drizzle-fill')), + 'cloud-drizzle': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-drizzle')), + 'cloud-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-fill')), + 'cloud-fog-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-fog-fill')), + 'cloud-fog': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-fog')), + 'cloud-fog2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-fog2-fill')), + 'cloud-fog2': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-fog2')), + 'cloud-hail-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-hail-fill')), + 'cloud-hail': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-hail')), + 'cloud-haze-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-haze-fill')), + 'cloud-haze': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-haze')), + 'cloud-haze2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-haze2-fill')), + 'cloud-haze2': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-haze2')), + 'cloud-lightning-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-lightning-fill')), + 'cloud-lightning-rain-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-lightning-rain-fill')), + 'cloud-lightning-rain': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-lightning-rain')), + 'cloud-lightning': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-lightning')), + 'cloud-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-minus-fill')), + 'cloud-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-minus')), + 'cloud-moon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-moon-fill')), + 'cloud-moon': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-moon')), + 'cloud-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-plus-fill')), + 'cloud-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-plus')), + 'cloud-rain-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-rain-fill')), + 'cloud-rain-heavy-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-rain-heavy-fill')), + 'cloud-rain-heavy': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-rain-heavy')), + 'cloud-rain': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-rain')), + 'cloud-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-slash-fill')), + 'cloud-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-slash')), + 'cloud-sleet-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-sleet-fill')), + 'cloud-sleet': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-sleet')), + 'cloud-snow-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-snow-fill')), + 'cloud-snow': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-snow')), + 'cloud-sun-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-sun-fill')), + 'cloud-sun': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-sun')), + 'cloud-upload-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-upload-fill')), + 'cloud-upload': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud-upload')), + cloud: React.lazy(() => import('react-bootstrap-icons/dist/icons/cloud')), + 'clouds-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/clouds-fill')), + clouds: React.lazy(() => import('react-bootstrap-icons/dist/icons/clouds')), + 'cloudy-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cloudy-fill')), + cloudy: React.lazy(() => import('react-bootstrap-icons/dist/icons/cloudy')), + 'code-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/code-slash')), + 'code-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/code-square')), + code: React.lazy(() => import('react-bootstrap-icons/dist/icons/code')), + coin: React.lazy(() => import('react-bootstrap-icons/dist/icons/coin')), + 'collection-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/collection-fill')), + 'collection-play-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/collection-play-fill')), + 'collection-play': React.lazy(() => import('react-bootstrap-icons/dist/icons/collection-play')), + collection: React.lazy(() => import('react-bootstrap-icons/dist/icons/collection')), + 'columns-gap': React.lazy(() => import('react-bootstrap-icons/dist/icons/columns-gap')), + columns: React.lazy(() => import('react-bootstrap-icons/dist/icons/columns')), + command: React.lazy(() => import('react-bootstrap-icons/dist/icons/command')), + 'compass-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/compass-fill')), + compass: React.lazy(() => import('react-bootstrap-icons/dist/icons/compass')), + 'cone-striped': React.lazy(() => import('react-bootstrap-icons/dist/icons/cone-striped')), + cone: React.lazy(() => import('react-bootstrap-icons/dist/icons/cone')), + controller: React.lazy(() => import('react-bootstrap-icons/dist/icons/controller')), + 'cpu-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cpu-fill')), + cpu: React.lazy(() => import('react-bootstrap-icons/dist/icons/cpu')), + 'credit-card-2-back-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/credit-card-2-back-fill')), + 'credit-card-2-back': React.lazy(() => import('react-bootstrap-icons/dist/icons/credit-card-2-back')), + 'credit-card-2-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/credit-card-2-front-fill')), + 'credit-card-2-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/credit-card-2-front')), + 'credit-card-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/credit-card-fill')), + 'credit-card': React.lazy(() => import('react-bootstrap-icons/dist/icons/credit-card')), + crop: React.lazy(() => import('react-bootstrap-icons/dist/icons/crop')), + 'cup-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cup-fill')), + 'cup-hot-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cup-hot-fill')), + 'cup-hot': React.lazy(() => import('react-bootstrap-icons/dist/icons/cup-hot')), + 'cup-straw': React.lazy(() => import('react-bootstrap-icons/dist/icons/cup-straw')), + cup: React.lazy(() => import('react-bootstrap-icons/dist/icons/cup')), + 'currency-bitcoin': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-bitcoin')), + 'currency-dollar': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-dollar')), + 'currency-euro': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-euro')), + 'currency-exchange': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-exchange')), + 'currency-pound': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-pound')), + 'currency-rupee': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-rupee')), + 'currency-yen': React.lazy(() => import('react-bootstrap-icons/dist/icons/currency-yen')), + 'cursor-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/cursor-fill')), + 'cursor-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/cursor-text')), + cursor: React.lazy(() => import('react-bootstrap-icons/dist/icons/cursor')), + 'dash-circle-dotted': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-circle-dotted')), + 'dash-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-circle-fill')), + 'dash-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-circle')), + 'dash-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-lg')), + 'dash-square-dotted': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-square-dotted')), + 'dash-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-square-fill')), + 'dash-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/dash-square')), + dash: React.lazy(() => import('react-bootstrap-icons/dist/icons/dash')), + 'database-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-add')), + 'database-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-check')), + 'database-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-dash')), + 'database-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-down')), + 'database-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-exclamation')), + 'database-fill-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-add')), + 'database-fill-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-check')), + 'database-fill-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-dash')), + 'database-fill-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-down')), + 'database-fill-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-exclamation')), + 'database-fill-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-gear')), + 'database-fill-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-lock')), + 'database-fill-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-slash')), + 'database-fill-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-up')), + 'database-fill-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill-x')), + 'database-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-fill')), + 'database-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-gear')), + 'database-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-lock')), + 'database-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-slash')), + 'database-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-up')), + 'database-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/database-x')), + database: React.lazy(() => import('react-bootstrap-icons/dist/icons/database')), + 'device-hdd-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/device-hdd-fill')), + 'device-hdd': React.lazy(() => import('react-bootstrap-icons/dist/icons/device-hdd')), + 'device-ssd-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/device-ssd-fill')), + 'device-ssd': React.lazy(() => import('react-bootstrap-icons/dist/icons/device-ssd')), + 'diagram-2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/diagram-2-fill')), + 'diagram-2': React.lazy(() => import('react-bootstrap-icons/dist/icons/diagram-2')), + 'diagram-3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/diagram-3-fill')), + 'diagram-3': React.lazy(() => import('react-bootstrap-icons/dist/icons/diagram-3')), + 'diamond-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/diamond-fill')), + 'diamond-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/diamond-half')), + diamond: React.lazy(() => import('react-bootstrap-icons/dist/icons/diamond')), + 'dice-1-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-1-fill')), + 'dice-1': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-1')), + 'dice-2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-2-fill')), + 'dice-2': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-2')), + 'dice-3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-3-fill')), + 'dice-3': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-3')), + 'dice-4-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-4-fill')), + 'dice-4': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-4')), + 'dice-5-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-5-fill')), + 'dice-5': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-5')), + 'dice-6-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-6-fill')), + 'dice-6': React.lazy(() => import('react-bootstrap-icons/dist/icons/dice-6')), + 'disc-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/disc-fill')), + disc: React.lazy(() => import('react-bootstrap-icons/dist/icons/disc')), + discord: React.lazy(() => import('react-bootstrap-icons/dist/icons/discord')), + 'display-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/display-fill')), + display: React.lazy(() => import('react-bootstrap-icons/dist/icons/display')), + 'displayport-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/displayport-fill')), + displayport: React.lazy(() => import('react-bootstrap-icons/dist/icons/displayport')), + 'distribute-horizontal': React.lazy(() => import('react-bootstrap-icons/dist/icons/distribute-horizontal')), + 'distribute-vertical': React.lazy(() => import('react-bootstrap-icons/dist/icons/distribute-vertical')), + 'door-closed-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/door-closed-fill')), + 'door-closed': React.lazy(() => import('react-bootstrap-icons/dist/icons/door-closed')), + 'door-open-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/door-open-fill')), + 'door-open': React.lazy(() => import('react-bootstrap-icons/dist/icons/door-open')), + dot: React.lazy(() => import('react-bootstrap-icons/dist/icons/dot')), + download: React.lazy(() => import('react-bootstrap-icons/dist/icons/download')), + 'dpad-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/dpad-fill')), + dpad: React.lazy(() => import('react-bootstrap-icons/dist/icons/dpad')), + dribbble: React.lazy(() => import('react-bootstrap-icons/dist/icons/dribbble')), + dropbox: React.lazy(() => import('react-bootstrap-icons/dist/icons/dropbox')), + 'droplet-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/droplet-fill')), + 'droplet-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/droplet-half')), + droplet: React.lazy(() => import('react-bootstrap-icons/dist/icons/droplet')), + 'ear-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/ear-fill')), + ear: React.lazy(() => import('react-bootstrap-icons/dist/icons/ear')), + earbuds: React.lazy(() => import('react-bootstrap-icons/dist/icons/earbuds')), + 'easel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/easel-fill')), + easel: React.lazy(() => import('react-bootstrap-icons/dist/icons/easel')), + 'easel2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/easel2-fill')), + easel2: React.lazy(() => import('react-bootstrap-icons/dist/icons/easel2')), + 'easel3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/easel3-fill')), + easel3: React.lazy(() => import('react-bootstrap-icons/dist/icons/easel3')), + 'egg-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/egg-fill')), + 'egg-fried': React.lazy(() => import('react-bootstrap-icons/dist/icons/egg-fried')), + egg: React.lazy(() => import('react-bootstrap-icons/dist/icons/egg')), + 'eject-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/eject-fill')), + eject: React.lazy(() => import('react-bootstrap-icons/dist/icons/eject')), + 'emoji-angry-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-angry-fill')), + 'emoji-angry': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-angry')), + 'emoji-dizzy-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-dizzy-fill')), + 'emoji-dizzy': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-dizzy')), + 'emoji-expressionless-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-expressionless-fill')), + 'emoji-expressionless': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-expressionless')), + 'emoji-frown-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-frown-fill')), + 'emoji-frown': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-frown')), + 'emoji-heart-eyes-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-heart-eyes-fill')), + 'emoji-heart-eyes': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-heart-eyes')), + 'emoji-kiss-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-kiss-fill')), + 'emoji-kiss': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-kiss')), + 'emoji-laughing-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-laughing-fill')), + 'emoji-laughing': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-laughing')), + 'emoji-neutral-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-neutral-fill')), + 'emoji-neutral': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-neutral')), + 'emoji-smile-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-smile-fill')), + 'emoji-smile-upside-down-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/emoji-smile-upside-down-fill') + ), + 'emoji-smile-upside-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-smile-upside-down')), + 'emoji-smile': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-smile')), + 'emoji-sunglasses-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-sunglasses-fill')), + 'emoji-sunglasses': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-sunglasses')), + 'emoji-wink-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-wink-fill')), + 'emoji-wink': React.lazy(() => import('react-bootstrap-icons/dist/icons/emoji-wink')), + 'envelope-at-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-at-fill')), + 'envelope-at': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-at')), + 'envelope-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-check-fill')), + 'envelope-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-check')), + 'envelope-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-dash-fill')), + 'envelope-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-dash')), + 'envelope-exclamation-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-exclamation-fill')), + 'envelope-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-exclamation')), + 'envelope-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-fill')), + 'envelope-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-heart-fill')), + 'envelope-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-heart')), + 'envelope-open-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-open-fill')), + 'envelope-open-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-open-heart-fill')), + 'envelope-open-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-open-heart')), + 'envelope-open': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-open')), + 'envelope-paper-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-paper-fill')), + 'envelope-paper-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-paper-heart-fill')), + 'envelope-paper-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-paper-heart')), + 'envelope-paper': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-paper')), + 'envelope-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-plus-fill')), + 'envelope-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-plus')), + 'envelope-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-slash-fill')), + 'envelope-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-slash')), + 'envelope-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-x-fill')), + 'envelope-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope-x')), + envelope: React.lazy(() => import('react-bootstrap-icons/dist/icons/envelope')), + 'eraser-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/eraser-fill')), + eraser: React.lazy(() => import('react-bootstrap-icons/dist/icons/eraser')), + escape: React.lazy(() => import('react-bootstrap-icons/dist/icons/escape')), + ethernet: React.lazy(() => import('react-bootstrap-icons/dist/icons/ethernet')), + 'ev-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/ev-front-fill')), + 'ev-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/ev-front')), + 'ev-station-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/ev-station-fill')), + 'ev-station': React.lazy(() => import('react-bootstrap-icons/dist/icons/ev-station')), + 'exclamation-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-circle-fill')), + 'exclamation-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-circle')), + 'exclamation-diamond-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-diamond-fill')), + 'exclamation-diamond': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-diamond')), + 'exclamation-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-lg')), + 'exclamation-octagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-octagon-fill')), + 'exclamation-octagon': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-octagon')), + 'exclamation-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-square-fill')), + 'exclamation-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-square')), + 'exclamation-triangle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-triangle-fill')), + 'exclamation-triangle': React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation-triangle')), + exclamation: React.lazy(() => import('react-bootstrap-icons/dist/icons/exclamation')), + exclude: React.lazy(() => import('react-bootstrap-icons/dist/icons/exclude')), + 'explicit-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/explicit-fill')), + explicit: React.lazy(() => import('react-bootstrap-icons/dist/icons/explicit')), + 'eye-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/eye-fill')), + 'eye-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/eye-slash-fill')), + 'eye-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/eye-slash')), + eye: React.lazy(() => import('react-bootstrap-icons/dist/icons/eye')), + eyedropper: React.lazy(() => import('react-bootstrap-icons/dist/icons/eyedropper')), + eyeglasses: React.lazy(() => import('react-bootstrap-icons/dist/icons/eyeglasses')), + facebook: React.lazy(() => import('react-bootstrap-icons/dist/icons/facebook')), + fan: React.lazy(() => import('react-bootstrap-icons/dist/icons/fan')), + 'fast-forward-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/fast-forward-btn-fill')), + 'fast-forward-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/fast-forward-btn')), + 'fast-forward-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/fast-forward-circle-fill')), + 'fast-forward-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/fast-forward-circle')), + 'fast-forward-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/fast-forward-fill')), + 'fast-forward': React.lazy(() => import('react-bootstrap-icons/dist/icons/fast-forward')), + 'file-arrow-down-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-arrow-down-fill')), + 'file-arrow-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-arrow-down')), + 'file-arrow-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-arrow-up-fill')), + 'file-arrow-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-arrow-up')), + 'file-bar-graph-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-bar-graph-fill')), + 'file-bar-graph': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-bar-graph')), + 'file-binary-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-binary-fill')), + 'file-binary': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-binary')), + 'file-break-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-break-fill')), + 'file-break': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-break')), + 'file-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-check-fill')), + 'file-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-check')), + 'file-code-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-code-fill')), + 'file-code': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-code')), + 'file-diff-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-diff-fill')), + 'file-diff': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-diff')), + 'file-earmark-arrow-down-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/file-earmark-arrow-down-fill') + ), + 'file-earmark-arrow-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-arrow-down')), + 'file-earmark-arrow-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-arrow-up-fill')), + 'file-earmark-arrow-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-arrow-up')), + 'file-earmark-bar-graph-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/file-earmark-bar-graph-fill') + ), + 'file-earmark-bar-graph': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-bar-graph')), + 'file-earmark-binary-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-binary-fill')), + 'file-earmark-binary': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-binary')), + 'file-earmark-break-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-break-fill')), + 'file-earmark-break': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-break')), + 'file-earmark-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-check-fill')), + 'file-earmark-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-check')), + 'file-earmark-code-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-code-fill')), + 'file-earmark-code': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-code')), + 'file-earmark-diff-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-diff-fill')), + 'file-earmark-diff': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-diff')), + 'file-earmark-easel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-easel-fill')), + 'file-earmark-easel': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-easel')), + 'file-earmark-excel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-excel-fill')), + 'file-earmark-excel': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-excel')), + 'file-earmark-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-fill')), + 'file-earmark-font-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-font-fill')), + 'file-earmark-font': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-font')), + 'file-earmark-image-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-image-fill')), + 'file-earmark-image': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-image')), + 'file-earmark-lock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-lock-fill')), + 'file-earmark-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-lock')), + 'file-earmark-lock2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-lock2-fill')), + 'file-earmark-lock2': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-lock2')), + 'file-earmark-medical-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-medical-fill')), + 'file-earmark-medical': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-medical')), + 'file-earmark-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-minus-fill')), + 'file-earmark-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-minus')), + 'file-earmark-music-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-music-fill')), + 'file-earmark-music': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-music')), + 'file-earmark-pdf-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-pdf-fill')), + 'file-earmark-pdf': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-pdf')), + 'file-earmark-person-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-person-fill')), + 'file-earmark-person': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-person')), + 'file-earmark-play-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-play-fill')), + 'file-earmark-play': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-play')), + 'file-earmark-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-plus-fill')), + 'file-earmark-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-plus')), + 'file-earmark-post-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-post-fill')), + 'file-earmark-post': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-post')), + 'file-earmark-ppt-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-ppt-fill')), + 'file-earmark-ppt': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-ppt')), + 'file-earmark-richtext-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-richtext-fill')), + 'file-earmark-richtext': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-richtext')), + 'file-earmark-ruled-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-ruled-fill')), + 'file-earmark-ruled': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-ruled')), + 'file-earmark-slides-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-slides-fill')), + 'file-earmark-slides': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-slides')), + 'file-earmark-spreadsheet-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/file-earmark-spreadsheet-fill') + ), + 'file-earmark-spreadsheet': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-spreadsheet')), + 'file-earmark-text-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-text-fill')), + 'file-earmark-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-text')), + 'file-earmark-word-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-word-fill')), + 'file-earmark-word': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-word')), + 'file-earmark-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-x-fill')), + 'file-earmark-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-x')), + 'file-earmark-zip-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-zip-fill')), + 'file-earmark-zip': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark-zip')), + 'file-earmark': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-earmark')), + 'file-easel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-easel-fill')), + 'file-easel': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-easel')), + 'file-excel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-excel-fill')), + 'file-excel': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-excel')), + 'file-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-fill')), + 'file-font-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-font-fill')), + 'file-font': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-font')), + 'file-image-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-image-fill')), + 'file-image': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-image')), + 'file-lock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-lock-fill')), + 'file-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-lock')), + 'file-lock2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-lock2-fill')), + 'file-lock2': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-lock2')), + 'file-medical-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-medical-fill')), + 'file-medical': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-medical')), + 'file-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-minus-fill')), + 'file-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-minus')), + 'file-music-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-music-fill')), + 'file-music': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-music')), + 'file-pdf-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-pdf-fill')), + 'file-pdf': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-pdf')), + 'file-person-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-person-fill')), + 'file-person': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-person')), + 'file-play-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-play-fill')), + 'file-play': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-play')), + 'file-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-plus-fill')), + 'file-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-plus')), + 'file-post-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-post-fill')), + 'file-post': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-post')), + 'file-ppt-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-ppt-fill')), + 'file-ppt': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-ppt')), + 'file-richtext-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-richtext-fill')), + 'file-richtext': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-richtext')), + 'file-ruled-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-ruled-fill')), + 'file-ruled': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-ruled')), + 'file-slides-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-slides-fill')), + 'file-slides': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-slides')), + 'file-spreadsheet-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-spreadsheet-fill')), + 'file-spreadsheet': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-spreadsheet')), + 'file-text-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-text-fill')), + 'file-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-text')), + 'file-word-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-word-fill')), + 'file-word': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-word')), + 'file-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-x-fill')), + 'file-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-x')), + 'file-zip-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-zip-fill')), + 'file-zip': React.lazy(() => import('react-bootstrap-icons/dist/icons/file-zip')), + file: React.lazy(() => import('react-bootstrap-icons/dist/icons/file')), + 'files-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/files-alt')), + files: React.lazy(() => import('react-bootstrap-icons/dist/icons/files')), + 'filetype-aac': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-aac')), + 'filetype-ai': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-ai')), + 'filetype-bmp': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-bmp')), + 'filetype-cs': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-cs')), + 'filetype-css': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-css')), + 'filetype-csv': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-csv')), + 'filetype-doc': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-doc')), + 'filetype-docx': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-docx')), + 'filetype-exe': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-exe')), + 'filetype-gif': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-gif')), + 'filetype-heic': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-heic')), + 'filetype-html': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-html')), + 'filetype-java': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-java')), + 'filetype-jpg': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-jpg')), + 'filetype-js': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-js')), + 'filetype-json': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-json')), + 'filetype-jsx': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-jsx')), + 'filetype-key': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-key')), + 'filetype-m4p': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-m4p')), + 'filetype-md': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-md')), + 'filetype-mdx': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-mdx')), + 'filetype-mov': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-mov')), + 'filetype-mp3': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-mp3')), + 'filetype-mp4': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-mp4')), + 'filetype-otf': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-otf')), + 'filetype-pdf': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-pdf')), + 'filetype-php': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-php')), + 'filetype-png': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-png')), + 'filetype-ppt': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-ppt')), + 'filetype-pptx': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-pptx')), + 'filetype-psd': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-psd')), + 'filetype-py': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-py')), + 'filetype-raw': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-raw')), + 'filetype-rb': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-rb')), + 'filetype-sass': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-sass')), + 'filetype-scss': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-scss')), + 'filetype-sh': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-sh')), + 'filetype-sql': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-sql')), + 'filetype-svg': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-svg')), + 'filetype-tiff': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-tiff')), + 'filetype-tsx': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-tsx')), + 'filetype-ttf': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-ttf')), + 'filetype-txt': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-txt')), + 'filetype-wav': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-wav')), + 'filetype-woff': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-woff')), + 'filetype-xls': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-xls')), + 'filetype-xlsx': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-xlsx')), + 'filetype-xml': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-xml')), + 'filetype-yml': React.lazy(() => import('react-bootstrap-icons/dist/icons/filetype-yml')), + film: React.lazy(() => import('react-bootstrap-icons/dist/icons/film')), + 'filter-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/filter-circle-fill')), + 'filter-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/filter-circle')), + 'filter-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/filter-left')), + 'filter-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/filter-right')), + 'filter-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/filter-square-fill')), + 'filter-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/filter-square')), + filter: React.lazy(() => import('react-bootstrap-icons/dist/icons/filter')), + fingerprint: React.lazy(() => import('react-bootstrap-icons/dist/icons/fingerprint')), + fire: React.lazy(() => import('react-bootstrap-icons/dist/icons/fire')), + 'flag-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/flag-fill')), + flag: React.lazy(() => import('react-bootstrap-icons/dist/icons/flag')), + flower1: React.lazy(() => import('react-bootstrap-icons/dist/icons/flower1')), + flower2: React.lazy(() => import('react-bootstrap-icons/dist/icons/flower2')), + flower3: React.lazy(() => import('react-bootstrap-icons/dist/icons/flower3')), + 'folder-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-check')), + 'folder-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-fill')), + 'folder-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-minus')), + 'folder-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-plus')), + 'folder-symlink-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-symlink-fill')), + 'folder-symlink': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-symlink')), + 'folder-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder-x')), + folder: React.lazy(() => import('react-bootstrap-icons/dist/icons/folder')), + 'folder2-open': React.lazy(() => import('react-bootstrap-icons/dist/icons/folder2-open')), + folder2: React.lazy(() => import('react-bootstrap-icons/dist/icons/folder2')), + fonts: React.lazy(() => import('react-bootstrap-icons/dist/icons/fonts')), + 'forward-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/forward-fill')), + forward: React.lazy(() => import('react-bootstrap-icons/dist/icons/forward')), + front: React.lazy(() => import('react-bootstrap-icons/dist/icons/front')), + 'fuel-pump-diesel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/fuel-pump-diesel-fill')), + 'fuel-pump-diesel': React.lazy(() => import('react-bootstrap-icons/dist/icons/fuel-pump-diesel')), + 'fuel-pump-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/fuel-pump-fill')), + 'fuel-pump': React.lazy(() => import('react-bootstrap-icons/dist/icons/fuel-pump')), + 'fullscreen-exit': React.lazy(() => import('react-bootstrap-icons/dist/icons/fullscreen-exit')), + fullscreen: React.lazy(() => import('react-bootstrap-icons/dist/icons/fullscreen')), + 'funnel-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/funnel-fill')), + funnel: React.lazy(() => import('react-bootstrap-icons/dist/icons/funnel')), + 'gear-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/gear-fill')), + 'gear-wide-connected': React.lazy(() => import('react-bootstrap-icons/dist/icons/gear-wide-connected')), + 'gear-wide': React.lazy(() => import('react-bootstrap-icons/dist/icons/gear-wide')), + gear: React.lazy(() => import('react-bootstrap-icons/dist/icons/gear')), + gem: React.lazy(() => import('react-bootstrap-icons/dist/icons/gem')), + 'gender-ambiguous': React.lazy(() => import('react-bootstrap-icons/dist/icons/gender-ambiguous')), + 'gender-female': React.lazy(() => import('react-bootstrap-icons/dist/icons/gender-female')), + 'gender-male': React.lazy(() => import('react-bootstrap-icons/dist/icons/gender-male')), + 'gender-trans': React.lazy(() => import('react-bootstrap-icons/dist/icons/gender-trans')), + 'geo-alt-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/geo-alt-fill')), + 'geo-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/geo-alt')), + 'geo-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/geo-fill')), + geo: React.lazy(() => import('react-bootstrap-icons/dist/icons/geo')), + 'gift-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/gift-fill')), + gift: React.lazy(() => import('react-bootstrap-icons/dist/icons/gift')), + git: React.lazy(() => import('react-bootstrap-icons/dist/icons/git')), + github: React.lazy(() => import('react-bootstrap-icons/dist/icons/github')), + 'globe-americas': React.lazy(() => import('react-bootstrap-icons/dist/icons/globe-americas')), + 'globe-asia-australia': React.lazy(() => import('react-bootstrap-icons/dist/icons/globe-asia-australia')), + 'globe-central-south-asia': React.lazy(() => import('react-bootstrap-icons/dist/icons/globe-central-south-asia')), + 'globe-europe-africa': React.lazy(() => import('react-bootstrap-icons/dist/icons/globe-europe-africa')), + globe: React.lazy(() => import('react-bootstrap-icons/dist/icons/globe')), + globe2: React.lazy(() => import('react-bootstrap-icons/dist/icons/globe2')), + 'google-play': React.lazy(() => import('react-bootstrap-icons/dist/icons/google-play')), + google: React.lazy(() => import('react-bootstrap-icons/dist/icons/google')), + 'gpu-card': React.lazy(() => import('react-bootstrap-icons/dist/icons/gpu-card')), + 'graph-down-arrow': React.lazy(() => import('react-bootstrap-icons/dist/icons/graph-down-arrow')), + 'graph-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/graph-down')), + 'graph-up-arrow': React.lazy(() => import('react-bootstrap-icons/dist/icons/graph-up-arrow')), + 'graph-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/graph-up')), + 'grid-1x2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-1x2-fill')), + 'grid-1x2': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-1x2')), + 'grid-3x2-gap-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-3x2-gap-fill')), + 'grid-3x2-gap': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-3x2-gap')), + 'grid-3x2': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-3x2')), + 'grid-3x3-gap-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-3x3-gap-fill')), + 'grid-3x3-gap': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-3x3-gap')), + 'grid-3x3': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-3x3')), + 'grid-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/grid-fill')), + grid: React.lazy(() => import('react-bootstrap-icons/dist/icons/grid')), + 'grip-horizontal': React.lazy(() => import('react-bootstrap-icons/dist/icons/grip-horizontal')), + 'grip-vertical': React.lazy(() => import('react-bootstrap-icons/dist/icons/grip-vertical')), + 'h-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/h-circle-fill')), + 'h-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/h-circle')), + 'h-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/h-square-fill')), + 'h-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/h-square')), + hammer: React.lazy(() => import('react-bootstrap-icons/dist/icons/hammer')), + 'hand-index-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-index-fill')), + 'hand-index-thumb-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-index-thumb-fill')), + 'hand-index-thumb': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-index-thumb')), + 'hand-index': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-index')), + 'hand-thumbs-down-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-thumbs-down-fill')), + 'hand-thumbs-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-thumbs-down')), + 'hand-thumbs-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-thumbs-up-fill')), + 'hand-thumbs-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/hand-thumbs-up')), + 'handbag-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/handbag-fill')), + handbag: React.lazy(() => import('react-bootstrap-icons/dist/icons/handbag')), + hash: React.lazy(() => import('react-bootstrap-icons/dist/icons/hash')), + 'hdd-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-fill')), + 'hdd-network-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-network-fill')), + 'hdd-network': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-network')), + 'hdd-rack-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-rack-fill')), + 'hdd-rack': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-rack')), + 'hdd-stack-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-stack-fill')), + 'hdd-stack': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd-stack')), + hdd: React.lazy(() => import('react-bootstrap-icons/dist/icons/hdd')), + 'hdmi-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hdmi-fill')), + hdmi: React.lazy(() => import('react-bootstrap-icons/dist/icons/hdmi')), + headphones: React.lazy(() => import('react-bootstrap-icons/dist/icons/headphones')), + 'headset-vr': React.lazy(() => import('react-bootstrap-icons/dist/icons/headset-vr')), + headset: React.lazy(() => import('react-bootstrap-icons/dist/icons/headset')), + 'heart-arrow': React.lazy(() => import('react-bootstrap-icons/dist/icons/heart-arrow')), + 'heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/heart-fill')), + 'heart-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/heart-half')), + 'heart-pulse-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/heart-pulse-fill')), + 'heart-pulse': React.lazy(() => import('react-bootstrap-icons/dist/icons/heart-pulse')), + heart: React.lazy(() => import('react-bootstrap-icons/dist/icons/heart')), + 'heartbreak-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/heartbreak-fill')), + heartbreak: React.lazy(() => import('react-bootstrap-icons/dist/icons/heartbreak')), + hearts: React.lazy(() => import('react-bootstrap-icons/dist/icons/hearts')), + 'heptagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/heptagon-fill')), + 'heptagon-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/heptagon-half')), + heptagon: React.lazy(() => import('react-bootstrap-icons/dist/icons/heptagon')), + 'hexagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hexagon-fill')), + 'hexagon-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/hexagon-half')), + hexagon: React.lazy(() => import('react-bootstrap-icons/dist/icons/hexagon')), + 'hospital-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/hospital-fill')), + hospital: React.lazy(() => import('react-bootstrap-icons/dist/icons/hospital')), + 'hourglass-bottom': React.lazy(() => import('react-bootstrap-icons/dist/icons/hourglass-bottom')), + 'hourglass-split': React.lazy(() => import('react-bootstrap-icons/dist/icons/hourglass-split')), + 'hourglass-top': React.lazy(() => import('react-bootstrap-icons/dist/icons/hourglass-top')), + hourglass: React.lazy(() => import('react-bootstrap-icons/dist/icons/hourglass')), + 'house-add-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-add-fill')), + 'house-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-add')), + 'house-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-check-fill')), + 'house-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-check')), + 'house-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-dash-fill')), + 'house-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-dash')), + 'house-door-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-door-fill')), + 'house-door': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-door')), + 'house-down-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-down-fill')), + 'house-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-down')), + 'house-exclamation-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-exclamation-fill')), + 'house-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-exclamation')), + 'house-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-fill')), + 'house-gear-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-gear-fill')), + 'house-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-gear')), + 'house-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-heart-fill')), + 'house-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-heart')), + 'house-lock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-lock-fill')), + 'house-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-lock')), + 'house-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-slash-fill')), + 'house-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-slash')), + 'house-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-up-fill')), + 'house-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-up')), + 'house-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-x-fill')), + 'house-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/house-x')), + house: React.lazy(() => import('react-bootstrap-icons/dist/icons/house')), + 'houses-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/houses-fill')), + houses: React.lazy(() => import('react-bootstrap-icons/dist/icons/houses')), + hr: React.lazy(() => import('react-bootstrap-icons/dist/icons/hr')), + hurricane: React.lazy(() => import('react-bootstrap-icons/dist/icons/hurricane')), + hypnotize: React.lazy(() => import('react-bootstrap-icons/dist/icons/hypnotize')), + 'image-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/image-alt')), + 'image-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/image-fill')), + image: React.lazy(() => import('react-bootstrap-icons/dist/icons/image')), + images: React.lazy(() => import('react-bootstrap-icons/dist/icons/images')), + 'inbox-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/inbox-fill')), + inbox: React.lazy(() => import('react-bootstrap-icons/dist/icons/inbox')), + 'inboxes-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/inboxes-fill')), + inboxes: React.lazy(() => import('react-bootstrap-icons/dist/icons/inboxes')), + incognito: React.lazy(() => import('react-bootstrap-icons/dist/icons/incognito')), + indent: React.lazy(() => import('react-bootstrap-icons/dist/icons/indent')), + infinity: React.lazy(() => import('react-bootstrap-icons/dist/icons/infinity')), + 'info-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/info-circle-fill')), + 'info-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/info-circle')), + 'info-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/info-lg')), + 'info-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/info-square-fill')), + 'info-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/info-square')), + info: React.lazy(() => import('react-bootstrap-icons/dist/icons/info')), + 'input-cursor-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/input-cursor-text')), + 'input-cursor': React.lazy(() => import('react-bootstrap-icons/dist/icons/input-cursor')), + instagram: React.lazy(() => import('react-bootstrap-icons/dist/icons/instagram')), + intersect: React.lazy(() => import('react-bootstrap-icons/dist/icons/intersect')), + 'journal-album': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-album')), + 'journal-arrow-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-arrow-down')), + 'journal-arrow-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-arrow-up')), + 'journal-bookmark-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-bookmark-fill')), + 'journal-bookmark': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-bookmark')), + 'journal-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-check')), + 'journal-code': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-code')), + 'journal-medical': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-medical')), + 'journal-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-minus')), + 'journal-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-plus')), + 'journal-richtext': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-richtext')), + 'journal-text': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-text')), + 'journal-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/journal-x')), + journal: React.lazy(() => import('react-bootstrap-icons/dist/icons/journal')), + journals: React.lazy(() => import('react-bootstrap-icons/dist/icons/journals')), + joystick: React.lazy(() => import('react-bootstrap-icons/dist/icons/joystick')), + 'justify-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/justify-left')), + 'justify-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/justify-right')), + justify: React.lazy(() => import('react-bootstrap-icons/dist/icons/justify')), + 'kanban-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/kanban-fill')), + kanban: React.lazy(() => import('react-bootstrap-icons/dist/icons/kanban')), + 'key-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/key-fill')), + key: React.lazy(() => import('react-bootstrap-icons/dist/icons/key')), + 'keyboard-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/keyboard-fill')), + keyboard: React.lazy(() => import('react-bootstrap-icons/dist/icons/keyboard')), + ladder: React.lazy(() => import('react-bootstrap-icons/dist/icons/ladder')), + 'lamp-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lamp-fill')), + lamp: React.lazy(() => import('react-bootstrap-icons/dist/icons/lamp')), + 'laptop-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/laptop-fill')), + laptop: React.lazy(() => import('react-bootstrap-icons/dist/icons/laptop')), + 'layer-backward': React.lazy(() => import('react-bootstrap-icons/dist/icons/layer-backward')), + 'layer-forward': React.lazy(() => import('react-bootstrap-icons/dist/icons/layer-forward')), + 'layers-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/layers-fill')), + 'layers-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/layers-half')), + layers: React.lazy(() => import('react-bootstrap-icons/dist/icons/layers')), + 'layout-sidebar-inset-reverse': React.lazy( + () => import('react-bootstrap-icons/dist/icons/layout-sidebar-inset-reverse') + ), + 'layout-sidebar-inset': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-sidebar-inset')), + 'layout-sidebar-reverse': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-sidebar-reverse')), + 'layout-sidebar': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-sidebar')), + 'layout-split': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-split')), + 'layout-text-sidebar-reverse': React.lazy( + () => import('react-bootstrap-icons/dist/icons/layout-text-sidebar-reverse') + ), + 'layout-text-sidebar': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-text-sidebar')), + 'layout-text-window-reverse': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-text-window-reverse')), + 'layout-text-window': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-text-window')), + 'layout-three-columns': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-three-columns')), + 'layout-wtf': React.lazy(() => import('react-bootstrap-icons/dist/icons/layout-wtf')), + 'life-preserver': React.lazy(() => import('react-bootstrap-icons/dist/icons/life-preserver')), + 'lightbulb-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lightbulb-fill')), + 'lightbulb-off-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lightbulb-off-fill')), + 'lightbulb-off': React.lazy(() => import('react-bootstrap-icons/dist/icons/lightbulb-off')), + lightbulb: React.lazy(() => import('react-bootstrap-icons/dist/icons/lightbulb')), + 'lightning-charge-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lightning-charge-fill')), + 'lightning-charge': React.lazy(() => import('react-bootstrap-icons/dist/icons/lightning-charge')), + 'lightning-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lightning-fill')), + lightning: React.lazy(() => import('react-bootstrap-icons/dist/icons/lightning')), + line: React.lazy(() => import('react-bootstrap-icons/dist/icons/line')), + 'link-45deg': React.lazy(() => import('react-bootstrap-icons/dist/icons/link-45deg')), + link: React.lazy(() => import('react-bootstrap-icons/dist/icons/link')), + linkedin: React.lazy(() => import('react-bootstrap-icons/dist/icons/linkedin')), + 'list-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-check')), + 'list-columns-reverse': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-columns-reverse')), + 'list-columns': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-columns')), + 'list-nested': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-nested')), + 'list-ol': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-ol')), + 'list-stars': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-stars')), + 'list-task': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-task')), + 'list-ul': React.lazy(() => import('react-bootstrap-icons/dist/icons/list-ul')), + list: React.lazy(() => import('react-bootstrap-icons/dist/icons/list')), + 'lock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lock-fill')), + lock: React.lazy(() => import('react-bootstrap-icons/dist/icons/lock')), + 'lungs-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/lungs-fill')), + lungs: React.lazy(() => import('react-bootstrap-icons/dist/icons/lungs')), + magic: React.lazy(() => import('react-bootstrap-icons/dist/icons/magic')), + 'magnet-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/magnet-fill')), + magnet: React.lazy(() => import('react-bootstrap-icons/dist/icons/magnet')), + mailbox: React.lazy(() => import('react-bootstrap-icons/dist/icons/mailbox')), + mailbox2: React.lazy(() => import('react-bootstrap-icons/dist/icons/mailbox2')), + 'map-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/map-fill')), + map: React.lazy(() => import('react-bootstrap-icons/dist/icons/map')), + 'markdown-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/markdown-fill')), + markdown: React.lazy(() => import('react-bootstrap-icons/dist/icons/markdown')), + mask: React.lazy(() => import('react-bootstrap-icons/dist/icons/mask')), + mastodon: React.lazy(() => import('react-bootstrap-icons/dist/icons/mastodon')), + medium: React.lazy(() => import('react-bootstrap-icons/dist/icons/medium')), + 'megaphone-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/megaphone-fill')), + megaphone: React.lazy(() => import('react-bootstrap-icons/dist/icons/megaphone')), + memory: React.lazy(() => import('react-bootstrap-icons/dist/icons/memory')), + 'menu-app-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-app-fill')), + 'menu-app': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-app')), + 'menu-button-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-button-fill')), + 'menu-button-wide-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-button-wide-fill')), + 'menu-button-wide': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-button-wide')), + 'menu-button': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-button')), + 'menu-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-down')), + 'menu-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/menu-up')), + messenger: React.lazy(() => import('react-bootstrap-icons/dist/icons/messenger')), + meta: React.lazy(() => import('react-bootstrap-icons/dist/icons/meta')), + 'mic-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/mic-fill')), + 'mic-mute-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/mic-mute-fill')), + 'mic-mute': React.lazy(() => import('react-bootstrap-icons/dist/icons/mic-mute')), + mic: React.lazy(() => import('react-bootstrap-icons/dist/icons/mic')), + 'microsoft-teams': React.lazy(() => import('react-bootstrap-icons/dist/icons/microsoft-teams')), + microsoft: React.lazy(() => import('react-bootstrap-icons/dist/icons/microsoft')), + 'minecart-loaded': React.lazy(() => import('react-bootstrap-icons/dist/icons/minecart-loaded')), + minecart: React.lazy(() => import('react-bootstrap-icons/dist/icons/minecart')), + 'modem-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/modem-fill')), + modem: React.lazy(() => import('react-bootstrap-icons/dist/icons/modem')), + moisture: React.lazy(() => import('react-bootstrap-icons/dist/icons/moisture')), + 'moon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/moon-fill')), + 'moon-stars-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/moon-stars-fill')), + 'moon-stars': React.lazy(() => import('react-bootstrap-icons/dist/icons/moon-stars')), + moon: React.lazy(() => import('react-bootstrap-icons/dist/icons/moon')), + 'mortarboard-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/mortarboard-fill')), + mortarboard: React.lazy(() => import('react-bootstrap-icons/dist/icons/mortarboard')), + 'motherboard-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/motherboard-fill')), + motherboard: React.lazy(() => import('react-bootstrap-icons/dist/icons/motherboard')), + 'mouse-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/mouse-fill')), + mouse: React.lazy(() => import('react-bootstrap-icons/dist/icons/mouse')), + 'mouse2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/mouse2-fill')), + mouse2: React.lazy(() => import('react-bootstrap-icons/dist/icons/mouse2')), + 'mouse3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/mouse3-fill')), + mouse3: React.lazy(() => import('react-bootstrap-icons/dist/icons/mouse3')), + 'music-note-beamed': React.lazy(() => import('react-bootstrap-icons/dist/icons/music-note-beamed')), + 'music-note-list': React.lazy(() => import('react-bootstrap-icons/dist/icons/music-note-list')), + 'music-note': React.lazy(() => import('react-bootstrap-icons/dist/icons/music-note')), + 'music-player-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/music-player-fill')), + 'music-player': React.lazy(() => import('react-bootstrap-icons/dist/icons/music-player')), + newspaper: React.lazy(() => import('react-bootstrap-icons/dist/icons/newspaper')), + 'nintendo-switch': React.lazy(() => import('react-bootstrap-icons/dist/icons/nintendo-switch')), + 'node-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/node-minus-fill')), + 'node-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/node-minus')), + 'node-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/node-plus-fill')), + 'node-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/node-plus')), + 'nut-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/nut-fill')), + nut: React.lazy(() => import('react-bootstrap-icons/dist/icons/nut')), + nvidia: React.lazy(() => import('react-bootstrap-icons/dist/icons/nvidia')), + 'octagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/octagon-fill')), + 'octagon-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/octagon-half')), + octagon: React.lazy(() => import('react-bootstrap-icons/dist/icons/octagon')), + 'optical-audio-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/optical-audio-fill')), + 'optical-audio': React.lazy(() => import('react-bootstrap-icons/dist/icons/optical-audio')), + option: React.lazy(() => import('react-bootstrap-icons/dist/icons/option')), + outlet: React.lazy(() => import('react-bootstrap-icons/dist/icons/outlet')), + 'p-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/p-circle-fill')), + 'p-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/p-circle')), + 'p-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/p-square-fill')), + 'p-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/p-square')), + 'paint-bucket': React.lazy(() => import('react-bootstrap-icons/dist/icons/paint-bucket')), + 'palette-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/palette-fill')), + palette: React.lazy(() => import('react-bootstrap-icons/dist/icons/palette')), + palette2: React.lazy(() => import('react-bootstrap-icons/dist/icons/palette2')), + paperclip: React.lazy(() => import('react-bootstrap-icons/dist/icons/paperclip')), + paragraph: React.lazy(() => import('react-bootstrap-icons/dist/icons/paragraph')), + 'pass-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pass-fill')), + pass: React.lazy(() => import('react-bootstrap-icons/dist/icons/pass')), + 'patch-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-check-fill')), + 'patch-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-check')), + 'patch-exclamation-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-exclamation-fill')), + 'patch-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-exclamation')), + 'patch-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-minus-fill')), + 'patch-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-minus')), + 'patch-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-plus-fill')), + 'patch-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-plus')), + 'patch-question-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-question-fill')), + 'patch-question': React.lazy(() => import('react-bootstrap-icons/dist/icons/patch-question')), + 'pause-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pause-btn-fill')), + 'pause-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/pause-btn')), + 'pause-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pause-circle-fill')), + 'pause-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/pause-circle')), + 'pause-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pause-fill')), + pause: React.lazy(() => import('react-bootstrap-icons/dist/icons/pause')), + paypal: React.lazy(() => import('react-bootstrap-icons/dist/icons/paypal')), + 'pc-display-horizontal': React.lazy(() => import('react-bootstrap-icons/dist/icons/pc-display-horizontal')), + 'pc-display': React.lazy(() => import('react-bootstrap-icons/dist/icons/pc-display')), + 'pc-horizontal': React.lazy(() => import('react-bootstrap-icons/dist/icons/pc-horizontal')), + pc: React.lazy(() => import('react-bootstrap-icons/dist/icons/pc')), + 'pci-card': React.lazy(() => import('react-bootstrap-icons/dist/icons/pci-card')), + 'peace-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/peace-fill')), + peace: React.lazy(() => import('react-bootstrap-icons/dist/icons/peace')), + 'pen-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pen-fill')), + pen: React.lazy(() => import('react-bootstrap-icons/dist/icons/pen')), + 'pencil-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pencil-fill')), + 'pencil-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/pencil-square')), + pencil: React.lazy(() => import('react-bootstrap-icons/dist/icons/pencil')), + 'pentagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pentagon-fill')), + 'pentagon-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/pentagon-half')), + pentagon: React.lazy(() => import('react-bootstrap-icons/dist/icons/pentagon')), + 'people-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/people-fill')), + people: React.lazy(() => import('react-bootstrap-icons/dist/icons/people')), + percent: React.lazy(() => import('react-bootstrap-icons/dist/icons/percent')), + 'person-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-add')), + 'person-badge-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-badge-fill')), + 'person-badge': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-badge')), + 'person-bounding-box': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-bounding-box')), + 'person-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-check-fill')), + 'person-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-check')), + 'person-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-circle')), + 'person-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-dash-fill')), + 'person-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-dash')), + 'person-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-down')), + 'person-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-exclamation')), + 'person-fill-add': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-add')), + 'person-fill-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-check')), + 'person-fill-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-dash')), + 'person-fill-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-down')), + 'person-fill-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-exclamation')), + 'person-fill-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-gear')), + 'person-fill-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-lock')), + 'person-fill-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-slash')), + 'person-fill-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-up')), + 'person-fill-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill-x')), + 'person-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-fill')), + 'person-gear': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-gear')), + 'person-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-heart')), + 'person-hearts': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-hearts')), + 'person-lines-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-lines-fill')), + 'person-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-lock')), + 'person-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-plus-fill')), + 'person-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-plus')), + 'person-rolodex': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-rolodex')), + 'person-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-slash')), + 'person-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-square')), + 'person-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-up')), + 'person-vcard-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-vcard-fill')), + 'person-vcard': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-vcard')), + 'person-video': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-video')), + 'person-video2': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-video2')), + 'person-video3': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-video3')), + 'person-workspace': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-workspace')), + 'person-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-x-fill')), + 'person-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/person-x')), + person: React.lazy(() => import('react-bootstrap-icons/dist/icons/person')), + 'phone-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/phone-fill')), + 'phone-flip': React.lazy(() => import('react-bootstrap-icons/dist/icons/phone-flip')), + 'phone-landscape-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/phone-landscape-fill')), + 'phone-landscape': React.lazy(() => import('react-bootstrap-icons/dist/icons/phone-landscape')), + 'phone-vibrate-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/phone-vibrate-fill')), + 'phone-vibrate': React.lazy(() => import('react-bootstrap-icons/dist/icons/phone-vibrate')), + phone: React.lazy(() => import('react-bootstrap-icons/dist/icons/phone')), + 'pie-chart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pie-chart-fill')), + 'pie-chart': React.lazy(() => import('react-bootstrap-icons/dist/icons/pie-chart')), + 'piggy-bank-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/piggy-bank-fill')), + 'piggy-bank': React.lazy(() => import('react-bootstrap-icons/dist/icons/piggy-bank')), + 'pin-angle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pin-angle-fill')), + 'pin-angle': React.lazy(() => import('react-bootstrap-icons/dist/icons/pin-angle')), + 'pin-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pin-fill')), + 'pin-map-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pin-map-fill')), + 'pin-map': React.lazy(() => import('react-bootstrap-icons/dist/icons/pin-map')), + pin: React.lazy(() => import('react-bootstrap-icons/dist/icons/pin')), + pinterest: React.lazy(() => import('react-bootstrap-icons/dist/icons/pinterest')), + 'pip-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/pip-fill')), + pip: React.lazy(() => import('react-bootstrap-icons/dist/icons/pip')), + 'play-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/play-btn-fill')), + 'play-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/play-btn')), + 'play-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/play-circle-fill')), + 'play-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/play-circle')), + 'play-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/play-fill')), + play: React.lazy(() => import('react-bootstrap-icons/dist/icons/play')), + playstation: React.lazy(() => import('react-bootstrap-icons/dist/icons/playstation')), + 'plug-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/plug-fill')), + plug: React.lazy(() => import('react-bootstrap-icons/dist/icons/plug')), + plugin: React.lazy(() => import('react-bootstrap-icons/dist/icons/plugin')), + 'plus-circle-dotted': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-circle-dotted')), + 'plus-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-circle-fill')), + 'plus-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-circle')), + 'plus-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-lg')), + 'plus-slash-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-slash-minus')), + 'plus-square-dotted': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-square-dotted')), + 'plus-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-square-fill')), + 'plus-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/plus-square')), + plus: React.lazy(() => import('react-bootstrap-icons/dist/icons/plus')), + 'postage-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/postage-fill')), + 'postage-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/postage-heart-fill')), + 'postage-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/postage-heart')), + postage: React.lazy(() => import('react-bootstrap-icons/dist/icons/postage')), + 'postcard-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/postcard-fill')), + 'postcard-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/postcard-heart-fill')), + 'postcard-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/postcard-heart')), + postcard: React.lazy(() => import('react-bootstrap-icons/dist/icons/postcard')), + power: React.lazy(() => import('react-bootstrap-icons/dist/icons/power')), + prescription: React.lazy(() => import('react-bootstrap-icons/dist/icons/prescription')), + prescription2: React.lazy(() => import('react-bootstrap-icons/dist/icons/prescription2')), + 'printer-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/printer-fill')), + printer: React.lazy(() => import('react-bootstrap-icons/dist/icons/printer')), + 'projector-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/projector-fill')), + projector: React.lazy(() => import('react-bootstrap-icons/dist/icons/projector')), + 'puzzle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/puzzle-fill')), + puzzle: React.lazy(() => import('react-bootstrap-icons/dist/icons/puzzle')), + 'qr-code-scan': React.lazy(() => import('react-bootstrap-icons/dist/icons/qr-code-scan')), + 'qr-code': React.lazy(() => import('react-bootstrap-icons/dist/icons/qr-code')), + 'question-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-circle-fill')), + 'question-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-circle')), + 'question-diamond-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-diamond-fill')), + 'question-diamond': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-diamond')), + 'question-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-lg')), + 'question-octagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-octagon-fill')), + 'question-octagon': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-octagon')), + 'question-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-square-fill')), + 'question-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/question-square')), + question: React.lazy(() => import('react-bootstrap-icons/dist/icons/question')), + quora: React.lazy(() => import('react-bootstrap-icons/dist/icons/quora')), + quote: React.lazy(() => import('react-bootstrap-icons/dist/icons/quote')), + 'r-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/r-circle-fill')), + 'r-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/r-circle')), + 'r-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/r-square-fill')), + 'r-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/r-square')), + radioactive: React.lazy(() => import('react-bootstrap-icons/dist/icons/radioactive')), + rainbow: React.lazy(() => import('react-bootstrap-icons/dist/icons/rainbow')), + 'receipt-cutoff': React.lazy(() => import('react-bootstrap-icons/dist/icons/receipt-cutoff')), + receipt: React.lazy(() => import('react-bootstrap-icons/dist/icons/receipt')), + 'reception-0': React.lazy(() => import('react-bootstrap-icons/dist/icons/reception-0')), + 'reception-1': React.lazy(() => import('react-bootstrap-icons/dist/icons/reception-1')), + 'reception-2': React.lazy(() => import('react-bootstrap-icons/dist/icons/reception-2')), + 'reception-3': React.lazy(() => import('react-bootstrap-icons/dist/icons/reception-3')), + 'reception-4': React.lazy(() => import('react-bootstrap-icons/dist/icons/reception-4')), + 'record-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/record-btn-fill')), + 'record-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/record-btn')), + 'record-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/record-circle-fill')), + 'record-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/record-circle')), + 'record-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/record-fill')), + record: React.lazy(() => import('react-bootstrap-icons/dist/icons/record')), + 'record2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/record2-fill')), + record2: React.lazy(() => import('react-bootstrap-icons/dist/icons/record2')), + recycle: React.lazy(() => import('react-bootstrap-icons/dist/icons/recycle')), + reddit: React.lazy(() => import('react-bootstrap-icons/dist/icons/reddit')), + regex: React.lazy(() => import('react-bootstrap-icons/dist/icons/regex')), + 'repeat-1': React.lazy(() => import('react-bootstrap-icons/dist/icons/repeat-1')), + repeat: React.lazy(() => import('react-bootstrap-icons/dist/icons/repeat')), + 'reply-all-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/reply-all-fill')), + 'reply-all': React.lazy(() => import('react-bootstrap-icons/dist/icons/reply-all')), + 'reply-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/reply-fill')), + reply: React.lazy(() => import('react-bootstrap-icons/dist/icons/reply')), + 'rewind-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/rewind-btn-fill')), + 'rewind-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/rewind-btn')), + 'rewind-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/rewind-circle-fill')), + 'rewind-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/rewind-circle')), + 'rewind-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/rewind-fill')), + rewind: React.lazy(() => import('react-bootstrap-icons/dist/icons/rewind')), + robot: React.lazy(() => import('react-bootstrap-icons/dist/icons/robot')), + 'rocket-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/rocket-fill')), + 'rocket-takeoff-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/rocket-takeoff-fill')), + 'rocket-takeoff': React.lazy(() => import('react-bootstrap-icons/dist/icons/rocket-takeoff')), + rocket: React.lazy(() => import('react-bootstrap-icons/dist/icons/rocket')), + 'router-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/router-fill')), + router: React.lazy(() => import('react-bootstrap-icons/dist/icons/router')), + 'rss-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/rss-fill')), + rss: React.lazy(() => import('react-bootstrap-icons/dist/icons/rss')), + rulers: React.lazy(() => import('react-bootstrap-icons/dist/icons/rulers')), + 'safe-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/safe-fill')), + safe: React.lazy(() => import('react-bootstrap-icons/dist/icons/safe')), + 'safe2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/safe2-fill')), + safe2: React.lazy(() => import('react-bootstrap-icons/dist/icons/safe2')), + 'save-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/save-fill')), + save: React.lazy(() => import('react-bootstrap-icons/dist/icons/save')), + 'save2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/save2-fill')), + save2: React.lazy(() => import('react-bootstrap-icons/dist/icons/save2')), + scissors: React.lazy(() => import('react-bootstrap-icons/dist/icons/scissors')), + scooter: React.lazy(() => import('react-bootstrap-icons/dist/icons/scooter')), + screwdriver: React.lazy(() => import('react-bootstrap-icons/dist/icons/screwdriver')), + 'sd-card-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sd-card-fill')), + 'sd-card': React.lazy(() => import('react-bootstrap-icons/dist/icons/sd-card')), + 'search-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/search-heart-fill')), + 'search-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/search-heart')), + search: React.lazy(() => import('react-bootstrap-icons/dist/icons/search')), + 'segmented-nav': React.lazy(() => import('react-bootstrap-icons/dist/icons/segmented-nav')), + 'send-check-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-check-fill')), + 'send-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-check')), + 'send-dash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-dash-fill')), + 'send-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-dash')), + 'send-exclamation-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-exclamation-fill')), + 'send-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-exclamation')), + 'send-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-fill')), + 'send-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-plus-fill')), + 'send-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-plus')), + 'send-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-slash-fill')), + 'send-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-slash')), + 'send-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-x-fill')), + 'send-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/send-x')), + send: React.lazy(() => import('react-bootstrap-icons/dist/icons/send')), + server: React.lazy(() => import('react-bootstrap-icons/dist/icons/server')), + 'share-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/share-fill')), + share: React.lazy(() => import('react-bootstrap-icons/dist/icons/share')), + 'shield-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-check')), + 'shield-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-exclamation')), + 'shield-fill-check': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-fill-check')), + 'shield-fill-exclamation': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-fill-exclamation')), + 'shield-fill-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-fill-minus')), + 'shield-fill-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-fill-plus')), + 'shield-fill-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-fill-x')), + 'shield-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-fill')), + 'shield-lock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-lock-fill')), + 'shield-lock': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-lock')), + 'shield-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-minus')), + 'shield-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-plus')), + 'shield-shaded': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-shaded')), + 'shield-slash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-slash-fill')), + 'shield-slash': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-slash')), + 'shield-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/shield-x')), + shield: React.lazy(() => import('react-bootstrap-icons/dist/icons/shield')), + 'shift-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/shift-fill')), + shift: React.lazy(() => import('react-bootstrap-icons/dist/icons/shift')), + 'shop-window': React.lazy(() => import('react-bootstrap-icons/dist/icons/shop-window')), + shop: React.lazy(() => import('react-bootstrap-icons/dist/icons/shop')), + shuffle: React.lazy(() => import('react-bootstrap-icons/dist/icons/shuffle')), + 'sign-dead-end-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-dead-end-fill')), + 'sign-dead-end': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-dead-end')), + 'sign-do-not-enter-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-do-not-enter-fill')), + 'sign-do-not-enter': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-do-not-enter')), + 'sign-intersection-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection-fill')), + 'sign-intersection-side-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/sign-intersection-side-fill') + ), + 'sign-intersection-side': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection-side')), + 'sign-intersection-t-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection-t-fill')), + 'sign-intersection-t': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection-t')), + 'sign-intersection-y-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection-y-fill')), + 'sign-intersection-y': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection-y')), + 'sign-intersection': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-intersection')), + 'sign-merge-left-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-merge-left-fill')), + 'sign-merge-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-merge-left')), + 'sign-merge-right-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-merge-right-fill')), + 'sign-merge-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-merge-right')), + 'sign-no-left-turn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-no-left-turn-fill')), + 'sign-no-left-turn': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-no-left-turn')), + 'sign-no-parking-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-no-parking-fill')), + 'sign-no-parking': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-no-parking')), + 'sign-no-right-turn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-no-right-turn-fill')), + 'sign-no-right-turn': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-no-right-turn')), + 'sign-railroad-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-railroad-fill')), + 'sign-railroad': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-railroad')), + 'sign-stop-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-stop-fill')), + 'sign-stop-lights-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-stop-lights-fill')), + 'sign-stop-lights': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-stop-lights')), + 'sign-stop': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-stop')), + 'sign-turn-left-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-left-fill')), + 'sign-turn-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-left')), + 'sign-turn-right-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-right-fill')), + 'sign-turn-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-right')), + 'sign-turn-slight-left-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-slight-left-fill')), + 'sign-turn-slight-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-slight-left')), + 'sign-turn-slight-right-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/sign-turn-slight-right-fill') + ), + 'sign-turn-slight-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-turn-slight-right')), + 'sign-yield-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-yield-fill')), + 'sign-yield': React.lazy(() => import('react-bootstrap-icons/dist/icons/sign-yield')), + signal: React.lazy(() => import('react-bootstrap-icons/dist/icons/signal')), + 'signpost-2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/signpost-2-fill')), + 'signpost-2': React.lazy(() => import('react-bootstrap-icons/dist/icons/signpost-2')), + 'signpost-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/signpost-fill')), + 'signpost-split-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/signpost-split-fill')), + 'signpost-split': React.lazy(() => import('react-bootstrap-icons/dist/icons/signpost-split')), + signpost: React.lazy(() => import('react-bootstrap-icons/dist/icons/signpost')), + 'sim-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sim-fill')), + sim: React.lazy(() => import('react-bootstrap-icons/dist/icons/sim')), + 'sina-weibo': React.lazy(() => import('react-bootstrap-icons/dist/icons/sina-weibo')), + 'skip-backward-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-backward-btn-fill')), + 'skip-backward-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-backward-btn')), + 'skip-backward-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-backward-circle-fill')), + 'skip-backward-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-backward-circle')), + 'skip-backward-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-backward-fill')), + 'skip-backward': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-backward')), + 'skip-end-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-end-btn-fill')), + 'skip-end-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-end-btn')), + 'skip-end-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-end-circle-fill')), + 'skip-end-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-end-circle')), + 'skip-end-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-end-fill')), + 'skip-end': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-end')), + 'skip-forward-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-forward-btn-fill')), + 'skip-forward-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-forward-btn')), + 'skip-forward-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-forward-circle-fill')), + 'skip-forward-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-forward-circle')), + 'skip-forward-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-forward-fill')), + 'skip-forward': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-forward')), + 'skip-start-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-start-btn-fill')), + 'skip-start-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-start-btn')), + 'skip-start-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-start-circle-fill')), + 'skip-start-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-start-circle')), + 'skip-start-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-start-fill')), + 'skip-start': React.lazy(() => import('react-bootstrap-icons/dist/icons/skip-start')), + skype: React.lazy(() => import('react-bootstrap-icons/dist/icons/skype')), + slack: React.lazy(() => import('react-bootstrap-icons/dist/icons/slack')), + 'slash-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/slash-circle-fill')), + 'slash-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/slash-circle')), + 'slash-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/slash-lg')), + 'slash-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/slash-square-fill')), + 'slash-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/slash-square')), + slash: React.lazy(() => import('react-bootstrap-icons/dist/icons/slash')), + sliders: React.lazy(() => import('react-bootstrap-icons/dist/icons/sliders')), + 'sliders2-vertical': React.lazy(() => import('react-bootstrap-icons/dist/icons/sliders2-vertical')), + sliders2: React.lazy(() => import('react-bootstrap-icons/dist/icons/sliders2')), + smartwatch: React.lazy(() => import('react-bootstrap-icons/dist/icons/smartwatch')), + snapchat: React.lazy(() => import('react-bootstrap-icons/dist/icons/snapchat')), + snow: React.lazy(() => import('react-bootstrap-icons/dist/icons/snow')), + snow2: React.lazy(() => import('react-bootstrap-icons/dist/icons/snow2')), + snow3: React.lazy(() => import('react-bootstrap-icons/dist/icons/snow3')), + 'sort-alpha-down-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-alpha-down-alt')), + 'sort-alpha-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-alpha-down')), + 'sort-alpha-up-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-alpha-up-alt')), + 'sort-alpha-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-alpha-up')), + 'sort-down-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-down-alt')), + 'sort-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-down')), + 'sort-numeric-down-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-numeric-down-alt')), + 'sort-numeric-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-numeric-down')), + 'sort-numeric-up-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-numeric-up-alt')), + 'sort-numeric-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-numeric-up')), + 'sort-up-alt': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-up-alt')), + 'sort-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/sort-up')), + soundwave: React.lazy(() => import('react-bootstrap-icons/dist/icons/soundwave')), + 'speaker-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/speaker-fill')), + speaker: React.lazy(() => import('react-bootstrap-icons/dist/icons/speaker')), + speedometer: React.lazy(() => import('react-bootstrap-icons/dist/icons/speedometer')), + speedometer2: React.lazy(() => import('react-bootstrap-icons/dist/icons/speedometer2')), + spellcheck: React.lazy(() => import('react-bootstrap-icons/dist/icons/spellcheck')), + spotify: React.lazy(() => import('react-bootstrap-icons/dist/icons/spotify')), + 'square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/square-fill')), + 'square-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/square-half')), + square: React.lazy(() => import('react-bootstrap-icons/dist/icons/square')), + 'stack-overflow': React.lazy(() => import('react-bootstrap-icons/dist/icons/stack-overflow')), + stack: React.lazy(() => import('react-bootstrap-icons/dist/icons/stack')), + 'star-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/star-fill')), + 'star-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/star-half')), + star: React.lazy(() => import('react-bootstrap-icons/dist/icons/star')), + stars: React.lazy(() => import('react-bootstrap-icons/dist/icons/stars')), + steam: React.lazy(() => import('react-bootstrap-icons/dist/icons/steam')), + 'stickies-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/stickies-fill')), + stickies: React.lazy(() => import('react-bootstrap-icons/dist/icons/stickies')), + 'sticky-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sticky-fill')), + sticky: React.lazy(() => import('react-bootstrap-icons/dist/icons/sticky')), + 'stop-btn-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/stop-btn-fill')), + 'stop-btn': React.lazy(() => import('react-bootstrap-icons/dist/icons/stop-btn')), + 'stop-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/stop-circle-fill')), + 'stop-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/stop-circle')), + 'stop-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/stop-fill')), + stop: React.lazy(() => import('react-bootstrap-icons/dist/icons/stop')), + 'stoplights-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/stoplights-fill')), + stoplights: React.lazy(() => import('react-bootstrap-icons/dist/icons/stoplights')), + 'stopwatch-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/stopwatch-fill')), + stopwatch: React.lazy(() => import('react-bootstrap-icons/dist/icons/stopwatch')), + strava: React.lazy(() => import('react-bootstrap-icons/dist/icons/strava')), + stripe: React.lazy(() => import('react-bootstrap-icons/dist/icons/stripe')), + subscript: React.lazy(() => import('react-bootstrap-icons/dist/icons/subscript')), + subtract: React.lazy(() => import('react-bootstrap-icons/dist/icons/subtract')), + 'suit-club-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-club-fill')), + 'suit-club': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-club')), + 'suit-diamond-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-diamond-fill')), + 'suit-diamond': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-diamond')), + 'suit-heart-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-heart-fill')), + 'suit-heart': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-heart')), + 'suit-spade-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-spade-fill')), + 'suit-spade': React.lazy(() => import('react-bootstrap-icons/dist/icons/suit-spade')), + 'sun-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sun-fill')), + sun: React.lazy(() => import('react-bootstrap-icons/dist/icons/sun')), + sunglasses: React.lazy(() => import('react-bootstrap-icons/dist/icons/sunglasses')), + 'sunrise-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sunrise-fill')), + sunrise: React.lazy(() => import('react-bootstrap-icons/dist/icons/sunrise')), + 'sunset-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/sunset-fill')), + sunset: React.lazy(() => import('react-bootstrap-icons/dist/icons/sunset')), + superscript: React.lazy(() => import('react-bootstrap-icons/dist/icons/superscript')), + 'symmetry-horizontal': React.lazy(() => import('react-bootstrap-icons/dist/icons/symmetry-horizontal')), + 'symmetry-vertical': React.lazy(() => import('react-bootstrap-icons/dist/icons/symmetry-vertical')), + table: React.lazy(() => import('react-bootstrap-icons/dist/icons/table')), + 'tablet-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/tablet-fill')), + 'tablet-landscape-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/tablet-landscape-fill')), + 'tablet-landscape': React.lazy(() => import('react-bootstrap-icons/dist/icons/tablet-landscape')), + tablet: React.lazy(() => import('react-bootstrap-icons/dist/icons/tablet')), + 'tag-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/tag-fill')), + tag: React.lazy(() => import('react-bootstrap-icons/dist/icons/tag')), + 'tags-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/tags-fill')), + tags: React.lazy(() => import('react-bootstrap-icons/dist/icons/tags')), + 'taxi-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/taxi-front-fill')), + 'taxi-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/taxi-front')), + telegram: React.lazy(() => import('react-bootstrap-icons/dist/icons/telegram')), + 'telephone-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-fill')), + 'telephone-forward-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-forward-fill')), + 'telephone-forward': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-forward')), + 'telephone-inbound-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-inbound-fill')), + 'telephone-inbound': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-inbound')), + 'telephone-minus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-minus-fill')), + 'telephone-minus': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-minus')), + 'telephone-outbound-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-outbound-fill')), + 'telephone-outbound': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-outbound')), + 'telephone-plus-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-plus-fill')), + 'telephone-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-plus')), + 'telephone-x-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-x-fill')), + 'telephone-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone-x')), + telephone: React.lazy(() => import('react-bootstrap-icons/dist/icons/telephone')), + 'tencent-qq': React.lazy(() => import('react-bootstrap-icons/dist/icons/tencent-qq')), + 'terminal-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/terminal-dash')), + 'terminal-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/terminal-fill')), + 'terminal-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/terminal-plus')), + 'terminal-split': React.lazy(() => import('react-bootstrap-icons/dist/icons/terminal-split')), + 'terminal-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/terminal-x')), + terminal: React.lazy(() => import('react-bootstrap-icons/dist/icons/terminal')), + 'text-center': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-center')), + 'text-indent-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-indent-left')), + 'text-indent-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-indent-right')), + 'text-left': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-left')), + 'text-paragraph': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-paragraph')), + 'text-right': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-right')), + 'text-wrap': React.lazy(() => import('react-bootstrap-icons/dist/icons/text-wrap')), + 'textarea-resize': React.lazy(() => import('react-bootstrap-icons/dist/icons/textarea-resize')), + 'textarea-t': React.lazy(() => import('react-bootstrap-icons/dist/icons/textarea-t')), + textarea: React.lazy(() => import('react-bootstrap-icons/dist/icons/textarea')), + 'thermometer-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/thermometer-half')), + 'thermometer-high': React.lazy(() => import('react-bootstrap-icons/dist/icons/thermometer-high')), + 'thermometer-low': React.lazy(() => import('react-bootstrap-icons/dist/icons/thermometer-low')), + 'thermometer-snow': React.lazy(() => import('react-bootstrap-icons/dist/icons/thermometer-snow')), + 'thermometer-sun': React.lazy(() => import('react-bootstrap-icons/dist/icons/thermometer-sun')), + thermometer: React.lazy(() => import('react-bootstrap-icons/dist/icons/thermometer')), + 'three-dots-vertical': React.lazy(() => import('react-bootstrap-icons/dist/icons/three-dots-vertical')), + 'three-dots': React.lazy(() => import('react-bootstrap-icons/dist/icons/three-dots')), + 'thunderbolt-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/thunderbolt-fill')), + thunderbolt: React.lazy(() => import('react-bootstrap-icons/dist/icons/thunderbolt')), + 'ticket-detailed-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/ticket-detailed-fill')), + 'ticket-detailed': React.lazy(() => import('react-bootstrap-icons/dist/icons/ticket-detailed')), + 'ticket-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/ticket-fill')), + 'ticket-perforated-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/ticket-perforated-fill')), + 'ticket-perforated': React.lazy(() => import('react-bootstrap-icons/dist/icons/ticket-perforated')), + ticket: React.lazy(() => import('react-bootstrap-icons/dist/icons/ticket')), + tiktok: React.lazy(() => import('react-bootstrap-icons/dist/icons/tiktok')), + 'toggle-off': React.lazy(() => import('react-bootstrap-icons/dist/icons/toggle-off')), + 'toggle-on': React.lazy(() => import('react-bootstrap-icons/dist/icons/toggle-on')), + 'toggle2-off': React.lazy(() => import('react-bootstrap-icons/dist/icons/toggle2-off')), + 'toggle2-on': React.lazy(() => import('react-bootstrap-icons/dist/icons/toggle2-on')), + toggles: React.lazy(() => import('react-bootstrap-icons/dist/icons/toggles')), + toggles2: React.lazy(() => import('react-bootstrap-icons/dist/icons/toggles2')), + tools: React.lazy(() => import('react-bootstrap-icons/dist/icons/tools')), + tornado: React.lazy(() => import('react-bootstrap-icons/dist/icons/tornado')), + 'train-freight-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/train-freight-front-fill')), + 'train-freight-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/train-freight-front')), + 'train-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/train-front-fill')), + 'train-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/train-front')), + 'train-lightrail-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/train-lightrail-front-fill')), + 'train-lightrail-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/train-lightrail-front')), + translate: React.lazy(() => import('react-bootstrap-icons/dist/icons/translate')), + 'trash-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/trash-fill')), + trash: React.lazy(() => import('react-bootstrap-icons/dist/icons/trash')), + 'trash2-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/trash2-fill')), + trash2: React.lazy(() => import('react-bootstrap-icons/dist/icons/trash2')), + 'trash3-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/trash3-fill')), + trash3: React.lazy(() => import('react-bootstrap-icons/dist/icons/trash3')), + 'tree-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/tree-fill')), + tree: React.lazy(() => import('react-bootstrap-icons/dist/icons/tree')), + trello: React.lazy(() => import('react-bootstrap-icons/dist/icons/trello')), + 'triangle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/triangle-fill')), + 'triangle-half': React.lazy(() => import('react-bootstrap-icons/dist/icons/triangle-half')), + triangle: React.lazy(() => import('react-bootstrap-icons/dist/icons/triangle')), + 'trophy-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/trophy-fill')), + trophy: React.lazy(() => import('react-bootstrap-icons/dist/icons/trophy')), + 'tropical-storm': React.lazy(() => import('react-bootstrap-icons/dist/icons/tropical-storm')), + 'truck-flatbed': React.lazy(() => import('react-bootstrap-icons/dist/icons/truck-flatbed')), + 'truck-front-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/truck-front-fill')), + 'truck-front': React.lazy(() => import('react-bootstrap-icons/dist/icons/truck-front')), + truck: React.lazy(() => import('react-bootstrap-icons/dist/icons/truck')), + tsunami: React.lazy(() => import('react-bootstrap-icons/dist/icons/tsunami')), + 'tv-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/tv-fill')), + tv: React.lazy(() => import('react-bootstrap-icons/dist/icons/tv')), + twitch: React.lazy(() => import('react-bootstrap-icons/dist/icons/twitch')), + twitter: React.lazy(() => import('react-bootstrap-icons/dist/icons/twitter')), + 'type-bold': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-bold')), + 'type-h1': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-h1')), + 'type-h2': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-h2')), + 'type-h3': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-h3')), + 'type-italic': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-italic')), + 'type-strikethrough': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-strikethrough')), + 'type-underline': React.lazy(() => import('react-bootstrap-icons/dist/icons/type-underline')), + type: React.lazy(() => import('react-bootstrap-icons/dist/icons/type')), + ubuntu: React.lazy(() => import('react-bootstrap-icons/dist/icons/ubuntu')), + 'ui-checks-grid': React.lazy(() => import('react-bootstrap-icons/dist/icons/ui-checks-grid')), + 'ui-checks': React.lazy(() => import('react-bootstrap-icons/dist/icons/ui-checks')), + 'ui-radios-grid': React.lazy(() => import('react-bootstrap-icons/dist/icons/ui-radios-grid')), + 'ui-radios': React.lazy(() => import('react-bootstrap-icons/dist/icons/ui-radios')), + 'umbrella-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/umbrella-fill')), + umbrella: React.lazy(() => import('react-bootstrap-icons/dist/icons/umbrella')), + unindent: React.lazy(() => import('react-bootstrap-icons/dist/icons/unindent')), + union: React.lazy(() => import('react-bootstrap-icons/dist/icons/union')), + unity: React.lazy(() => import('react-bootstrap-icons/dist/icons/unity')), + 'universal-access-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/universal-access-circle')), + 'universal-access': React.lazy(() => import('react-bootstrap-icons/dist/icons/universal-access')), + 'unlock-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/unlock-fill')), + unlock: React.lazy(() => import('react-bootstrap-icons/dist/icons/unlock')), + 'upc-scan': React.lazy(() => import('react-bootstrap-icons/dist/icons/upc-scan')), + upc: React.lazy(() => import('react-bootstrap-icons/dist/icons/upc')), + upload: React.lazy(() => import('react-bootstrap-icons/dist/icons/upload')), + 'usb-c-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-c-fill')), + 'usb-c': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-c')), + 'usb-drive-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-drive-fill')), + 'usb-drive': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-drive')), + 'usb-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-fill')), + 'usb-micro-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-micro-fill')), + 'usb-micro': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-micro')), + 'usb-mini-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-mini-fill')), + 'usb-mini': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-mini')), + 'usb-plug-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-plug-fill')), + 'usb-plug': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-plug')), + 'usb-symbol': React.lazy(() => import('react-bootstrap-icons/dist/icons/usb-symbol')), + usb: React.lazy(() => import('react-bootstrap-icons/dist/icons/usb')), + valentine: React.lazy(() => import('react-bootstrap-icons/dist/icons/valentine')), + valentine2: React.lazy(() => import('react-bootstrap-icons/dist/icons/valentine2')), + 'vector-pen': React.lazy(() => import('react-bootstrap-icons/dist/icons/vector-pen')), + 'view-list': React.lazy(() => import('react-bootstrap-icons/dist/icons/view-list')), + 'view-stacked': React.lazy(() => import('react-bootstrap-icons/dist/icons/view-stacked')), + vimeo: React.lazy(() => import('react-bootstrap-icons/dist/icons/vimeo')), + 'vinyl-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/vinyl-fill')), + vinyl: React.lazy(() => import('react-bootstrap-icons/dist/icons/vinyl')), + virus: React.lazy(() => import('react-bootstrap-icons/dist/icons/virus')), + virus2: React.lazy(() => import('react-bootstrap-icons/dist/icons/virus2')), + voicemail: React.lazy(() => import('react-bootstrap-icons/dist/icons/voicemail')), + 'volume-down-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-down-fill')), + 'volume-down': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-down')), + 'volume-mute-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-mute-fill')), + 'volume-mute': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-mute')), + 'volume-off-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-off-fill')), + 'volume-off': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-off')), + 'volume-up-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-up-fill')), + 'volume-up': React.lazy(() => import('react-bootstrap-icons/dist/icons/volume-up')), + vr: React.lazy(() => import('react-bootstrap-icons/dist/icons/vr')), + 'wallet-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/wallet-fill')), + wallet: React.lazy(() => import('react-bootstrap-icons/dist/icons/wallet')), + wallet2: React.lazy(() => import('react-bootstrap-icons/dist/icons/wallet2')), + watch: React.lazy(() => import('react-bootstrap-icons/dist/icons/watch')), + water: React.lazy(() => import('react-bootstrap-icons/dist/icons/water')), + 'webcam-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/webcam-fill')), + webcam: React.lazy(() => import('react-bootstrap-icons/dist/icons/webcam')), + wechat: React.lazy(() => import('react-bootstrap-icons/dist/icons/wechat')), + whatsapp: React.lazy(() => import('react-bootstrap-icons/dist/icons/whatsapp')), + 'wifi-1': React.lazy(() => import('react-bootstrap-icons/dist/icons/wifi-1')), + 'wifi-2': React.lazy(() => import('react-bootstrap-icons/dist/icons/wifi-2')), + 'wifi-off': React.lazy(() => import('react-bootstrap-icons/dist/icons/wifi-off')), + wifi: React.lazy(() => import('react-bootstrap-icons/dist/icons/wifi')), + wikipedia: React.lazy(() => import('react-bootstrap-icons/dist/icons/wikipedia')), + wind: React.lazy(() => import('react-bootstrap-icons/dist/icons/wind')), + 'window-dash': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-dash')), + 'window-desktop': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-desktop')), + 'window-dock': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-dock')), + 'window-fullscreen': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-fullscreen')), + 'window-plus': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-plus')), + 'window-sidebar': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-sidebar')), + 'window-split': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-split')), + 'window-stack': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-stack')), + 'window-x': React.lazy(() => import('react-bootstrap-icons/dist/icons/window-x')), + window: React.lazy(() => import('react-bootstrap-icons/dist/icons/window')), + windows: React.lazy(() => import('react-bootstrap-icons/dist/icons/windows')), + wordpress: React.lazy(() => import('react-bootstrap-icons/dist/icons/wordpress')), + 'wrench-adjustable-circle-fill': React.lazy( + () => import('react-bootstrap-icons/dist/icons/wrench-adjustable-circle-fill') + ), + 'wrench-adjustable-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/wrench-adjustable-circle')), + 'wrench-adjustable': React.lazy(() => import('react-bootstrap-icons/dist/icons/wrench-adjustable')), + wrench: React.lazy(() => import('react-bootstrap-icons/dist/icons/wrench')), + 'x-circle-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-circle-fill')), + 'x-circle': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-circle')), + 'x-diamond-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-diamond-fill')), + 'x-diamond': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-diamond')), + 'x-lg': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-lg')), + 'x-octagon-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-octagon-fill')), + 'x-octagon': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-octagon')), + 'x-square-fill': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-square-fill')), + 'x-square': React.lazy(() => import('react-bootstrap-icons/dist/icons/x-square')), + x: React.lazy(() => import('react-bootstrap-icons/dist/icons/x')), + xbox: React.lazy(() => import('react-bootstrap-icons/dist/icons/xbox')), + yelp: React.lazy(() => import('react-bootstrap-icons/dist/icons/yelp')), + 'yin-yang': React.lazy(() => import('react-bootstrap-icons/dist/icons/yin-yang')), + youtube: React.lazy(() => import('react-bootstrap-icons/dist/icons/youtube')), + 'zoom-in': React.lazy(() => import('react-bootstrap-icons/dist/icons/zoom-in')), + 'zoom-out': React.lazy(() => import('react-bootstrap-icons/dist/icons/zoom-out')) +} as const diff --git a/frontend/src/components/common/icons/lazy-bootstrap-icon.tsx b/frontend/src/components/common/icons/lazy-bootstrap-icon.tsx new file mode 100644 index 000000000..4021e3896 --- /dev/null +++ b/frontend/src/components/common/icons/lazy-bootstrap-icon.tsx @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { testId } from '../../../utils/test-id' +import { BootstrapLazyIcons } from './bootstrap-icons' +import type { BootstrapIconName } from './bootstrap-icons' +import React, { Suspense, useMemo } from 'react' + +export interface LazyBootstrapIconProps { + icon: BootstrapIconName + size?: number + className?: string +} + +/** + * Renders a bootstrap icon. + * + * @param iconName the internal name of the icon + * @param size the size of the icon - the default is 1 + * @see https://icons.getbootstrap.com/ + */ +export const LazyBootstrapIcon: React.FC<LazyBootstrapIconProps> = ({ icon, size, className }) => { + const fullSize = useMemo(() => `${size ?? 1}em`, [size]) + const Icon = BootstrapLazyIcons[icon] + + return ( + <Suspense fallback={<></>}> + <Icon + width={fullSize} + height={fullSize} + fill={'currentColor'} + className={className} + {...testId(`lazy-bootstrap-icon-${icon}`)}></Icon> + </Suspense> + ) +} diff --git a/frontend/src/components/common/icons/ui-icon.tsx b/frontend/src/components/common/icons/ui-icon.tsx new file mode 100644 index 000000000..6f1d4189b --- /dev/null +++ b/frontend/src/components/common/icons/ui-icon.tsx @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import styles from './ui-icons.module.scss' +import React, { Fragment, useMemo } from 'react' +import type { Icon } from 'react-bootstrap-icons' + +export interface UiIconProps { + icon: Icon | undefined + nbsp?: boolean + size?: number | string + className?: string + spin?: boolean +} + +export const UiIcon: React.FC<UiIconProps> = ({ icon, nbsp, className, size, spin }) => { + const finalSize = useMemo(() => { + if (size === undefined) { + return '1em' + } else if (typeof size === 'number') { + return `${size}em` + } else { + return size + } + }, [size]) + + const finalClassName = useMemo(() => { + return `${spin ? styles.spin : ''} ${className ?? ''}` + }, [className, spin]) + + if (icon) { + return ( + <Fragment> + {React.createElement(icon, { + className: finalClassName, + width: finalSize, + height: finalSize + })} + {nbsp ? <Fragment>&nbsp;</Fragment> : null} + </Fragment> + ) + } else { + return null + } +} diff --git a/frontend/src/components/common/icons/ui-icons.module.scss b/frontend/src/components/common/icons/ui-icons.module.scss new file mode 100644 index 000000000..131fa67f9 --- /dev/null +++ b/frontend/src/components/common/icons/ui-icons.module.scss @@ -0,0 +1,20 @@ +/*! + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +.spin { + transform-origin: center center; + + @keyframes rotation { + 0% { + transform: rotateZ(0deg); + } + 100% { + transform: rotateZ(360deg); + } + } + + animation: rotation linear 2s infinite; +} diff --git a/frontend/src/components/common/links/__snapshots__/external-link.test.tsx.snap b/frontend/src/components/common/links/__snapshots__/external-link.test.tsx.snap index c7c28b6f6..191a471cd 100644 --- a/frontend/src/components/common/links/__snapshots__/external-link.test.tsx.snap +++ b/frontend/src/components/common/links/__snapshots__/external-link.test.tsx.snap @@ -52,9 +52,7 @@ exports[`ExternalLink renders an external link with an icon 1`] = ` rel="noopener noreferrer" target="_blank" > - <i - class="fa fa-fw fa-heart " - /> + BootstrapIconMock_Heart   testText </a> diff --git a/frontend/src/components/common/links/__snapshots__/internal-link.test.tsx.snap b/frontend/src/components/common/links/__snapshots__/internal-link.test.tsx.snap index d60ebf423..8312497bd 100644 --- a/frontend/src/components/common/links/__snapshots__/internal-link.test.tsx.snap +++ b/frontend/src/components/common/links/__snapshots__/internal-link.test.tsx.snap @@ -40,9 +40,7 @@ exports[`InternalLink renders an internal link with an icon 1`] = ` class="text-light" href="/test" > - <i - class="fa fa-fw fa-heart " - /> + BootstrapIconMock_Heart   testText </a> diff --git a/frontend/src/components/common/links/external-link.test.tsx b/frontend/src/components/common/links/external-link.test.tsx index 66a61195a..6b126ae5e 100644 --- a/frontend/src/components/common/links/external-link.test.tsx +++ b/frontend/src/components/common/links/external-link.test.tsx @@ -5,6 +5,7 @@ */ import { ExternalLink } from './external-link' import { render } from '@testing-library/react' +import { Heart as IconHeart } from 'react-bootstrap-icons' describe('ExternalLink', () => { const href = 'https://example.com' @@ -14,7 +15,7 @@ describe('ExternalLink', () => { expect(view.container).toMatchSnapshot() }) it('renders an external link with an icon', () => { - const view = render(<ExternalLink text={text} href={href} icon={'heart'} />) + const view = render(<ExternalLink text={text} href={href} icon={IconHeart} />) expect(view.container).toMatchSnapshot() }) it('renders an external link with an id', () => { diff --git a/frontend/src/components/common/links/external-link.tsx b/frontend/src/components/common/links/external-link.tsx index e293ad28b..8cd6e4927 100644 --- a/frontend/src/components/common/links/external-link.tsx +++ b/frontend/src/components/common/links/external-link.tsx @@ -3,9 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' -import type { IconName } from '../fork-awesome/types' -import { ShowIf } from '../show-if/show-if' +import { UiIcon } from '../icons/ui-icon' import type { LinkWithTextProps } from './types' import React from 'react' @@ -31,10 +29,7 @@ export const ExternalLink: React.FC<LinkWithTextProps> = ({ }) => { return ( <a href={href} target='_blank' rel='noopener noreferrer' id={id} className={className} title={title} dir='auto'> - <ShowIf condition={!!icon}> - <ForkAwesomeIcon icon={icon as IconName} fixedWidth={true} /> - &nbsp; - </ShowIf> + <UiIcon icon={icon} nbsp={true} /> {text} </a> ) diff --git a/frontend/src/components/common/links/internal-link.test.tsx b/frontend/src/components/common/links/internal-link.test.tsx index c81fba1ed..9a740504c 100644 --- a/frontend/src/components/common/links/internal-link.test.tsx +++ b/frontend/src/components/common/links/internal-link.test.tsx @@ -5,6 +5,7 @@ */ import { InternalLink } from './internal-link' import { render } from '@testing-library/react' +import { Heart as IconHeart } from 'react-bootstrap-icons' describe('InternalLink', () => { const href = '/test' @@ -14,7 +15,7 @@ describe('InternalLink', () => { expect(view.container).toMatchSnapshot() }) it('renders an internal link with an icon', () => { - const view = render(<InternalLink text={text} href={href} icon={'heart'} />) + const view = render(<InternalLink text={text} href={href} icon={IconHeart} />) expect(view.container).toMatchSnapshot() }) it('renders an internal link with an id', () => { diff --git a/frontend/src/components/common/links/internal-link.tsx b/frontend/src/components/common/links/internal-link.tsx index d087d567d..b6bffc2c5 100644 --- a/frontend/src/components/common/links/internal-link.tsx +++ b/frontend/src/components/common/links/internal-link.tsx @@ -3,9 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' -import type { IconName } from '../fork-awesome/types' -import { ShowIf } from '../show-if/show-if' +import { UiIcon } from '../icons/ui-icon' import type { LinkWithTextProps } from './types' import Link from 'next/link' import React from 'react' @@ -31,10 +29,7 @@ export const InternalLink: React.FC<LinkWithTextProps> = ({ }) => { return ( <Link href={href} className={className} id={id} title={title}> - <ShowIf condition={!!icon}> - <ForkAwesomeIcon icon={icon as IconName} fixedWidth={true} /> - &nbsp; - </ShowIf> + <UiIcon icon={icon} nbsp={true} /> {text} </Link> ) diff --git a/frontend/src/components/common/links/types.d.ts b/frontend/src/components/common/links/types.d.ts index cbb2a2003..86b20d316 100644 --- a/frontend/src/components/common/links/types.d.ts +++ b/frontend/src/components/common/links/types.d.ts @@ -3,12 +3,12 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { IconName } from '../fork-awesome/fork-awesome-icon' import type { TOptionsBase } from 'i18next' +import type { Icon } from 'react-bootstrap-icons' interface GeneralLinkProp { href: string - icon?: IconName + icon?: Icon id?: string className?: string title?: string diff --git a/frontend/src/components/common/lock-button/lock-button.tsx b/frontend/src/components/common/lock-button/lock-button.tsx deleted file mode 100644 index e7a6fc699..000000000 --- a/frontend/src/components/common/lock-button/lock-button.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' -import React from 'react' -import { Button } from 'react-bootstrap' - -export interface LockButtonProps { - locked: boolean - onLockedChanged: (newState: boolean) => void - title: string -} - -/** - * A button with a lock icon. - * - * @param locked If the button should be shown as locked or not - * @param onLockedChanged The callback to change the state from locked to unlocked and vise-versa. - * @param title The title for the button. - */ -export const LockButton: React.FC<LockButtonProps> = ({ locked, onLockedChanged, title }) => { - return ( - <Button variant='dark' size='sm' onClick={() => onLockedChanged(!locked)} title={title}> - {locked ? <ForkAwesomeIcon icon='lock' /> : <ForkAwesomeIcon icon='unlock' />} - </Button> - ) -} diff --git a/frontend/src/components/common/modals/__snapshots__/common-modal.test.tsx.snap b/frontend/src/components/common/modals/__snapshots__/common-modal.test.tsx.snap index 8e8eed99a..6e45df329 100644 --- a/frontend/src/components/common/modals/__snapshots__/common-modal.test.tsx.snap +++ b/frontend/src/components/common/modals/__snapshots__/common-modal.test.tsx.snap @@ -148,9 +148,7 @@ exports[`CommonModal render correctly with title icon 1`] = ` <div class="modal-title h4" > - <i - class="fa fa-heart " - /> + BootstrapIconMock_Heart   <span /> </div> diff --git a/frontend/src/components/common/modals/common-modal.test.tsx b/frontend/src/components/common/modals/common-modal.test.tsx index 70d7f237a..20d044579 100644 --- a/frontend/src/components/common/modals/common-modal.test.tsx +++ b/frontend/src/components/common/modals/common-modal.test.tsx @@ -7,6 +7,7 @@ import { mockI18n } from '../../markdown-renderer/test-utils/mock-i18n' import { CommonModal } from './common-modal' import { fireEvent, render, screen } from '@testing-library/react' import React from 'react' +import { Heart as IconHeart } from 'react-bootstrap-icons' describe('CommonModal', () => { afterAll(() => { @@ -65,7 +66,7 @@ describe('CommonModal', () => { it('render correctly with title icon', async () => { render( - <CommonModal show={true} titleIcon={'heart'}> + <CommonModal show={true} titleIcon={IconHeart}> testText </CommonModal> ) diff --git a/frontend/src/components/common/modals/common-modal.tsx b/frontend/src/components/common/modals/common-modal.tsx index 470fb3ea1..e992b59d0 100644 --- a/frontend/src/components/common/modals/common-modal.tsx +++ b/frontend/src/components/common/modals/common-modal.tsx @@ -6,12 +6,12 @@ import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute' import { cypressId } from '../../../utils/cypress-attribute' import { testId } from '../../../utils/test-id' -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' -import type { IconName } from '../fork-awesome/types' +import { UiIcon } from '../icons/ui-icon' import { ShowIf } from '../show-if/show-if' import type { PropsWithChildren } from 'react' import React, { useMemo } from 'react' import { Modal } from 'react-bootstrap' +import type { Icon } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface ModalVisibilityProps { @@ -23,7 +23,7 @@ export interface ModalContentProps { titleI18nKey?: string title?: string showCloseButton?: boolean - titleIcon?: IconName + titleIcon?: Icon modalSize?: 'lg' | 'sm' | 'xl' additionalClasses?: string } @@ -74,10 +74,7 @@ export const CommonModal: React.FC<PropsWithChildren<CommonModalProps>> = ({ size={modalSize}> <Modal.Header closeButton={!!showCloseButton}> <Modal.Title> - <ShowIf condition={!!titleIcon}> - <ForkAwesomeIcon icon={titleIcon as IconName} /> - &nbsp; - </ShowIf> + <UiIcon icon={titleIcon} nbsp={true} /> {titleElement} </Modal.Title> </Modal.Header> diff --git a/frontend/src/components/common/note-loading-boundary/__snapshots__/create-non-existing-note-hint.test.tsx.snap b/frontend/src/components/common/note-loading-boundary/__snapshots__/create-non-existing-note-hint.test.tsx.snap index 9a8bd4bc8..6fd3da83b 100644 --- a/frontend/src/components/common/note-loading-boundary/__snapshots__/create-non-existing-note-hint.test.tsx.snap +++ b/frontend/src/components/common/note-loading-boundary/__snapshots__/create-non-existing-note-hint.test.tsx.snap @@ -1,20 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`create non existing note hint shows success message when the note has been created 1`] = ` -<div> - <div - class="fade mt-5 alert alert-info show" - data-testid="noteCreated" - role="alert" - > - <i - class="fa fa-check-circle me-2 " - /> - noteLoadingBoundary.createNote.success - </div> -</div> -`; - exports[`create non existing note hint renders a waiting message when button is clicked 1`] = ` <div> <div @@ -22,9 +7,7 @@ exports[`create non existing note hint renders a waiting message when button is data-testid="loadingMessage" role="alert" > - <i - class="fa fa-spinner fa-spin me-2 " - /> + BootstrapIconMock_ArrowRepeat noteLoadingBoundary.createNote.creating </div> </div> @@ -62,10 +45,21 @@ exports[`create non existing note hint shows an error message if note couldn't b data-testid="failedMessage" role="alert" > - <i - class="fa fa-exclamation-triangle me-1 " - /> + BootstrapIconMock_ExclamationTriangle noteLoadingBoundary.createNote.error </div> </div> `; + +exports[`create non existing note hint shows success message when the note has been created 1`] = ` +<div> + <div + class="fade mt-5 alert alert-info show" + data-testid="noteCreated" + role="alert" + > + BootstrapIconMock_CheckCircle + noteLoadingBoundary.createNote.success + </div> +</div> +`; diff --git a/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx b/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx index 641f182cd..522373026 100644 --- a/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx +++ b/frontend/src/components/common/note-loading-boundary/create-non-existing-note-hint.tsx @@ -6,10 +6,13 @@ import { createNoteWithPrimaryAlias } from '../../../api/notes' import { useSingleStringUrlParameter } from '../../../hooks/common/use-single-string-url-parameter' import { testId } from '../../../utils/test-id' -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' +import { UiIcon } from '../icons/ui-icon' import { ShowIf } from '../show-if/show-if' import React, { useCallback, useEffect } from 'react' import { Alert, Button } from 'react-bootstrap' +import { ArrowRepeat as IconArrowRepeat } from 'react-bootstrap-icons' +import { CheckCircle as IconCheckCircle } from 'react-bootstrap-icons' +import { ExclamationTriangle as IconExclamationTriangle } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' import { useAsyncFn } from 'react-use' @@ -49,21 +52,21 @@ export const CreateNonExistingNoteHint: React.FC<CreateNonExistingNoteHintProps> } else if (returnState.value) { return ( <Alert variant={'info'} {...testId('noteCreated')} className={'mt-5'}> - <ForkAwesomeIcon icon={'check-circle'} className={'me-2'} /> + <UiIcon icon={IconCheckCircle} className={'me-2'} /> <Trans i18nKey={'noteLoadingBoundary.createNote.success'} /> </Alert> ) } else if (returnState.loading) { return ( <Alert variant={'info'} {...testId('loadingMessage')} className={'mt-5'}> - <ForkAwesomeIcon icon={'spinner'} className={'fa-spin me-2'} /> + <UiIcon icon={IconArrowRepeat} className={'me-2'} spin={true} /> <Trans i18nKey={'noteLoadingBoundary.createNote.creating'} /> </Alert> ) } else if (returnState.error !== undefined) { return ( <Alert variant={'danger'} {...testId('failedMessage')} className={'mt-5'}> - <ForkAwesomeIcon icon={'exclamation-triangle'} className={'me-1'} /> + <UiIcon icon={IconExclamationTriangle} className={'me-1'} /> <Trans i18nKey={'noteLoadingBoundary.createNote.error'} /> </Alert> ) @@ -82,7 +85,7 @@ export const CreateNonExistingNoteHint: React.FC<CreateNonExistingNoteHintProps> onClick={onClickHandler} {...testId('createNoteButton')}> <ShowIf condition={returnState.loading}> - <ForkAwesomeIcon icon={'spinner'} className={'fa-spin me-2'} /> + <UiIcon icon={IconArrowRepeat} className={'me-2'} spin={true} /> </ShowIf> <Trans i18nKey={'noteLoadingBoundary.createNote.create'} /> </Button> diff --git a/frontend/src/components/common/wait-spinner/wait-spinner.tsx b/frontend/src/components/common/wait-spinner/wait-spinner.tsx index 22d571780..f16be4f87 100644 --- a/frontend/src/components/common/wait-spinner/wait-spinner.tsx +++ b/frontend/src/components/common/wait-spinner/wait-spinner.tsx @@ -3,8 +3,9 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon' +import { UiIcon } from '../icons/ui-icon' import React from 'react' +import { ArrowRepeat as IconArrowRepeat } from 'react-bootstrap-icons' /** * Renders a indefinitely spinning spinner. @@ -12,7 +13,7 @@ import React from 'react' export const WaitSpinner: React.FC = () => { return ( <div className={'m-3 d-flex align-items-center justify-content-center'}> - <ForkAwesomeIcon icon={'spinner'} className={'fa-spin'} /> + <UiIcon icon={IconArrowRepeat} spin={true} /> </div> ) } diff --git a/frontend/src/components/document-read-only-page/document-infobar.tsx b/frontend/src/components/document-read-only-page/document-infobar.tsx index 7b40aa2b2..d3822e5ad 100644 --- a/frontend/src/components/document-read-only-page/document-infobar.tsx +++ b/frontend/src/components/document-read-only-page/document-infobar.tsx @@ -10,6 +10,7 @@ import { NoteInfoLineCreated } from '../editor-page/document-bar/note-info/note- import { NoteInfoLineUpdated } from '../editor-page/document-bar/note-info/note-info-line-updated' import styles from './document-infobar.module.scss' import React from 'react' +import { Pencil as IconPencil } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -35,7 +36,7 @@ export const DocumentInfobar: React.FC = () => { <InternalLink text={''} href={`/n/${noteDetails.primaryAddress}`} - icon={'pencil'} + icon={IconPencil} className={'text-primary text-decoration-none mx-1'} title={t('views.readOnly.editNote') ?? undefined} /> diff --git a/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-tab-content.tsx b/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-tab-content.tsx index f0ed3ec26..6f9febc16 100644 --- a/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-tab-content.tsx +++ b/frontend/src/components/editor-page/app-bar/help-button/cheatsheet-tab-content.tsx @@ -34,6 +34,7 @@ export const CheatsheetTabContent: React.FC = () => { `[${t('editor.editorToolbar.link')}](https://example.com)`, `![${t('editor.editorToolbar.image')}](/icons/apple-touch-icon.png)`, ':smile:', + ':bi-bootstrap:', `:::info\n${t('editor.help.cheatsheet.exampleAlert')}\n:::` ], [checked, t] diff --git a/frontend/src/components/editor-page/app-bar/help-button/help-button.tsx b/frontend/src/components/editor-page/app-bar/help-button/help-button.tsx index 51a2a8fbc..b4addbc5a 100644 --- a/frontend/src/components/editor-page/app-bar/help-button/help-button.tsx +++ b/frontend/src/components/editor-page/app-bar/help-button/help-button.tsx @@ -5,10 +5,11 @@ */ import { useBooleanState } from '../../../../hooks/common/use-boolean-state' import { cypressId } from '../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { HelpModal } from './help-modal' import React, { Fragment } from 'react' import { Button } from 'react-bootstrap' +import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -27,7 +28,7 @@ export const HelpButton: React.FC = () => { size='sm' variant='outline-light' onClick={showModal}> - <ForkAwesomeIcon icon='question-circle' /> + <UiIcon icon={IconQuestionCircle} /> </Button> <HelpModal show={modalVisibility} onHide={closeModal} /> </Fragment> diff --git a/frontend/src/components/editor-page/app-bar/help-button/help-modal.tsx b/frontend/src/components/editor-page/app-bar/help-button/help-modal.tsx index 8860a30ec..868511b1c 100644 --- a/frontend/src/components/editor-page/app-bar/help-button/help-modal.tsx +++ b/frontend/src/components/editor-page/app-bar/help-button/help-modal.tsx @@ -10,6 +10,7 @@ import { LinksTabContent } from './links-tab-content' import { ShortcutTabContent } from './shortcuts-tab-content' import React, { useMemo, useState } from 'react' import { Button, Modal } from 'react-bootstrap' +import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export enum HelpTabStatus { @@ -47,7 +48,7 @@ export const HelpModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => { const modalTitle = useMemo(() => t('editor.documentBar.help') + ' - ' + t(`editor.help.${tab}`), [t, tab]) return ( - <CommonModal modalSize={'lg'} titleIcon={'question-circle'} show={show} onHide={onHide} title={modalTitle}> + <CommonModal modalSize={'lg'} titleIcon={IconQuestionCircle} show={show} onHide={onHide} title={modalTitle}> <Modal.Body> <nav className='nav nav-tabs'> <Button diff --git a/frontend/src/components/editor-page/app-bar/help-button/links-tab-content.tsx b/frontend/src/components/editor-page/app-bar/help-button/links-tab-content.tsx index fb8fb1164..3e53c87f3 100644 --- a/frontend/src/components/editor-page/app-bar/help-button/links-tab-content.tsx +++ b/frontend/src/components/editor-page/app-bar/help-button/links-tab-content.tsx @@ -8,6 +8,11 @@ import { TranslatedExternalLink } from '../../../common/links/translated-externa import { TranslatedInternalLink } from '../../../common/links/translated-internal-link' import React from 'react' import { Col, Row } from 'react-bootstrap' +import { Dot as IconDot } from 'react-bootstrap-icons' +import { Flag as IconFlag } from 'react-bootstrap-icons' +import { Hash as IconHash } from 'react-bootstrap-icons' +import { PeopleFill as IconPeopleFill } from 'react-bootstrap-icons' +import { Tag as IconTag } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -28,7 +33,7 @@ export const LinksTabContent: React.FC = () => { <TranslatedExternalLink i18nKey='editor.help.contacts.community' href={links.community} - icon='users' + icon={IconPeopleFill} className='text-primary' /> </li> @@ -37,7 +42,7 @@ export const LinksTabContent: React.FC = () => { i18nKey='editor.help.contacts.meetUsOn' i18nOption={{ service: 'Matrix' }} href={links.chat} - icon='hashtag' + icon={IconHash} className='text-primary' /> </li> @@ -45,7 +50,7 @@ export const LinksTabContent: React.FC = () => { <TranslatedExternalLink i18nKey='editor.help.contacts.reportIssue' href={links.backendIssues} - icon='tag' + icon={IconTag} className='text-primary' /> </li> @@ -53,7 +58,7 @@ export const LinksTabContent: React.FC = () => { <TranslatedExternalLink i18nKey='editor.help.contacts.helpTranslating' href={links.translate} - icon='language' + icon={IconFlag} className='text-primary' /> </li> @@ -70,7 +75,7 @@ export const LinksTabContent: React.FC = () => { <TranslatedInternalLink i18nKey='editor.help.documents.features' href='/n/features' - icon='dot-circle-o' + icon={IconDot} className='text-primary' /> </li> @@ -78,7 +83,7 @@ export const LinksTabContent: React.FC = () => { <TranslatedInternalLink i18nKey='editor.help.documents.yamlMetadata' href='/n/yaml-metadata' - icon='dot-circle-o' + icon={IconDot} className='text-primary' /> </li> @@ -86,7 +91,7 @@ export const LinksTabContent: React.FC = () => { <TranslatedInternalLink i18nKey='editor.help.documents.slideExample' href='/n/slide-example' - icon='dot-circle-o' + icon={IconDot} className='text-primary' /> </li> diff --git a/frontend/src/components/editor-page/app-bar/new-note-button.tsx b/frontend/src/components/editor-page/app-bar/new-note-button.tsx index 939b0a821..a2bb3556d 100644 --- a/frontend/src/components/editor-page/app-bar/new-note-button.tsx +++ b/frontend/src/components/editor-page/app-bar/new-note-button.tsx @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { IconButton } from '../../common/icon-button/icon-button' import Link from 'next/link' import React from 'react' -import { Button } from 'react-bootstrap' +import { Plus as IconPlus } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -17,9 +17,9 @@ export const NewNoteButton: React.FC = () => { return ( <Link href={'/new'} passHref={true}> - <Button className='mx-2' size='sm' variant='primary'> - <ForkAwesomeIcon icon='plus' /> <Trans i18nKey='editor.appBar.new' /> - </Button> + <IconButton className='mx-2' iconSize={1.5} icon={IconPlus}> + <Trans i18nKey='editor.appBar.new' /> + </IconButton> </Link> ) } diff --git a/frontend/src/components/editor-page/app-bar/read-only-mode-button.tsx b/frontend/src/components/editor-page/app-bar/read-only-mode-button.tsx index 83de49938..be34eb4a9 100644 --- a/frontend/src/components/editor-page/app-bar/read-only-mode-button.tsx +++ b/frontend/src/components/editor-page/app-bar/read-only-mode-button.tsx @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useApplicationState } from '../../../hooks/common/use-application-state' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import Link from 'next/link' import React from 'react' import { Button } from 'react-bootstrap' +import { FileEarmarkTextFill as IconFileEarmarkTextFill } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -24,7 +25,7 @@ export const ReadOnlyModeButton: React.FC = () => { className='ms-2 text-secondary' size='sm' variant='outline-light'> - <ForkAwesomeIcon icon='file-text-o' /> + <UiIcon icon={IconFileEarmarkTextFill} /> </Button> </Link> ) diff --git a/frontend/src/components/editor-page/app-bar/slide-mode-button.tsx b/frontend/src/components/editor-page/app-bar/slide-mode-button.tsx index 989382fb6..4e5d43291 100644 --- a/frontend/src/components/editor-page/app-bar/slide-mode-button.tsx +++ b/frontend/src/components/editor-page/app-bar/slide-mode-button.tsx @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useApplicationState } from '../../../hooks/common/use-application-state' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import Link from 'next/link' import React from 'react' import { Button } from 'react-bootstrap' +import { Tv as IconTv } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -24,7 +25,7 @@ export const SlideModeButton: React.FC = () => { className='ms-2 text-secondary' size='sm' variant='outline-light'> - <ForkAwesomeIcon icon='television' /> + <UiIcon icon={IconTv} /> </Button> </Link> ) diff --git a/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-add-form.test.tsx.snap b/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-add-form.test.tsx.snap index c087058c7..4fb774a3a 100644 --- a/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-add-form.test.tsx.snap +++ b/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-add-form.test.tsx.snap @@ -20,9 +20,7 @@ exports[`AliasesAddForm renders the input form 1`] = ` title="editor.modal.aliases.addAlias" type="submit" > - <i - class="fa fa-plus " - /> + BootstrapIconMock_Plus </button> </div> </form> diff --git a/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-list-entry.test.tsx.snap b/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-list-entry.test.tsx.snap index 0fb0f96cd..cd6cb2fdf 100644 --- a/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-list-entry.test.tsx.snap +++ b/frontend/src/components/editor-page/document-bar/aliases/__snapshots__/aliases-list-entry.test.tsx.snap @@ -13,9 +13,7 @@ exports[`AliasesListEntry renders an AliasesListEntry that is not primary 1`] = title="editor.modal.aliases.makePrimary" type="button" > - <i - class="fa fa-star-o " - /> + BootstrapIconMock_StarFill </button> <button class="text-danger btn btn-light" @@ -23,9 +21,7 @@ exports[`AliasesListEntry renders an AliasesListEntry that is not primary 1`] = title="editor.modal.aliases.removeAlias" type="button" > - <i - class="fa fa-times " - /> + BootstrapIconMock_X </button> </div> </li> @@ -46,9 +42,7 @@ exports[`AliasesListEntry renders an AliasesListEntry that is primary 1`] = ` title="editor.modal.aliases.isPrimary" type="button" > - <i - class="fa fa-star " - /> + BootstrapIconMock_Star </button> <button class="text-danger btn btn-light" @@ -56,9 +50,7 @@ exports[`AliasesListEntry renders an AliasesListEntry that is primary 1`] = ` title="editor.modal.aliases.removeAlias" type="button" > - <i - class="fa fa-times " - /> + BootstrapIconMock_X </button> </div> </li> diff --git a/frontend/src/components/editor-page/document-bar/aliases/aliases-add-form.tsx b/frontend/src/components/editor-page/document-bar/aliases/aliases-add-form.tsx index 4ed473e18..3cb3a5f67 100644 --- a/frontend/src/components/editor-page/document-bar/aliases/aliases-add-form.tsx +++ b/frontend/src/components/editor-page/document-bar/aliases/aliases-add-form.tsx @@ -8,11 +8,12 @@ import { useApplicationState } from '../../../../hooks/common/use-application-st import { useOnInputChange } from '../../../../hooks/common/use-on-input-change' import { updateMetadata } from '../../../../redux/note-details/methods' import { testId } from '../../../../utils/test-id' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { useUiNotifications } from '../../../notifications/ui-notification-boundary' import type { FormEvent } from 'react' import React, { useCallback, useMemo, useState } from 'react' import { Button, Form, InputGroup } from 'react-bootstrap' +import { Plus as IconPlus } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' const validAliasRegex = /^[a-z0-9_-]*$/ @@ -63,7 +64,7 @@ export const AliasesAddForm: React.FC = () => { disabled={!newAliasValid || newAlias === ''} title={t('editor.modal.aliases.addAlias') ?? undefined} {...testId('addAliasButton')}> - <ForkAwesomeIcon icon={'plus'} /> + <UiIcon icon={IconPlus} /> </Button> </InputGroup> </form> diff --git a/frontend/src/components/editor-page/document-bar/aliases/aliases-list-entry.tsx b/frontend/src/components/editor-page/document-bar/aliases/aliases-list-entry.tsx index beb8cedf9..231c6e7ea 100644 --- a/frontend/src/components/editor-page/document-bar/aliases/aliases-list-entry.tsx +++ b/frontend/src/components/editor-page/document-bar/aliases/aliases-list-entry.tsx @@ -7,11 +7,14 @@ import { deleteAlias, markAliasAsPrimary } from '../../../../api/alias' import type { Alias } from '../../../../api/alias/types' import { updateMetadata } from '../../../../redux/note-details/methods' import { testId } from '../../../../utils/test-id' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { ShowIf } from '../../../common/show-if/show-if' import { useUiNotifications } from '../../../notifications/ui-notification-boundary' import React, { useCallback } from 'react' import { Button } from 'react-bootstrap' +import { StarFill as IconStarFill } from 'react-bootstrap-icons' +import { Star as IconStar } from 'react-bootstrap-icons' +import { X as IconX } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface AliasesListEntryProps { @@ -50,7 +53,7 @@ export const AliasesListEntry: React.FC<AliasesListEntryProps> = ({ alias }) => disabled={true} title={t('editor.modal.aliases.isPrimary') ?? undefined} {...testId('aliasIsPrimary')}> - <ForkAwesomeIcon icon={'star'} /> + <UiIcon icon={IconStar} /> </Button> </ShowIf> <ShowIf condition={!alias.primaryAlias}> @@ -60,7 +63,7 @@ export const AliasesListEntry: React.FC<AliasesListEntryProps> = ({ alias }) => title={t('editor.modal.aliases.makePrimary') ?? undefined} onClick={onMakePrimaryClick} {...testId('aliasButtonMakePrimary')}> - <ForkAwesomeIcon icon={'star-o'} /> + <UiIcon icon={IconStarFill} /> </Button> </ShowIf> <Button @@ -69,7 +72,7 @@ export const AliasesListEntry: React.FC<AliasesListEntryProps> = ({ alias }) => title={t('editor.modal.aliases.removeAlias') ?? undefined} onClick={onRemoveClick} {...testId('aliasButtonRemove')}> - <ForkAwesomeIcon icon={'times'} /> + <UiIcon icon={IconX} /> </Button> </div> </li> diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-contributors.tsx b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-contributors.tsx index 9cccf3567..f0bc8b0a0 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-contributors.tsx +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-contributors.tsx @@ -7,6 +7,7 @@ import { useApplicationState } from '../../../../hooks/common/use-application-st import { NoteInfoLine } from './note-info-line' import { UnitalicBoldContent } from './unitalic-bold-content' import React from 'react' +import { People as IconPeople } from 'react-bootstrap-icons' import { Trans } from 'react-i18next' /** @@ -16,7 +17,7 @@ export const NoteInfoLineContributors: React.FC = () => { const contributors = useApplicationState((state) => state.noteDetails.editedBy.length) return ( - <NoteInfoLine icon={'users'} size={'2x'}> + <NoteInfoLine icon={IconPeople} size={2}> <Trans i18nKey={'editor.modal.documentInfo.usersContributed'}> <UnitalicBoldContent text={contributors} /> </Trans> diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-created.tsx b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-created.tsx index 8219c98e1..3f356e1c8 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-created.tsx +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-created.tsx @@ -9,6 +9,7 @@ import type { NoteInfoTimeLineProps } from './note-info-time-line' import { UnitalicBoldTimeFromNow } from './utils/unitalic-bold-time-from-now' import { DateTime } from 'luxon' import React, { useMemo } from 'react' +import { Plus as IconPlus } from 'react-bootstrap-icons' import { Trans } from 'react-i18next' /** @@ -21,7 +22,7 @@ export const NoteInfoLineCreated: React.FC<NoteInfoTimeLineProps> = ({ size }) = const noteCreateDateTime = useMemo(() => DateTime.fromSeconds(noteCreateTime), [noteCreateTime]) return ( - <NoteInfoLine icon={'plus'} size={size}> + <NoteInfoLine icon={IconPlus} size={size}> <Trans i18nKey={'editor.modal.documentInfo.created'}> <UnitalicBoldTimeFromNow time={noteCreateDateTime} /> </Trans> diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-updated.tsx b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-updated.tsx index 23bc97236..fe8d863e9 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-updated.tsx +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-updated.tsx @@ -11,6 +11,7 @@ import { UnitalicBoldTimeFromNow } from './utils/unitalic-bold-time-from-now' import { UnitalicBoldTrans } from './utils/unitalic-bold-trans' import { DateTime } from 'luxon' import React, { useMemo } from 'react' +import { Pencil as IconPencil } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -38,7 +39,7 @@ export const NoteInfoLineUpdated: React.FC<NoteInfoTimeLineProps> = ({ size }) = }, [noteUpdateUser, size]) return ( - <NoteInfoLine icon={'pencil'} size={size}> + <NoteInfoLine icon={IconPencil} size={size}> <Trans i18nKey={'editor.modal.documentInfo.edited'}> {userBlock} <UnitalicBoldTimeFromNow time={noteUpdateDateTime} /> diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-word-count.tsx b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-word-count.tsx index 3d874816a..665eb9ecf 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-line-word-count.tsx +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-line-word-count.tsx @@ -14,6 +14,7 @@ import { NoteInfoLine } from './note-info-line' import { UnitalicBoldContent } from './unitalic-bold-content' import type { PropsWithChildren } from 'react' import React, { useCallback, useEffect, useState } from 'react' +import { AlignStart as IconAlignStart } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -38,7 +39,7 @@ export const NoteInfoLineWordCount: React.FC<PropsWithChildren<unknown>> = () => }, [editorToRendererCommunicator, rendererReady]) return ( - <NoteInfoLine icon={'align-left'} size={'2x'}> + <NoteInfoLine icon={IconAlignStart} size={2}> <ShowIf condition={wordCount === null}> <Trans i18nKey={'common.loading'} /> </ShowIf> diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-line.tsx b/frontend/src/components/editor-page/document-bar/note-info/note-info-line.tsx index 48b66746d..d89fdd9b5 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-line.tsx +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-line.tsx @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../../common/fork-awesome/types' +import { UiIcon } from '../../../common/icons/ui-icon' import type { PropsWithChildren } from 'react' import React from 'react' +import type { Icon } from 'react-bootstrap-icons' export interface NoteInfoLineProps { - icon: IconName - size?: '2x' | '3x' | '4x' | '5x' | undefined + icon: Icon + size?: 2 | 3 | 4 | 5 | undefined } /** @@ -24,7 +24,7 @@ export interface NoteInfoLineProps { export const NoteInfoLine: React.FC<PropsWithChildren<NoteInfoLineProps>> = ({ icon, size, children }) => { return ( <span className={'d-flex align-items-center'}> - <ForkAwesomeIcon icon={icon} size={size} fixedWidth={true} className={'mx-2'} /> + <UiIcon icon={icon} size={size} className={'mx-2'} /> <i className={'d-flex align-items-center'}>{children}</i> </span> ) diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-modal.tsx b/frontend/src/components/editor-page/document-bar/note-info/note-info-modal.tsx index 5720d88f3..b628a1caf 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-modal.tsx +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-modal.tsx @@ -33,10 +33,10 @@ export const NoteInfoModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) <Modal.Body> <ListGroup> <ListGroup.Item> - <NoteInfoLineCreated size={'2x'} /> + <NoteInfoLineCreated size={2} /> </ListGroup.Item> <ListGroup.Item> - <NoteInfoLineUpdated size={'2x'} /> + <NoteInfoLineUpdated size={2} /> </ListGroup.Item> <ListGroup.Item> <NoteInfoLineContributors /> diff --git a/frontend/src/components/editor-page/document-bar/note-info/note-info-time-line.ts b/frontend/src/components/editor-page/document-bar/note-info/note-info-time-line.ts index 658de67b0..414ab8082 100644 --- a/frontend/src/components/editor-page/document-bar/note-info/note-info-time-line.ts +++ b/frontend/src/components/editor-page/document-bar/note-info/note-info-time-line.ts @@ -4,5 +4,5 @@ * SPDX-License-Identifier: AGPL-3.0-only */ export interface NoteInfoTimeLineProps { - size?: '2x' | '3x' | '4x' | '5x' + size?: 2 | 3 | 4 | 5 } diff --git a/frontend/src/components/editor-page/document-bar/permissions/permission-add-entry-field.tsx b/frontend/src/components/editor-page/document-bar/permissions/permission-add-entry-field.tsx index 26c15e263..53802af8c 100644 --- a/frontend/src/components/editor-page/document-bar/permissions/permission-add-entry-field.tsx +++ b/frontend/src/components/editor-page/document-bar/permissions/permission-add-entry-field.tsx @@ -4,9 +4,10 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useOnInputChange } from '../../../../hooks/common/use-on-input-change' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import React, { useCallback, useState } from 'react' import { Button, FormControl, InputGroup } from 'react-bootstrap' +import { Plus as IconPlus } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface PermissionAddEntryFieldProps { @@ -35,7 +36,7 @@ export const PermissionAddEntryField: React.FC<PermissionAddEntryFieldProps> = ( <InputGroup className={'me-1 mb-1'}> <FormControl value={newEntryIdentifier} placeholder={t(i18nKey) ?? undefined} onChange={onChange} /> <Button variant='light' className={'text-secondary ms-2'} title={t(i18nKey) ?? undefined} onClick={onSubmit}> - <ForkAwesomeIcon icon={'plus'} /> + <UiIcon icon={IconPlus} /> </Button> </InputGroup> </li> diff --git a/frontend/src/components/editor-page/document-bar/permissions/permission-entry-buttons.tsx b/frontend/src/components/editor-page/document-bar/permissions/permission-entry-buttons.tsx index 7cae24e78..a899f0087 100644 --- a/frontend/src/components/editor-page/document-bar/permissions/permission-entry-buttons.tsx +++ b/frontend/src/components/editor-page/document-bar/permissions/permission-entry-buttons.tsx @@ -3,10 +3,13 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { AccessLevel } from './types' import React, { useMemo } from 'react' import { Button, ToggleButtonGroup } from 'react-bootstrap' +import { Eye as IconEye } from 'react-bootstrap-icons' +import { Pencil as IconPencil } from 'react-bootstrap-icons' +import { X as IconX } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' interface PermissionEntryButtonI18nKeys { @@ -73,20 +76,20 @@ export const PermissionEntryButtons: React.FC<PermissionEntryButtonsProps> = ({ className={'text-danger me-2'} title={t(i18nKeys.remove, { name }) ?? undefined} onClick={onRemove}> - <ForkAwesomeIcon icon={'times'} /> + <UiIcon icon={IconX} /> </Button> <ToggleButtonGroup type='radio' name='edit-mode' value={currentSetting}> <Button title={t(i18nKeys.setReadOnly, { name }) ?? undefined} variant={currentSetting === AccessLevel.READ_ONLY ? 'secondary' : 'outline-secondary'} onClick={onSetReadOnly}> - <ForkAwesomeIcon icon='eye' /> + <UiIcon icon={IconEye} /> </Button> <Button title={t(i18nKeys.setWriteable, { name }) ?? undefined} variant={currentSetting === AccessLevel.WRITEABLE ? 'secondary' : 'outline-secondary'} onClick={onSetWriteable}> - <ForkAwesomeIcon icon='pencil' /> + <UiIcon icon={IconPencil} /> </Button> </ToggleButtonGroup> </div> diff --git a/frontend/src/components/editor-page/document-bar/permissions/permission-entry-special-group.tsx b/frontend/src/components/editor-page/document-bar/permissions/permission-entry-special-group.tsx index f8f50cd99..2f72b36ea 100644 --- a/frontend/src/components/editor-page/document-bar/permissions/permission-entry-special-group.tsx +++ b/frontend/src/components/editor-page/document-bar/permissions/permission-entry-special-group.tsx @@ -6,11 +6,14 @@ import { removeGroupPermission, setGroupPermission } from '../../../../api/permissions' import { useApplicationState } from '../../../../hooks/common/use-application-state' import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { IconButton } from '../../../common/icon-button/icon-button' import { useUiNotifications } from '../../../notifications/ui-notification-boundary' import { AccessLevel, SpecialGroup } from './types' import React, { useCallback, useMemo } from 'react' -import { Button, ToggleButtonGroup } from 'react-bootstrap' +import { ToggleButtonGroup } from 'react-bootstrap' +import { Eye as IconEye } from 'react-bootstrap-icons' +import { Pencil as IconPencil } from 'react-bootstrap-icons' +import { SlashCircle as IconSlashCircle } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface PermissionEntrySpecialGroupProps { @@ -67,24 +70,27 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr <span>{name}</span> <div> <ToggleButtonGroup type='radio' name='edit-mode'> - <Button + <IconButton + icon={IconSlashCircle} title={t('editor.modal.permissions.denyGroup', { name }) ?? undefined} variant={level === AccessLevel.NONE ? 'secondary' : 'outline-secondary'} - onClick={onSetEntryDenied}> - <ForkAwesomeIcon icon={'ban'} /> - </Button> - <Button + onClick={onSetEntryDenied} + className={'p-1'} + /> + <IconButton + icon={IconEye} title={t('editor.modal.permissions.viewOnlyGroup', { name }) ?? undefined} variant={level === AccessLevel.READ_ONLY ? 'secondary' : 'outline-secondary'} - onClick={onSetEntryReadOnly}> - <ForkAwesomeIcon icon={'eye'} /> - </Button> - <Button + onClick={onSetEntryReadOnly} + className={'p-1'} + /> + <IconButton + icon={IconPencil} title={t('editor.modal.permissions.editGroup', { name }) ?? undefined} variant={level === AccessLevel.WRITEABLE ? 'secondary' : 'outline-secondary'} - onClick={() => onSetEntryWriteable}> - <ForkAwesomeIcon icon={'pencil'} /> - </Button> + onClick={onSetEntryWriteable} + className={'p-1'} + /> </ToggleButtonGroup> </div> </li> diff --git a/frontend/src/components/editor-page/document-bar/permissions/permission-owner-change.tsx b/frontend/src/components/editor-page/document-bar/permissions/permission-owner-change.tsx index 46de1aa27..5cad33660 100644 --- a/frontend/src/components/editor-page/document-bar/permissions/permission-owner-change.tsx +++ b/frontend/src/components/editor-page/document-bar/permissions/permission-owner-change.tsx @@ -4,9 +4,10 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useOnInputChange } from '../../../../hooks/common/use-on-input-change' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import React, { useCallback, useMemo, useState } from 'react' import { Button, FormControl, InputGroup } from 'react-bootstrap' +import { Check as IconCheck } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface PermissionOwnerChangeProps { @@ -44,7 +45,7 @@ export const PermissionOwnerChange: React.FC<PermissionOwnerChangeProps> = ({ on onClick={onClickConfirm} className={'ms-2'} disabled={confirmButtonDisabled}> - <ForkAwesomeIcon icon={'check'} /> + <UiIcon icon={IconCheck} /> </Button> </InputGroup> ) diff --git a/frontend/src/components/editor-page/document-bar/permissions/permission-owner-info.tsx b/frontend/src/components/editor-page/document-bar/permissions/permission-owner-info.tsx index 5e6755821..4ffacc033 100644 --- a/frontend/src/components/editor-page/document-bar/permissions/permission-owner-info.tsx +++ b/frontend/src/components/editor-page/document-bar/permissions/permission-owner-info.tsx @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useApplicationState } from '../../../../hooks/common/use-application-state' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { UserAvatarForUsername } from '../../../common/user-avatar/user-avatar-for-username' import React, { Fragment } from 'react' import { Button } from 'react-bootstrap' +import { Pencil as IconPencil } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface PermissionOwnerInfoProps { @@ -30,7 +31,7 @@ export const PermissionOwnerInfo: React.FC<PermissionOwnerInfoProps> = ({ onEdit variant='light' title={t('editor.modal.permissions.ownerChange.button') ?? undefined} onClick={onEditOwner}> - <ForkAwesomeIcon icon={'pencil'} /> + <UiIcon icon={IconPencil} /> </Button> </Fragment> ) diff --git a/frontend/src/components/editor-page/document-bar/revisions/revision-list-entry.tsx b/frontend/src/components/editor-page/document-bar/revisions/revision-list-entry.tsx index b3d7f8878..aae9e8f69 100644 --- a/frontend/src/components/editor-page/document-bar/revisions/revision-list-entry.tsx +++ b/frontend/src/components/editor-page/document-bar/revisions/revision-list-entry.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import type { RevisionMetadata } from '../../../../api/revisions/types' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { ShowIf } from '../../../common/show-if/show-if' import { UserAvatar } from '../../../common/user-avatar/user-avatar' import { WaitSpinner } from '../../../common/wait-spinner/wait-spinner' @@ -14,6 +14,9 @@ import { getUserDataForRevision } from './utils' import { DateTime } from 'luxon' import React, { useMemo } from 'react' import { ListGroup } from 'react-bootstrap' +import { Clock as IconClock } from 'react-bootstrap-icons' +import { FileText as IconFileText } from 'react-bootstrap-icons' +import { Person as IconPerson } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' import { useAsync } from 'react-use' @@ -57,15 +60,15 @@ export const RevisionListEntry: React.FC<RevisionListEntryProps> = ({ active, on action className={`${styles['revision-item']} d-flex flex-column`}> <span> - <ForkAwesomeIcon icon={'clock-o'} className='mx-2' /> + <UiIcon icon={IconClock} className='mx-2' /> {revisionCreationTime} </span> <span> - <ForkAwesomeIcon icon={'file-text-o'} className='mx-2' /> + <UiIcon icon={IconFileText} className='mx-2' /> <Trans i18nKey={'editor.modal.revision.length'} />: {revision.length} </span> <span className={'d-flex flex-row my-1 align-items-center'}> - <ForkAwesomeIcon icon={'user-o'} className={'mx-2'} /> + <UiIcon icon={IconPerson} className={'mx-2'} /> <ShowIf condition={revisionAuthors.loading}> <WaitSpinner /> </ShowIf> diff --git a/frontend/src/components/editor-page/document-bar/revisions/revision-modal.tsx b/frontend/src/components/editor-page/document-bar/revisions/revision-modal.tsx index 466c7c82c..035b80d67 100644 --- a/frontend/src/components/editor-page/document-bar/revisions/revision-modal.tsx +++ b/frontend/src/components/editor-page/document-bar/revisions/revision-modal.tsx @@ -11,6 +11,7 @@ import styles from './revision-modal.module.scss' import { RevisionViewer } from './revision-viewer' import React, { useState } from 'react' import { Col, Modal, Row } from 'react-bootstrap' +import { ClockHistory as IconClockHistory } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -28,7 +29,7 @@ export const RevisionModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) show={show} onHide={onHide} titleI18nKey={'editor.modal.revision.title'} - titleIcon={'history'} + titleIcon={IconClockHistory} showCloseButton={true} modalSize={'xl'} additionalClasses={styles['revision-modal']}> diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx index d95e0c384..186220d68 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/bold-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { TypeBold as IconTypeBold } from 'react-bootstrap-icons' /** * Renders a button to make the selection in the {@link Editor editor} bold. @@ -15,5 +16,5 @@ export const BoldButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '**', '**') }, []) - return <ToolbarButton i18nKey={'bold'} iconName={'bold'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'bold'} icon={IconTypeBold} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx index 4029984be..e1d6bca92 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/check-list-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { CheckSquare as IconCheckSquare } from 'react-bootstrap-icons' /** * Renders a button to create a checklist in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const CheckListButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return prependLinesOfSelection(markdownContent, currentSelection, () => `- [ ] `) }, []) - return <ToolbarButton i18nKey={'checkList'} iconName={'check-square'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'checkList'} icon={IconCheckSquare} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx index a346c18f1..1b87ff4ef 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/code-fence-button.tsx @@ -8,6 +8,7 @@ import { changeCursorsToWholeLineIfNoToCursor } from '../formatters/utils/change import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Code as IconCode } from 'react-bootstrap-icons' /** * Renders a button to create a code fence in the {@link Editor editor}. @@ -16,5 +17,5 @@ export const CodeFenceButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return wrapSelection(changeCursorsToWholeLineIfNoToCursor(markdownContent, currentSelection), '```\n', '\n```') }, []) - return <ToolbarButton i18nKey={'code'} iconName={'code'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'code'} icon={IconCode} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx index 7749eab0b..c47b4c8ec 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/collapsible-block-button.tsx @@ -8,6 +8,7 @@ import { changeCursorsToWholeLineIfNoToCursor } from '../formatters/utils/change import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { ArrowsCollapse as IconArrowsCollapse } from 'react-bootstrap-icons' /** * Renders a button to create a spoiler section in the {@link Editor editor}. @@ -20,7 +21,5 @@ export const CollapsibleBlockButton: React.FC = () => { '\n:::\n' ) }, []) - return ( - <ToolbarButton i18nKey={'collapsibleBlock'} iconName={'caret-square-o-down'} formatter={formatter}></ToolbarButton> - ) + return <ToolbarButton i18nKey={'collapsibleBlock'} icon={IconArrowsCollapse} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx index 7bfad486a..167b2c25c 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/comment-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { replaceSelection } from '../formatters/replace-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { ChatDots as IconChatDots } from 'react-bootstrap-icons' /** * Renders a button to create a comment in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const CommentButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return replaceSelection({ from: currentSelection.to ?? currentSelection.from }, '> []', true) }, []) - return <ToolbarButton i18nKey={'comment'} iconName={'comment'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'comment'} icon={IconChatDots} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx index 8d9d96654..112bf63e7 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/header-level-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { TypeH1 as IconTypeH1 } from 'react-bootstrap-icons' /** * Renders a button to add a header in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const HeaderLevelButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return prependLinesOfSelection(markdownContent, currentSelection, (line) => (line.startsWith('#') ? `#` : `# `)) }, []) - return <ToolbarButton i18nKey={'header'} iconName={'header'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'header'} icon={IconTypeH1} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx index 85abe6783..4e39ccf20 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/highlight-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Eraser as IconEraser } from 'react-bootstrap-icons' /** * Renders a button that highlights the selection in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const HighlightButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '==', '==') }, []) - return <ToolbarButton i18nKey={'highlight'} iconName={'eraser'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'highlight'} icon={IconEraser} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx index c33983ad3..46ba420d1 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/horizontal-line-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { replaceSelection } from '../formatters/replace-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { DashLg as IconDashLg } from 'react-bootstrap-icons' /** * Renders a button to insert a horizontal line in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const HorizontalLineButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return replaceSelection({ from: currentSelection.to ?? currentSelection.from }, '----\n', true) }, []) - return <ToolbarButton i18nKey={'horizontalLine'} iconName={'minus'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'horizontalLine'} icon={IconDashLg} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx index 7498e5875..d932f2806 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/image-link-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { addLink } from '../formatters/add-link' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Image as IconImage } from 'react-bootstrap-icons' /** * Renders a button to insert an image in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const ImageLinkButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return addLink(markdownContent, currentSelection, '!') }, []) - return <ToolbarButton i18nKey={'imageLink'} iconName={'picture-o'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'imageLink'} icon={IconImage} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx index c97d45d12..6d3e736cc 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/italic-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { TypeItalic as IconTypeItalic } from 'react-bootstrap-icons' /** * Renders a button to make the selection in the {@link Editor editor} italic. @@ -15,5 +16,5 @@ export const ItalicButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '*', '*') }, []) - return <ToolbarButton i18nKey={'italic'} iconName={'italic'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'italic'} icon={IconTypeItalic} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx index 84421b22f..211290d37 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/link-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { addLink } from '../formatters/add-link' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Link as IconLink } from 'react-bootstrap-icons' /** * Renders a button to insert a link in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const LinkButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return addLink(markdownContent, currentSelection) }, []) - return <ToolbarButton i18nKey={'link'} iconName={'link'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'link'} icon={IconLink} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx index 0c2ccb6a6..7bdf1f4b4 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/ordered-list-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { ListOl as IconListOl } from 'react-bootstrap-icons' /** * Renders a button to insert an ordered list in the {@link Editor editor}. @@ -19,5 +20,5 @@ export const OrderedListButton: React.FC = () => { (line, lineIndexInBlock) => `${lineIndexInBlock + 1}. ` ) }, []) - return <ToolbarButton i18nKey={'orderedList'} iconName={'list-ol'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'orderedList'} icon={IconListOl} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx index 8e1437f5b..3f49240be 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/quotes-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Quote as IconQuote } from 'react-bootstrap-icons' /** * Renders a button to insert a quotation in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const QuotesButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return prependLinesOfSelection(markdownContent, currentSelection, () => `> `) }, []) - return <ToolbarButton i18nKey={'blockquote'} iconName={'quote-right'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'blockquote'} icon={IconQuote} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx index c5edca5a3..845c81ba1 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/strikethrough-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { TypeStrikethrough as IconTypeStrikethrough } from 'react-bootstrap-icons' /** * Renders a button to strike through the selection in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const StrikethroughButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '~~', '~~') }, []) - return <ToolbarButton i18nKey={'strikethrough'} iconName={'strikethrough'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'strikethrough'} icon={IconTypeStrikethrough} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx index 3459a43ff..a9943bf8f 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/subscript-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Subscript as IconSubscript } from 'react-bootstrap-icons' /** * Renders a button to format the selection in the {@link Editor editor} as subscript. @@ -15,5 +16,5 @@ export const SubscriptButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '~', '~') }, []) - return <ToolbarButton i18nKey={'subscript'} iconName={'subscript'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'subscript'} icon={IconSubscript} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx index eb3313548..abb63668c 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/superscript-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { Superscript as IconSuperscript } from 'react-bootstrap-icons' /** * Renders a button to format the selection in the {@link Editor editor} as superscript. @@ -15,5 +16,5 @@ export const SuperscriptButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '^', '^') }, []) - return <ToolbarButton i18nKey={'superscript'} iconName={'superscript'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'superscript'} icon={IconSuperscript} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx index b554a83af..17e44f6db 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/underline-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { wrapSelection } from '../formatters/wrap-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { TypeUnderline as IconTypeUnderline } from 'react-bootstrap-icons' /** * Renders a button to underline the selection in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const UnderlineButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection }) => { return wrapSelection(currentSelection, '++', '++') }, []) - return <ToolbarButton i18nKey={'underline'} iconName={'underline'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'underline'} icon={IconTypeUnderline} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx index 7adfc7a6b..90a3281b8 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/buttons/unordered-list-button.tsx @@ -7,6 +7,7 @@ import type { ContentFormatter } from '../../../change-content-context/change-co import { prependLinesOfSelection } from '../formatters/prepend-lines-of-selection' import { ToolbarButton } from '../toolbar-button' import React, { useCallback } from 'react' +import { List as IconList } from 'react-bootstrap-icons' /** * Renders a button to insert an unordered list in the {@link Editor editor}. @@ -15,5 +16,5 @@ export const UnorderedListButton: React.FC = () => { const formatter: ContentFormatter = useCallback(({ currentSelection, markdownContent }) => { return prependLinesOfSelection(markdownContent, currentSelection, () => `- `) }, []) - return <ToolbarButton i18nKey={'unorderedList'} iconName={'list'} formatter={formatter}></ToolbarButton> + return <ToolbarButton i18nKey={'unorderedList'} icon={IconList} formatter={formatter}></ToolbarButton> } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx index c29e5fb61..fc2bc753a 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-button.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../../common/icons/ui-icon' import { useChangeEditorContentCallback } from '../../../change-content-context/use-change-editor-content-callback' import { replaceSelection } from '../formatters/replace-selection' import { EmojiPickerPopover } from './emoji-picker-popover' @@ -13,6 +13,7 @@ import { extractEmojiShortCode } from './extract-emoji-short-code' import type { EmojiClickEventDetail } from 'emoji-picker-element/shared' import React, { Fragment, useCallback, useRef, useState } from 'react' import { Button, Overlay } from 'react-bootstrap' +import { EmojiSmile as IconEmojiSmile } from 'react-bootstrap-icons' import type { OverlayInjectedProps } from 'react-bootstrap/Overlay' import { useTranslation } from 'react-i18next' @@ -63,7 +64,7 @@ export const EmojiPickerButton: React.FC = () => { title={t('editor.editorToolbar.emoji') ?? undefined} disabled={!changeEditorContent} ref={buttonRef}> - <ForkAwesomeIcon icon='smile-o' /> + <UiIcon icon={IconEmojiSmile} /> </Button> </Fragment> ) diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-popover.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-popover.tsx index 348979cda..288864546 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-popover.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/emoji-picker-popover.tsx @@ -1,30 +1,21 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import fontStyles from '../../../../../../global-styles/variables.module.scss' import { useDarkModeState } from '../../../../../hooks/common/use-dark-mode-state' -import { ForkAwesomeIcons } from '../../../../common/fork-awesome/fork-awesome-icons' import styles from './emoji-picker.module.scss' -import forkawesomeIcon from './forkawesome.png' import { Picker } from 'emoji-picker-element' -import type { CustomEmoji, EmojiClickEvent, EmojiClickEventDetail } from 'emoji-picker-element/shared' +import type { EmojiClickEvent, EmojiClickEventDetail } from 'emoji-picker-element/shared' +import type { PickerConstructorOptions } from 'emoji-picker-element/shared' import React, { useEffect, useRef } from 'react' import { Popover } from 'react-bootstrap' import type { PopoverProps } from 'react-bootstrap/Popover' -const customEmojis: CustomEmoji[] = ForkAwesomeIcons.map((name) => ({ - name: `fa-${name}`, - shortcodes: [`fa-${name.toLowerCase()}`], - url: forkawesomeIcon.src, - category: 'ForkAwesome' -})) - const EMOJI_DATA_PATH = '_next/static/js/emoji-data.json' -const emojiPickerConfig = { - customEmoji: customEmojis, +const emojiPickerConfig: PickerConstructorOptions = { dataSource: EMOJI_DATA_PATH } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/forkawesome.png b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/forkawesome.png deleted file mode 100644 index c1a976795..000000000 Binary files a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/forkawesome.png and /dev/null differ diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/forkawesome.png.license b/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/forkawesome.png.license deleted file mode 100644 index e2be82106..000000000 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/emoji-picker/forkawesome.png.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2018 Dave Gandy & Fork Awesome - -SPDX-License-Identifier: OFL-1.1 diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/custom-table-size-modal.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/custom-table-size-modal.tsx index 8f67eff6b..6414c35bd 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/custom-table-size-modal.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/custom-table-size-modal.tsx @@ -4,12 +4,14 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../../common/icons/ui-icon' import { CommonModal } from '../../../../common/modals/common-modal' import type { TableSize } from './table-size-picker-popover' import type { ChangeEvent } from 'react' import React, { useCallback, useEffect, useState } from 'react' import { Button, Form, ModalFooter } from 'react-bootstrap' +import { Table as IconTable } from 'react-bootstrap-icons' +import { X as IconX } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface CustomTableSizeModalProps { @@ -67,7 +69,7 @@ export const CustomTableSizeModal: React.FC<CustomTableSizeModalProps> = ({ show onHide={onDismiss} titleI18nKey={'editor.editorToolbar.table.customSize'} showCloseButton={true} - titleIcon={'table'} + titleIcon={IconTable} {...cypressId('custom-table-size-modal')}> <div className={'col-lg-10 d-flex flex-row p-3 align-items-center'}> <Form.Control @@ -77,7 +79,7 @@ export const CustomTableSizeModal: React.FC<CustomTableSizeModalProps> = ({ show isInvalid={tableSize.columns <= 0} onChange={onColChange} /> - <ForkAwesomeIcon icon='times' className='mx-2' fixedWidth={true} /> + <UiIcon icon={IconX} className='mx-2' /> <Form.Control type={'number'} min={1} diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx index b7edae4a5..f4a243fc9 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-picker-button.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../../common/icons/ui-icon' import { useChangeEditorContentCallback } from '../../../change-content-context/use-change-editor-content-callback' import { replaceSelection } from '../formatters/replace-selection' import { createMarkdownTable } from './create-markdown-table' @@ -13,6 +13,7 @@ import './table-picker.module.scss' import { TableSizePickerPopover } from './table-size-picker-popover' import React, { Fragment, useCallback, useMemo, useRef, useState } from 'react' import { Button, Overlay } from 'react-bootstrap' +import { Table as IconTable } from 'react-bootstrap-icons' import type { OverlayInjectedProps } from 'react-bootstrap/Overlay' import { useTranslation } from 'react-i18next' @@ -77,7 +78,7 @@ export const TablePickerButton: React.FC = () => { title={tableTitle} ref={button} disabled={!changeEditorContent}> - <ForkAwesomeIcon icon='table' /> + <UiIcon icon={IconTable} /> </Button> <Overlay target={button.current} diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-size-picker-popover.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-size-picker-popover.tsx index c0a67a464..78012f555 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-size-picker-popover.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/table-picker/table-size-picker-popover.tsx @@ -4,12 +4,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressAttribute, cypressId } from '../../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../../common/icons/ui-icon' import { createNumberRangeArray } from '../../../../common/number-range/number-range' import styles from './table-picker.module.scss' import { TableSizeText } from './table-size-text' import React, { useCallback, useMemo, useState } from 'react' import { Button, Popover } from 'react-bootstrap' +import { Table as IconTable } from 'react-bootstrap-icons' import type { PopoverProps } from 'react-bootstrap/Popover' import { Trans, useTranslation } from 'react-i18next' @@ -79,7 +80,7 @@ export const TableSizePickerPopover = React.forwardRef<HTMLDivElement, TableSize </div> <div className='d-flex justify-content-center mt-2'> <Button {...cypressId('show-custom-table-modal')} className={'text-center'} onClick={onShowCustomSizeModal}> - <ForkAwesomeIcon icon='table' /> + <UiIcon icon={IconTable} /> &nbsp; <Trans i18nKey={'editor.editorToolbar.table.customSize'} /> </Button> diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx index 1cb22768c..38a720bde 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/toolbar-button.tsx @@ -4,17 +4,17 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../../common/fork-awesome/types' +import { UiIcon } from '../../../common/icons/ui-icon' import type { ContentFormatter } from '../../change-content-context/change-content-context' import { useChangeEditorContentCallback } from '../../change-content-context/use-change-editor-content-callback' import React, { useCallback, useMemo } from 'react' import { Button } from 'react-bootstrap' +import type { Icon } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export interface ToolbarButtonProps { i18nKey: string - iconName: IconName + icon: Icon formatter: ContentFormatter } @@ -25,7 +25,7 @@ export interface ToolbarButtonProps { * @param iconName A fork awesome icon name that is shown in the button * @param formatter The formatter function changes the editor content on click */ -export const ToolbarButton: React.FC<ToolbarButtonProps> = ({ i18nKey, iconName, formatter }) => { +export const ToolbarButton: React.FC<ToolbarButtonProps> = ({ i18nKey, icon, formatter }) => { const { t } = useTranslation('', { keyPrefix: 'editor.editorToolbar' }) const changeEditorContent = useChangeEditorContentCallback() @@ -41,7 +41,7 @@ export const ToolbarButton: React.FC<ToolbarButtonProps> = ({ i18nKey, iconName, title={title} disabled={!changeEditorContent} {...cypressId('toolbar.' + i18nKey)}> - <ForkAwesomeIcon icon={iconName} /> + <UiIcon icon={icon} /> </Button> ) } diff --git a/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx b/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx index 0fb1929ca..7402b12f2 100644 --- a/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx +++ b/frontend/src/components/editor-page/editor-pane/tool-bar/upload-image-button/upload-image-button.tsx @@ -5,7 +5,7 @@ */ import { cypressId } from '../../../../../utils/cypress-attribute' import { Logger } from '../../../../../utils/logger' -import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../../common/icons/ui-icon' import { ShowIf } from '../../../../common/show-if/show-if' import { acceptedMimeTypes } from '../../../../common/upload-image-mimetypes' import { useCodeMirrorReference } from '../../../change-content-context/change-content-context' @@ -15,6 +15,7 @@ import { extractSelectedText } from './extract-selected-text' import { Optional } from '@mrdrogdrog/optional' import React, { Fragment, useCallback, useRef } from 'react' import { Button } from 'react-bootstrap' +import { Upload as IconUpload } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' const logger = new Logger('Upload image button') @@ -54,7 +55,7 @@ export const UploadImageButton: React.FC = () => { disabled={!codeMirror} title={t('editor.editorToolbar.uploadImage') ?? undefined} {...cypressId('editor-toolbar-upload-image-button')}> - <ForkAwesomeIcon icon={'upload'} /> + <UiIcon icon={IconUpload} /> </Button> <ShowIf condition={!!codeMirror}> <UploadInput diff --git a/frontend/src/components/editor-page/sidebar/delete-note-sidebar-entry/delete-note-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/delete-note-sidebar-entry/delete-note-sidebar-entry.tsx index 65e4f492a..9e8484762 100644 --- a/frontend/src/components/editor-page/sidebar/delete-note-sidebar-entry/delete-note-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/delete-note-sidebar-entry/delete-note-sidebar-entry.tsx @@ -15,6 +15,7 @@ import { DeleteNoteModal } from './delete-note-modal' import { useRouter } from 'next/router' import type { PropsWithChildren } from 'react' import React, { Fragment, useCallback } from 'react' +import { Trash as IconTrash } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' const logger = new Logger('note-deletion') @@ -45,7 +46,7 @@ export const DeleteNoteSidebarEntry: React.FC<PropsWithChildren<SpecificSidebarE <Fragment> <SidebarButton {...cypressId('sidebar.deleteNote.button')} - icon={'trash'} + icon={IconTrash} className={className} hide={hide} onClick={showModal}> diff --git a/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx b/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx index 61154be09..8c166a8c0 100644 --- a/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx +++ b/frontend/src/components/editor-page/sidebar/sidebar-button/sidebar-button.tsx @@ -3,8 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../../common/fork-awesome/types' +import { UiIcon } from '../../../common/icons/ui-icon' import { ShowIf } from '../../../common/show-if/show-if' import type { SidebarEntryProps } from '../types' import styles from './sidebar-button.module.scss' @@ -40,7 +39,7 @@ export const SidebarButton: React.FC<PropsWithChildren<SidebarEntryProps>> = ({ {...props}> <ShowIf condition={!!icon}> <span className={`sidebar-button-icon ${styles['sidebar-icon']}`}> - <ForkAwesomeIcon icon={icon as IconName} /> + <UiIcon icon={icon} /> </span> </ShowIf> <span className={styles['sidebar-text']}>{children}</span> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry.tsx index 1dfeb2f1a..c7bc3b797 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry.tsx @@ -8,6 +8,7 @@ import { AliasesModal } from '../../document-bar/aliases/aliases-modal' import { SidebarButton } from '../sidebar-button/sidebar-button' import type { SpecificSidebarEntryProps } from '../types' import React, { Fragment } from 'react' +import { Tags as IconTags } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -22,7 +23,7 @@ export const AliasesSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ class return ( <Fragment> - <SidebarButton hide={hide} className={className} icon={'tags'} onClick={setShowModal}> + <SidebarButton hide={hide} className={className} icon={IconTags} onClick={setShowModal}> <Trans i18nKey={'editor.modal.aliases.title'} /> </SidebarButton> <AliasesModal show={showModal} onHide={setHideModal} /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-markdown-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-markdown-sidebar-entry.tsx index 1f54b6e1f..45aab361a 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-markdown-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-markdown-sidebar-entry.tsx @@ -9,6 +9,7 @@ import { cypressId } from '../../../../utils/cypress-attribute' import { download } from '../../../common/download/download' import { SidebarButton } from '../sidebar-button/sidebar-button' import React, { useCallback } from 'react' +import { FileText as IconFileText } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' import sanitize from 'sanitize-filename' @@ -24,7 +25,7 @@ export const ExportMarkdownSidebarEntry: React.FC = () => { }, [markdownContent, t]) return ( - <SidebarButton {...cypressId('menu-export-markdown')} onClick={onClick} icon={'file-text'}> + <SidebarButton {...cypressId('menu-export-markdown')} onClick={onClick} icon={IconFileText}> <Trans i18nKey={'editor.export.markdown-file'} /> </SidebarButton> ) diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-menu-sidebar-menu.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-menu-sidebar-menu.tsx index 2ae37fa41..0c23c33d1 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-menu-sidebar-menu.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/export-menu-sidebar-menu.tsx @@ -10,6 +10,11 @@ import type { SpecificSidebarMenuProps } from '../types' import { DocumentSidebarMenuSelection } from '../types' import { ExportMarkdownSidebarEntry } from './export-markdown-sidebar-entry' import React, { Fragment, useCallback } from 'react' +import { ArrowLeft as IconArrowLeft } from 'react-bootstrap-icons' +import { CloudDownload as IconCloudDownload } from 'react-bootstrap-icons' +import { FileCode as IconFileCode } from 'react-bootstrap-icons' +import { Git as IconGit } from 'react-bootstrap-icons' +import { Github as IconGithub } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -33,25 +38,25 @@ export const ExportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({ const onClickHandler = useCallback(() => { onClick(menuId) }, [menuId, onClick]) - + //todo: replace git with gitlab icon return ( <Fragment> <SidebarButton {...cypressId('menu-export')} hide={hide} - icon={expand ? 'arrow-left' : 'cloud-download'} + icon={expand ? IconArrowLeft : IconCloudDownload} className={className} onClick={onClickHandler}> <Trans i18nKey={'editor.documentBar.export'} /> </SidebarButton> <SidebarMenu expand={expand}> - <SidebarButton icon={'github'}>Gist</SidebarButton> - <SidebarButton icon={'gitlab'}>Gitlab Snippet</SidebarButton> + <SidebarButton icon={IconGithub}>Gist</SidebarButton> + <SidebarButton icon={IconGit}>Gitlab Snippet</SidebarButton> <ExportMarkdownSidebarEntry /> - <SidebarButton icon={'file-code-o'}>HTML</SidebarButton> - <SidebarButton icon={'file-code-o'}> + <SidebarButton icon={IconFileCode}>HTML</SidebarButton> + <SidebarButton icon={IconFileCode}> <Trans i18nKey='editor.export.rawHtml' /> </SidebarButton> </SidebarMenu> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx index d4fe74c76..c003dc0d2 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-markdown-sidebar-entry.tsx @@ -10,6 +10,7 @@ import { useChangeEditorContentCallback } from '../../change-content-context/use import { SidebarButton } from '../sidebar-button/sidebar-button' import { UploadInput } from '../upload-input' import React, { Fragment, useCallback, useRef } from 'react' +import { FileText as IconFileText } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -48,7 +49,7 @@ export const ImportMarkdownSidebarEntry: React.FC = () => { <Fragment> <SidebarButton {...cypressId('menu-import-markdown-button')} - icon={'file-text-o'} + icon={IconFileText} onClick={buttonClick} disabled={!changeEditorContent}> <Trans i18nKey={'editor.import.file'} /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-menu-sidebar-menu.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-menu-sidebar-menu.tsx index bf706cdb9..19b6d33e7 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-menu-sidebar-menu.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/import-menu-sidebar-menu.tsx @@ -10,6 +10,11 @@ import type { SpecificSidebarMenuProps } from '../types' import { DocumentSidebarMenuSelection } from '../types' import { ImportMarkdownSidebarEntry } from './import-markdown-sidebar-entry' import React, { Fragment, useCallback } from 'react' +import { ArrowLeft as IconArrowLeft } from 'react-bootstrap-icons' +import { Clipboard as IconClipboard } from 'react-bootstrap-icons' +import { CloudUpload as IconCloudUpload } from 'react-bootstrap-icons' +import { Git as IconGit } from 'react-bootstrap-icons' +import { Github as IconGithub } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -33,21 +38,21 @@ export const ImportMenuSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({ const onClickHandler = useCallback(() => { onClick(menuId) }, [menuId, onClick]) - + //todo: replace git with gitlab return ( <Fragment> <SidebarButton {...cypressId('menu-import')} hide={hide} - icon={expand ? 'arrow-left' : 'cloud-upload'} + icon={expand ? IconArrowLeft : IconCloudUpload} className={className} onClick={onClickHandler}> <Trans i18nKey={'editor.documentBar.import'} /> </SidebarButton> <SidebarMenu expand={expand}> - <SidebarButton icon={'github'}>Gist</SidebarButton> - <SidebarButton icon={'gitlab'}>Gitlab Snippet</SidebarButton> - <SidebarButton icon={'clipboard'}> + <SidebarButton icon={IconGithub}>Gist</SidebarButton> + <SidebarButton icon={IconGit}>Gitlab Snippet</SidebarButton> + <SidebarButton icon={IconClipboard}> <Trans i18nKey={'editor.import.clipboard'} /> </SidebarButton> <ImportMarkdownSidebarEntry /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-entry.tsx index 1e425a6f7..80a4068db 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/note-info-sidebar-entry.tsx @@ -9,6 +9,7 @@ import { NoteInfoModal } from '../../document-bar/note-info/note-info-modal' import { SidebarButton } from '../sidebar-button/sidebar-button' import type { SpecificSidebarEntryProps } from '../types' import React, { Fragment } from 'react' +import { GraphUp as IconGraphUp } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -26,7 +27,7 @@ export const NoteInfoSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ clas <SidebarButton hide={hide} className={className} - icon={'line-chart'} + icon={IconGraphUp} onClick={showModal} {...cypressId('sidebar-btn-document-info')}> <Trans i18nKey={'editor.modal.documentInfo.title'} /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry.tsx index d8f2041f9..fb7fb8a3d 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry.tsx @@ -8,6 +8,7 @@ import { PermissionModal } from '../../document-bar/permissions/permission-modal import { SidebarButton } from '../sidebar-button/sidebar-button' import type { SpecificSidebarEntryProps } from '../types' import React, { Fragment } from 'react' +import { Lock as IconLock } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -22,7 +23,7 @@ export const PermissionsSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ c return ( <Fragment> - <SidebarButton hide={hide} className={className} icon={'lock'} onClick={showModal}> + <SidebarButton hide={hide} className={className} icon={IconLock} onClick={showModal}> <Trans i18nKey={'editor.modal.permissions.title'} /> </SidebarButton> <PermissionModal show={modalVisibility} onHide={closeModal} /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/pin-note-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/pin-note-sidebar-entry.tsx index 704d324a9..b2f1416b0 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/pin-note-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/pin-note-sidebar-entry.tsx @@ -10,6 +10,7 @@ import { SidebarButton } from '../sidebar-button/sidebar-button' import type { SpecificSidebarEntryProps } from '../types' import styles from './pin-note-sidebar-entry.module.css' import React, { useCallback, useMemo } from 'react' +import { Pin as IconPin } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -38,7 +39,7 @@ export const PinNoteSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ class return ( <SidebarButton - icon={'thumb-tack'} + icon={IconPin} hide={hide} onClick={onPinClicked} className={`${className ?? ''} ${isPinned ? styles['highlighted'] : ''}`}> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revision-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revision-sidebar-entry.tsx index a0c0452b7..c93282ce6 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revision-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/revision-sidebar-entry.tsx @@ -8,6 +8,7 @@ import { RevisionModal } from '../../document-bar/revisions/revision-modal' import { SidebarButton } from '../sidebar-button/sidebar-button' import type { SpecificSidebarEntryProps } from '../types' import React, { Fragment } from 'react' +import { ClockHistory as IconClockHistory } from 'react-bootstrap-icons' import { Trans } from 'react-i18next' /** @@ -21,7 +22,7 @@ export const RevisionSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ clas return ( <Fragment> - <SidebarButton hide={hide} className={className} icon={'history'} onClick={showModal}> + <SidebarButton hide={hide} className={className} icon={IconClockHistory} onClick={showModal}> <Trans i18nKey={'editor.modal.revision.title'} /> </SidebarButton> <RevisionModal show={modalVisibility} onHide={closeModal} /> diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-sidebar-entry.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-sidebar-entry.tsx index c741fdb36..ea5978463 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-sidebar-entry.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/share-sidebar-entry.tsx @@ -8,6 +8,7 @@ import { ShareModal } from '../../document-bar/share/share-modal' import { SidebarButton } from '../sidebar-button/sidebar-button' import type { SpecificSidebarEntryProps } from '../types' import React, { Fragment } from 'react' +import { Share as IconShare } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -22,7 +23,7 @@ export const ShareSidebarEntry: React.FC<SpecificSidebarEntryProps> = ({ classNa return ( <Fragment> - <SidebarButton hide={hide} className={className} icon={'share'} onClick={showModal}> + <SidebarButton hide={hide} className={className} icon={IconShare} onClick={showModal}> <Trans i18nKey={'editor.modal.shareLink.title'} /> </SidebarButton> <ShareModal show={modalVisibility} onHide={closeModal} /> diff --git a/frontend/src/components/editor-page/sidebar/types.ts b/frontend/src/components/editor-page/sidebar/types.ts index d664be4e9..97979ed62 100644 --- a/frontend/src/components/editor-page/sidebar/types.ts +++ b/frontend/src/components/editor-page/sidebar/types.ts @@ -4,8 +4,8 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import type { PropsWithDataCypressId } from '../../../utils/cypress-attribute' -import type { IconName } from '../../common/fork-awesome/types' import type { RefObject } from 'react' +import type { Icon } from 'react-bootstrap-icons' export interface SpecificSidebarEntryProps { className?: string @@ -14,7 +14,7 @@ export interface SpecificSidebarEntryProps { } export interface SidebarEntryProps extends PropsWithDataCypressId { - icon?: IconName + icon?: Icon buttonRef?: RefObject<HTMLButtonElement> hide?: boolean className?: string diff --git a/frontend/src/components/editor-page/sidebar/users-online-sidebar-menu/users-online-sidebar-menu.tsx b/frontend/src/components/editor-page/sidebar/users-online-sidebar-menu/users-online-sidebar-menu.tsx index b9aec7ece..040928bd7 100644 --- a/frontend/src/components/editor-page/sidebar/users-online-sidebar-menu/users-online-sidebar-menu.tsx +++ b/frontend/src/components/editor-page/sidebar/users-online-sidebar-menu/users-online-sidebar-menu.tsx @@ -11,6 +11,8 @@ import { DocumentSidebarMenuSelection } from '../types' import { UserLine } from '../user-line/user-line' import styles from './online-counter.module.scss' import React, { Fragment, useCallback, useEffect, useMemo, useRef } from 'react' +import { ArrowLeft as IconArrowLeft } from 'react-bootstrap-icons' +import { People as IconPeople } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -68,7 +70,7 @@ export const UsersOnlineSidebarMenu: React.FC<SpecificSidebarMenuProps> = ({ hide={hide} buttonRef={buttonRef} onClick={onClickHandler} - icon={expand ? 'arrow-left' : 'users'} + icon={expand ? IconArrowLeft : IconPeople} className={`${styles['online-entry']} ${className ?? ''}`}> <Trans i18nKey={'editor.onlineStatus.online'} /> </SidebarButton> diff --git a/frontend/src/components/editor-page/splitter/__snapshots__/splitter.test.tsx.snap b/frontend/src/components/editor-page/splitter/__snapshots__/splitter.test.tsx.snap index d1a0c60cb..cecea1518 100644 --- a/frontend/src/components/editor-page/splitter/__snapshots__/splitter.test.tsx.snap +++ b/frontend/src/components/editor-page/splitter/__snapshots__/splitter.test.tsx.snap @@ -29,24 +29,18 @@ exports[`Splitter resize can change size with mouse 1`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -94,24 +88,18 @@ exports[`Splitter resize can change size with mouse 2`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -159,24 +147,18 @@ exports[`Splitter resize can change size with mouse 3`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -224,24 +206,18 @@ exports[`Splitter resize can change size with mouse 4`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -289,24 +265,18 @@ exports[`Splitter resize can change size with touch 1`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -354,24 +324,18 @@ exports[`Splitter resize can change size with touch 2`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -419,24 +383,18 @@ exports[`Splitter resize can change size with touch 3`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -484,24 +442,18 @@ exports[`Splitter resize can change size with touch 4`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -549,24 +501,18 @@ exports[`Splitter resize can react to shortcuts 1`] = ` class="btn btn-secondary" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -614,24 +560,18 @@ exports[`Splitter resize can react to shortcuts 2`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-secondary" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> @@ -679,24 +619,18 @@ exports[`Splitter resize can react to shortcuts 3`] = ` class="btn btn-light" type="button" > - <i - class="fa fa-arrow-left " - /> + BootstrapIconMock_ArrowLeft </button> <span class="grabber" > - <i - class="fa fa-arrows-h " - /> + BootstrapIconMock_ArrowLeftRight </span> <button class="btn btn-light" type="button" > - <i - class="fa fa-arrow-right " - /> + BootstrapIconMock_ArrowRight </button> </div> </div> diff --git a/frontend/src/components/editor-page/splitter/split-divider/split-divider.tsx b/frontend/src/components/editor-page/splitter/split-divider/split-divider.tsx index 013a4b6fb..42393b9dc 100644 --- a/frontend/src/components/editor-page/splitter/split-divider/split-divider.tsx +++ b/frontend/src/components/editor-page/splitter/split-divider/split-divider.tsx @@ -4,10 +4,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { testId } from '../../../../utils/test-id' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import styles from './split-divider.module.scss' import React from 'react' import { Button } from 'react-bootstrap' +import { ArrowLeftRight as IconArrowLeftRight } from 'react-bootstrap-icons' +import { ArrowLeft as IconArrowLeft } from 'react-bootstrap-icons' +import { ArrowRight as IconArrowRight } from 'react-bootstrap-icons' export enum DividerButtonsShift { SHIFT_TO_LEFT = 'shift-left', @@ -53,13 +56,13 @@ export const SplitDivider: React.FC<SplitDividerProps> = ({ <div className={`bg-light ${styles['middle']} ${forceOpen ? styles['open'] : ''} ${shiftClass}`}> <div className={styles['buttons']}> <Button variant={focusLeft ? 'secondary' : 'light'} onClick={onLeftButtonClick}> - <ForkAwesomeIcon icon={'arrow-left'} /> + <UiIcon icon={IconArrowLeft} /> </Button> <span onMouseDown={onGrab} onTouchStart={onGrab} className={styles['grabber']}> - <ForkAwesomeIcon icon={'arrows-h'} /> + <UiIcon icon={IconArrowLeftRight} /> </span> <Button variant={focusRight ? 'secondary' : 'light'} onClick={onRightButtonClick}> - <ForkAwesomeIcon icon={'arrow-right'} /> + <UiIcon icon={IconArrowRight} /> </Button> </div> </div> diff --git a/frontend/src/components/error-boundary/error-boundary.tsx b/frontend/src/components/error-boundary/error-boundary.tsx index c3167dc73..e02058057 100644 --- a/frontend/src/components/error-boundary/error-boundary.tsx +++ b/frontend/src/components/error-boundary/error-boundary.tsx @@ -6,11 +6,12 @@ import links from '../../links.json' import { Logger } from '../../utils/logger' import frontendVersion from '../../version.json' -import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../common/icons/ui-icon' import { ExternalLink } from '../common/links/external-link' import type { ErrorInfo, PropsWithChildren, ReactNode } from 'react' import React, { Component } from 'react' import { Button, Container } from 'react-bootstrap' +import { ArrowRepeat as IconArrowRepeat } from 'react-bootstrap-icons' const log = new Logger('ErrorBoundary') @@ -60,7 +61,7 @@ export class ErrorBoundary extends Component<PropsWithChildren<unknown>> { /> &#32; or <ExternalLink text={'contact us on matrix.'} href={links.chat} className={'text-primary'} /> <Button onClick={() => this.refreshPage()} title={'Reload App'} className={'mt-4'}> - <ForkAwesomeIcon icon={'refresh'} /> + <UiIcon icon={IconArrowRepeat} /> &nbsp;Reload App </Button> </div> diff --git a/frontend/src/components/history-page/entry-menu/delete-note-item.tsx b/frontend/src/components/history-page/entry-menu/delete-note-item.tsx index af26d8fe0..7f67d68ee 100644 --- a/frontend/src/components/history-page/entry-menu/delete-note-item.tsx +++ b/frontend/src/components/history-page/entry-menu/delete-note-item.tsx @@ -5,6 +5,7 @@ */ import { DropdownItemWithDeletionModal } from './dropdown-item-with-deletion-modal' import React from 'react' +import { Trash as IconTrash } from 'react-bootstrap-icons' export interface DeleteNoteItemProps { onConfirm: () => void @@ -22,7 +23,7 @@ export const DeleteNoteItem: React.FC<DeleteNoteItemProps> = ({ noteTitle, onCon <DropdownItemWithDeletionModal onConfirm={onConfirm} itemI18nKey={'landing.history.menu.deleteNote'} - modalIcon={'trash'} + modalIcon={IconTrash} noteTitle={noteTitle} /> ) diff --git a/frontend/src/components/history-page/entry-menu/dropdown-item-with-deletion-modal.tsx b/frontend/src/components/history-page/entry-menu/dropdown-item-with-deletion-modal.tsx index 91d4fe2df..ba78c6ee0 100644 --- a/frontend/src/components/history-page/entry-menu/dropdown-item-with-deletion-modal.tsx +++ b/frontend/src/components/history-page/entry-menu/dropdown-item-with-deletion-modal.tsx @@ -4,18 +4,18 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useBooleanState } from '../../../hooks/common/use-boolean-state' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../common/fork-awesome/types' +import { UiIcon } from '../../common/icons/ui-icon' import type { DeleteHistoryNoteModalProps } from '../../editor-page/sidebar/delete-note-sidebar-entry/delete-note-modal' import { DeleteNoteModal } from '../../editor-page/sidebar/delete-note-sidebar-entry/delete-note-modal' import React, { Fragment, useCallback } from 'react' import { Dropdown } from 'react-bootstrap' +import type { Icon } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface DropdownItemWithDeletionModalProps { onConfirm: () => void itemI18nKey: string - modalIcon: IconName + modalIcon: Icon noteTitle: string className?: string } @@ -57,7 +57,7 @@ export const DropdownItemWithDeletionModal: React.FC< return ( <Fragment> <Dropdown.Item onClick={showModal} className={className}> - <ForkAwesomeIcon icon={modalIcon} fixedWidth={true} className='mx-2' /> + <UiIcon icon={modalIcon} className='mx-2' /> <Trans i18nKey={itemI18nKey} /> </Dropdown.Item> <DeleteNoteModal diff --git a/frontend/src/components/history-page/entry-menu/entry-menu.tsx b/frontend/src/components/history-page/entry-menu/entry-menu.tsx index 773757090..8bdf8557c 100644 --- a/frontend/src/components/history-page/entry-menu/entry-menu.tsx +++ b/frontend/src/components/history-page/entry-menu/entry-menu.tsx @@ -6,13 +6,16 @@ import { HistoryEntryOrigin } from '../../../api/history/types' import { useApplicationState } from '../../../hooks/common/use-application-state' import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { ShowIf } from '../../common/show-if/show-if' import { DeleteNoteItem } from './delete-note-item' import styles from './entry-menu.module.scss' import { RemoveNoteEntryItem } from './remove-note-entry-item' import React from 'react' import { Dropdown } from 'react-bootstrap' +import { Cloud as IconCloud } from 'react-bootstrap-icons' +import { Laptop as IconLaptop } from 'react-bootstrap-icons' +import { ThreeDots as IconThreeDots } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface EntryMenuProps { @@ -51,7 +54,7 @@ export const EntryMenu: React.FC<EntryMenuProps> = ({ variant={'light'} id={`dropdown-card-${id}`} className={`no-arrow ${styles['history-menu']} d-inline-flex align-items-center`}> - <ForkAwesomeIcon icon='ellipsis-v' fixedWidth={true} /> + <UiIcon icon={IconThreeDots} /> </Dropdown.Toggle> <Dropdown.Menu> @@ -61,14 +64,14 @@ export const EntryMenu: React.FC<EntryMenuProps> = ({ <ShowIf condition={origin === HistoryEntryOrigin.LOCAL}> <Dropdown.Item disabled> - <ForkAwesomeIcon icon='laptop' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconLaptop} className='mx-2' /> <Trans i18nKey='landing.history.menu.entryLocal' /> </Dropdown.Item> </ShowIf> <ShowIf condition={origin === HistoryEntryOrigin.REMOTE}> <Dropdown.Item disabled> - <ForkAwesomeIcon icon='cloud' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconCloud} className='mx-2' /> <Trans i18nKey='landing.history.menu.entryRemote' /> </Dropdown.Item> </ShowIf> diff --git a/frontend/src/components/history-page/entry-menu/remove-note-entry-item.tsx b/frontend/src/components/history-page/entry-menu/remove-note-entry-item.tsx index f129deac8..d47bfa848 100644 --- a/frontend/src/components/history-page/entry-menu/remove-note-entry-item.tsx +++ b/frontend/src/components/history-page/entry-menu/remove-note-entry-item.tsx @@ -6,6 +6,7 @@ import { cypressId } from '../../../utils/cypress-attribute' import { DropdownItemWithDeletionModal } from './dropdown-item-with-deletion-modal' import React from 'react' +import { Archive as IconArchive } from 'react-bootstrap-icons' export interface RemoveNoteEntryItemProps { onConfirm: () => void @@ -24,7 +25,7 @@ export const RemoveNoteEntryItem: React.FC<RemoveNoteEntryItemProps> = ({ noteTi onConfirm={onConfirm} itemI18nKey={'landing.history.menu.removeEntry'} modalButtonI18nKey={'landing.history.modal.removeNote.button'} - modalIcon={'archive'} + modalIcon={IconArchive} modalTitleI18nKey={'landing.history.modal.removeNote.title'} modalQuestionI18nKey={'landing.history.modal.removeNote.question'} modalWarningI18nKey={'landing.history.modal.removeNote.warning'} diff --git a/frontend/src/components/history-page/history-card/history-card.tsx b/frontend/src/components/history-page/history-card/history-card.tsx index b67c9ba08..6932678f4 100644 --- a/frontend/src/components/history-page/history-card/history-card.tsx +++ b/frontend/src/components/history-page/history-card/history-card.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressAttribute, cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { EntryMenu } from '../entry-menu/entry-menu' import type { HistoryEntryProps, HistoryEventHandlers } from '../history-content/history-content' import { PinButton } from '../pin-button/pin-button' @@ -15,6 +15,7 @@ import { DateTime } from 'luxon' import Link from 'next/link' import React, { useCallback, useMemo } from 'react' import { Badge, Card } from 'react-bootstrap' +import { Clock as IconClock } from 'react-bootstrap-icons' /** * Renders a history entry as a card. @@ -73,7 +74,7 @@ export const HistoryCard: React.FC<HistoryEntryProps & HistoryEventHandlers> = ( </Card.Title> <div> <div className='text-black-50 mt-2'> - <ForkAwesomeIcon icon='clock-o' /> {DateTime.fromISO(entry.lastVisitedAt).toRelative()} + <UiIcon icon={IconClock} /> {DateTime.fromISO(entry.lastVisitedAt).toRelative()} <br /> {lastVisited} </div> diff --git a/frontend/src/components/history-page/history-toolbar/clear-history-button.tsx b/frontend/src/components/history-page/history-toolbar/clear-history-button.tsx index 4fd291d46..26f6d8121 100644 --- a/frontend/src/components/history-page/history-toolbar/clear-history-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/clear-history-button.tsx @@ -6,12 +6,13 @@ import { useBooleanState } from '../../../hooks/common/use-boolean-state' import { deleteAllHistoryEntries } from '../../../redux/history/methods' import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { DeletionModal } from '../../common/modals/deletion-modal' import { useUiNotifications } from '../../notifications/ui-notification-boundary' import { useSafeRefreshHistoryStateCallback } from './hooks/use-safe-refresh-history-state' import React, { Fragment, useCallback } from 'react' import { Button } from 'react-bootstrap' +import { Trash as IconTrash } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -39,7 +40,7 @@ export const ClearHistoryButton: React.FC = () => { title={t('landing.history.toolbar.clear') ?? undefined} onClick={showModal} {...cypressId('history-clear-button')}> - <ForkAwesomeIcon icon={'trash'} /> + <UiIcon icon={IconTrash} /> </Button> <DeletionModal onConfirm={onConfirm} diff --git a/frontend/src/components/history-page/history-toolbar/export-history-button.tsx b/frontend/src/components/history-page/history-toolbar/export-history-button.tsx index a2592f19c..02ca86d9c 100644 --- a/frontend/src/components/history-page/history-toolbar/export-history-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/export-history-button.tsx @@ -4,9 +4,10 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { downloadHistory } from '../../../redux/history/methods' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import React from 'react' import { Button } from 'react-bootstrap' +import { Download as IconDownload } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -17,7 +18,7 @@ export const ExportHistoryButton: React.FC = () => { return ( <Button variant={'light'} title={t('landing.history.toolbar.export') ?? undefined} onClick={downloadHistory}> - <ForkAwesomeIcon icon='download' /> + <UiIcon icon={IconDownload} /> </Button> ) } diff --git a/frontend/src/components/history-page/history-toolbar/history-refresh-button.tsx b/frontend/src/components/history-page/history-toolbar/history-refresh-button.tsx index c89572b01..3f009d415 100644 --- a/frontend/src/components/history-page/history-toolbar/history-refresh-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/history-refresh-button.tsx @@ -3,10 +3,11 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { useSafeRefreshHistoryStateCallback } from './hooks/use-safe-refresh-history-state' import React from 'react' import { Button } from 'react-bootstrap' +import { ArrowRepeat as IconArrowRepeat } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -19,7 +20,7 @@ export const HistoryRefreshButton: React.FC = () => { return ( <Button variant={'light'} title={t('landing.history.toolbar.refresh') ?? undefined} onClick={refreshHistory}> - <ForkAwesomeIcon icon='refresh' /> + <UiIcon icon={IconArrowRepeat} /> </Button> ) } diff --git a/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx b/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx index 31e64624c..24177e4c4 100644 --- a/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx +++ b/frontend/src/components/history-page/history-toolbar/history-toolbar.tsx @@ -6,7 +6,7 @@ import { HistoryEntryOrigin } from '../../../api/history/types' import { useApplicationState } from '../../../hooks/common/use-application-state' import { importHistoryEntries, setHistoryEntries } from '../../../redux/history/methods' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { ShowIf } from '../../common/show-if/show-if' import { useUiNotifications } from '../../notifications/ui-notification-boundary' import { ClearHistoryButton } from './clear-history-button' @@ -22,6 +22,7 @@ import { TagSelectionInput } from './tag-selection-input' import { useSyncToolbarStateToUrlEffect } from './toolbar-context/use-sync-toolbar-state-to-url-effect' import React, { useCallback } from 'react' import { Button, Col } from 'react-bootstrap' +import { CloudUpload as IconCloudUpload } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' export enum ViewStateEnum { @@ -92,7 +93,7 @@ export const HistoryToolbar: React.FC = () => { variant={'light'} title={t('landing.history.toolbar.uploadAll') ?? undefined} onClick={onUploadAllToRemote}> - <ForkAwesomeIcon icon='cloud-upload' /> + <UiIcon icon={IconCloudUpload} /> </Button> </div> </ShowIf> diff --git a/frontend/src/components/history-page/history-toolbar/history-view-mode-toggle-button.tsx b/frontend/src/components/history-page/history-toolbar/history-view-mode-toggle-button.tsx index 5714c36b3..fa8085455 100644 --- a/frontend/src/components/history-page/history-toolbar/history-view-mode-toggle-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/history-view-mode-toggle-button.tsx @@ -4,11 +4,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { ViewStateEnum } from './history-toolbar' import { useHistoryToolbarState } from './toolbar-context/use-history-toolbar-state' import React, { useCallback } from 'react' import { Button, ToggleButtonGroup } from 'react-bootstrap' +import { StickyFill as IconStickyFill } from 'react-bootstrap-icons' +import { Table as IconTable } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -34,14 +36,14 @@ export const HistoryViewModeToggleButton: React.FC = () => { title={t('landing.history.toolbar.cards') ?? undefined} variant={historyToolbarState.viewState === ViewStateEnum.CARD ? 'light' : 'outline-light'} onClick={() => onViewStateChange(ViewStateEnum.CARD)}> - <ForkAwesomeIcon icon={'sticky-note'} className={'fa-fix-line-height'} /> + <UiIcon icon={IconStickyFill} className={'fa-fix-line-height'} /> </Button> <Button {...cypressId('history-mode-table')} variant={historyToolbarState.viewState === ViewStateEnum.TABLE ? 'light' : 'outline-light'} title={t('landing.history.toolbar.table') ?? undefined} onClick={() => onViewStateChange(ViewStateEnum.TABLE)}> - <ForkAwesomeIcon icon={'table'} className={'fa-fix-line-height'} /> + <UiIcon icon={IconTable} className={'fa-fix-line-height'} /> </Button> </ToggleButtonGroup> ) diff --git a/frontend/src/components/history-page/history-toolbar/import-history-button.tsx b/frontend/src/components/history-page/history-toolbar/import-history-button.tsx index bee1bfc63..59ff6cb22 100644 --- a/frontend/src/components/history-page/history-toolbar/import-history-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/import-history-button.tsx @@ -9,11 +9,12 @@ import { useApplicationState } from '../../../hooks/common/use-application-state import { convertV1History, importHistoryEntries, mergeHistoryEntries } from '../../../redux/history/methods' import type { HistoryExportJson, V1HistoryEntry } from '../../../redux/history/types' import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { useUiNotifications } from '../../notifications/ui-notification-boundary' import { useSafeRefreshHistoryStateCallback } from './hooks/use-safe-refresh-history-state' import React, { useCallback, useRef, useState } from 'react' import { Button } from 'react-bootstrap' +import { Upload as IconUpload } from 'react-bootstrap-icons' import { useTranslation } from 'react-i18next' /** @@ -131,7 +132,7 @@ export const ImportHistoryButton: React.FC = () => { title={t('landing.history.toolbar.import') ?? undefined} onClick={onUploadButtonClick} {...cypressId('import-history-file-button')}> - <ForkAwesomeIcon icon='upload' /> + <UiIcon icon={IconUpload} /> </Button> </div> ) diff --git a/frontend/src/components/history-page/history-toolbar/sort-by-last-visited-button.tsx b/frontend/src/components/history-page/history-toolbar/sort-by-last-visited-button.tsx index b0654824b..98be5a083 100644 --- a/frontend/src/components/history-page/history-toolbar/sort-by-last-visited-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/sort-by-last-visited-button.tsx @@ -27,10 +27,7 @@ export const SortByLastVisitedButton: React.FC = () => { ) return ( - <SortButton - onDirectionChange={lastVisitedSortChanged} - direction={historyToolbarState.lastVisitedSortDirection} - variant={'light'}> + <SortButton onDirectionChange={lastVisitedSortChanged} direction={historyToolbarState.lastVisitedSortDirection}> <Trans i18nKey={'landing.history.toolbar.sortByLastVisited'} /> </SortButton> ) diff --git a/frontend/src/components/history-page/history-toolbar/sort-by-title-button.tsx b/frontend/src/components/history-page/history-toolbar/sort-by-title-button.tsx index 92d457d70..3c939882d 100644 --- a/frontend/src/components/history-page/history-toolbar/sort-by-title-button.tsx +++ b/frontend/src/components/history-page/history-toolbar/sort-by-title-button.tsx @@ -27,10 +27,7 @@ export const SortByTitleButton: React.FC = () => { ) return ( - <SortButton - onDirectionChange={titleSortChanged} - direction={historyToolbarState.titleSortDirection} - variant={'light'}> + <SortButton onDirectionChange={titleSortChanged} direction={historyToolbarState.titleSortDirection}> <Trans i18nKey={'landing.history.toolbar.sortByTitle'} /> </SortButton> ) diff --git a/frontend/src/components/history-page/pin-button/pin-button.module.scss b/frontend/src/components/history-page/pin-button/pin-button.module.scss index 9f5f769dc..6a3143aea 100644 --- a/frontend/src/components/history-page/pin-button/pin-button.module.scss +++ b/frontend/src/components/history-page/pin-button/pin-button.module.scss @@ -5,16 +5,16 @@ */ .history-pin { - .fa { - opacity: 0.2; + svg { + opacity: 0.5; transition: opacity 0.2s ease-in-out, color 0.2s ease-in-out; } - &:hover .fa { + &:hover svg { opacity: 1; } - &.pinned .fa { + &.pinned svg { color: #d43f3a; opacity: 1; } diff --git a/frontend/src/components/history-page/pin-button/pin-button.tsx b/frontend/src/components/history-page/pin-button/pin-button.tsx index 8d27f7a79..086bfd163 100644 --- a/frontend/src/components/history-page/pin-button/pin-button.tsx +++ b/frontend/src/components/history-page/pin-button/pin-button.tsx @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressAttribute, cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import styles from './pin-button.module.scss' import React from 'react' import { Button } from 'react-bootstrap' +import { PinFill as IconPinFill } from 'react-bootstrap-icons' export interface PinButtonProps { isPinned: boolean @@ -32,7 +33,7 @@ export const PinButton: React.FC<PinButtonProps> = ({ isPinned, onPinClick, isDa onClick={onPinClick} {...cypressId('history-entry-pin-button')} {...cypressAttribute('pinned', isPinned ? 'true' : 'false')}> - <ForkAwesomeIcon className={styles['fa']} icon='thumb-tack' /> + <UiIcon icon={IconPinFill} /> </Button> ) } diff --git a/frontend/src/components/history-page/sort-button/sort-button.tsx b/frontend/src/components/history-page/sort-button/sort-button.tsx index bf94364c8..5f56f12ee 100644 --- a/frontend/src/components/history-page/sort-button/sort-button.tsx +++ b/frontend/src/components/history-page/sort-button/sort-button.tsx @@ -3,10 +3,12 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { IconName } from '../../common/fork-awesome/types' import { IconButton } from '../../common/icon-button/icon-button' -import React from 'react' +import React, { useCallback, useMemo } from 'react' import type { ButtonProps } from 'react-bootstrap' +import { SortAlphaDown as IconSortAlphaDown } from 'react-bootstrap-icons' +import { SortAlphaUp as IconSortAlphaUp } from 'react-bootstrap-icons' +import { X as IconX } from 'react-bootstrap-icons' export enum SortModeEnum { up = 1, @@ -14,25 +16,6 @@ export enum SortModeEnum { no = 0 } -/** - * Returns the proper icon for the given sorting direction. - * - * @param direction The sorting direction for which to get the icon - * @return The name of the icon fitting to the given sorting direction - */ -const getIcon = (direction: SortModeEnum): IconName => { - switch (direction) { - case SortModeEnum.no: - return 'sort' - case SortModeEnum.up: - return 'sort-asc' - case SortModeEnum.down: - return 'sort-desc' - default: - return 'sort' - } -} - export interface SortButtonProps extends ButtonProps { onDirectionChange: (direction: SortModeEnum) => void direction: SortModeEnum @@ -64,13 +47,24 @@ const toggleDirection = (direction: SortModeEnum) => { * @param onDirectionChange Callback that is fired when the sorting direction is changed * @param direction The sorting direction that is used */ -export const SortButton: React.FC<SortButtonProps> = ({ children, variant, onDirectionChange, direction }) => { - const toggleSort = () => { +export const SortButton: React.FC<SortButtonProps> = ({ children, onDirectionChange, direction }) => { + const toggleSort = useCallback(() => { onDirectionChange(toggleDirection(direction)) - } + }, [direction, onDirectionChange]) + + const icon = useMemo(() => { + switch (direction) { + case SortModeEnum.down: + return IconSortAlphaDown + case SortModeEnum.up: + return IconSortAlphaUp + case SortModeEnum.no: + return IconX + } + }, [direction]) return ( - <IconButton onClick={toggleSort} variant={variant} icon={getIcon(direction)} border={true}> + <IconButton onClick={toggleSort} variant={'light'} icon={icon} iconSize={1.5} border={true}> {children} </IconButton> ) diff --git a/frontend/src/components/landing-layout/footer/social-links.tsx b/frontend/src/components/landing-layout/footer/social-links.tsx index fa6f8134d..f1ec43bad 100644 --- a/frontend/src/components/landing-layout/footer/social-links.tsx +++ b/frontend/src/components/landing-layout/footer/social-links.tsx @@ -6,6 +6,11 @@ import links from '../../../links.json' import { ExternalLink } from '../../common/links/external-link' import React from 'react' +import { Chat as IconChat } from 'react-bootstrap-icons' +import { Github as IconGithub } from 'react-bootstrap-icons' +import { Globe as IconGlobe } from 'react-bootstrap-icons' +import { Mastodon as IconMastodon } from 'react-bootstrap-icons' +import { People as IconPeople } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -18,11 +23,11 @@ export const SocialLink: React.FC = () => { <Trans i18nKey='landing.footer.followUs' components={[ - <ExternalLink href={links.githubOrg} icon='github' key={'github'} text='GitHub' />, - <ExternalLink href={links.community} icon='users' key={'users'} text='Discourse' />, - <ExternalLink href={links.chat} icon='comment' key={'comment'} text='Matrix' />, - <ExternalLink href={links.mastodon} icon='mastodon' key={'mastodon'} text='Mastodon' />, - <ExternalLink href={links.translate} icon='globe' key={'globe'} text='POEditor' /> + <ExternalLink href={links.githubOrg} icon={IconGithub} key={'github'} text='GitHub' />, + <ExternalLink href={links.community} icon={IconPeople} key={'users'} text='Discourse' />, + <ExternalLink href={links.chat} icon={IconChat} key={'comment'} text='Matrix' />, + <ExternalLink href={links.mastodon} icon={IconMastodon} key={'mastodon'} text='Mastodon' />, + <ExternalLink href={links.translate} icon={IconGlobe} key={'globe'} text='POEditor' /> ]} /> </p> diff --git a/frontend/src/components/landing-layout/navigation/new-guest-note-button.tsx b/frontend/src/components/landing-layout/navigation/new-guest-note-button.tsx index 7046ec221..d0b5c9308 100644 --- a/frontend/src/components/landing-layout/navigation/new-guest-note-button.tsx +++ b/frontend/src/components/landing-layout/navigation/new-guest-note-button.tsx @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import Link from 'next/link' import React from 'react' import { Button } from 'react-bootstrap' +import { Plus as IconPlus } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -23,7 +24,7 @@ export const NewGuestNoteButton: React.FC = () => { size='sm' className='d-inline-flex align-items-center' {...cypressId('new-guest-note-button')}> - <ForkAwesomeIcon icon='plus' className='mx-1' /> + <UiIcon icon={IconPlus} className='mx-1' size={2} /> <span> <Trans i18nKey='landing.navigation.newGuestNote' /> </span> diff --git a/frontend/src/components/landing-layout/navigation/new-user-note-button.tsx b/frontend/src/components/landing-layout/navigation/new-user-note-button.tsx index aaf75085f..bc34dce11 100644 --- a/frontend/src/components/landing-layout/navigation/new-user-note-button.tsx +++ b/frontend/src/components/landing-layout/navigation/new-user-note-button.tsx @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import Link from 'next/link' import React from 'react' import { Button } from 'react-bootstrap' +import { Plus as IconPlus } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -23,7 +24,7 @@ export const NewUserNoteButton: React.FC = () => { size='sm' className='d-inline-flex align-items-center' {...cypressId('new-note-button')}> - <ForkAwesomeIcon icon='plus' className='mx-1' /> + <UiIcon icon={IconPlus} className='mx-1' size={2} /> <span> <Trans i18nKey='landing.navigation.newNote' /> </span> diff --git a/frontend/src/components/landing-layout/navigation/sign-out-dropdown-button.tsx b/frontend/src/components/landing-layout/navigation/sign-out-dropdown-button.tsx index b5dd9b961..51dfc0222 100644 --- a/frontend/src/components/landing-layout/navigation/sign-out-dropdown-button.tsx +++ b/frontend/src/components/landing-layout/navigation/sign-out-dropdown-button.tsx @@ -6,10 +6,11 @@ import { doLogout } from '../../../api/auth' import { clearUser } from '../../../redux/user/methods' import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { useUiNotifications } from '../../notifications/ui-notification-boundary' import React, { useCallback } from 'react' import { Dropdown } from 'react-bootstrap' +import { BoxArrowRight as IconBoxArrowRight } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -26,7 +27,7 @@ export const SignOutDropdownButton: React.FC = () => { return ( <Dropdown.Item dir='auto' onClick={onSignOut} {...cypressId('user-dropdown-sign-out-button')}> - <ForkAwesomeIcon icon='sign-out' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconBoxArrowRight} className='mx-2' /> <Trans i18nKey='login.signOut' /> </Dropdown.Item> ) diff --git a/frontend/src/components/landing-layout/navigation/user-dropdown.tsx b/frontend/src/components/landing-layout/navigation/user-dropdown.tsx index 3c00f9252..9d07b0624 100644 --- a/frontend/src/components/landing-layout/navigation/user-dropdown.tsx +++ b/frontend/src/components/landing-layout/navigation/user-dropdown.tsx @@ -5,12 +5,14 @@ */ import { useApplicationState } from '../../../hooks/common/use-application-state' import { cypressId } from '../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { UserAvatar } from '../../common/user-avatar/user-avatar' import { SignOutDropdownButton } from './sign-out-dropdown-button' import Link from 'next/link' import React from 'react' import { Dropdown } from 'react-bootstrap' +import { Lightning as IconLightning } from 'react-bootstrap-icons' +import { Person as IconPerson } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -33,13 +35,13 @@ export const UserDropdown: React.FC = () => { <Dropdown.Menu className='text-start'> <Link href={'/n/features'} passHref={true}> <Dropdown.Item dir='auto' {...cypressId('user-dropdown-features-button')}> - <ForkAwesomeIcon icon='bolt' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconLightning} className='mx-2' /> <Trans i18nKey='editor.help.documents.features' /> </Dropdown.Item> </Link> <Link href={'/profile'} passHref={true}> <Dropdown.Item dir='auto' {...cypressId('user-dropdown-profile-button')}> - <ForkAwesomeIcon icon='user' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconPerson} className='mx-2' /> <Trans i18nKey='profile.userProfile' /> </Dropdown.Item> </Link> diff --git a/frontend/src/components/layout/settings-dialog/settings-button.tsx b/frontend/src/components/layout/settings-dialog/settings-button.tsx index 7fda07b73..381070270 100644 --- a/frontend/src/components/layout/settings-dialog/settings-button.tsx +++ b/frontend/src/components/layout/settings-dialog/settings-button.tsx @@ -9,6 +9,7 @@ import { IconButton } from '../../common/icon-button/icon-button' import { SettingsModal } from './settings-modal' import React, { Fragment } from 'react' import type { ButtonProps } from 'react-bootstrap' +import { Gear as IconGear } from 'react-bootstrap-icons' export type SettingsButtonProps = Omit<ButtonProps, 'onClick'> /** @@ -18,7 +19,7 @@ export const SettingsButton: React.FC<SettingsButtonProps> = (props) => { const [show, showModal, hideModal] = useBooleanState(false) return ( <Fragment> - <IconButton {...props} {...cypressId('settingsButton')} onClick={showModal} icon={'cog'} /> + <IconButton {...props} {...cypressId('settingsButton')} onClick={showModal} icon={IconGear} /> <SettingsModal show={show} onHide={hideModal} /> </Fragment> ) diff --git a/frontend/src/components/layout/settings-dialog/settings-modal.tsx b/frontend/src/components/layout/settings-dialog/settings-modal.tsx index 778dbb433..c08f5f561 100644 --- a/frontend/src/components/layout/settings-dialog/settings-modal.tsx +++ b/frontend/src/components/layout/settings-dialog/settings-modal.tsx @@ -10,6 +10,7 @@ import { GlobalSettingsTabContent } from './global/global-settings-tab-content' import { t } from 'i18next' import React from 'react' import { Modal, Tab, Tabs } from 'react-bootstrap' +import { Gear as IconGear } from 'react-bootstrap-icons' /** * Shows global and scope specific settings @@ -23,7 +24,7 @@ export const SettingsModal: React.FC<CommonModalProps> = ({ show, onHide }) => { show={show} modalSize={'lg'} onHide={onHide} - titleIcon={'cog'} + titleIcon={IconGear} titleI18nKey={'settings.title'} showCloseButton={true}> <Modal.Body> diff --git a/frontend/src/components/login-page/auth/social-link-button/social-link-button.tsx b/frontend/src/components/login-page/auth/social-link-button/social-link-button.tsx index 3204f92a6..25aae271e 100644 --- a/frontend/src/components/login-page/auth/social-link-button/social-link-button.tsx +++ b/frontend/src/components/login-page/auth/social-link-button/social-link-button.tsx @@ -3,16 +3,16 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../../common/fork-awesome/types' +import { UiIcon } from '../../../common/icons/ui-icon' import styles from './social-link-button.module.scss' import type { PropsWithChildren } from 'react' import React from 'react' +import type { Icon } from 'react-bootstrap-icons' export interface SocialButtonProps { backgroundClass: string href: string - icon: IconName + icon: Icon title?: string } @@ -38,7 +38,7 @@ export const SocialLinkButton: React.FC<PropsWithChildren<SocialButtonProps>> = title={title} className={`btn ${styles['social-link-button']} p-0 d-inline-flex align-items-stretch ${backgroundClass}`}> <span className={`${styles['icon-part']} d-flex align-items-center`}> - <ForkAwesomeIcon icon={icon} className={'social-icon'} fixedWidth={true} /> + <UiIcon icon={icon} className={styles['social-icon']} /> </span> <span className={`${styles['text-part']} d-flex align-items-center mx-auto`}>{children}</span> </a> diff --git a/frontend/src/components/login-page/auth/utils/get-one-click-provider-metadata.ts b/frontend/src/components/login-page/auth/utils/get-one-click-provider-metadata.ts index 92f53ee61..d92bdf0a7 100644 --- a/frontend/src/components/login-page/auth/utils/get-one-click-provider-metadata.ts +++ b/frontend/src/components/login-page/auth/utils/get-one-click-provider-metadata.ts @@ -6,12 +6,21 @@ import type { AuthProvider } from '../../../../api/config/types' import { AuthProviderType } from '../../../../api/config/types' import { Logger } from '../../../../utils/logger' -import type { IconName } from '../../../common/fork-awesome/types' import styles from '../via-one-click.module.scss' +import type { Icon } from 'react-bootstrap-icons' +import { Dropbox as IconDropbox } from 'react-bootstrap-icons' +import { Exclamation as IconExclamation } from 'react-bootstrap-icons' +import { Facebook as IconFacebook } from 'react-bootstrap-icons' +import { Git as IconGit } from 'react-bootstrap-icons' +import { Github as IconGithub } from 'react-bootstrap-icons' +import { Google as IconGoogle } from 'react-bootstrap-icons' +import { People as IconPeople } from 'react-bootstrap-icons' +import { PersonRolodex as IconPersonRolodex } from 'react-bootstrap-icons' +import { Twitter as IconTwitter } from 'react-bootstrap-icons' export interface OneClickMetadata { name: string - icon: IconName + icon: Icon className: string url: string } @@ -33,56 +42,56 @@ export const getOneClickProviderMetadata = (provider: AuthProvider): OneClickMet case AuthProviderType.DROPBOX: return { name: 'Dropbox', - icon: 'dropbox', + icon: IconDropbox, className: styles['btn-social-dropbox'], url: getBackendAuthUrl('dropbox') } case AuthProviderType.FACEBOOK: return { name: 'Facebook', - icon: 'facebook', + icon: IconFacebook, className: styles['btn-social-facebook'], url: getBackendAuthUrl('facebook') } case AuthProviderType.GITHUB: return { name: 'GitHub', - icon: 'github', + icon: IconGithub, className: styles['btn-social-github'], url: getBackendAuthUrl('github') } case AuthProviderType.GITLAB: return { name: provider.providerName, - icon: 'gitlab', + icon: IconGit, //TODO: gitlab icon className: styles['btn-social-gitlab'], url: getBackendAuthUrl(provider.identifier) } case AuthProviderType.GOOGLE: return { name: 'Google', - icon: 'google', + icon: IconGoogle, className: styles['btn-social-google'], url: getBackendAuthUrl('google') } case AuthProviderType.OAUTH2: return { name: provider.providerName, - icon: 'address-card', + icon: IconPersonRolodex, className: 'btn-primary', url: getBackendAuthUrl(provider.identifier) } case AuthProviderType.SAML: return { name: provider.providerName, - icon: 'users', + icon: IconPeople, className: 'btn-success', url: getBackendAuthUrl(provider.identifier) } case AuthProviderType.TWITTER: return { name: 'Twitter', - icon: 'twitter', + icon: IconTwitter, className: styles['btn-social-twitter'], url: getBackendAuthUrl('twitter') } @@ -90,7 +99,7 @@ export const getOneClickProviderMetadata = (provider: AuthProvider): OneClickMet logger.warn('Metadata for one-click-provider does not exist', provider) return { name: '', - icon: 'exclamation', + icon: IconExclamation, className: '', url: '#' } diff --git a/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/__snapshots__/bootstrap-icon-markdown-extension.test.tsx.snap b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/__snapshots__/bootstrap-icon-markdown-extension.test.tsx.snap new file mode 100644 index 000000000..a74cc484b --- /dev/null +++ b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/__snapshots__/bootstrap-icon-markdown-extension.test.tsx.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`bootstrap icon markdown extension doesn't render invalid icon 1`] = ` +<div> + <p /> + + +</div> +`; + +exports[`bootstrap icon markdown extension doesn't render missing icon 1`] = ` +<div> + <p> + :bi-: + </p> + + +</div> +`; + +exports[`bootstrap icon markdown extension renders correct icon 1`] = ` +<div> + <p> + <span + data-svg-mock="true" + data-testid="lazy-bootstrap-icon-alarm" + fill="currentColor" + height="1em" + width="1em" + /> + </p> + + +</div> +`; diff --git a/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-component-replacer.ts b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-component-replacer.ts new file mode 100644 index 000000000..4f10ab5f4 --- /dev/null +++ b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-component-replacer.ts @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { isBootstrapIconName } from '../../../common/icons/bootstrap-icons' +import { LazyBootstrapIcon } from '../../../common/icons/lazy-bootstrap-icon' +import type { NodeReplacement } from '../../replace-components/component-replacer' +import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer' +import { BootstrapIconMarkdownExtension } from './bootstrap-icon-markdown-extension' +import type { Element } from 'domhandler' +import React from 'react' + +/** + * Replaces a bootstrap icon tag with the bootstrap icon react component. + * + * @see BootstrapIcon + */ +export class BootstrapIconComponentReplacer extends ComponentReplacer { + constructor() { + super() + } + + public replace(node: Element): NodeReplacement { + const iconName = this.extractIconName(node) + if (!iconName || !isBootstrapIconName(iconName)) { + return DO_NOT_REPLACE + } + return React.createElement(LazyBootstrapIcon, { icon: iconName }) + } + + private extractIconName(element: Element): string | undefined { + return element.name === BootstrapIconMarkdownExtension.tagName && element.attribs && element.attribs.id + ? element.attribs.id + : undefined + } +} diff --git a/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-markdown-extension.test.tsx b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-markdown-extension.test.tsx new file mode 100644 index 000000000..5989994b2 --- /dev/null +++ b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-markdown-extension.test.tsx @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { TestMarkdownRenderer } from '../../test-utils/test-markdown-renderer' +import { BootstrapIconMarkdownExtension } from './bootstrap-icon-markdown-extension' +import { render, screen } from '@testing-library/react' +import React from 'react' + +describe('bootstrap icon markdown extension', () => { + it('renders correct icon', async () => { + const view = render( + <TestMarkdownRenderer extensions={[new BootstrapIconMarkdownExtension()]} content={':bi-alarm:'} /> + ) + await screen.findByTestId('lazy-bootstrap-icon-alarm') + expect(view.container).toMatchSnapshot() + }) + + it("doesn't render missing icon", () => { + const view = render(<TestMarkdownRenderer extensions={[new BootstrapIconMarkdownExtension()]} content={':bi-:'} />) + expect(view.container).toMatchSnapshot() + }) + + it("doesn't render invalid icon", () => { + const view = render( + <TestMarkdownRenderer extensions={[new BootstrapIconMarkdownExtension()]} content={':bi-123:'} /> + ) + expect(view.container).toMatchSnapshot() + }) +}) diff --git a/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-markdown-extension.ts b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-markdown-extension.ts new file mode 100644 index 000000000..9f765ae31 --- /dev/null +++ b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/bootstrap-icon-markdown-extension.ts @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import type { ComponentReplacer } from '../../replace-components/component-replacer' +import { MarkdownRendererExtension } from '../base/markdown-renderer-extension' +import { BootstrapIconComponentReplacer } from './bootstrap-icon-component-replacer' +import { replaceBootstrapIconsMarkdownItPlugin } from './replace-bootstrap-icons' +import type MarkdownIt from 'markdown-it' + +/** + * Adds Bootstrap icons via the :bi-$name: syntax. + */ +export class BootstrapIconMarkdownExtension extends MarkdownRendererExtension { + public static readonly tagName = 'app-bootstrap-icon' + + public configureMarkdownIt(markdownIt: MarkdownIt): void { + replaceBootstrapIconsMarkdownItPlugin(markdownIt) + } + + public buildReplacers(): ComponentReplacer[] { + return [new BootstrapIconComponentReplacer()] + } + + public buildTagNameAllowList(): string[] { + return [BootstrapIconMarkdownExtension.tagName] + } +} diff --git a/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/replace-bootstrap-icons.test.ts b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/replace-bootstrap-icons.test.ts new file mode 100644 index 000000000..80d576abb --- /dev/null +++ b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/replace-bootstrap-icons.test.ts @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { replaceBootstrapIconsMarkdownItPlugin } from './replace-bootstrap-icons' +import MarkdownIt from 'markdown-it' + +describe('Replace bootstrap icons', () => { + let markdownIt: MarkdownIt + + beforeEach(() => { + markdownIt = new MarkdownIt('default', { + html: false, + breaks: true, + langPrefix: '', + typographer: true + }) + markdownIt.use(replaceBootstrapIconsMarkdownItPlugin) + }) + it(`can detect a correct icon`, () => { + expect(markdownIt.renderInline(':bi-alarm:')).toBe('<app-bootstrap-icon id="alarm"></app-bootstrap-icon>') + }) + + it("won't detect an invalid id", () => { + const invalidIcon = ':bi-invalid:' + expect(markdownIt.renderInline(invalidIcon)).toBe(invalidIcon) + }) + + it("won't detect an empty id", () => { + const invalidIcon = ':bi-:' + expect(markdownIt.renderInline(invalidIcon)).toBe(invalidIcon) + }) + + it("won't detect a wrong id", () => { + const invalidIcon = ':bi-%?(:' + expect(markdownIt.renderInline(invalidIcon)).toBe(invalidIcon) + }) +}) diff --git a/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/replace-bootstrap-icons.ts b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/replace-bootstrap-icons.ts new file mode 100644 index 000000000..7fdd3e0bb --- /dev/null +++ b/frontend/src/components/markdown-renderer/extensions/bootstrap-icons/replace-bootstrap-icons.ts @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import type { RegexOptions } from '../../../../external-types/markdown-it-regex/interface' +import { isBootstrapIconName } from '../../../common/icons/bootstrap-icons' +import { BootstrapIconMarkdownExtension } from './bootstrap-icon-markdown-extension' +import type MarkdownIt from 'markdown-it' +import markdownItRegex from 'markdown-it-regex' + +const biRegex = /:bi-([\w-]+):/i + +/** + * Replacer for bootstrap icon via the :bi-$name: syntax. + */ +export const replaceBootstrapIconsMarkdownItPlugin: MarkdownIt.PluginSimple = (markdownIt: MarkdownIt) => + markdownItRegex(markdownIt, { + name: 'bootstrap-icons', + regex: biRegex, + replace: (match) => { + if (isBootstrapIconName(match)) { + // ESLint wants to collapse this tag, but then the tag won't be valid html anymore. + // noinspection CheckTagEmptyBody + return `<${BootstrapIconMarkdownExtension.tagName} id="${match}"></${BootstrapIconMarkdownExtension.tagName}>` + } else { + return `:bi-${match}:` + } + } + } as RegexOptions) diff --git a/frontend/src/components/markdown-renderer/extensions/emoji/__snapshots__/emoji-markdown-extension.test.tsx.snap b/frontend/src/components/markdown-renderer/extensions/emoji/__snapshots__/emoji-markdown-extension.test.tsx.snap index 995759c49..e52d9d8e3 100644 --- a/frontend/src/components/markdown-renderer/extensions/emoji/__snapshots__/emoji-markdown-extension.test.tsx.snap +++ b/frontend/src/components/markdown-renderer/extensions/emoji/__snapshots__/emoji-markdown-extension.test.tsx.snap @@ -1,17 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Emoji Markdown Extension renders a fork awesome code 1`] = ` -<div> - <p> - <i - class="fa fa-circle-thin" - /> - </p> - - -</div> -`; - exports[`Emoji Markdown Extension renders a skin tone code 1`] = ` <div> <p> diff --git a/frontend/src/components/markdown-renderer/extensions/emoji/emoji-markdown-extension.test.tsx b/frontend/src/components/markdown-renderer/extensions/emoji/emoji-markdown-extension.test.tsx index fcedfc162..dc0d9510f 100644 --- a/frontend/src/components/markdown-renderer/extensions/emoji/emoji-markdown-extension.test.tsx +++ b/frontend/src/components/markdown-renderer/extensions/emoji/emoji-markdown-extension.test.tsx @@ -24,13 +24,6 @@ describe('Emoji Markdown Extension', () => { expect(view.container).toMatchSnapshot() }) - it('renders a fork awesome code', () => { - const view = render( - <TestMarkdownRenderer extensions={[new EmojiMarkdownExtension()]} content={':fa-circle-thin:'} /> - ) - expect(view.container).toMatchSnapshot() - }) - it('renders a skin tone code', () => { const view = render(<TestMarkdownRenderer extensions={[new EmojiMarkdownExtension()]} content={':skin-tone-3:'} />) expect(view.container).toMatchSnapshot() diff --git a/frontend/src/components/markdown-renderer/extensions/emoji/mapping.ts b/frontend/src/components/markdown-renderer/extensions/emoji/mapping.ts index 793463483..ff5651212 100644 --- a/frontend/src/components/markdown-renderer/extensions/emoji/mapping.ts +++ b/frontend/src/components/markdown-renderer/extensions/emoji/mapping.ts @@ -3,7 +3,6 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcons } from '../../../common/fork-awesome/fork-awesome-icons' import emojiData from 'emoji-picker-element-data/en/emojibase/data.json' interface EmojiEntry { @@ -28,15 +27,7 @@ const emojiSkinToneModifierMap = [1, 2, 3, 4, 5].reduce((reduceObject, modifierV return reduceObject }, {} as ShortCodeMap) -const forkAwesomeIconMap = ForkAwesomeIcons.reduce((reduceObject, icon) => { - const shortcode = `fa-${icon}` - // noinspection CheckTagEmptyBody - reduceObject[shortcode] = `<i class='fa fa-${icon}'></i>` - return reduceObject -}, {} as ShortCodeMap) - export const combinedEmojiData = { ...shortCodeMap, - ...emojiSkinToneModifierMap, - ...forkAwesomeIconMap + ...emojiSkinToneModifierMap } diff --git a/frontend/src/components/markdown-renderer/extensions/iframe-capsule/iframe-capsule-replacer.tsx b/frontend/src/components/markdown-renderer/extensions/iframe-capsule/iframe-capsule-replacer.tsx index 27d8a6d85..662d9e8c0 100644 --- a/frontend/src/components/markdown-renderer/extensions/iframe-capsule/iframe-capsule-replacer.tsx +++ b/frontend/src/components/markdown-renderer/extensions/iframe-capsule/iframe-capsule-replacer.tsx @@ -7,6 +7,8 @@ import { ClickShield } from '../../replace-components/click-shield/click-shield' import type { NativeRenderer, NodeReplacement, SubNodeTransform } from '../../replace-components/component-replacer' import { ComponentReplacer, DO_NOT_REPLACE } from '../../replace-components/component-replacer' import type { Element } from 'domhandler' +import React from 'react' +import { Globe as IconGlobe } from 'react-bootstrap-icons' /** * Capsules <iframe> elements with a click shield. @@ -19,7 +21,7 @@ export class IframeCapsuleReplacer extends ComponentReplacer { DO_NOT_REPLACE ) : ( <ClickShield - hoverIcon={'globe'} + hoverIcon={IconGlobe} targetDescription={node.attribs.src} data-cypress-id={'iframe-capsule-click-shield'}> {nativeRenderer()} diff --git a/frontend/src/components/markdown-renderer/extensions/image-placeholder/image-placeholder.tsx b/frontend/src/components/markdown-renderer/extensions/image-placeholder/image-placeholder.tsx index c2da5b3e3..1a9aacdce 100644 --- a/frontend/src/components/markdown-renderer/extensions/image-placeholder/image-placeholder.tsx +++ b/frontend/src/components/markdown-renderer/extensions/image-placeholder/image-placeholder.tsx @@ -4,13 +4,14 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { cypressId } from '../../../../utils/cypress-attribute' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { acceptedMimeTypes } from '../../../common/upload-image-mimetypes' import { useOnImageUpload } from './hooks/use-on-image-upload' import { usePlaceholderSizeStyle } from './hooks/use-placeholder-size-style' import styles from './image-placeholder.module.scss' import React, { useCallback, useMemo, useRef, useState } from 'react' import { Button } from 'react-bootstrap' +import { Upload as IconUpload } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface PlaceholderImageFrameProps { @@ -105,7 +106,7 @@ export const ImagePlaceholder: React.FC<PlaceholderImageFrameProps> = ({ </div> </div> <Button size={'sm'} variant={'primary'} onClick={uploadButtonClicked}> - <ForkAwesomeIcon icon={'upload'} fixedWidth={true} className='my-2' /> + <UiIcon icon={IconUpload} className='my-2' /> <Trans i18nKey={'editor.embeddings.placeholderImage.upload'} className='my-2' /> </Button> </span> diff --git a/frontend/src/components/markdown-renderer/extensions/upload-indicating-image-frame/upload-indicating-frame.tsx b/frontend/src/components/markdown-renderer/extensions/upload-indicating-image-frame/upload-indicating-frame.tsx index b040f1b06..6802d669f 100644 --- a/frontend/src/components/markdown-renderer/extensions/upload-indicating-image-frame/upload-indicating-frame.tsx +++ b/frontend/src/components/markdown-renderer/extensions/upload-indicating-image-frame/upload-indicating-frame.tsx @@ -3,9 +3,10 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../common/icons/ui-icon' import { usePlaceholderSizeStyle } from '../image-placeholder/hooks/use-placeholder-size-style' import React from 'react' +import { GearFill as IconGearFill } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface UploadIndicatingFrameProps { @@ -30,7 +31,7 @@ export const UploadIndicatingFrame: React.FC<UploadIndicatingFrameProps> = ({ wi <span className={'h1 border-bottom-0 my-2'}> <Trans i18nKey={'renderer.uploadIndicator.uploadMessage'} /> </span> - <ForkAwesomeIcon icon={'cog'} size={'5x'} fixedWidth={true} className='my-2 fa-spin' /> + <UiIcon icon={IconGearFill} size={5} className='my-2' spin={true} /> </span> ) } diff --git a/frontend/src/components/markdown-renderer/hooks/use-markdown-extensions.ts b/frontend/src/components/markdown-renderer/hooks/use-markdown-extensions.ts index dd9e80ba0..c8484ef00 100644 --- a/frontend/src/components/markdown-renderer/hooks/use-markdown-extensions.ts +++ b/frontend/src/components/markdown-renderer/hooks/use-markdown-extensions.ts @@ -5,6 +5,7 @@ */ import { optionalAppExtensions } from '../../../extensions/extra-integrations/optional-app-extensions' import type { MarkdownRendererExtension } from '../extensions/base/markdown-renderer-extension' +import { BootstrapIconMarkdownExtension } from '../extensions/bootstrap-icons/bootstrap-icon-markdown-extension' import { DebuggerMarkdownExtension } from '../extensions/debugger-markdown-extension' import { EmojiMarkdownExtension } from '../extensions/emoji/emoji-markdown-extension' import { GenericSyntaxMarkdownExtension } from '../extensions/generic-syntax-markdown-extension' @@ -53,6 +54,7 @@ export const useMarkdownExtensions = ( new UploadIndicatingImageFrameMarkdownExtension(), new LinkAdjustmentMarkdownExtension(baseUrl), new EmojiMarkdownExtension(), + new BootstrapIconMarkdownExtension(), new GenericSyntaxMarkdownExtension(), new LinkifyFixMarkdownExtension(), new DebuggerMarkdownExtension(), diff --git a/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx b/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx index f5144f312..7e8990524 100644 --- a/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx +++ b/frontend/src/components/markdown-renderer/replace-components/click-shield/click-shield.tsx @@ -6,14 +6,13 @@ import type { PropsWithDataCypressId } from '../../../../utils/cypress-attribute' import { cypressId } from '../../../../utils/cypress-attribute' import { Logger } from '../../../../utils/logger' -import { ForkAwesomeIcon } from '../../../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../../../common/fork-awesome/types' import { ShowIf } from '../../../common/show-if/show-if' import { ProxyImageFrame } from '../../extensions/image/proxy-image-frame' import styles from './click-shield.module.scss' import type { Property } from 'csstype' import type { PropsWithChildren } from 'react' import React, { useCallback, useEffect, useMemo, useState } from 'react' +import type { Icon } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' const log = new Logger('OneClickEmbedding') @@ -21,7 +20,7 @@ const log = new Logger('OneClickEmbedding') export interface ClickShieldProps extends PropsWithChildren<PropsWithDataCypressId> { onImageFetch?: () => Promise<string> fallbackPreviewImageUrl?: string - hoverIcon: IconName + hoverIcon: Icon targetDescription: string containerClassName?: string fallbackBackgroundColor?: Property.BackgroundColor @@ -104,6 +103,16 @@ export const ClickShield: React.FC<ClickShieldProps> = ({ const hoverTextTranslationValues = useMemo(() => ({ target: targetDescription }), [targetDescription]) + const icon = useMemo( + () => + React.createElement(hoverIcon, { + width: '5em', + height: '5em', + className: 'mb-2' + }), + [hoverIcon] + ) + return ( <span className={containerClassName} {...cypressId(props['data-cypress-id'])}> <ShowIf condition={showChildren}>{children}</ShowIf> @@ -114,7 +123,7 @@ export const ClickShield: React.FC<ClickShieldProps> = ({ <span className={`${styles['preview-hover-text']}`}> <Trans i18nKey={'renderer.clickShield.previewHoverText'} values={hoverTextTranslationValues} /> </span> - <ForkAwesomeIcon icon={hoverIcon} size={'5x'} className={'mb-2'} /> + {icon} </span> </span> </ShowIf> diff --git a/frontend/src/components/notifications/types.ts b/frontend/src/components/notifications/types.ts index 89fb35701..2c000f197 100644 --- a/frontend/src/components/notifications/types.ts +++ b/frontend/src/components/notifications/types.ts @@ -3,8 +3,8 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { IconName } from '../common/fork-awesome/types' import type { TOptions } from 'i18next' +import type { Icon } from 'react-bootstrap-icons' export interface UiNotificationButton { label: string @@ -15,7 +15,7 @@ export interface DispatchOptions { titleI18nOptions: TOptions contentI18nOptions: TOptions durationInSecond: number - icon?: IconName + icon?: Icon buttons: UiNotificationButton[] } diff --git a/frontend/src/components/notifications/ui-notification-boundary.tsx b/frontend/src/components/notifications/ui-notification-boundary.tsx index 220e42f28..d3d2131a8 100644 --- a/frontend/src/components/notifications/ui-notification-boundary.tsx +++ b/frontend/src/components/notifications/ui-notification-boundary.tsx @@ -11,6 +11,7 @@ import { t } from 'i18next' import { DateTime } from 'luxon' import type { PropsWithChildren } from 'react' import React, { createContext, useCallback, useContext, useMemo, useState } from 'react' +import { ExclamationTriangle as IconExclamationTriangle } from 'react-bootstrap-icons' import { v4 as uuid } from 'uuid' const log = new Logger('Notifications') @@ -80,7 +81,7 @@ export const UiNotificationBoundary: React.FC<PropsWithChildren> = ({ children } log.error(t(messageI18nKey, messageI18nOptions), error) void dispatchUiNotification('common.errorOccurred', messageI18nKey, { contentI18nOptions: messageI18nOptions, - icon: 'exclamation-triangle' + icon: IconExclamationTriangle }) }, [dispatchUiNotification] diff --git a/frontend/src/components/notifications/ui-notification-toast.tsx b/frontend/src/components/notifications/ui-notification-toast.tsx index 8053d9021..7a16726f0 100644 --- a/frontend/src/components/notifications/ui-notification-toast.tsx +++ b/frontend/src/components/notifications/ui-notification-toast.tsx @@ -5,8 +5,7 @@ */ import { cypressId } from '../../utils/cypress-attribute' import { Logger } from '../../utils/logger' -import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon' -import type { IconName } from '../common/fork-awesome/types' +import { UiIcon } from '../common/icons/ui-icon' import { ShowIf } from '../common/show-if/show-if' import styles from './notifications.module.scss' import type { UiNotification } from './types' @@ -102,7 +101,7 @@ export const UiNotificationToast: React.FC<UiNotificationProps> = ({ notificatio <Toast.Header> <strong className='me-auto'> <ShowIf condition={!!notification.icon}> - <ForkAwesomeIcon icon={notification.icon as IconName} fixedWidth={true} className={'me-1'} /> + <UiIcon icon={notification.icon} className={'me-1'} /> </ShowIf> <Trans i18nKey={notification.titleI18nKey} tOptions={notification.titleI18nOptions} /> </strong> diff --git a/frontend/src/components/profile-page/access-tokens/access-token-list-entry.tsx b/frontend/src/components/profile-page/access-tokens/access-token-list-entry.tsx index 054592f82..04f43c11d 100644 --- a/frontend/src/components/profile-page/access-tokens/access-token-list-entry.tsx +++ b/frontend/src/components/profile-page/access-tokens/access-token-list-entry.tsx @@ -12,6 +12,7 @@ import type { AccessTokenUpdateProps } from './profile-access-tokens' import { DateTime } from 'luxon' import React, { useCallback, useMemo } from 'react' import { Col, ListGroup, Row } from 'react-bootstrap' +import { Trash as IconTrash } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' export interface AccessTokenListEntryProps { @@ -61,7 +62,7 @@ export const AccessTokenListEntry: React.FC<AccessTokenListEntryProps & AccessTo <Col className='text-start text-white-50'>{lastUsed}</Col> <Col xs='auto'> <IconButton - icon='trash-o' + icon={IconTrash} variant='danger' onClick={showModal} {...cypressId('access-token-delete-button')} diff --git a/frontend/src/components/profile-page/account-management/profile-account-management.tsx b/frontend/src/components/profile-page/account-management/profile-account-management.tsx index a8076ffef..ea299dcd1 100644 --- a/frontend/src/components/profile-page/account-management/profile-account-management.tsx +++ b/frontend/src/components/profile-page/account-management/profile-account-management.tsx @@ -4,10 +4,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { useBooleanState } from '../../../hooks/common/use-boolean-state' -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { AccountDeletionModal } from './account-deletion-modal' import React, { Fragment } from 'react' import { Button, Card, Row } from 'react-bootstrap' +import { Trash as IconTrash } from 'react-bootstrap-icons' +import { CloudDownload as IconCloudDownload } from 'react-bootstrap-icons' import { Trans, useTranslation } from 'react-i18next' /** @@ -26,13 +28,13 @@ export const ProfileAccountManagement: React.FC = () => { </Card.Title> <Row> <Button variant='secondary' href={'me/export'} className='mb-2'> - <ForkAwesomeIcon icon='cloud-download' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconCloudDownload} className='mx-2' /> <Trans i18nKey='profile.exportUserData' /> </Button> </Row> <Row> <Button variant='danger' onClick={showModal}> - <ForkAwesomeIcon icon='trash' fixedWidth={true} className='mx-2' /> + <UiIcon icon={IconTrash} className='mx-2' /> <Trans i18nKey='profile.deleteUser' /> </Button> </Row> diff --git a/frontend/src/components/render-page/markdown-toc-button/table-of-contents-hovering-button.tsx b/frontend/src/components/render-page/markdown-toc-button/table-of-contents-hovering-button.tsx index af7f94492..43dc8c845 100644 --- a/frontend/src/components/render-page/markdown-toc-button/table-of-contents-hovering-button.tsx +++ b/frontend/src/components/render-page/markdown-toc-button/table-of-contents-hovering-button.tsx @@ -3,12 +3,13 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../common/icons/ui-icon' import { TableOfContents } from '../../editor-page/table-of-contents/table-of-contents' import styles from './markdown-toc-button.module.scss' import type { TocAst } from '@hedgedoc/markdown-it-plugins' import React from 'react' import { Dropdown } from 'react-bootstrap' +import { ListOl as IconListOl } from 'react-bootstrap-icons' export interface MarkdownTocButtonProps { tocAst: TocAst @@ -26,7 +27,7 @@ export const TableOfContentsHoveringButton: React.FC<MarkdownTocButtonProps> = ( <div className={styles['markdown-toc-sidebar-button']}> <Dropdown drop={'up'}> <Dropdown.Toggle id='toc-overlay-button' variant={'secondary'} className={'no-arrow'}> - <ForkAwesomeIcon icon={'list-ol'} /> + <UiIcon icon={IconListOl} /> </Dropdown.Toggle> <Dropdown.Menu> <div className={'p-2'}> diff --git a/frontend/src/extensions/extra-integrations/abcjs/__snapshots__/abc-frame.test.tsx.snap b/frontend/src/extensions/extra-integrations/abcjs/__snapshots__/abc-frame.test.tsx.snap index efe7dc3dc..c1802557f 100644 --- a/frontend/src/extensions/extra-integrations/abcjs/__snapshots__/abc-frame.test.tsx.snap +++ b/frontend/src/extensions/extra-integrations/abcjs/__snapshots__/abc-frame.test.tsx.snap @@ -5,9 +5,7 @@ exports[`AbcFrame renders a music sheet 1`] = ` <div class="m-3 d-flex align-items-center justify-content-center" > - <i - class="fa fa-spinner fa-spin " - /> + BootstrapIconMock_ArrowRepeat </div> </div> `; @@ -2358,9 +2356,7 @@ exports[`AbcFrame renders an error if abcjs file can't be loaded 1`] = ` <div class="m-3 d-flex align-items-center justify-content-center" > - <i - class="fa fa-spinner fa-spin " - /> + BootstrapIconMock_ArrowRepeat </div> </div> `; @@ -2381,9 +2377,7 @@ exports[`AbcFrame renders an error if abcjs render function crashes 1`] = ` <div class="m-3 d-flex align-items-center justify-content-center" > - <i - class="fa fa-spinner fa-spin " - /> + BootstrapIconMock_ArrowRepeat </div> </div> `; @@ -2402,9 +2396,7 @@ exports[`AbcFrame renders an error if abcjs render function crashes 2`] = ` <div class="m-3 d-flex align-items-center justify-content-center" > - <i - class="fa fa-spinner fa-spin " - /> + BootstrapIconMock_ArrowRepeat </div> </div> </div> diff --git a/frontend/src/extensions/extra-integrations/asciinema/asciinema-frame.tsx b/frontend/src/extensions/extra-integrations/asciinema/asciinema-frame.tsx index a2420e2b0..9f17fef77 100644 --- a/frontend/src/extensions/extra-integrations/asciinema/asciinema-frame.tsx +++ b/frontend/src/extensions/extra-integrations/asciinema/asciinema-frame.tsx @@ -6,6 +6,7 @@ import { ClickShield } from '../../../components/markdown-renderer/replace-components/click-shield/click-shield' import type { IdProps } from '../../../components/markdown-renderer/replace-components/custom-tag-with-id-component-replacer' import React from 'react' +import { Play as IconPlay } from 'react-bootstrap-icons' /** * Renders an embedding for https://asciinema.org @@ -15,7 +16,7 @@ import React from 'react' export const AsciinemaFrame: React.FC<IdProps> = ({ id }) => { return ( <ClickShield - hoverIcon={'play'} + hoverIcon={IconPlay} targetDescription={'asciinema'} fallbackPreviewImageUrl={`https://asciinema.org/a/${id}.png`} fallbackBackgroundColor={'#d40000'} diff --git a/frontend/src/extensions/extra-integrations/blockquote/__snapshots__/blockquote-extra-tag-markdown-extension.test.tsx.snap b/frontend/src/extensions/extra-integrations/blockquote/__snapshots__/blockquote-extra-tag-markdown-extension.test.tsx.snap index ac7c97934..6e3361fb1 100644 --- a/frontend/src/extensions/extra-integrations/blockquote/__snapshots__/blockquote-extra-tag-markdown-extension.test.tsx.snap +++ b/frontend/src/extensions/extra-integrations/blockquote/__snapshots__/blockquote-extra-tag-markdown-extension.test.tsx.snap @@ -35,9 +35,7 @@ exports[`blockquote extra tag renders the tag "[color=#abcdef]" correctly 1`] = class="blockquote-extra" style="color: rgb(171, 205, 239);" > - <i - class="fa fa-tag mx-1 " - /> + BootstrapIconMock_Tag </span> </p> @@ -52,9 +50,7 @@ exports[`blockquote extra tag renders the tag "[color=#dfe]" correctly 1`] = ` class="blockquote-extra" style="color: rgb(221, 255, 238);" > - <i - class="fa fa-tag mx-1 " - /> + BootstrapIconMock_Tag </span> </p> @@ -78,9 +74,6 @@ exports[`blockquote extra tag renders the tag "[color=notarealcolor]" correctly <span class="blockquote-extra" > - <i - class="fa fa-tag mx-1 " - /> notarealcolor </span> </p> @@ -96,9 +89,7 @@ exports[`blockquote extra tag renders the tag "[color=white]" correctly 1`] = ` class="blockquote-extra" style="color: white;" > - <i - class="fa fa-tag mx-1 " - /> + BootstrapIconMock_Tag </span> </p> @@ -142,9 +133,6 @@ exports[`blockquote extra tag renders the tag "[name=giowehg]" correctly 1`] = ` <span class="blockquote-extra" > - <i - class="fa fa-user mx-1 " - /> giowehg </span> </p> @@ -169,9 +157,6 @@ exports[`blockquote extra tag renders the tag "[time=tomorrow]" correctly 1`] = <span class="blockquote-extra" > - <i - class="fa fa-clock-o mx-1 " - /> tomorrow </span> </p> diff --git a/frontend/src/extensions/extra-integrations/blockquote/blockquote-color-extra-tag-replacer.tsx b/frontend/src/extensions/extra-integrations/blockquote/blockquote-color-extra-tag-replacer.tsx index 93cc8b8fe..807b2ba97 100644 --- a/frontend/src/extensions/extra-integrations/blockquote/blockquote-color-extra-tag-replacer.tsx +++ b/frontend/src/extensions/extra-integrations/blockquote/blockquote-color-extra-tag-replacer.tsx @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ForkAwesomeIcon } from '../../../components/common/fork-awesome/fork-awesome-icon' +import { UiIcon } from '../../../components/common/icons/ui-icon' import type { NodeReplacement } from '../../../components/markdown-renderer/replace-components/component-replacer' import { ComponentReplacer, @@ -15,6 +15,7 @@ import { Optional } from '@mrdrogdrog/optional' import type { Element } from 'domhandler' import { isText } from 'domhandler' import type { Text } from 'domhandler/lib/node' +import { Tag as IconTag } from 'react-bootstrap-icons' /** * Replaces <blockquote-tag> elements with "color" as label and a valid color as content @@ -35,7 +36,7 @@ export class BlockquoteColorExtraTagReplacer extends ComponentReplacer { .filter((content) => cssColor.test(content)) .map((color) => ( <span className={'blockquote-extra'} key={1} style={{ color: color }}> - <ForkAwesomeIcon key='icon' className={'mx-1'} icon={'tag'} /> + <UiIcon icon={IconTag} key='icon' className={'mx-1'} /> </span> )) .orElse(DO_NOT_REPLACE) diff --git a/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-extension.ts b/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-extension.ts index 38b6b8e1a..ea41e5483 100644 --- a/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-extension.ts +++ b/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-extension.ts @@ -20,8 +20,8 @@ export class BlockquoteExtraTagMarkdownExtension extends MarkdownRendererExtensi public configureMarkdownIt(markdownIt: MarkdownIt): void { new BlockquoteExtraTagMarkdownItPlugin('color', 'tag').registerRule(markdownIt) - new BlockquoteExtraTagMarkdownItPlugin('name', 'user').registerRule(markdownIt) - new BlockquoteExtraTagMarkdownItPlugin('time', 'clock-o').registerRule(markdownIt) + new BlockquoteExtraTagMarkdownItPlugin('name', 'person').registerRule(markdownIt) + new BlockquoteExtraTagMarkdownItPlugin('time', 'clock').registerRule(markdownIt) } public buildReplacers(): ComponentReplacer[] { diff --git a/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-it-plugin.ts b/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-it-plugin.ts index 82407198a..0fa66efd4 100644 --- a/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-it-plugin.ts +++ b/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-markdown-it-plugin.ts @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { IconName } from '../../../components/common/fork-awesome/types' +import type { BootstrapIconName } from '../../../components/common/icons/bootstrap-icons' import { BlockquoteExtraTagMarkdownExtension } from './blockquote-extra-tag-markdown-extension' import { Optional } from '@mrdrogdrog/optional' import type MarkdownIt from 'markdown-it/lib' @@ -11,12 +11,6 @@ import type { RuleInline } from 'markdown-it/lib/parser_inline' import type StateInline from 'markdown-it/lib/rules_inline/state_inline' import type Token from 'markdown-it/lib/token' -export interface BlockquoteTagOptions { - parseSubTags?: boolean - valueRegex?: RegExp - icon?: IconName -} - export interface QuoteExtraTagValues { labelStartIndex: number labelEndIndex: number @@ -32,7 +26,7 @@ export interface QuoteExtraTagValues { export class BlockquoteExtraTagMarkdownItPlugin { private static readonly BlockquoteExtraTagRuleName = 'blockquote_extra_tag' - constructor(private tagName: string, private icon: IconName) {} + constructor(private tagName: string, private icon: BootstrapIconName) {} /** * Registers an inline rule that detects blockquote extra tags and replaces them with blockquote tokens. diff --git a/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-replacer.tsx b/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-replacer.tsx index 851dc369e..98a5e7cbb 100644 --- a/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-replacer.tsx +++ b/frontend/src/extensions/extra-integrations/blockquote/blockquote-extra-tag-replacer.tsx @@ -3,10 +3,10 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { ForkAwesomeIconProps } from '../../../components/common/fork-awesome/fork-awesome-icon' -import { ForkAwesomeIcon } from '../../../components/common/fork-awesome/fork-awesome-icon' -import { ForkAwesomeIcons } from '../../../components/common/fork-awesome/fork-awesome-icons' -import type { IconName } from '../../../components/common/fork-awesome/types' +import type { BootstrapIconName } from '../../../components/common/icons/bootstrap-icons' +import { isBootstrapIconName } from '../../../components/common/icons/bootstrap-icons' +import type { LazyBootstrapIconProps } from '../../../components/common/icons/lazy-bootstrap-icon' +import { LazyBootstrapIcon } from '../../../components/common/icons/lazy-bootstrap-icon' import type { NodeReplacement, SubNodeTransform @@ -42,15 +42,15 @@ export class BlockquoteExtraTagReplacer extends ComponentReplacer { } /** - * Extracts a fork awesome icon name from the node and builds a {@link ForkAwesomeIcon fork awesome icon react element}. + * Extracts an icon name from the node and builds a {@link LazyBootstrapIcon icon react element}. * * @param node The node that holds the "data-icon" attribute. - * @return the {@link ForkAwesomeIcon fork awesome icon react element} or {@link undefined} if no icon name was found. + * @return the {@link LazyBootstrapIcon icon react element} or {@link undefined} if no icon name was found. */ - private buildIconElement(node: Element): ReactElement<ForkAwesomeIconProps> | undefined { - return Optional.ofNullable(node.attribs['data-icon'] as IconName) - .filter((iconName) => ForkAwesomeIcons.includes(iconName)) - .map((iconName) => <ForkAwesomeIcon key='icon' className={'mx-1'} icon={iconName} />) + private buildIconElement(node: Element): ReactElement<LazyBootstrapIconProps> | undefined { + return Optional.ofNullable(node.attribs['data-icon'] as BootstrapIconName) + .filter((iconName) => isBootstrapIconName(iconName)) + .map((iconName) => <LazyBootstrapIcon key='icon' className={'mx-1'} icon={iconName} />) .orElse(undefined) } } diff --git a/frontend/src/extensions/extra-integrations/fork-awesome/fork-awesome-app-extension.ts b/frontend/src/extensions/extra-integrations/fork-awesome-html-tag/fork-awesome-html-tag-app-extension.ts similarity index 86% rename from frontend/src/extensions/extra-integrations/fork-awesome/fork-awesome-app-extension.ts rename to frontend/src/extensions/extra-integrations/fork-awesome-html-tag/fork-awesome-html-tag-app-extension.ts index 1dcd975ed..4eef52412 100644 --- a/frontend/src/extensions/extra-integrations/fork-awesome/fork-awesome-app-extension.ts +++ b/frontend/src/extensions/extra-integrations/fork-awesome-html-tag/fork-awesome-html-tag-app-extension.ts @@ -11,9 +11,9 @@ import { t } from 'i18next' const forkAwesomeRegex = /<i class=["'][\w\s]*fa-[\w-]+[\w\s-]*["'][^>]*\/?>(?:<\/i>)?/ /** - * Adds support for flow charts to the markdown rendering. + * Adds a linter for the icon html tag. */ -export class ForkAwesomeAppExtension extends AppExtension { +export class ForkAwesomeHtmlTagAppExtension extends AppExtension { buildCodeMirrorLinter(): Linter[] { return [ new SingleLineRegexLinter( diff --git a/frontend/src/extensions/extra-integrations/gist/gist-frame.tsx b/frontend/src/extensions/extra-integrations/gist/gist-frame.tsx index 9785a32d7..65b552245 100644 --- a/frontend/src/extensions/extra-integrations/gist/gist-frame.tsx +++ b/frontend/src/extensions/extra-integrations/gist/gist-frame.tsx @@ -9,6 +9,7 @@ import { cypressId } from '../../../utils/cypress-attribute' import styles from './gist-frame.module.scss' import { useResizeGistFrame } from './use-resize-gist-frame' import React, { useCallback } from 'react' +import { Github as IconGithub } from 'react-bootstrap-icons' /** * This component renders a GitHub Gist by placing the gist URL in an {@link HTMLIFrameElement iframe}. @@ -28,7 +29,7 @@ export const GistFrame: React.FC<IdProps> = ({ id }) => { return ( <ClickShield fallbackBackgroundColor={'#161b22'} - hoverIcon={'github'} + hoverIcon={IconGithub} targetDescription={'GitHub Gist'} data-cypress-id={'click-shield-gist'}> <iframe diff --git a/frontend/src/extensions/extra-integrations/optional-app-extensions.ts b/frontend/src/extensions/extra-integrations/optional-app-extensions.ts index f3e0e0937..426925725 100644 --- a/frontend/src/extensions/extra-integrations/optional-app-extensions.ts +++ b/frontend/src/extensions/extra-integrations/optional-app-extensions.ts @@ -10,7 +10,7 @@ import { AsciinemaAppExtension } from './asciinema/asciinema-app-extension' import { BlockquoteAppExtension } from './blockquote/blockquote-app-extension' import { CsvTableAppExtension } from './csv/csv-table-app-extension' import { FlowchartAppExtension } from './flowchart/flowchart-app-extension' -import { ForkAwesomeAppExtension } from './fork-awesome/fork-awesome-app-extension' +import { ForkAwesomeHtmlTagAppExtension } from './fork-awesome-html-tag/fork-awesome-html-tag-app-extension' import { GistAppExtension } from './gist/gist-app-extension' import { GraphvizAppExtension } from './graphviz/graphviz-app-extension' import { HighlightedCodeFenceAppExtension } from './highlighted-code-fence/highlighted-code-fence-app-extension' @@ -48,5 +48,5 @@ export const optionalAppExtensions: AppExtension[] = [ new YoutubeAppExtension(), new TaskListCheckboxAppExtension(), new HighlightedCodeFenceAppExtension(), - new ForkAwesomeAppExtension() + new ForkAwesomeHtmlTagAppExtension() ] diff --git a/frontend/src/extensions/extra-integrations/vimeo/vimeo-frame.tsx b/frontend/src/extensions/extra-integrations/vimeo/vimeo-frame.tsx index 166824d7d..43a29cc91 100644 --- a/frontend/src/extensions/extra-integrations/vimeo/vimeo-frame.tsx +++ b/frontend/src/extensions/extra-integrations/vimeo/vimeo-frame.tsx @@ -6,6 +6,7 @@ import { ClickShield } from '../../../components/markdown-renderer/replace-components/click-shield/click-shield' import type { IdProps } from '../../../components/markdown-renderer/replace-components/custom-tag-with-id-component-replacer' import React, { useCallback } from 'react' +import { Vimeo as IconVimeo } from 'react-bootstrap-icons' interface VimeoApiResponse { // Vimeo uses strange names for their fields. ESLint doesn't like that. @@ -38,7 +39,7 @@ export const VimeoFrame: React.FC<IdProps> = ({ id }) => { return ( <ClickShield - hoverIcon={'vimeo-square'} + hoverIcon={IconVimeo} targetDescription={'Vimeo'} onImageFetch={getPreviewImageLink} fallbackBackgroundColor={'#00adef'} diff --git a/frontend/src/extensions/extra-integrations/youtube/youtube-frame.tsx b/frontend/src/extensions/extra-integrations/youtube/youtube-frame.tsx index 103dba162..6e9b0d713 100644 --- a/frontend/src/extensions/extra-integrations/youtube/youtube-frame.tsx +++ b/frontend/src/extensions/extra-integrations/youtube/youtube-frame.tsx @@ -6,6 +6,7 @@ import { ClickShield } from '../../../components/markdown-renderer/replace-components/click-shield/click-shield' import type { IdProps } from '../../../components/markdown-renderer/replace-components/custom-tag-with-id-component-replacer' import React from 'react' +import { Youtube as IconYoutube } from 'react-bootstrap-icons' /** * Renders a video player embedding for https://youtube.com @@ -15,7 +16,7 @@ import React from 'react' export const YouTubeFrame: React.FC<IdProps> = ({ id }) => { return ( <ClickShield - hoverIcon={'youtube-play'} + hoverIcon={IconYoutube} targetDescription={'YouTube'} fallbackPreviewImageUrl={`https://i.ytimg.com/vi/${id}/maxresdefault.jpg`} fallbackBackgroundColor={'#ff0000'} diff --git a/frontend/src/external-types/images/index.d.ts b/frontend/src/external-types/images/index.d.ts new file mode 100644 index 000000000..b5035cddc --- /dev/null +++ b/frontend/src/external-types/images/index.d.ts @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +declare module '*.svg' { + import type React from 'react' + const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>> + export default ReactComponent +} diff --git a/frontend/src/external-types/react-bootstrap-icons/index.d.ts b/frontend/src/external-types/react-bootstrap-icons/index.d.ts new file mode 100644 index 000000000..b5dbfc875 --- /dev/null +++ b/frontend/src/external-types/react-bootstrap-icons/index.d.ts @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +declare module 'react-bootstrap-icons/dist/icons/*' { + import type { Icon } from 'react-bootstrap-icons' + const ReactComponent: Icon + export default ReactComponent +} diff --git a/frontend/src/test-utils/bootstrap-icon-mocks.tsx b/frontend/src/test-utils/bootstrap-icon-mocks.tsx new file mode 100644 index 000000000..b1606376e --- /dev/null +++ b/frontend/src/test-utils/bootstrap-icon-mocks.tsx @@ -0,0 +1,1961 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import type { Icon } from 'react-bootstrap-icons' + +export const Icon0CircleFill: Icon = () => <>BootstrapIconMock_Icon0CircleFill</> +export const Icon0Circle: Icon = () => <>BootstrapIconMock_Icon0Circle</> +export const Icon0SquareFill: Icon = () => <>BootstrapIconMock_Icon0SquareFill</> +export const Icon0Square: Icon = () => <>BootstrapIconMock_Icon0Square</> +export const Icon1CircleFill: Icon = () => <>BootstrapIconMock_Icon1CircleFill</> +export const Icon1Circle: Icon = () => <>BootstrapIconMock_Icon1Circle</> +export const Icon1SquareFill: Icon = () => <>BootstrapIconMock_Icon1SquareFill</> +export const Icon1Square: Icon = () => <>BootstrapIconMock_Icon1Square</> +export const Icon123: Icon = () => <>BootstrapIconMock_Icon123</> +export const Icon2CircleFill: Icon = () => <>BootstrapIconMock_Icon2CircleFill</> +export const Icon2Circle: Icon = () => <>BootstrapIconMock_Icon2Circle</> +export const Icon2SquareFill: Icon = () => <>BootstrapIconMock_Icon2SquareFill</> +export const Icon2Square: Icon = () => <>BootstrapIconMock_Icon2Square</> +export const Icon3CircleFill: Icon = () => <>BootstrapIconMock_Icon3CircleFill</> +export const Icon3Circle: Icon = () => <>BootstrapIconMock_Icon3Circle</> +export const Icon3SquareFill: Icon = () => <>BootstrapIconMock_Icon3SquareFill</> +export const Icon3Square: Icon = () => <>BootstrapIconMock_Icon3Square</> +export const Icon4CircleFill: Icon = () => <>BootstrapIconMock_Icon4CircleFill</> +export const Icon4Circle: Icon = () => <>BootstrapIconMock_Icon4Circle</> +export const Icon4SquareFill: Icon = () => <>BootstrapIconMock_Icon4SquareFill</> +export const Icon4Square: Icon = () => <>BootstrapIconMock_Icon4Square</> +export const Icon5CircleFill: Icon = () => <>BootstrapIconMock_Icon5CircleFill</> +export const Icon5Circle: Icon = () => <>BootstrapIconMock_Icon5Circle</> +export const Icon5SquareFill: Icon = () => <>BootstrapIconMock_Icon5SquareFill</> +export const Icon5Square: Icon = () => <>BootstrapIconMock_Icon5Square</> +export const Icon6CircleFill: Icon = () => <>BootstrapIconMock_Icon6CircleFill</> +export const Icon6Circle: Icon = () => <>BootstrapIconMock_Icon6Circle</> +export const Icon6SquareFill: Icon = () => <>BootstrapIconMock_Icon6SquareFill</> +export const Icon6Square: Icon = () => <>BootstrapIconMock_Icon6Square</> +export const Icon7CircleFill: Icon = () => <>BootstrapIconMock_Icon7CircleFill</> +export const Icon7Circle: Icon = () => <>BootstrapIconMock_Icon7Circle</> +export const Icon7SquareFill: Icon = () => <>BootstrapIconMock_Icon7SquareFill</> +export const Icon7Square: Icon = () => <>BootstrapIconMock_Icon7Square</> +export const Icon8CircleFill: Icon = () => <>BootstrapIconMock_Icon8CircleFill</> +export const Icon8Circle: Icon = () => <>BootstrapIconMock_Icon8Circle</> +export const Icon8SquareFill: Icon = () => <>BootstrapIconMock_Icon8SquareFill</> +export const Icon8Square: Icon = () => <>BootstrapIconMock_Icon8Square</> +export const Icon9CircleFill: Icon = () => <>BootstrapIconMock_Icon9CircleFill</> +export const Icon9Circle: Icon = () => <>BootstrapIconMock_Icon9Circle</> +export const Icon9SquareFill: Icon = () => <>BootstrapIconMock_Icon9SquareFill</> +export const Icon9Square: Icon = () => <>BootstrapIconMock_Icon9Square</> +export const Activity: Icon = () => <>BootstrapIconMock_Activity</> +export const AirplaneEnginesFill: Icon = () => <>BootstrapIconMock_AirplaneEnginesFill</> +export const AirplaneEngines: Icon = () => <>BootstrapIconMock_AirplaneEngines</> +export const AirplaneFill: Icon = () => <>BootstrapIconMock_AirplaneFill</> +export const Airplane: Icon = () => <>BootstrapIconMock_Airplane</> +export const AlarmFill: Icon = () => <>BootstrapIconMock_AlarmFill</> +export const Alarm: Icon = () => <>BootstrapIconMock_Alarm</> +export const Alexa: Icon = () => <>BootstrapIconMock_Alexa</> +export const AlignBottom: Icon = () => <>BootstrapIconMock_AlignBottom</> +export const AlignCenter: Icon = () => <>BootstrapIconMock_AlignCenter</> +export const AlignEnd: Icon = () => <>BootstrapIconMock_AlignEnd</> +export const AlignMiddle: Icon = () => <>BootstrapIconMock_AlignMiddle</> +export const AlignStart: Icon = () => <>BootstrapIconMock_AlignStart</> +export const AlignTop: Icon = () => <>BootstrapIconMock_AlignTop</> +export const Alipay: Icon = () => <>BootstrapIconMock_Alipay</> +export const Alt: Icon = () => <>BootstrapIconMock_Alt</> +export const Amd: Icon = () => <>BootstrapIconMock_Amd</> +export const Android: Icon = () => <>BootstrapIconMock_Android</> +export const Android2: Icon = () => <>BootstrapIconMock_Android2</> +export const AppIndicator: Icon = () => <>BootstrapIconMock_AppIndicator</> +export const App: Icon = () => <>BootstrapIconMock_App</> +export const Apple: Icon = () => <>BootstrapIconMock_Apple</> +export const ArchiveFill: Icon = () => <>BootstrapIconMock_ArchiveFill</> +export const Archive: Icon = () => <>BootstrapIconMock_Archive</> +export const Arrow90degDown: Icon = () => <>BootstrapIconMock_Arrow90degDown</> +export const Arrow90degLeft: Icon = () => <>BootstrapIconMock_Arrow90degLeft</> +export const Arrow90degRight: Icon = () => <>BootstrapIconMock_Arrow90degRight</> +export const Arrow90degUp: Icon = () => <>BootstrapIconMock_Arrow90degUp</> +export const ArrowBarDown: Icon = () => <>BootstrapIconMock_ArrowBarDown</> +export const ArrowBarLeft: Icon = () => <>BootstrapIconMock_ArrowBarLeft</> +export const ArrowBarRight: Icon = () => <>BootstrapIconMock_ArrowBarRight</> +export const ArrowBarUp: Icon = () => <>BootstrapIconMock_ArrowBarUp</> +export const ArrowClockwise: Icon = () => <>BootstrapIconMock_ArrowClockwise</> +export const ArrowCounterclockwise: Icon = () => <>BootstrapIconMock_ArrowCounterclockwise</> +export const ArrowDownCircleFill: Icon = () => <>BootstrapIconMock_ArrowDownCircleFill</> +export const ArrowDownCircle: Icon = () => <>BootstrapIconMock_ArrowDownCircle</> +export const ArrowDownLeftCircleFill: Icon = () => <>BootstrapIconMock_ArrowDownLeftCircleFill</> +export const ArrowDownLeftCircle: Icon = () => <>BootstrapIconMock_ArrowDownLeftCircle</> +export const ArrowDownLeftSquareFill: Icon = () => <>BootstrapIconMock_ArrowDownLeftSquareFill</> +export const ArrowDownLeftSquare: Icon = () => <>BootstrapIconMock_ArrowDownLeftSquare</> +export const ArrowDownLeft: Icon = () => <>BootstrapIconMock_ArrowDownLeft</> +export const ArrowDownRightCircleFill: Icon = () => <>BootstrapIconMock_ArrowDownRightCircleFill</> +export const ArrowDownRightCircle: Icon = () => <>BootstrapIconMock_ArrowDownRightCircle</> +export const ArrowDownRightSquareFill: Icon = () => <>BootstrapIconMock_ArrowDownRightSquareFill</> +export const ArrowDownRightSquare: Icon = () => <>BootstrapIconMock_ArrowDownRightSquare</> +export const ArrowDownRight: Icon = () => <>BootstrapIconMock_ArrowDownRight</> +export const ArrowDownShort: Icon = () => <>BootstrapIconMock_ArrowDownShort</> +export const ArrowDownSquareFill: Icon = () => <>BootstrapIconMock_ArrowDownSquareFill</> +export const ArrowDownSquare: Icon = () => <>BootstrapIconMock_ArrowDownSquare</> +export const ArrowDownUp: Icon = () => <>BootstrapIconMock_ArrowDownUp</> +export const ArrowDown: Icon = () => <>BootstrapIconMock_ArrowDown</> +export const ArrowLeftCircleFill: Icon = () => <>BootstrapIconMock_ArrowLeftCircleFill</> +export const ArrowLeftCircle: Icon = () => <>BootstrapIconMock_ArrowLeftCircle</> +export const ArrowLeftRight: Icon = () => <>BootstrapIconMock_ArrowLeftRight</> +export const ArrowLeftShort: Icon = () => <>BootstrapIconMock_ArrowLeftShort</> +export const ArrowLeftSquareFill: Icon = () => <>BootstrapIconMock_ArrowLeftSquareFill</> +export const ArrowLeftSquare: Icon = () => <>BootstrapIconMock_ArrowLeftSquare</> +export const ArrowLeft: Icon = () => <>BootstrapIconMock_ArrowLeft</> +export const ArrowRepeat: Icon = () => <>BootstrapIconMock_ArrowRepeat</> +export const ArrowReturnLeft: Icon = () => <>BootstrapIconMock_ArrowReturnLeft</> +export const ArrowReturnRight: Icon = () => <>BootstrapIconMock_ArrowReturnRight</> +export const ArrowRightCircleFill: Icon = () => <>BootstrapIconMock_ArrowRightCircleFill</> +export const ArrowRightCircle: Icon = () => <>BootstrapIconMock_ArrowRightCircle</> +export const ArrowRightShort: Icon = () => <>BootstrapIconMock_ArrowRightShort</> +export const ArrowRightSquareFill: Icon = () => <>BootstrapIconMock_ArrowRightSquareFill</> +export const ArrowRightSquare: Icon = () => <>BootstrapIconMock_ArrowRightSquare</> +export const ArrowRight: Icon = () => <>BootstrapIconMock_ArrowRight</> +export const ArrowThroughHeartFill: Icon = () => <>BootstrapIconMock_ArrowThroughHeartFill</> +export const ArrowThroughHeart: Icon = () => <>BootstrapIconMock_ArrowThroughHeart</> +export const ArrowUpCircleFill: Icon = () => <>BootstrapIconMock_ArrowUpCircleFill</> +export const ArrowUpCircle: Icon = () => <>BootstrapIconMock_ArrowUpCircle</> +export const ArrowUpLeftCircleFill: Icon = () => <>BootstrapIconMock_ArrowUpLeftCircleFill</> +export const ArrowUpLeftCircle: Icon = () => <>BootstrapIconMock_ArrowUpLeftCircle</> +export const ArrowUpLeftSquareFill: Icon = () => <>BootstrapIconMock_ArrowUpLeftSquareFill</> +export const ArrowUpLeftSquare: Icon = () => <>BootstrapIconMock_ArrowUpLeftSquare</> +export const ArrowUpLeft: Icon = () => <>BootstrapIconMock_ArrowUpLeft</> +export const ArrowUpRightCircleFill: Icon = () => <>BootstrapIconMock_ArrowUpRightCircleFill</> +export const ArrowUpRightCircle: Icon = () => <>BootstrapIconMock_ArrowUpRightCircle</> +export const ArrowUpRightSquareFill: Icon = () => <>BootstrapIconMock_ArrowUpRightSquareFill</> +export const ArrowUpRightSquare: Icon = () => <>BootstrapIconMock_ArrowUpRightSquare</> +export const ArrowUpRight: Icon = () => <>BootstrapIconMock_ArrowUpRight</> +export const ArrowUpShort: Icon = () => <>BootstrapIconMock_ArrowUpShort</> +export const ArrowUpSquareFill: Icon = () => <>BootstrapIconMock_ArrowUpSquareFill</> +export const ArrowUpSquare: Icon = () => <>BootstrapIconMock_ArrowUpSquare</> +export const ArrowUp: Icon = () => <>BootstrapIconMock_ArrowUp</> +export const ArrowsAngleContract: Icon = () => <>BootstrapIconMock_ArrowsAngleContract</> +export const ArrowsAngleExpand: Icon = () => <>BootstrapIconMock_ArrowsAngleExpand</> +export const ArrowsCollapse: Icon = () => <>BootstrapIconMock_ArrowsCollapse</> +export const ArrowsExpand: Icon = () => <>BootstrapIconMock_ArrowsExpand</> +export const ArrowsFullscreen: Icon = () => <>BootstrapIconMock_ArrowsFullscreen</> +export const ArrowsMove: Icon = () => <>BootstrapIconMock_ArrowsMove</> +export const AspectRatioFill: Icon = () => <>BootstrapIconMock_AspectRatioFill</> +export const AspectRatio: Icon = () => <>BootstrapIconMock_AspectRatio</> +export const Asterisk: Icon = () => <>BootstrapIconMock_Asterisk</> +export const At: Icon = () => <>BootstrapIconMock_At</> +export const AwardFill: Icon = () => <>BootstrapIconMock_AwardFill</> +export const Award: Icon = () => <>BootstrapIconMock_Award</> +export const Back: Icon = () => <>BootstrapIconMock_Back</> +export const BackspaceFill: Icon = () => <>BootstrapIconMock_BackspaceFill</> +export const BackspaceReverseFill: Icon = () => <>BootstrapIconMock_BackspaceReverseFill</> +export const BackspaceReverse: Icon = () => <>BootstrapIconMock_BackspaceReverse</> +export const Backspace: Icon = () => <>BootstrapIconMock_Backspace</> +export const Badge3dFill: Icon = () => <>BootstrapIconMock_Badge3dFill</> +export const Badge3d: Icon = () => <>BootstrapIconMock_Badge3d</> +export const Badge4kFill: Icon = () => <>BootstrapIconMock_Badge4kFill</> +export const Badge4k: Icon = () => <>BootstrapIconMock_Badge4k</> +export const Badge8kFill: Icon = () => <>BootstrapIconMock_Badge8kFill</> +export const Badge8k: Icon = () => <>BootstrapIconMock_Badge8k</> +export const BadgeAdFill: Icon = () => <>BootstrapIconMock_BadgeAdFill</> +export const BadgeAd: Icon = () => <>BootstrapIconMock_BadgeAd</> +export const BadgeArFill: Icon = () => <>BootstrapIconMock_BadgeArFill</> +export const BadgeAr: Icon = () => <>BootstrapIconMock_BadgeAr</> +export const BadgeCcFill: Icon = () => <>BootstrapIconMock_BadgeCcFill</> +export const BadgeCc: Icon = () => <>BootstrapIconMock_BadgeCc</> +export const BadgeHdFill: Icon = () => <>BootstrapIconMock_BadgeHdFill</> +export const BadgeHd: Icon = () => <>BootstrapIconMock_BadgeHd</> +export const BadgeSdFill: Icon = () => <>BootstrapIconMock_BadgeSdFill</> +export const BadgeSd: Icon = () => <>BootstrapIconMock_BadgeSd</> +export const BadgeTmFill: Icon = () => <>BootstrapIconMock_BadgeTmFill</> +export const BadgeTm: Icon = () => <>BootstrapIconMock_BadgeTm</> +export const BadgeVoFill: Icon = () => <>BootstrapIconMock_BadgeVoFill</> +export const BadgeVo: Icon = () => <>BootstrapIconMock_BadgeVo</> +export const BadgeVrFill: Icon = () => <>BootstrapIconMock_BadgeVrFill</> +export const BadgeVr: Icon = () => <>BootstrapIconMock_BadgeVr</> +export const BadgeWcFill: Icon = () => <>BootstrapIconMock_BadgeWcFill</> +export const BadgeWc: Icon = () => <>BootstrapIconMock_BadgeWc</> +export const BagCheckFill: Icon = () => <>BootstrapIconMock_BagCheckFill</> +export const BagCheck: Icon = () => <>BootstrapIconMock_BagCheck</> +export const BagDashFill: Icon = () => <>BootstrapIconMock_BagDashFill</> +export const BagDash: Icon = () => <>BootstrapIconMock_BagDash</> +export const BagFill: Icon = () => <>BootstrapIconMock_BagFill</> +export const BagHeartFill: Icon = () => <>BootstrapIconMock_BagHeartFill</> +export const BagHeart: Icon = () => <>BootstrapIconMock_BagHeart</> +export const BagPlusFill: Icon = () => <>BootstrapIconMock_BagPlusFill</> +export const BagPlus: Icon = () => <>BootstrapIconMock_BagPlus</> +export const BagXFill: Icon = () => <>BootstrapIconMock_BagXFill</> +export const BagX: Icon = () => <>BootstrapIconMock_BagX</> +export const Bag: Icon = () => <>BootstrapIconMock_Bag</> +export const BalloonFill: Icon = () => <>BootstrapIconMock_BalloonFill</> +export const BalloonHeartFill: Icon = () => <>BootstrapIconMock_BalloonHeartFill</> +export const BalloonHeart: Icon = () => <>BootstrapIconMock_BalloonHeart</> +export const Balloon: Icon = () => <>BootstrapIconMock_Balloon</> +export const BandaidFill: Icon = () => <>BootstrapIconMock_BandaidFill</> +export const Bandaid: Icon = () => <>BootstrapIconMock_Bandaid</> +export const Bank: Icon = () => <>BootstrapIconMock_Bank</> +export const Bank2: Icon = () => <>BootstrapIconMock_Bank2</> +export const BarChartFill: Icon = () => <>BootstrapIconMock_BarChartFill</> +export const BarChartLineFill: Icon = () => <>BootstrapIconMock_BarChartLineFill</> +export const BarChartLine: Icon = () => <>BootstrapIconMock_BarChartLine</> +export const BarChartSteps: Icon = () => <>BootstrapIconMock_BarChartSteps</> +export const BarChart: Icon = () => <>BootstrapIconMock_BarChart</> +export const BasketFill: Icon = () => <>BootstrapIconMock_BasketFill</> +export const Basket: Icon = () => <>BootstrapIconMock_Basket</> +export const Basket2Fill: Icon = () => <>BootstrapIconMock_Basket2Fill</> +export const Basket2: Icon = () => <>BootstrapIconMock_Basket2</> +export const Basket3Fill: Icon = () => <>BootstrapIconMock_Basket3Fill</> +export const Basket3: Icon = () => <>BootstrapIconMock_Basket3</> +export const BatteryCharging: Icon = () => <>BootstrapIconMock_BatteryCharging</> +export const BatteryFull: Icon = () => <>BootstrapIconMock_BatteryFull</> +export const BatteryHalf: Icon = () => <>BootstrapIconMock_BatteryHalf</> +export const Battery: Icon = () => <>BootstrapIconMock_Battery</> +export const Behance: Icon = () => <>BootstrapIconMock_Behance</> +export const BellFill: Icon = () => <>BootstrapIconMock_BellFill</> +export const BellSlashFill: Icon = () => <>BootstrapIconMock_BellSlashFill</> +export const BellSlash: Icon = () => <>BootstrapIconMock_BellSlash</> +export const Bell: Icon = () => <>BootstrapIconMock_Bell</> +export const Bezier: Icon = () => <>BootstrapIconMock_Bezier</> +export const Bezier2: Icon = () => <>BootstrapIconMock_Bezier2</> +export const Bicycle: Icon = () => <>BootstrapIconMock_Bicycle</> +export const BinocularsFill: Icon = () => <>BootstrapIconMock_BinocularsFill</> +export const Binoculars: Icon = () => <>BootstrapIconMock_Binoculars</> +export const BlockquoteLeft: Icon = () => <>BootstrapIconMock_BlockquoteLeft</> +export const BlockquoteRight: Icon = () => <>BootstrapIconMock_BlockquoteRight</> +export const Bluetooth: Icon = () => <>BootstrapIconMock_Bluetooth</> +export const BodyText: Icon = () => <>BootstrapIconMock_BodyText</> +export const BookFill: Icon = () => <>BootstrapIconMock_BookFill</> +export const BookHalf: Icon = () => <>BootstrapIconMock_BookHalf</> +export const Book: Icon = () => <>BootstrapIconMock_Book</> +export const BookmarkCheckFill: Icon = () => <>BootstrapIconMock_BookmarkCheckFill</> +export const BookmarkCheck: Icon = () => <>BootstrapIconMock_BookmarkCheck</> +export const BookmarkDashFill: Icon = () => <>BootstrapIconMock_BookmarkDashFill</> +export const BookmarkDash: Icon = () => <>BootstrapIconMock_BookmarkDash</> +export const BookmarkFill: Icon = () => <>BootstrapIconMock_BookmarkFill</> +export const BookmarkHeartFill: Icon = () => <>BootstrapIconMock_BookmarkHeartFill</> +export const BookmarkHeart: Icon = () => <>BootstrapIconMock_BookmarkHeart</> +export const BookmarkPlusFill: Icon = () => <>BootstrapIconMock_BookmarkPlusFill</> +export const BookmarkPlus: Icon = () => <>BootstrapIconMock_BookmarkPlus</> +export const BookmarkStarFill: Icon = () => <>BootstrapIconMock_BookmarkStarFill</> +export const BookmarkStar: Icon = () => <>BootstrapIconMock_BookmarkStar</> +export const BookmarkXFill: Icon = () => <>BootstrapIconMock_BookmarkXFill</> +export const BookmarkX: Icon = () => <>BootstrapIconMock_BookmarkX</> +export const Bookmark: Icon = () => <>BootstrapIconMock_Bookmark</> +export const BookmarksFill: Icon = () => <>BootstrapIconMock_BookmarksFill</> +export const Bookmarks: Icon = () => <>BootstrapIconMock_Bookmarks</> +export const Bookshelf: Icon = () => <>BootstrapIconMock_Bookshelf</> +export const BoomboxFill: Icon = () => <>BootstrapIconMock_BoomboxFill</> +export const Boombox: Icon = () => <>BootstrapIconMock_Boombox</> +export const BootstrapFill: Icon = () => <>BootstrapIconMock_BootstrapFill</> +export const BootstrapReboot: Icon = () => <>BootstrapIconMock_BootstrapReboot</> +export const Bootstrap: Icon = () => <>BootstrapIconMock_Bootstrap</> +export const BorderAll: Icon = () => <>BootstrapIconMock_BorderAll</> +export const BorderBottom: Icon = () => <>BootstrapIconMock_BorderBottom</> +export const BorderCenter: Icon = () => <>BootstrapIconMock_BorderCenter</> +export const BorderInner: Icon = () => <>BootstrapIconMock_BorderInner</> +export const BorderLeft: Icon = () => <>BootstrapIconMock_BorderLeft</> +export const BorderMiddle: Icon = () => <>BootstrapIconMock_BorderMiddle</> +export const BorderOuter: Icon = () => <>BootstrapIconMock_BorderOuter</> +export const BorderRight: Icon = () => <>BootstrapIconMock_BorderRight</> +export const BorderStyle: Icon = () => <>BootstrapIconMock_BorderStyle</> +export const BorderTop: Icon = () => <>BootstrapIconMock_BorderTop</> +export const BorderWidth: Icon = () => <>BootstrapIconMock_BorderWidth</> +export const Border: Icon = () => <>BootstrapIconMock_Border</> +export const BoundingBoxCircles: Icon = () => <>BootstrapIconMock_BoundingBoxCircles</> +export const BoundingBox: Icon = () => <>BootstrapIconMock_BoundingBox</> +export const BoxArrowDownLeft: Icon = () => <>BootstrapIconMock_BoxArrowDownLeft</> +export const BoxArrowDownRight: Icon = () => <>BootstrapIconMock_BoxArrowDownRight</> +export const BoxArrowDown: Icon = () => <>BootstrapIconMock_BoxArrowDown</> +export const BoxArrowInDownLeft: Icon = () => <>BootstrapIconMock_BoxArrowInDownLeft</> +export const BoxArrowInDownRight: Icon = () => <>BootstrapIconMock_BoxArrowInDownRight</> +export const BoxArrowInDown: Icon = () => <>BootstrapIconMock_BoxArrowInDown</> +export const BoxArrowInLeft: Icon = () => <>BootstrapIconMock_BoxArrowInLeft</> +export const BoxArrowInRight: Icon = () => <>BootstrapIconMock_BoxArrowInRight</> +export const BoxArrowInUpLeft: Icon = () => <>BootstrapIconMock_BoxArrowInUpLeft</> +export const BoxArrowInUpRight: Icon = () => <>BootstrapIconMock_BoxArrowInUpRight</> +export const BoxArrowInUp: Icon = () => <>BootstrapIconMock_BoxArrowInUp</> +export const BoxArrowLeft: Icon = () => <>BootstrapIconMock_BoxArrowLeft</> +export const BoxArrowRight: Icon = () => <>BootstrapIconMock_BoxArrowRight</> +export const BoxArrowUpLeft: Icon = () => <>BootstrapIconMock_BoxArrowUpLeft</> +export const BoxArrowUpRight: Icon = () => <>BootstrapIconMock_BoxArrowUpRight</> +export const BoxArrowUp: Icon = () => <>BootstrapIconMock_BoxArrowUp</> +export const BoxFill: Icon = () => <>BootstrapIconMock_BoxFill</> +export const BoxSeamFill: Icon = () => <>BootstrapIconMock_BoxSeamFill</> +export const BoxSeam: Icon = () => <>BootstrapIconMock_BoxSeam</> +export const Box: Icon = () => <>BootstrapIconMock_Box</> +export const Box2Fill: Icon = () => <>BootstrapIconMock_Box2Fill</> +export const Box2HeartFill: Icon = () => <>BootstrapIconMock_Box2HeartFill</> +export const Box2Heart: Icon = () => <>BootstrapIconMock_Box2Heart</> +export const Box2: Icon = () => <>BootstrapIconMock_Box2</> +export const Boxes: Icon = () => <>BootstrapIconMock_Boxes</> +export const BracesAsterisk: Icon = () => <>BootstrapIconMock_BracesAsterisk</> +export const Braces: Icon = () => <>BootstrapIconMock_Braces</> +export const Bricks: Icon = () => <>BootstrapIconMock_Bricks</> +export const BriefcaseFill: Icon = () => <>BootstrapIconMock_BriefcaseFill</> +export const Briefcase: Icon = () => <>BootstrapIconMock_Briefcase</> +export const BrightnessAltHighFill: Icon = () => <>BootstrapIconMock_BrightnessAltHighFill</> +export const BrightnessAltHigh: Icon = () => <>BootstrapIconMock_BrightnessAltHigh</> +export const BrightnessAltLowFill: Icon = () => <>BootstrapIconMock_BrightnessAltLowFill</> +export const BrightnessAltLow: Icon = () => <>BootstrapIconMock_BrightnessAltLow</> +export const BrightnessHighFill: Icon = () => <>BootstrapIconMock_BrightnessHighFill</> +export const BrightnessHigh: Icon = () => <>BootstrapIconMock_BrightnessHigh</> +export const BrightnessLowFill: Icon = () => <>BootstrapIconMock_BrightnessLowFill</> +export const BrightnessLow: Icon = () => <>BootstrapIconMock_BrightnessLow</> +export const BroadcastPin: Icon = () => <>BootstrapIconMock_BroadcastPin</> +export const Broadcast: Icon = () => <>BootstrapIconMock_Broadcast</> +export const BrowserChrome: Icon = () => <>BootstrapIconMock_BrowserChrome</> +export const BrowserEdge: Icon = () => <>BootstrapIconMock_BrowserEdge</> +export const BrowserFirefox: Icon = () => <>BootstrapIconMock_BrowserFirefox</> +export const BrowserSafari: Icon = () => <>BootstrapIconMock_BrowserSafari</> +export const BrushFill: Icon = () => <>BootstrapIconMock_BrushFill</> +export const Brush: Icon = () => <>BootstrapIconMock_Brush</> +export const BucketFill: Icon = () => <>BootstrapIconMock_BucketFill</> +export const Bucket: Icon = () => <>BootstrapIconMock_Bucket</> +export const BugFill: Icon = () => <>BootstrapIconMock_BugFill</> +export const Bug: Icon = () => <>BootstrapIconMock_Bug</> +export const BuildingAdd: Icon = () => <>BootstrapIconMock_BuildingAdd</> +export const BuildingCheck: Icon = () => <>BootstrapIconMock_BuildingCheck</> +export const BuildingDash: Icon = () => <>BootstrapIconMock_BuildingDash</> +export const BuildingDown: Icon = () => <>BootstrapIconMock_BuildingDown</> +export const BuildingExclamation: Icon = () => <>BootstrapIconMock_BuildingExclamation</> +export const BuildingFillAdd: Icon = () => <>BootstrapIconMock_BuildingFillAdd</> +export const BuildingFillCheck: Icon = () => <>BootstrapIconMock_BuildingFillCheck</> +export const BuildingFillDash: Icon = () => <>BootstrapIconMock_BuildingFillDash</> +export const BuildingFillDown: Icon = () => <>BootstrapIconMock_BuildingFillDown</> +export const BuildingFillExclamation: Icon = () => <>BootstrapIconMock_BuildingFillExclamation</> +export const BuildingFillGear: Icon = () => <>BootstrapIconMock_BuildingFillGear</> +export const BuildingFillLock: Icon = () => <>BootstrapIconMock_BuildingFillLock</> +export const BuildingFillSlash: Icon = () => <>BootstrapIconMock_BuildingFillSlash</> +export const BuildingFillUp: Icon = () => <>BootstrapIconMock_BuildingFillUp</> +export const BuildingFillX: Icon = () => <>BootstrapIconMock_BuildingFillX</> +export const BuildingFill: Icon = () => <>BootstrapIconMock_BuildingFill</> +export const BuildingGear: Icon = () => <>BootstrapIconMock_BuildingGear</> +export const BuildingLock: Icon = () => <>BootstrapIconMock_BuildingLock</> +export const BuildingSlash: Icon = () => <>BootstrapIconMock_BuildingSlash</> +export const BuildingUp: Icon = () => <>BootstrapIconMock_BuildingUp</> +export const BuildingX: Icon = () => <>BootstrapIconMock_BuildingX</> +export const Building: Icon = () => <>BootstrapIconMock_Building</> +export const BuildingsFill: Icon = () => <>BootstrapIconMock_BuildingsFill</> +export const Buildings: Icon = () => <>BootstrapIconMock_Buildings</> +export const Bullseye: Icon = () => <>BootstrapIconMock_Bullseye</> +export const BusFrontFill: Icon = () => <>BootstrapIconMock_BusFrontFill</> +export const BusFront: Icon = () => <>BootstrapIconMock_BusFront</> +export const CCircleFill: Icon = () => <>BootstrapIconMock_CCircleFill</> +export const CCircle: Icon = () => <>BootstrapIconMock_CCircle</> +export const CSquareFill: Icon = () => <>BootstrapIconMock_CSquareFill</> +export const CSquare: Icon = () => <>BootstrapIconMock_CSquare</> +export const CalculatorFill: Icon = () => <>BootstrapIconMock_CalculatorFill</> +export const Calculator: Icon = () => <>BootstrapIconMock_Calculator</> +export const CalendarCheckFill: Icon = () => <>BootstrapIconMock_CalendarCheckFill</> +export const CalendarCheck: Icon = () => <>BootstrapIconMock_CalendarCheck</> +export const CalendarDateFill: Icon = () => <>BootstrapIconMock_CalendarDateFill</> +export const CalendarDate: Icon = () => <>BootstrapIconMock_CalendarDate</> +export const CalendarDayFill: Icon = () => <>BootstrapIconMock_CalendarDayFill</> +export const CalendarDay: Icon = () => <>BootstrapIconMock_CalendarDay</> +export const CalendarEventFill: Icon = () => <>BootstrapIconMock_CalendarEventFill</> +export const CalendarEvent: Icon = () => <>BootstrapIconMock_CalendarEvent</> +export const CalendarFill: Icon = () => <>BootstrapIconMock_CalendarFill</> +export const CalendarHeartFill: Icon = () => <>BootstrapIconMock_CalendarHeartFill</> +export const CalendarHeart: Icon = () => <>BootstrapIconMock_CalendarHeart</> +export const CalendarMinusFill: Icon = () => <>BootstrapIconMock_CalendarMinusFill</> +export const CalendarMinus: Icon = () => <>BootstrapIconMock_CalendarMinus</> +export const CalendarMonthFill: Icon = () => <>BootstrapIconMock_CalendarMonthFill</> +export const CalendarMonth: Icon = () => <>BootstrapIconMock_CalendarMonth</> +export const CalendarPlusFill: Icon = () => <>BootstrapIconMock_CalendarPlusFill</> +export const CalendarPlus: Icon = () => <>BootstrapIconMock_CalendarPlus</> +export const CalendarRangeFill: Icon = () => <>BootstrapIconMock_CalendarRangeFill</> +export const CalendarRange: Icon = () => <>BootstrapIconMock_CalendarRange</> +export const CalendarWeekFill: Icon = () => <>BootstrapIconMock_CalendarWeekFill</> +export const CalendarWeek: Icon = () => <>BootstrapIconMock_CalendarWeek</> +export const CalendarXFill: Icon = () => <>BootstrapIconMock_CalendarXFill</> +export const CalendarX: Icon = () => <>BootstrapIconMock_CalendarX</> +export const Calendar: Icon = () => <>BootstrapIconMock_Calendar</> +export const Calendar2CheckFill: Icon = () => <>BootstrapIconMock_Calendar2CheckFill</> +export const Calendar2Check: Icon = () => <>BootstrapIconMock_Calendar2Check</> +export const Calendar2DateFill: Icon = () => <>BootstrapIconMock_Calendar2DateFill</> +export const Calendar2Date: Icon = () => <>BootstrapIconMock_Calendar2Date</> +export const Calendar2DayFill: Icon = () => <>BootstrapIconMock_Calendar2DayFill</> +export const Calendar2Day: Icon = () => <>BootstrapIconMock_Calendar2Day</> +export const Calendar2EventFill: Icon = () => <>BootstrapIconMock_Calendar2EventFill</> +export const Calendar2Event: Icon = () => <>BootstrapIconMock_Calendar2Event</> +export const Calendar2Fill: Icon = () => <>BootstrapIconMock_Calendar2Fill</> +export const Calendar2HeartFill: Icon = () => <>BootstrapIconMock_Calendar2HeartFill</> +export const Calendar2Heart: Icon = () => <>BootstrapIconMock_Calendar2Heart</> +export const Calendar2MinusFill: Icon = () => <>BootstrapIconMock_Calendar2MinusFill</> +export const Calendar2Minus: Icon = () => <>BootstrapIconMock_Calendar2Minus</> +export const Calendar2MonthFill: Icon = () => <>BootstrapIconMock_Calendar2MonthFill</> +export const Calendar2Month: Icon = () => <>BootstrapIconMock_Calendar2Month</> +export const Calendar2PlusFill: Icon = () => <>BootstrapIconMock_Calendar2PlusFill</> +export const Calendar2Plus: Icon = () => <>BootstrapIconMock_Calendar2Plus</> +export const Calendar2RangeFill: Icon = () => <>BootstrapIconMock_Calendar2RangeFill</> +export const Calendar2Range: Icon = () => <>BootstrapIconMock_Calendar2Range</> +export const Calendar2WeekFill: Icon = () => <>BootstrapIconMock_Calendar2WeekFill</> +export const Calendar2Week: Icon = () => <>BootstrapIconMock_Calendar2Week</> +export const Calendar2XFill: Icon = () => <>BootstrapIconMock_Calendar2XFill</> +export const Calendar2X: Icon = () => <>BootstrapIconMock_Calendar2X</> +export const Calendar2: Icon = () => <>BootstrapIconMock_Calendar2</> +export const Calendar3EventFill: Icon = () => <>BootstrapIconMock_Calendar3EventFill</> +export const Calendar3Event: Icon = () => <>BootstrapIconMock_Calendar3Event</> +export const Calendar3Fill: Icon = () => <>BootstrapIconMock_Calendar3Fill</> +export const Calendar3RangeFill: Icon = () => <>BootstrapIconMock_Calendar3RangeFill</> +export const Calendar3Range: Icon = () => <>BootstrapIconMock_Calendar3Range</> +export const Calendar3WeekFill: Icon = () => <>BootstrapIconMock_Calendar3WeekFill</> +export const Calendar3Week: Icon = () => <>BootstrapIconMock_Calendar3Week</> +export const Calendar3: Icon = () => <>BootstrapIconMock_Calendar3</> +export const Calendar4Event: Icon = () => <>BootstrapIconMock_Calendar4Event</> +export const Calendar4Range: Icon = () => <>BootstrapIconMock_Calendar4Range</> +export const Calendar4Week: Icon = () => <>BootstrapIconMock_Calendar4Week</> +export const Calendar4: Icon = () => <>BootstrapIconMock_Calendar4</> +export const CameraFill: Icon = () => <>BootstrapIconMock_CameraFill</> +export const CameraReelsFill: Icon = () => <>BootstrapIconMock_CameraReelsFill</> +export const CameraReels: Icon = () => <>BootstrapIconMock_CameraReels</> +export const CameraVideoFill: Icon = () => <>BootstrapIconMock_CameraVideoFill</> +export const CameraVideoOffFill: Icon = () => <>BootstrapIconMock_CameraVideoOffFill</> +export const CameraVideoOff: Icon = () => <>BootstrapIconMock_CameraVideoOff</> +export const CameraVideo: Icon = () => <>BootstrapIconMock_CameraVideo</> +export const Camera: Icon = () => <>BootstrapIconMock_Camera</> +export const Camera2: Icon = () => <>BootstrapIconMock_Camera2</> +export const CapslockFill: Icon = () => <>BootstrapIconMock_CapslockFill</> +export const Capslock: Icon = () => <>BootstrapIconMock_Capslock</> +export const CapsulePill: Icon = () => <>BootstrapIconMock_CapsulePill</> +export const Capsule: Icon = () => <>BootstrapIconMock_Capsule</> +export const CarFrontFill: Icon = () => <>BootstrapIconMock_CarFrontFill</> +export const CarFront: Icon = () => <>BootstrapIconMock_CarFront</> +export const CardChecklist: Icon = () => <>BootstrapIconMock_CardChecklist</> +export const CardHeading: Icon = () => <>BootstrapIconMock_CardHeading</> +export const CardImage: Icon = () => <>BootstrapIconMock_CardImage</> +export const CardList: Icon = () => <>BootstrapIconMock_CardList</> +export const CardText: Icon = () => <>BootstrapIconMock_CardText</> +export const CaretDownFill: Icon = () => <>BootstrapIconMock_CaretDownFill</> +export const CaretDownSquareFill: Icon = () => <>BootstrapIconMock_CaretDownSquareFill</> +export const CaretDownSquare: Icon = () => <>BootstrapIconMock_CaretDownSquare</> +export const CaretDown: Icon = () => <>BootstrapIconMock_CaretDown</> +export const CaretLeftFill: Icon = () => <>BootstrapIconMock_CaretLeftFill</> +export const CaretLeftSquareFill: Icon = () => <>BootstrapIconMock_CaretLeftSquareFill</> +export const CaretLeftSquare: Icon = () => <>BootstrapIconMock_CaretLeftSquare</> +export const CaretLeft: Icon = () => <>BootstrapIconMock_CaretLeft</> +export const CaretRightFill: Icon = () => <>BootstrapIconMock_CaretRightFill</> +export const CaretRightSquareFill: Icon = () => <>BootstrapIconMock_CaretRightSquareFill</> +export const CaretRightSquare: Icon = () => <>BootstrapIconMock_CaretRightSquare</> +export const CaretRight: Icon = () => <>BootstrapIconMock_CaretRight</> +export const CaretUpFill: Icon = () => <>BootstrapIconMock_CaretUpFill</> +export const CaretUpSquareFill: Icon = () => <>BootstrapIconMock_CaretUpSquareFill</> +export const CaretUpSquare: Icon = () => <>BootstrapIconMock_CaretUpSquare</> +export const CaretUp: Icon = () => <>BootstrapIconMock_CaretUp</> +export const CartCheckFill: Icon = () => <>BootstrapIconMock_CartCheckFill</> +export const CartCheck: Icon = () => <>BootstrapIconMock_CartCheck</> +export const CartDashFill: Icon = () => <>BootstrapIconMock_CartDashFill</> +export const CartDash: Icon = () => <>BootstrapIconMock_CartDash</> +export const CartFill: Icon = () => <>BootstrapIconMock_CartFill</> +export const CartPlusFill: Icon = () => <>BootstrapIconMock_CartPlusFill</> +export const CartPlus: Icon = () => <>BootstrapIconMock_CartPlus</> +export const CartXFill: Icon = () => <>BootstrapIconMock_CartXFill</> +export const CartX: Icon = () => <>BootstrapIconMock_CartX</> +export const Cart: Icon = () => <>BootstrapIconMock_Cart</> +export const Cart2: Icon = () => <>BootstrapIconMock_Cart2</> +export const Cart3: Icon = () => <>BootstrapIconMock_Cart3</> +export const Cart4: Icon = () => <>BootstrapIconMock_Cart4</> +export const CashCoin: Icon = () => <>BootstrapIconMock_CashCoin</> +export const CashStack: Icon = () => <>BootstrapIconMock_CashStack</> +export const Cash: Icon = () => <>BootstrapIconMock_Cash</> +export const CassetteFill: Icon = () => <>BootstrapIconMock_CassetteFill</> +export const Cassette: Icon = () => <>BootstrapIconMock_Cassette</> +export const Cast: Icon = () => <>BootstrapIconMock_Cast</> +export const CcCircleFill: Icon = () => <>BootstrapIconMock_CcCircleFill</> +export const CcCircle: Icon = () => <>BootstrapIconMock_CcCircle</> +export const CcSquareFill: Icon = () => <>BootstrapIconMock_CcSquareFill</> +export const CcSquare: Icon = () => <>BootstrapIconMock_CcSquare</> +export const ChatDotsFill: Icon = () => <>BootstrapIconMock_ChatDotsFill</> +export const ChatDots: Icon = () => <>BootstrapIconMock_ChatDots</> +export const ChatFill: Icon = () => <>BootstrapIconMock_ChatFill</> +export const ChatHeartFill: Icon = () => <>BootstrapIconMock_ChatHeartFill</> +export const ChatHeart: Icon = () => <>BootstrapIconMock_ChatHeart</> +export const ChatLeftDotsFill: Icon = () => <>BootstrapIconMock_ChatLeftDotsFill</> +export const ChatLeftDots: Icon = () => <>BootstrapIconMock_ChatLeftDots</> +export const ChatLeftFill: Icon = () => <>BootstrapIconMock_ChatLeftFill</> +export const ChatLeftHeartFill: Icon = () => <>BootstrapIconMock_ChatLeftHeartFill</> +export const ChatLeftHeart: Icon = () => <>BootstrapIconMock_ChatLeftHeart</> +export const ChatLeftQuoteFill: Icon = () => <>BootstrapIconMock_ChatLeftQuoteFill</> +export const ChatLeftQuote: Icon = () => <>BootstrapIconMock_ChatLeftQuote</> +export const ChatLeftTextFill: Icon = () => <>BootstrapIconMock_ChatLeftTextFill</> +export const ChatLeftText: Icon = () => <>BootstrapIconMock_ChatLeftText</> +export const ChatLeft: Icon = () => <>BootstrapIconMock_ChatLeft</> +export const ChatQuoteFill: Icon = () => <>BootstrapIconMock_ChatQuoteFill</> +export const ChatQuote: Icon = () => <>BootstrapIconMock_ChatQuote</> +export const ChatRightDotsFill: Icon = () => <>BootstrapIconMock_ChatRightDotsFill</> +export const ChatRightDots: Icon = () => <>BootstrapIconMock_ChatRightDots</> +export const ChatRightFill: Icon = () => <>BootstrapIconMock_ChatRightFill</> +export const ChatRightHeartFill: Icon = () => <>BootstrapIconMock_ChatRightHeartFill</> +export const ChatRightHeart: Icon = () => <>BootstrapIconMock_ChatRightHeart</> +export const ChatRightQuoteFill: Icon = () => <>BootstrapIconMock_ChatRightQuoteFill</> +export const ChatRightQuote: Icon = () => <>BootstrapIconMock_ChatRightQuote</> +export const ChatRightTextFill: Icon = () => <>BootstrapIconMock_ChatRightTextFill</> +export const ChatRightText: Icon = () => <>BootstrapIconMock_ChatRightText</> +export const ChatRight: Icon = () => <>BootstrapIconMock_ChatRight</> +export const ChatSquareDotsFill: Icon = () => <>BootstrapIconMock_ChatSquareDotsFill</> +export const ChatSquareDots: Icon = () => <>BootstrapIconMock_ChatSquareDots</> +export const ChatSquareFill: Icon = () => <>BootstrapIconMock_ChatSquareFill</> +export const ChatSquareHeartFill: Icon = () => <>BootstrapIconMock_ChatSquareHeartFill</> +export const ChatSquareHeart: Icon = () => <>BootstrapIconMock_ChatSquareHeart</> +export const ChatSquareQuoteFill: Icon = () => <>BootstrapIconMock_ChatSquareQuoteFill</> +export const ChatSquareQuote: Icon = () => <>BootstrapIconMock_ChatSquareQuote</> +export const ChatSquareTextFill: Icon = () => <>BootstrapIconMock_ChatSquareTextFill</> +export const ChatSquareText: Icon = () => <>BootstrapIconMock_ChatSquareText</> +export const ChatSquare: Icon = () => <>BootstrapIconMock_ChatSquare</> +export const ChatTextFill: Icon = () => <>BootstrapIconMock_ChatTextFill</> +export const ChatText: Icon = () => <>BootstrapIconMock_ChatText</> +export const Chat: Icon = () => <>BootstrapIconMock_Chat</> +export const CheckAll: Icon = () => <>BootstrapIconMock_CheckAll</> +export const CheckCircleFill: Icon = () => <>BootstrapIconMock_CheckCircleFill</> +export const CheckCircle: Icon = () => <>BootstrapIconMock_CheckCircle</> +export const CheckLg: Icon = () => <>BootstrapIconMock_CheckLg</> +export const CheckSquareFill: Icon = () => <>BootstrapIconMock_CheckSquareFill</> +export const CheckSquare: Icon = () => <>BootstrapIconMock_CheckSquare</> +export const Check: Icon = () => <>BootstrapIconMock_Check</> +export const Check2All: Icon = () => <>BootstrapIconMock_Check2All</> +export const Check2Circle: Icon = () => <>BootstrapIconMock_Check2Circle</> +export const Check2Square: Icon = () => <>BootstrapIconMock_Check2Square</> +export const Check2: Icon = () => <>BootstrapIconMock_Check2</> +export const ChevronBarContract: Icon = () => <>BootstrapIconMock_ChevronBarContract</> +export const ChevronBarDown: Icon = () => <>BootstrapIconMock_ChevronBarDown</> +export const ChevronBarExpand: Icon = () => <>BootstrapIconMock_ChevronBarExpand</> +export const ChevronBarLeft: Icon = () => <>BootstrapIconMock_ChevronBarLeft</> +export const ChevronBarRight: Icon = () => <>BootstrapIconMock_ChevronBarRight</> +export const ChevronBarUp: Icon = () => <>BootstrapIconMock_ChevronBarUp</> +export const ChevronCompactDown: Icon = () => <>BootstrapIconMock_ChevronCompactDown</> +export const ChevronCompactLeft: Icon = () => <>BootstrapIconMock_ChevronCompactLeft</> +export const ChevronCompactRight: Icon = () => <>BootstrapIconMock_ChevronCompactRight</> +export const ChevronCompactUp: Icon = () => <>BootstrapIconMock_ChevronCompactUp</> +export const ChevronContract: Icon = () => <>BootstrapIconMock_ChevronContract</> +export const ChevronDoubleDown: Icon = () => <>BootstrapIconMock_ChevronDoubleDown</> +export const ChevronDoubleLeft: Icon = () => <>BootstrapIconMock_ChevronDoubleLeft</> +export const ChevronDoubleRight: Icon = () => <>BootstrapIconMock_ChevronDoubleRight</> +export const ChevronDoubleUp: Icon = () => <>BootstrapIconMock_ChevronDoubleUp</> +export const ChevronDown: Icon = () => <>BootstrapIconMock_ChevronDown</> +export const ChevronExpand: Icon = () => <>BootstrapIconMock_ChevronExpand</> +export const ChevronLeft: Icon = () => <>BootstrapIconMock_ChevronLeft</> +export const ChevronRight: Icon = () => <>BootstrapIconMock_ChevronRight</> +export const ChevronUp: Icon = () => <>BootstrapIconMock_ChevronUp</> +export const CircleFill: Icon = () => <>BootstrapIconMock_CircleFill</> +export const CircleHalf: Icon = () => <>BootstrapIconMock_CircleHalf</> +export const CircleSquare: Icon = () => <>BootstrapIconMock_CircleSquare</> +export const Circle: Icon = () => <>BootstrapIconMock_Circle</> +export const ClipboardCheckFill: Icon = () => <>BootstrapIconMock_ClipboardCheckFill</> +export const ClipboardCheck: Icon = () => <>BootstrapIconMock_ClipboardCheck</> +export const ClipboardDataFill: Icon = () => <>BootstrapIconMock_ClipboardDataFill</> +export const ClipboardData: Icon = () => <>BootstrapIconMock_ClipboardData</> +export const ClipboardFill: Icon = () => <>BootstrapIconMock_ClipboardFill</> +export const ClipboardHeartFill: Icon = () => <>BootstrapIconMock_ClipboardHeartFill</> +export const ClipboardHeart: Icon = () => <>BootstrapIconMock_ClipboardHeart</> +export const ClipboardMinusFill: Icon = () => <>BootstrapIconMock_ClipboardMinusFill</> +export const ClipboardMinus: Icon = () => <>BootstrapIconMock_ClipboardMinus</> +export const ClipboardPlusFill: Icon = () => <>BootstrapIconMock_ClipboardPlusFill</> +export const ClipboardPlus: Icon = () => <>BootstrapIconMock_ClipboardPlus</> +export const ClipboardPulse: Icon = () => <>BootstrapIconMock_ClipboardPulse</> +export const ClipboardXFill: Icon = () => <>BootstrapIconMock_ClipboardXFill</> +export const ClipboardX: Icon = () => <>BootstrapIconMock_ClipboardX</> +export const Clipboard: Icon = () => <>BootstrapIconMock_Clipboard</> +export const Clipboard2CheckFill: Icon = () => <>BootstrapIconMock_Clipboard2CheckFill</> +export const Clipboard2Check: Icon = () => <>BootstrapIconMock_Clipboard2Check</> +export const Clipboard2DataFill: Icon = () => <>BootstrapIconMock_Clipboard2DataFill</> +export const Clipboard2Data: Icon = () => <>BootstrapIconMock_Clipboard2Data</> +export const Clipboard2Fill: Icon = () => <>BootstrapIconMock_Clipboard2Fill</> +export const Clipboard2HeartFill: Icon = () => <>BootstrapIconMock_Clipboard2HeartFill</> +export const Clipboard2Heart: Icon = () => <>BootstrapIconMock_Clipboard2Heart</> +export const Clipboard2MinusFill: Icon = () => <>BootstrapIconMock_Clipboard2MinusFill</> +export const Clipboard2Minus: Icon = () => <>BootstrapIconMock_Clipboard2Minus</> +export const Clipboard2PlusFill: Icon = () => <>BootstrapIconMock_Clipboard2PlusFill</> +export const Clipboard2Plus: Icon = () => <>BootstrapIconMock_Clipboard2Plus</> +export const Clipboard2PulseFill: Icon = () => <>BootstrapIconMock_Clipboard2PulseFill</> +export const Clipboard2Pulse: Icon = () => <>BootstrapIconMock_Clipboard2Pulse</> +export const Clipboard2XFill: Icon = () => <>BootstrapIconMock_Clipboard2XFill</> +export const Clipboard2X: Icon = () => <>BootstrapIconMock_Clipboard2X</> +export const Clipboard2: Icon = () => <>BootstrapIconMock_Clipboard2</> +export const ClockFill: Icon = () => <>BootstrapIconMock_ClockFill</> +export const ClockHistory: Icon = () => <>BootstrapIconMock_ClockHistory</> +export const Clock: Icon = () => <>BootstrapIconMock_Clock</> +export const CloudArrowDownFill: Icon = () => <>BootstrapIconMock_CloudArrowDownFill</> +export const CloudArrowDown: Icon = () => <>BootstrapIconMock_CloudArrowDown</> +export const CloudArrowUpFill: Icon = () => <>BootstrapIconMock_CloudArrowUpFill</> +export const CloudArrowUp: Icon = () => <>BootstrapIconMock_CloudArrowUp</> +export const CloudCheckFill: Icon = () => <>BootstrapIconMock_CloudCheckFill</> +export const CloudCheck: Icon = () => <>BootstrapIconMock_CloudCheck</> +export const CloudDownloadFill: Icon = () => <>BootstrapIconMock_CloudDownloadFill</> +export const CloudDownload: Icon = () => <>BootstrapIconMock_CloudDownload</> +export const CloudDrizzleFill: Icon = () => <>BootstrapIconMock_CloudDrizzleFill</> +export const CloudDrizzle: Icon = () => <>BootstrapIconMock_CloudDrizzle</> +export const CloudFill: Icon = () => <>BootstrapIconMock_CloudFill</> +export const CloudFogFill: Icon = () => <>BootstrapIconMock_CloudFogFill</> +export const CloudFog: Icon = () => <>BootstrapIconMock_CloudFog</> +export const CloudFog2Fill: Icon = () => <>BootstrapIconMock_CloudFog2Fill</> +export const CloudFog2: Icon = () => <>BootstrapIconMock_CloudFog2</> +export const CloudHailFill: Icon = () => <>BootstrapIconMock_CloudHailFill</> +export const CloudHail: Icon = () => <>BootstrapIconMock_CloudHail</> +export const CloudHazeFill: Icon = () => <>BootstrapIconMock_CloudHazeFill</> +export const CloudHaze: Icon = () => <>BootstrapIconMock_CloudHaze</> +export const CloudHaze2Fill: Icon = () => <>BootstrapIconMock_CloudHaze2Fill</> +export const CloudHaze2: Icon = () => <>BootstrapIconMock_CloudHaze2</> +export const CloudLightningFill: Icon = () => <>BootstrapIconMock_CloudLightningFill</> +export const CloudLightningRainFill: Icon = () => <>BootstrapIconMock_CloudLightningRainFill</> +export const CloudLightningRain: Icon = () => <>BootstrapIconMock_CloudLightningRain</> +export const CloudLightning: Icon = () => <>BootstrapIconMock_CloudLightning</> +export const CloudMinusFill: Icon = () => <>BootstrapIconMock_CloudMinusFill</> +export const CloudMinus: Icon = () => <>BootstrapIconMock_CloudMinus</> +export const CloudMoonFill: Icon = () => <>BootstrapIconMock_CloudMoonFill</> +export const CloudMoon: Icon = () => <>BootstrapIconMock_CloudMoon</> +export const CloudPlusFill: Icon = () => <>BootstrapIconMock_CloudPlusFill</> +export const CloudPlus: Icon = () => <>BootstrapIconMock_CloudPlus</> +export const CloudRainFill: Icon = () => <>BootstrapIconMock_CloudRainFill</> +export const CloudRainHeavyFill: Icon = () => <>BootstrapIconMock_CloudRainHeavyFill</> +export const CloudRainHeavy: Icon = () => <>BootstrapIconMock_CloudRainHeavy</> +export const CloudRain: Icon = () => <>BootstrapIconMock_CloudRain</> +export const CloudSlashFill: Icon = () => <>BootstrapIconMock_CloudSlashFill</> +export const CloudSlash: Icon = () => <>BootstrapIconMock_CloudSlash</> +export const CloudSleetFill: Icon = () => <>BootstrapIconMock_CloudSleetFill</> +export const CloudSleet: Icon = () => <>BootstrapIconMock_CloudSleet</> +export const CloudSnowFill: Icon = () => <>BootstrapIconMock_CloudSnowFill</> +export const CloudSnow: Icon = () => <>BootstrapIconMock_CloudSnow</> +export const CloudSunFill: Icon = () => <>BootstrapIconMock_CloudSunFill</> +export const CloudSun: Icon = () => <>BootstrapIconMock_CloudSun</> +export const CloudUploadFill: Icon = () => <>BootstrapIconMock_CloudUploadFill</> +export const CloudUpload: Icon = () => <>BootstrapIconMock_CloudUpload</> +export const Cloud: Icon = () => <>BootstrapIconMock_Cloud</> +export const CloudsFill: Icon = () => <>BootstrapIconMock_CloudsFill</> +export const Clouds: Icon = () => <>BootstrapIconMock_Clouds</> +export const CloudyFill: Icon = () => <>BootstrapIconMock_CloudyFill</> +export const Cloudy: Icon = () => <>BootstrapIconMock_Cloudy</> +export const CodeSlash: Icon = () => <>BootstrapIconMock_CodeSlash</> +export const CodeSquare: Icon = () => <>BootstrapIconMock_CodeSquare</> +export const Code: Icon = () => <>BootstrapIconMock_Code</> +export const Coin: Icon = () => <>BootstrapIconMock_Coin</> +export const CollectionFill: Icon = () => <>BootstrapIconMock_CollectionFill</> +export const CollectionPlayFill: Icon = () => <>BootstrapIconMock_CollectionPlayFill</> +export const CollectionPlay: Icon = () => <>BootstrapIconMock_CollectionPlay</> +export const Collection: Icon = () => <>BootstrapIconMock_Collection</> +export const ColumnsGap: Icon = () => <>BootstrapIconMock_ColumnsGap</> +export const Columns: Icon = () => <>BootstrapIconMock_Columns</> +export const Command: Icon = () => <>BootstrapIconMock_Command</> +export const CompassFill: Icon = () => <>BootstrapIconMock_CompassFill</> +export const Compass: Icon = () => <>BootstrapIconMock_Compass</> +export const ConeStriped: Icon = () => <>BootstrapIconMock_ConeStriped</> +export const Cone: Icon = () => <>BootstrapIconMock_Cone</> +export const Controller: Icon = () => <>BootstrapIconMock_Controller</> +export const CpuFill: Icon = () => <>BootstrapIconMock_CpuFill</> +export const Cpu: Icon = () => <>BootstrapIconMock_Cpu</> +export const CreditCard2BackFill: Icon = () => <>BootstrapIconMock_CreditCard2BackFill</> +export const CreditCard2Back: Icon = () => <>BootstrapIconMock_CreditCard2Back</> +export const CreditCard2FrontFill: Icon = () => <>BootstrapIconMock_CreditCard2FrontFill</> +export const CreditCard2Front: Icon = () => <>BootstrapIconMock_CreditCard2Front</> +export const CreditCardFill: Icon = () => <>BootstrapIconMock_CreditCardFill</> +export const CreditCard: Icon = () => <>BootstrapIconMock_CreditCard</> +export const Crop: Icon = () => <>BootstrapIconMock_Crop</> +export const CupFill: Icon = () => <>BootstrapIconMock_CupFill</> +export const CupHotFill: Icon = () => <>BootstrapIconMock_CupHotFill</> +export const CupHot: Icon = () => <>BootstrapIconMock_CupHot</> +export const CupStraw: Icon = () => <>BootstrapIconMock_CupStraw</> +export const Cup: Icon = () => <>BootstrapIconMock_Cup</> +export const CurrencyBitcoin: Icon = () => <>BootstrapIconMock_CurrencyBitcoin</> +export const CurrencyDollar: Icon = () => <>BootstrapIconMock_CurrencyDollar</> +export const CurrencyEuro: Icon = () => <>BootstrapIconMock_CurrencyEuro</> +export const CurrencyExchange: Icon = () => <>BootstrapIconMock_CurrencyExchange</> +export const CurrencyPound: Icon = () => <>BootstrapIconMock_CurrencyPound</> +export const CurrencyRupee: Icon = () => <>BootstrapIconMock_CurrencyRupee</> +export const CurrencyYen: Icon = () => <>BootstrapIconMock_CurrencyYen</> +export const CursorFill: Icon = () => <>BootstrapIconMock_CursorFill</> +export const CursorText: Icon = () => <>BootstrapIconMock_CursorText</> +export const Cursor: Icon = () => <>BootstrapIconMock_Cursor</> +export const DashCircleDotted: Icon = () => <>BootstrapIconMock_DashCircleDotted</> +export const DashCircleFill: Icon = () => <>BootstrapIconMock_DashCircleFill</> +export const DashCircle: Icon = () => <>BootstrapIconMock_DashCircle</> +export const DashLg: Icon = () => <>BootstrapIconMock_DashLg</> +export const DashSquareDotted: Icon = () => <>BootstrapIconMock_DashSquareDotted</> +export const DashSquareFill: Icon = () => <>BootstrapIconMock_DashSquareFill</> +export const DashSquare: Icon = () => <>BootstrapIconMock_DashSquare</> +export const Dash: Icon = () => <>BootstrapIconMock_Dash</> +export const DatabaseAdd: Icon = () => <>BootstrapIconMock_DatabaseAdd</> +export const DatabaseCheck: Icon = () => <>BootstrapIconMock_DatabaseCheck</> +export const DatabaseDash: Icon = () => <>BootstrapIconMock_DatabaseDash</> +export const DatabaseDown: Icon = () => <>BootstrapIconMock_DatabaseDown</> +export const DatabaseExclamation: Icon = () => <>BootstrapIconMock_DatabaseExclamation</> +export const DatabaseFillAdd: Icon = () => <>BootstrapIconMock_DatabaseFillAdd</> +export const DatabaseFillCheck: Icon = () => <>BootstrapIconMock_DatabaseFillCheck</> +export const DatabaseFillDash: Icon = () => <>BootstrapIconMock_DatabaseFillDash</> +export const DatabaseFillDown: Icon = () => <>BootstrapIconMock_DatabaseFillDown</> +export const DatabaseFillExclamation: Icon = () => <>BootstrapIconMock_DatabaseFillExclamation</> +export const DatabaseFillGear: Icon = () => <>BootstrapIconMock_DatabaseFillGear</> +export const DatabaseFillLock: Icon = () => <>BootstrapIconMock_DatabaseFillLock</> +export const DatabaseFillSlash: Icon = () => <>BootstrapIconMock_DatabaseFillSlash</> +export const DatabaseFillUp: Icon = () => <>BootstrapIconMock_DatabaseFillUp</> +export const DatabaseFillX: Icon = () => <>BootstrapIconMock_DatabaseFillX</> +export const DatabaseFill: Icon = () => <>BootstrapIconMock_DatabaseFill</> +export const DatabaseGear: Icon = () => <>BootstrapIconMock_DatabaseGear</> +export const DatabaseLock: Icon = () => <>BootstrapIconMock_DatabaseLock</> +export const DatabaseSlash: Icon = () => <>BootstrapIconMock_DatabaseSlash</> +export const DatabaseUp: Icon = () => <>BootstrapIconMock_DatabaseUp</> +export const DatabaseX: Icon = () => <>BootstrapIconMock_DatabaseX</> +export const Database: Icon = () => <>BootstrapIconMock_Database</> +export const DeviceHddFill: Icon = () => <>BootstrapIconMock_DeviceHddFill</> +export const DeviceHdd: Icon = () => <>BootstrapIconMock_DeviceHdd</> +export const DeviceSsdFill: Icon = () => <>BootstrapIconMock_DeviceSsdFill</> +export const DeviceSsd: Icon = () => <>BootstrapIconMock_DeviceSsd</> +export const Diagram2Fill: Icon = () => <>BootstrapIconMock_Diagram2Fill</> +export const Diagram2: Icon = () => <>BootstrapIconMock_Diagram2</> +export const Diagram3Fill: Icon = () => <>BootstrapIconMock_Diagram3Fill</> +export const Diagram3: Icon = () => <>BootstrapIconMock_Diagram3</> +export const DiamondFill: Icon = () => <>BootstrapIconMock_DiamondFill</> +export const DiamondHalf: Icon = () => <>BootstrapIconMock_DiamondHalf</> +export const Diamond: Icon = () => <>BootstrapIconMock_Diamond</> +export const Dice1Fill: Icon = () => <>BootstrapIconMock_Dice1Fill</> +export const Dice1: Icon = () => <>BootstrapIconMock_Dice1</> +export const Dice2Fill: Icon = () => <>BootstrapIconMock_Dice2Fill</> +export const Dice2: Icon = () => <>BootstrapIconMock_Dice2</> +export const Dice3Fill: Icon = () => <>BootstrapIconMock_Dice3Fill</> +export const Dice3: Icon = () => <>BootstrapIconMock_Dice3</> +export const Dice4Fill: Icon = () => <>BootstrapIconMock_Dice4Fill</> +export const Dice4: Icon = () => <>BootstrapIconMock_Dice4</> +export const Dice5Fill: Icon = () => <>BootstrapIconMock_Dice5Fill</> +export const Dice5: Icon = () => <>BootstrapIconMock_Dice5</> +export const Dice6Fill: Icon = () => <>BootstrapIconMock_Dice6Fill</> +export const Dice6: Icon = () => <>BootstrapIconMock_Dice6</> +export const DiscFill: Icon = () => <>BootstrapIconMock_DiscFill</> +export const Disc: Icon = () => <>BootstrapIconMock_Disc</> +export const Discord: Icon = () => <>BootstrapIconMock_Discord</> +export const DisplayFill: Icon = () => <>BootstrapIconMock_DisplayFill</> +export const Display: Icon = () => <>BootstrapIconMock_Display</> +export const DisplayportFill: Icon = () => <>BootstrapIconMock_DisplayportFill</> +export const Displayport: Icon = () => <>BootstrapIconMock_Displayport</> +export const DistributeHorizontal: Icon = () => <>BootstrapIconMock_DistributeHorizontal</> +export const DistributeVertical: Icon = () => <>BootstrapIconMock_DistributeVertical</> +export const DoorClosedFill: Icon = () => <>BootstrapIconMock_DoorClosedFill</> +export const DoorClosed: Icon = () => <>BootstrapIconMock_DoorClosed</> +export const DoorOpenFill: Icon = () => <>BootstrapIconMock_DoorOpenFill</> +export const DoorOpen: Icon = () => <>BootstrapIconMock_DoorOpen</> +export const Dot: Icon = () => <>BootstrapIconMock_Dot</> +export const Download: Icon = () => <>BootstrapIconMock_Download</> +export const DpadFill: Icon = () => <>BootstrapIconMock_DpadFill</> +export const Dpad: Icon = () => <>BootstrapIconMock_Dpad</> +export const Dribbble: Icon = () => <>BootstrapIconMock_Dribbble</> +export const Dropbox: Icon = () => <>BootstrapIconMock_Dropbox</> +export const DropletFill: Icon = () => <>BootstrapIconMock_DropletFill</> +export const DropletHalf: Icon = () => <>BootstrapIconMock_DropletHalf</> +export const Droplet: Icon = () => <>BootstrapIconMock_Droplet</> +export const EarFill: Icon = () => <>BootstrapIconMock_EarFill</> +export const Ear: Icon = () => <>BootstrapIconMock_Ear</> +export const Earbuds: Icon = () => <>BootstrapIconMock_Earbuds</> +export const EaselFill: Icon = () => <>BootstrapIconMock_EaselFill</> +export const Easel: Icon = () => <>BootstrapIconMock_Easel</> +export const Easel2Fill: Icon = () => <>BootstrapIconMock_Easel2Fill</> +export const Easel2: Icon = () => <>BootstrapIconMock_Easel2</> +export const Easel3Fill: Icon = () => <>BootstrapIconMock_Easel3Fill</> +export const Easel3: Icon = () => <>BootstrapIconMock_Easel3</> +export const EggFill: Icon = () => <>BootstrapIconMock_EggFill</> +export const EggFried: Icon = () => <>BootstrapIconMock_EggFried</> +export const Egg: Icon = () => <>BootstrapIconMock_Egg</> +export const EjectFill: Icon = () => <>BootstrapIconMock_EjectFill</> +export const Eject: Icon = () => <>BootstrapIconMock_Eject</> +export const EmojiAngryFill: Icon = () => <>BootstrapIconMock_EmojiAngryFill</> +export const EmojiAngry: Icon = () => <>BootstrapIconMock_EmojiAngry</> +export const EmojiDizzyFill: Icon = () => <>BootstrapIconMock_EmojiDizzyFill</> +export const EmojiDizzy: Icon = () => <>BootstrapIconMock_EmojiDizzy</> +export const EmojiExpressionlessFill: Icon = () => <>BootstrapIconMock_EmojiExpressionlessFill</> +export const EmojiExpressionless: Icon = () => <>BootstrapIconMock_EmojiExpressionless</> +export const EmojiFrownFill: Icon = () => <>BootstrapIconMock_EmojiFrownFill</> +export const EmojiFrown: Icon = () => <>BootstrapIconMock_EmojiFrown</> +export const EmojiHeartEyesFill: Icon = () => <>BootstrapIconMock_EmojiHeartEyesFill</> +export const EmojiHeartEyes: Icon = () => <>BootstrapIconMock_EmojiHeartEyes</> +export const EmojiKissFill: Icon = () => <>BootstrapIconMock_EmojiKissFill</> +export const EmojiKiss: Icon = () => <>BootstrapIconMock_EmojiKiss</> +export const EmojiLaughingFill: Icon = () => <>BootstrapIconMock_EmojiLaughingFill</> +export const EmojiLaughing: Icon = () => <>BootstrapIconMock_EmojiLaughing</> +export const EmojiNeutralFill: Icon = () => <>BootstrapIconMock_EmojiNeutralFill</> +export const EmojiNeutral: Icon = () => <>BootstrapIconMock_EmojiNeutral</> +export const EmojiSmileFill: Icon = () => <>BootstrapIconMock_EmojiSmileFill</> +export const EmojiSmileUpsideDownFill: Icon = () => <>BootstrapIconMock_EmojiSmileUpsideDownFill</> +export const EmojiSmileUpsideDown: Icon = () => <>BootstrapIconMock_EmojiSmileUpsideDown</> +export const EmojiSmile: Icon = () => <>BootstrapIconMock_EmojiSmile</> +export const EmojiSunglassesFill: Icon = () => <>BootstrapIconMock_EmojiSunglassesFill</> +export const EmojiSunglasses: Icon = () => <>BootstrapIconMock_EmojiSunglasses</> +export const EmojiWinkFill: Icon = () => <>BootstrapIconMock_EmojiWinkFill</> +export const EmojiWink: Icon = () => <>BootstrapIconMock_EmojiWink</> +export const EnvelopeAtFill: Icon = () => <>BootstrapIconMock_EnvelopeAtFill</> +export const EnvelopeAt: Icon = () => <>BootstrapIconMock_EnvelopeAt</> +export const EnvelopeCheckFill: Icon = () => <>BootstrapIconMock_EnvelopeCheckFill</> +export const EnvelopeCheck: Icon = () => <>BootstrapIconMock_EnvelopeCheck</> +export const EnvelopeDashFill: Icon = () => <>BootstrapIconMock_EnvelopeDashFill</> +export const EnvelopeDash: Icon = () => <>BootstrapIconMock_EnvelopeDash</> +export const EnvelopeExclamationFill: Icon = () => <>BootstrapIconMock_EnvelopeExclamationFill</> +export const EnvelopeExclamation: Icon = () => <>BootstrapIconMock_EnvelopeExclamation</> +export const EnvelopeFill: Icon = () => <>BootstrapIconMock_EnvelopeFill</> +export const EnvelopeHeartFill: Icon = () => <>BootstrapIconMock_EnvelopeHeartFill</> +export const EnvelopeHeart: Icon = () => <>BootstrapIconMock_EnvelopeHeart</> +export const EnvelopeOpenFill: Icon = () => <>BootstrapIconMock_EnvelopeOpenFill</> +export const EnvelopeOpenHeartFill: Icon = () => <>BootstrapIconMock_EnvelopeOpenHeartFill</> +export const EnvelopeOpenHeart: Icon = () => <>BootstrapIconMock_EnvelopeOpenHeart</> +export const EnvelopeOpen: Icon = () => <>BootstrapIconMock_EnvelopeOpen</> +export const EnvelopePaperFill: Icon = () => <>BootstrapIconMock_EnvelopePaperFill</> +export const EnvelopePaperHeartFill: Icon = () => <>BootstrapIconMock_EnvelopePaperHeartFill</> +export const EnvelopePaperHeart: Icon = () => <>BootstrapIconMock_EnvelopePaperHeart</> +export const EnvelopePaper: Icon = () => <>BootstrapIconMock_EnvelopePaper</> +export const EnvelopePlusFill: Icon = () => <>BootstrapIconMock_EnvelopePlusFill</> +export const EnvelopePlus: Icon = () => <>BootstrapIconMock_EnvelopePlus</> +export const EnvelopeSlashFill: Icon = () => <>BootstrapIconMock_EnvelopeSlashFill</> +export const EnvelopeSlash: Icon = () => <>BootstrapIconMock_EnvelopeSlash</> +export const EnvelopeXFill: Icon = () => <>BootstrapIconMock_EnvelopeXFill</> +export const EnvelopeX: Icon = () => <>BootstrapIconMock_EnvelopeX</> +export const Envelope: Icon = () => <>BootstrapIconMock_Envelope</> +export const EraserFill: Icon = () => <>BootstrapIconMock_EraserFill</> +export const Eraser: Icon = () => <>BootstrapIconMock_Eraser</> +export const Escape: Icon = () => <>BootstrapIconMock_Escape</> +export const Ethernet: Icon = () => <>BootstrapIconMock_Ethernet</> +export const EvFrontFill: Icon = () => <>BootstrapIconMock_EvFrontFill</> +export const EvFront: Icon = () => <>BootstrapIconMock_EvFront</> +export const EvStationFill: Icon = () => <>BootstrapIconMock_EvStationFill</> +export const EvStation: Icon = () => <>BootstrapIconMock_EvStation</> +export const ExclamationCircleFill: Icon = () => <>BootstrapIconMock_ExclamationCircleFill</> +export const ExclamationCircle: Icon = () => <>BootstrapIconMock_ExclamationCircle</> +export const ExclamationDiamondFill: Icon = () => <>BootstrapIconMock_ExclamationDiamondFill</> +export const ExclamationDiamond: Icon = () => <>BootstrapIconMock_ExclamationDiamond</> +export const ExclamationLg: Icon = () => <>BootstrapIconMock_ExclamationLg</> +export const ExclamationOctagonFill: Icon = () => <>BootstrapIconMock_ExclamationOctagonFill</> +export const ExclamationOctagon: Icon = () => <>BootstrapIconMock_ExclamationOctagon</> +export const ExclamationSquareFill: Icon = () => <>BootstrapIconMock_ExclamationSquareFill</> +export const ExclamationSquare: Icon = () => <>BootstrapIconMock_ExclamationSquare</> +export const ExclamationTriangleFill: Icon = () => <>BootstrapIconMock_ExclamationTriangleFill</> +export const ExclamationTriangle: Icon = () => <>BootstrapIconMock_ExclamationTriangle</> +export const Exclamation: Icon = () => <>BootstrapIconMock_Exclamation</> +export const Exclude: Icon = () => <>BootstrapIconMock_Exclude</> +export const ExplicitFill: Icon = () => <>BootstrapIconMock_ExplicitFill</> +export const Explicit: Icon = () => <>BootstrapIconMock_Explicit</> +export const EyeFill: Icon = () => <>BootstrapIconMock_EyeFill</> +export const EyeSlashFill: Icon = () => <>BootstrapIconMock_EyeSlashFill</> +export const EyeSlash: Icon = () => <>BootstrapIconMock_EyeSlash</> +export const Eye: Icon = () => <>BootstrapIconMock_Eye</> +export const Eyedropper: Icon = () => <>BootstrapIconMock_Eyedropper</> +export const Eyeglasses: Icon = () => <>BootstrapIconMock_Eyeglasses</> +export const Facebook: Icon = () => <>BootstrapIconMock_Facebook</> +export const Fan: Icon = () => <>BootstrapIconMock_Fan</> +export const FastForwardBtnFill: Icon = () => <>BootstrapIconMock_FastForwardBtnFill</> +export const FastForwardBtn: Icon = () => <>BootstrapIconMock_FastForwardBtn</> +export const FastForwardCircleFill: Icon = () => <>BootstrapIconMock_FastForwardCircleFill</> +export const FastForwardCircle: Icon = () => <>BootstrapIconMock_FastForwardCircle</> +export const FastForwardFill: Icon = () => <>BootstrapIconMock_FastForwardFill</> +export const FastForward: Icon = () => <>BootstrapIconMock_FastForward</> +export const FileArrowDownFill: Icon = () => <>BootstrapIconMock_FileArrowDownFill</> +export const FileArrowDown: Icon = () => <>BootstrapIconMock_FileArrowDown</> +export const FileArrowUpFill: Icon = () => <>BootstrapIconMock_FileArrowUpFill</> +export const FileArrowUp: Icon = () => <>BootstrapIconMock_FileArrowUp</> +export const FileBarGraphFill: Icon = () => <>BootstrapIconMock_FileBarGraphFill</> +export const FileBarGraph: Icon = () => <>BootstrapIconMock_FileBarGraph</> +export const FileBinaryFill: Icon = () => <>BootstrapIconMock_FileBinaryFill</> +export const FileBinary: Icon = () => <>BootstrapIconMock_FileBinary</> +export const FileBreakFill: Icon = () => <>BootstrapIconMock_FileBreakFill</> +export const FileBreak: Icon = () => <>BootstrapIconMock_FileBreak</> +export const FileCheckFill: Icon = () => <>BootstrapIconMock_FileCheckFill</> +export const FileCheck: Icon = () => <>BootstrapIconMock_FileCheck</> +export const FileCodeFill: Icon = () => <>BootstrapIconMock_FileCodeFill</> +export const FileCode: Icon = () => <>BootstrapIconMock_FileCode</> +export const FileDiffFill: Icon = () => <>BootstrapIconMock_FileDiffFill</> +export const FileDiff: Icon = () => <>BootstrapIconMock_FileDiff</> +export const FileEarmarkArrowDownFill: Icon = () => <>BootstrapIconMock_FileEarmarkArrowDownFill</> +export const FileEarmarkArrowDown: Icon = () => <>BootstrapIconMock_FileEarmarkArrowDown</> +export const FileEarmarkArrowUpFill: Icon = () => <>BootstrapIconMock_FileEarmarkArrowUpFill</> +export const FileEarmarkArrowUp: Icon = () => <>BootstrapIconMock_FileEarmarkArrowUp</> +export const FileEarmarkBarGraphFill: Icon = () => <>BootstrapIconMock_FileEarmarkBarGraphFill</> +export const FileEarmarkBarGraph: Icon = () => <>BootstrapIconMock_FileEarmarkBarGraph</> +export const FileEarmarkBinaryFill: Icon = () => <>BootstrapIconMock_FileEarmarkBinaryFill</> +export const FileEarmarkBinary: Icon = () => <>BootstrapIconMock_FileEarmarkBinary</> +export const FileEarmarkBreakFill: Icon = () => <>BootstrapIconMock_FileEarmarkBreakFill</> +export const FileEarmarkBreak: Icon = () => <>BootstrapIconMock_FileEarmarkBreak</> +export const FileEarmarkCheckFill: Icon = () => <>BootstrapIconMock_FileEarmarkCheckFill</> +export const FileEarmarkCheck: Icon = () => <>BootstrapIconMock_FileEarmarkCheck</> +export const FileEarmarkCodeFill: Icon = () => <>BootstrapIconMock_FileEarmarkCodeFill</> +export const FileEarmarkCode: Icon = () => <>BootstrapIconMock_FileEarmarkCode</> +export const FileEarmarkDiffFill: Icon = () => <>BootstrapIconMock_FileEarmarkDiffFill</> +export const FileEarmarkDiff: Icon = () => <>BootstrapIconMock_FileEarmarkDiff</> +export const FileEarmarkEaselFill: Icon = () => <>BootstrapIconMock_FileEarmarkEaselFill</> +export const FileEarmarkEasel: Icon = () => <>BootstrapIconMock_FileEarmarkEasel</> +export const FileEarmarkExcelFill: Icon = () => <>BootstrapIconMock_FileEarmarkExcelFill</> +export const FileEarmarkExcel: Icon = () => <>BootstrapIconMock_FileEarmarkExcel</> +export const FileEarmarkFill: Icon = () => <>BootstrapIconMock_FileEarmarkFill</> +export const FileEarmarkFontFill: Icon = () => <>BootstrapIconMock_FileEarmarkFontFill</> +export const FileEarmarkFont: Icon = () => <>BootstrapIconMock_FileEarmarkFont</> +export const FileEarmarkImageFill: Icon = () => <>BootstrapIconMock_FileEarmarkImageFill</> +export const FileEarmarkImage: Icon = () => <>BootstrapIconMock_FileEarmarkImage</> +export const FileEarmarkLockFill: Icon = () => <>BootstrapIconMock_FileEarmarkLockFill</> +export const FileEarmarkLock: Icon = () => <>BootstrapIconMock_FileEarmarkLock</> +export const FileEarmarkLock2Fill: Icon = () => <>BootstrapIconMock_FileEarmarkLock2Fill</> +export const FileEarmarkLock2: Icon = () => <>BootstrapIconMock_FileEarmarkLock2</> +export const FileEarmarkMedicalFill: Icon = () => <>BootstrapIconMock_FileEarmarkMedicalFill</> +export const FileEarmarkMedical: Icon = () => <>BootstrapIconMock_FileEarmarkMedical</> +export const FileEarmarkMinusFill: Icon = () => <>BootstrapIconMock_FileEarmarkMinusFill</> +export const FileEarmarkMinus: Icon = () => <>BootstrapIconMock_FileEarmarkMinus</> +export const FileEarmarkMusicFill: Icon = () => <>BootstrapIconMock_FileEarmarkMusicFill</> +export const FileEarmarkMusic: Icon = () => <>BootstrapIconMock_FileEarmarkMusic</> +export const FileEarmarkPdfFill: Icon = () => <>BootstrapIconMock_FileEarmarkPdfFill</> +export const FileEarmarkPdf: Icon = () => <>BootstrapIconMock_FileEarmarkPdf</> +export const FileEarmarkPersonFill: Icon = () => <>BootstrapIconMock_FileEarmarkPersonFill</> +export const FileEarmarkPerson: Icon = () => <>BootstrapIconMock_FileEarmarkPerson</> +export const FileEarmarkPlayFill: Icon = () => <>BootstrapIconMock_FileEarmarkPlayFill</> +export const FileEarmarkPlay: Icon = () => <>BootstrapIconMock_FileEarmarkPlay</> +export const FileEarmarkPlusFill: Icon = () => <>BootstrapIconMock_FileEarmarkPlusFill</> +export const FileEarmarkPlus: Icon = () => <>BootstrapIconMock_FileEarmarkPlus</> +export const FileEarmarkPostFill: Icon = () => <>BootstrapIconMock_FileEarmarkPostFill</> +export const FileEarmarkPost: Icon = () => <>BootstrapIconMock_FileEarmarkPost</> +export const FileEarmarkPptFill: Icon = () => <>BootstrapIconMock_FileEarmarkPptFill</> +export const FileEarmarkPpt: Icon = () => <>BootstrapIconMock_FileEarmarkPpt</> +export const FileEarmarkRichtextFill: Icon = () => <>BootstrapIconMock_FileEarmarkRichtextFill</> +export const FileEarmarkRichtext: Icon = () => <>BootstrapIconMock_FileEarmarkRichtext</> +export const FileEarmarkRuledFill: Icon = () => <>BootstrapIconMock_FileEarmarkRuledFill</> +export const FileEarmarkRuled: Icon = () => <>BootstrapIconMock_FileEarmarkRuled</> +export const FileEarmarkSlidesFill: Icon = () => <>BootstrapIconMock_FileEarmarkSlidesFill</> +export const FileEarmarkSlides: Icon = () => <>BootstrapIconMock_FileEarmarkSlides</> +export const FileEarmarkSpreadsheetFill: Icon = () => <>BootstrapIconMock_FileEarmarkSpreadsheetFill</> +export const FileEarmarkSpreadsheet: Icon = () => <>BootstrapIconMock_FileEarmarkSpreadsheet</> +export const FileEarmarkTextFill: Icon = () => <>BootstrapIconMock_FileEarmarkTextFill</> +export const FileEarmarkText: Icon = () => <>BootstrapIconMock_FileEarmarkText</> +export const FileEarmarkWordFill: Icon = () => <>BootstrapIconMock_FileEarmarkWordFill</> +export const FileEarmarkWord: Icon = () => <>BootstrapIconMock_FileEarmarkWord</> +export const FileEarmarkXFill: Icon = () => <>BootstrapIconMock_FileEarmarkXFill</> +export const FileEarmarkX: Icon = () => <>BootstrapIconMock_FileEarmarkX</> +export const FileEarmarkZipFill: Icon = () => <>BootstrapIconMock_FileEarmarkZipFill</> +export const FileEarmarkZip: Icon = () => <>BootstrapIconMock_FileEarmarkZip</> +export const FileEarmark: Icon = () => <>BootstrapIconMock_FileEarmark</> +export const FileEaselFill: Icon = () => <>BootstrapIconMock_FileEaselFill</> +export const FileEasel: Icon = () => <>BootstrapIconMock_FileEasel</> +export const FileExcelFill: Icon = () => <>BootstrapIconMock_FileExcelFill</> +export const FileExcel: Icon = () => <>BootstrapIconMock_FileExcel</> +export const FileFill: Icon = () => <>BootstrapIconMock_FileFill</> +export const FileFontFill: Icon = () => <>BootstrapIconMock_FileFontFill</> +export const FileFont: Icon = () => <>BootstrapIconMock_FileFont</> +export const FileImageFill: Icon = () => <>BootstrapIconMock_FileImageFill</> +export const FileImage: Icon = () => <>BootstrapIconMock_FileImage</> +export const FileLockFill: Icon = () => <>BootstrapIconMock_FileLockFill</> +export const FileLock: Icon = () => <>BootstrapIconMock_FileLock</> +export const FileLock2Fill: Icon = () => <>BootstrapIconMock_FileLock2Fill</> +export const FileLock2: Icon = () => <>BootstrapIconMock_FileLock2</> +export const FileMedicalFill: Icon = () => <>BootstrapIconMock_FileMedicalFill</> +export const FileMedical: Icon = () => <>BootstrapIconMock_FileMedical</> +export const FileMinusFill: Icon = () => <>BootstrapIconMock_FileMinusFill</> +export const FileMinus: Icon = () => <>BootstrapIconMock_FileMinus</> +export const FileMusicFill: Icon = () => <>BootstrapIconMock_FileMusicFill</> +export const FileMusic: Icon = () => <>BootstrapIconMock_FileMusic</> +export const FilePdfFill: Icon = () => <>BootstrapIconMock_FilePdfFill</> +export const FilePdf: Icon = () => <>BootstrapIconMock_FilePdf</> +export const FilePersonFill: Icon = () => <>BootstrapIconMock_FilePersonFill</> +export const FilePerson: Icon = () => <>BootstrapIconMock_FilePerson</> +export const FilePlayFill: Icon = () => <>BootstrapIconMock_FilePlayFill</> +export const FilePlay: Icon = () => <>BootstrapIconMock_FilePlay</> +export const FilePlusFill: Icon = () => <>BootstrapIconMock_FilePlusFill</> +export const FilePlus: Icon = () => <>BootstrapIconMock_FilePlus</> +export const FilePostFill: Icon = () => <>BootstrapIconMock_FilePostFill</> +export const FilePost: Icon = () => <>BootstrapIconMock_FilePost</> +export const FilePptFill: Icon = () => <>BootstrapIconMock_FilePptFill</> +export const FilePpt: Icon = () => <>BootstrapIconMock_FilePpt</> +export const FileRichtextFill: Icon = () => <>BootstrapIconMock_FileRichtextFill</> +export const FileRichtext: Icon = () => <>BootstrapIconMock_FileRichtext</> +export const FileRuledFill: Icon = () => <>BootstrapIconMock_FileRuledFill</> +export const FileRuled: Icon = () => <>BootstrapIconMock_FileRuled</> +export const FileSlidesFill: Icon = () => <>BootstrapIconMock_FileSlidesFill</> +export const FileSlides: Icon = () => <>BootstrapIconMock_FileSlides</> +export const FileSpreadsheetFill: Icon = () => <>BootstrapIconMock_FileSpreadsheetFill</> +export const FileSpreadsheet: Icon = () => <>BootstrapIconMock_FileSpreadsheet</> +export const FileTextFill: Icon = () => <>BootstrapIconMock_FileTextFill</> +export const FileText: Icon = () => <>BootstrapIconMock_FileText</> +export const FileWordFill: Icon = () => <>BootstrapIconMock_FileWordFill</> +export const FileWord: Icon = () => <>BootstrapIconMock_FileWord</> +export const FileXFill: Icon = () => <>BootstrapIconMock_FileXFill</> +export const FileX: Icon = () => <>BootstrapIconMock_FileX</> +export const FileZipFill: Icon = () => <>BootstrapIconMock_FileZipFill</> +export const FileZip: Icon = () => <>BootstrapIconMock_FileZip</> +export const File: Icon = () => <>BootstrapIconMock_File</> +export const FilesAlt: Icon = () => <>BootstrapIconMock_FilesAlt</> +export const Files: Icon = () => <>BootstrapIconMock_Files</> +export const FiletypeAac: Icon = () => <>BootstrapIconMock_FiletypeAac</> +export const FiletypeAi: Icon = () => <>BootstrapIconMock_FiletypeAi</> +export const FiletypeBmp: Icon = () => <>BootstrapIconMock_FiletypeBmp</> +export const FiletypeCs: Icon = () => <>BootstrapIconMock_FiletypeCs</> +export const FiletypeCss: Icon = () => <>BootstrapIconMock_FiletypeCss</> +export const FiletypeCsv: Icon = () => <>BootstrapIconMock_FiletypeCsv</> +export const FiletypeDoc: Icon = () => <>BootstrapIconMock_FiletypeDoc</> +export const FiletypeDocx: Icon = () => <>BootstrapIconMock_FiletypeDocx</> +export const FiletypeExe: Icon = () => <>BootstrapIconMock_FiletypeExe</> +export const FiletypeGif: Icon = () => <>BootstrapIconMock_FiletypeGif</> +export const FiletypeHeic: Icon = () => <>BootstrapIconMock_FiletypeHeic</> +export const FiletypeHtml: Icon = () => <>BootstrapIconMock_FiletypeHtml</> +export const FiletypeJava: Icon = () => <>BootstrapIconMock_FiletypeJava</> +export const FiletypeJpg: Icon = () => <>BootstrapIconMock_FiletypeJpg</> +export const FiletypeJs: Icon = () => <>BootstrapIconMock_FiletypeJs</> +export const FiletypeJson: Icon = () => <>BootstrapIconMock_FiletypeJson</> +export const FiletypeJsx: Icon = () => <>BootstrapIconMock_FiletypeJsx</> +export const FiletypeKey: Icon = () => <>BootstrapIconMock_FiletypeKey</> +export const FiletypeM4p: Icon = () => <>BootstrapIconMock_FiletypeM4p</> +export const FiletypeMd: Icon = () => <>BootstrapIconMock_FiletypeMd</> +export const FiletypeMdx: Icon = () => <>BootstrapIconMock_FiletypeMdx</> +export const FiletypeMov: Icon = () => <>BootstrapIconMock_FiletypeMov</> +export const FiletypeMp3: Icon = () => <>BootstrapIconMock_FiletypeMp3</> +export const FiletypeMp4: Icon = () => <>BootstrapIconMock_FiletypeMp4</> +export const FiletypeOtf: Icon = () => <>BootstrapIconMock_FiletypeOtf</> +export const FiletypePdf: Icon = () => <>BootstrapIconMock_FiletypePdf</> +export const FiletypePhp: Icon = () => <>BootstrapIconMock_FiletypePhp</> +export const FiletypePng: Icon = () => <>BootstrapIconMock_FiletypePng</> +export const FiletypePpt: Icon = () => <>BootstrapIconMock_FiletypePpt</> +export const FiletypePptx: Icon = () => <>BootstrapIconMock_FiletypePptx</> +export const FiletypePsd: Icon = () => <>BootstrapIconMock_FiletypePsd</> +export const FiletypePy: Icon = () => <>BootstrapIconMock_FiletypePy</> +export const FiletypeRaw: Icon = () => <>BootstrapIconMock_FiletypeRaw</> +export const FiletypeRb: Icon = () => <>BootstrapIconMock_FiletypeRb</> +export const FiletypeSass: Icon = () => <>BootstrapIconMock_FiletypeSass</> +export const FiletypeScss: Icon = () => <>BootstrapIconMock_FiletypeScss</> +export const FiletypeSh: Icon = () => <>BootstrapIconMock_FiletypeSh</> +export const FiletypeSql: Icon = () => <>BootstrapIconMock_FiletypeSql</> +export const FiletypeSvg: Icon = () => <>BootstrapIconMock_FiletypeSvg</> +export const FiletypeTiff: Icon = () => <>BootstrapIconMock_FiletypeTiff</> +export const FiletypeTsx: Icon = () => <>BootstrapIconMock_FiletypeTsx</> +export const FiletypeTtf: Icon = () => <>BootstrapIconMock_FiletypeTtf</> +export const FiletypeTxt: Icon = () => <>BootstrapIconMock_FiletypeTxt</> +export const FiletypeWav: Icon = () => <>BootstrapIconMock_FiletypeWav</> +export const FiletypeWoff: Icon = () => <>BootstrapIconMock_FiletypeWoff</> +export const FiletypeXls: Icon = () => <>BootstrapIconMock_FiletypeXls</> +export const FiletypeXlsx: Icon = () => <>BootstrapIconMock_FiletypeXlsx</> +export const FiletypeXml: Icon = () => <>BootstrapIconMock_FiletypeXml</> +export const FiletypeYml: Icon = () => <>BootstrapIconMock_FiletypeYml</> +export const Film: Icon = () => <>BootstrapIconMock_Film</> +export const FilterCircleFill: Icon = () => <>BootstrapIconMock_FilterCircleFill</> +export const FilterCircle: Icon = () => <>BootstrapIconMock_FilterCircle</> +export const FilterLeft: Icon = () => <>BootstrapIconMock_FilterLeft</> +export const FilterRight: Icon = () => <>BootstrapIconMock_FilterRight</> +export const FilterSquareFill: Icon = () => <>BootstrapIconMock_FilterSquareFill</> +export const FilterSquare: Icon = () => <>BootstrapIconMock_FilterSquare</> +export const Filter: Icon = () => <>BootstrapIconMock_Filter</> +export const Fingerprint: Icon = () => <>BootstrapIconMock_Fingerprint</> +export const Fire: Icon = () => <>BootstrapIconMock_Fire</> +export const FlagFill: Icon = () => <>BootstrapIconMock_FlagFill</> +export const Flag: Icon = () => <>BootstrapIconMock_Flag</> +export const Flower1: Icon = () => <>BootstrapIconMock_Flower1</> +export const Flower2: Icon = () => <>BootstrapIconMock_Flower2</> +export const Flower3: Icon = () => <>BootstrapIconMock_Flower3</> +export const FolderCheck: Icon = () => <>BootstrapIconMock_FolderCheck</> +export const FolderFill: Icon = () => <>BootstrapIconMock_FolderFill</> +export const FolderMinus: Icon = () => <>BootstrapIconMock_FolderMinus</> +export const FolderPlus: Icon = () => <>BootstrapIconMock_FolderPlus</> +export const FolderSymlinkFill: Icon = () => <>BootstrapIconMock_FolderSymlinkFill</> +export const FolderSymlink: Icon = () => <>BootstrapIconMock_FolderSymlink</> +export const FolderX: Icon = () => <>BootstrapIconMock_FolderX</> +export const Folder: Icon = () => <>BootstrapIconMock_Folder</> +export const Folder2Open: Icon = () => <>BootstrapIconMock_Folder2Open</> +export const Folder2: Icon = () => <>BootstrapIconMock_Folder2</> +export const Fonts: Icon = () => <>BootstrapIconMock_Fonts</> +export const ForwardFill: Icon = () => <>BootstrapIconMock_ForwardFill</> +export const Forward: Icon = () => <>BootstrapIconMock_Forward</> +export const Front: Icon = () => <>BootstrapIconMock_Front</> +export const FuelPumpDieselFill: Icon = () => <>BootstrapIconMock_FuelPumpDieselFill</> +export const FuelPumpDiesel: Icon = () => <>BootstrapIconMock_FuelPumpDiesel</> +export const FuelPumpFill: Icon = () => <>BootstrapIconMock_FuelPumpFill</> +export const FuelPump: Icon = () => <>BootstrapIconMock_FuelPump</> +export const FullscreenExit: Icon = () => <>BootstrapIconMock_FullscreenExit</> +export const Fullscreen: Icon = () => <>BootstrapIconMock_Fullscreen</> +export const FunnelFill: Icon = () => <>BootstrapIconMock_FunnelFill</> +export const Funnel: Icon = () => <>BootstrapIconMock_Funnel</> +export const GearFill: Icon = () => <>BootstrapIconMock_GearFill</> +export const GearWideConnected: Icon = () => <>BootstrapIconMock_GearWideConnected</> +export const GearWide: Icon = () => <>BootstrapIconMock_GearWide</> +export const Gear: Icon = () => <>BootstrapIconMock_Gear</> +export const Gem: Icon = () => <>BootstrapIconMock_Gem</> +export const GenderAmbiguous: Icon = () => <>BootstrapIconMock_GenderAmbiguous</> +export const GenderFemale: Icon = () => <>BootstrapIconMock_GenderFemale</> +export const GenderMale: Icon = () => <>BootstrapIconMock_GenderMale</> +export const GenderTrans: Icon = () => <>BootstrapIconMock_GenderTrans</> +export const GeoAltFill: Icon = () => <>BootstrapIconMock_GeoAltFill</> +export const GeoAlt: Icon = () => <>BootstrapIconMock_GeoAlt</> +export const GeoFill: Icon = () => <>BootstrapIconMock_GeoFill</> +export const Geo: Icon = () => <>BootstrapIconMock_Geo</> +export const GiftFill: Icon = () => <>BootstrapIconMock_GiftFill</> +export const Gift: Icon = () => <>BootstrapIconMock_Gift</> +export const Git: Icon = () => <>BootstrapIconMock_Git</> +export const Github: Icon = () => <>BootstrapIconMock_Github</> +export const GlobeAmericas: Icon = () => <>BootstrapIconMock_GlobeAmericas</> +export const GlobeAsiaAustralia: Icon = () => <>BootstrapIconMock_GlobeAsiaAustralia</> +export const GlobeCentralSouthAsia: Icon = () => <>BootstrapIconMock_GlobeCentralSouthAsia</> +export const GlobeEuropeAfrica: Icon = () => <>BootstrapIconMock_GlobeEuropeAfrica</> +export const Globe: Icon = () => <>BootstrapIconMock_Globe</> +export const Globe2: Icon = () => <>BootstrapIconMock_Globe2</> +export const GooglePlay: Icon = () => <>BootstrapIconMock_GooglePlay</> +export const Google: Icon = () => <>BootstrapIconMock_Google</> +export const GpuCard: Icon = () => <>BootstrapIconMock_GpuCard</> +export const GraphDownArrow: Icon = () => <>BootstrapIconMock_GraphDownArrow</> +export const GraphDown: Icon = () => <>BootstrapIconMock_GraphDown</> +export const GraphUpArrow: Icon = () => <>BootstrapIconMock_GraphUpArrow</> +export const GraphUp: Icon = () => <>BootstrapIconMock_GraphUp</> +export const Grid1x2Fill: Icon = () => <>BootstrapIconMock_Grid1x2Fill</> +export const Grid1x2: Icon = () => <>BootstrapIconMock_Grid1x2</> +export const Grid3x2GapFill: Icon = () => <>BootstrapIconMock_Grid3x2GapFill</> +export const Grid3x2Gap: Icon = () => <>BootstrapIconMock_Grid3x2Gap</> +export const Grid3x2: Icon = () => <>BootstrapIconMock_Grid3x2</> +export const Grid3x3GapFill: Icon = () => <>BootstrapIconMock_Grid3x3GapFill</> +export const Grid3x3Gap: Icon = () => <>BootstrapIconMock_Grid3x3Gap</> +export const Grid3x3: Icon = () => <>BootstrapIconMock_Grid3x3</> +export const GridFill: Icon = () => <>BootstrapIconMock_GridFill</> +export const Grid: Icon = () => <>BootstrapIconMock_Grid</> +export const GripHorizontal: Icon = () => <>BootstrapIconMock_GripHorizontal</> +export const GripVertical: Icon = () => <>BootstrapIconMock_GripVertical</> +export const HCircleFill: Icon = () => <>BootstrapIconMock_HCircleFill</> +export const HCircle: Icon = () => <>BootstrapIconMock_HCircle</> +export const HSquareFill: Icon = () => <>BootstrapIconMock_HSquareFill</> +export const HSquare: Icon = () => <>BootstrapIconMock_HSquare</> +export const Hammer: Icon = () => <>BootstrapIconMock_Hammer</> +export const HandIndexFill: Icon = () => <>BootstrapIconMock_HandIndexFill</> +export const HandIndexThumbFill: Icon = () => <>BootstrapIconMock_HandIndexThumbFill</> +export const HandIndexThumb: Icon = () => <>BootstrapIconMock_HandIndexThumb</> +export const HandIndex: Icon = () => <>BootstrapIconMock_HandIndex</> +export const HandThumbsDownFill: Icon = () => <>BootstrapIconMock_HandThumbsDownFill</> +export const HandThumbsDown: Icon = () => <>BootstrapIconMock_HandThumbsDown</> +export const HandThumbsUpFill: Icon = () => <>BootstrapIconMock_HandThumbsUpFill</> +export const HandThumbsUp: Icon = () => <>BootstrapIconMock_HandThumbsUp</> +export const HandbagFill: Icon = () => <>BootstrapIconMock_HandbagFill</> +export const Handbag: Icon = () => <>BootstrapIconMock_Handbag</> +export const Hash: Icon = () => <>BootstrapIconMock_Hash</> +export const HddFill: Icon = () => <>BootstrapIconMock_HddFill</> +export const HddNetworkFill: Icon = () => <>BootstrapIconMock_HddNetworkFill</> +export const HddNetwork: Icon = () => <>BootstrapIconMock_HddNetwork</> +export const HddRackFill: Icon = () => <>BootstrapIconMock_HddRackFill</> +export const HddRack: Icon = () => <>BootstrapIconMock_HddRack</> +export const HddStackFill: Icon = () => <>BootstrapIconMock_HddStackFill</> +export const HddStack: Icon = () => <>BootstrapIconMock_HddStack</> +export const Hdd: Icon = () => <>BootstrapIconMock_Hdd</> +export const HdmiFill: Icon = () => <>BootstrapIconMock_HdmiFill</> +export const Hdmi: Icon = () => <>BootstrapIconMock_Hdmi</> +export const Headphones: Icon = () => <>BootstrapIconMock_Headphones</> +export const HeadsetVr: Icon = () => <>BootstrapIconMock_HeadsetVr</> +export const Headset: Icon = () => <>BootstrapIconMock_Headset</> +export const HeartArrow: Icon = () => <>BootstrapIconMock_HeartArrow</> +export const HeartFill: Icon = () => <>BootstrapIconMock_HeartFill</> +export const HeartHalf: Icon = () => <>BootstrapIconMock_HeartHalf</> +export const HeartPulseFill: Icon = () => <>BootstrapIconMock_HeartPulseFill</> +export const HeartPulse: Icon = () => <>BootstrapIconMock_HeartPulse</> +export const Heart: Icon = () => <>BootstrapIconMock_Heart</> +export const HeartbreakFill: Icon = () => <>BootstrapIconMock_HeartbreakFill</> +export const Heartbreak: Icon = () => <>BootstrapIconMock_Heartbreak</> +export const Hearts: Icon = () => <>BootstrapIconMock_Hearts</> +export const HeptagonFill: Icon = () => <>BootstrapIconMock_HeptagonFill</> +export const HeptagonHalf: Icon = () => <>BootstrapIconMock_HeptagonHalf</> +export const Heptagon: Icon = () => <>BootstrapIconMock_Heptagon</> +export const HexagonFill: Icon = () => <>BootstrapIconMock_HexagonFill</> +export const HexagonHalf: Icon = () => <>BootstrapIconMock_HexagonHalf</> +export const Hexagon: Icon = () => <>BootstrapIconMock_Hexagon</> +export const HospitalFill: Icon = () => <>BootstrapIconMock_HospitalFill</> +export const Hospital: Icon = () => <>BootstrapIconMock_Hospital</> +export const HourglassBottom: Icon = () => <>BootstrapIconMock_HourglassBottom</> +export const HourglassSplit: Icon = () => <>BootstrapIconMock_HourglassSplit</> +export const HourglassTop: Icon = () => <>BootstrapIconMock_HourglassTop</> +export const Hourglass: Icon = () => <>BootstrapIconMock_Hourglass</> +export const HouseAddFill: Icon = () => <>BootstrapIconMock_HouseAddFill</> +export const HouseAdd: Icon = () => <>BootstrapIconMock_HouseAdd</> +export const HouseCheckFill: Icon = () => <>BootstrapIconMock_HouseCheckFill</> +export const HouseCheck: Icon = () => <>BootstrapIconMock_HouseCheck</> +export const HouseDashFill: Icon = () => <>BootstrapIconMock_HouseDashFill</> +export const HouseDash: Icon = () => <>BootstrapIconMock_HouseDash</> +export const HouseDoorFill: Icon = () => <>BootstrapIconMock_HouseDoorFill</> +export const HouseDoor: Icon = () => <>BootstrapIconMock_HouseDoor</> +export const HouseDownFill: Icon = () => <>BootstrapIconMock_HouseDownFill</> +export const HouseDown: Icon = () => <>BootstrapIconMock_HouseDown</> +export const HouseExclamationFill: Icon = () => <>BootstrapIconMock_HouseExclamationFill</> +export const HouseExclamation: Icon = () => <>BootstrapIconMock_HouseExclamation</> +export const HouseFill: Icon = () => <>BootstrapIconMock_HouseFill</> +export const HouseGearFill: Icon = () => <>BootstrapIconMock_HouseGearFill</> +export const HouseGear: Icon = () => <>BootstrapIconMock_HouseGear</> +export const HouseHeartFill: Icon = () => <>BootstrapIconMock_HouseHeartFill</> +export const HouseHeart: Icon = () => <>BootstrapIconMock_HouseHeart</> +export const HouseLockFill: Icon = () => <>BootstrapIconMock_HouseLockFill</> +export const HouseLock: Icon = () => <>BootstrapIconMock_HouseLock</> +export const HouseSlashFill: Icon = () => <>BootstrapIconMock_HouseSlashFill</> +export const HouseSlash: Icon = () => <>BootstrapIconMock_HouseSlash</> +export const HouseUpFill: Icon = () => <>BootstrapIconMock_HouseUpFill</> +export const HouseUp: Icon = () => <>BootstrapIconMock_HouseUp</> +export const HouseXFill: Icon = () => <>BootstrapIconMock_HouseXFill</> +export const HouseX: Icon = () => <>BootstrapIconMock_HouseX</> +export const House: Icon = () => <>BootstrapIconMock_House</> +export const HousesFill: Icon = () => <>BootstrapIconMock_HousesFill</> +export const Houses: Icon = () => <>BootstrapIconMock_Houses</> +export const Hr: Icon = () => <>BootstrapIconMock_Hr</> +export const Hurricane: Icon = () => <>BootstrapIconMock_Hurricane</> +export const Hypnotize: Icon = () => <>BootstrapIconMock_Hypnotize</> +export const ImageAlt: Icon = () => <>BootstrapIconMock_ImageAlt</> +export const ImageFill: Icon = () => <>BootstrapIconMock_ImageFill</> +export const Image: Icon = () => <>BootstrapIconMock_Image</> +export const Images: Icon = () => <>BootstrapIconMock_Images</> +export const InboxFill: Icon = () => <>BootstrapIconMock_InboxFill</> +export const Inbox: Icon = () => <>BootstrapIconMock_Inbox</> +export const InboxesFill: Icon = () => <>BootstrapIconMock_InboxesFill</> +export const Inboxes: Icon = () => <>BootstrapIconMock_Inboxes</> +export const Incognito: Icon = () => <>BootstrapIconMock_Incognito</> +export const Indent: Icon = () => <>BootstrapIconMock_Indent</> +// eslint-disable-next-line no-shadow-restricted-names +export const Infinity: Icon = () => <>BootstrapIconMock_Infinity</> +export const InfoCircleFill: Icon = () => <>BootstrapIconMock_InfoCircleFill</> +export const InfoCircle: Icon = () => <>BootstrapIconMock_InfoCircle</> +export const InfoLg: Icon = () => <>BootstrapIconMock_InfoLg</> +export const InfoSquareFill: Icon = () => <>BootstrapIconMock_InfoSquareFill</> +export const InfoSquare: Icon = () => <>BootstrapIconMock_InfoSquare</> +export const Info: Icon = () => <>BootstrapIconMock_Info</> +export const InputCursorText: Icon = () => <>BootstrapIconMock_InputCursorText</> +export const InputCursor: Icon = () => <>BootstrapIconMock_InputCursor</> +export const Instagram: Icon = () => <>BootstrapIconMock_Instagram</> +export const Intersect: Icon = () => <>BootstrapIconMock_Intersect</> +export const JournalAlbum: Icon = () => <>BootstrapIconMock_JournalAlbum</> +export const JournalArrowDown: Icon = () => <>BootstrapIconMock_JournalArrowDown</> +export const JournalArrowUp: Icon = () => <>BootstrapIconMock_JournalArrowUp</> +export const JournalBookmarkFill: Icon = () => <>BootstrapIconMock_JournalBookmarkFill</> +export const JournalBookmark: Icon = () => <>BootstrapIconMock_JournalBookmark</> +export const JournalCheck: Icon = () => <>BootstrapIconMock_JournalCheck</> +export const JournalCode: Icon = () => <>BootstrapIconMock_JournalCode</> +export const JournalMedical: Icon = () => <>BootstrapIconMock_JournalMedical</> +export const JournalMinus: Icon = () => <>BootstrapIconMock_JournalMinus</> +export const JournalPlus: Icon = () => <>BootstrapIconMock_JournalPlus</> +export const JournalRichtext: Icon = () => <>BootstrapIconMock_JournalRichtext</> +export const JournalText: Icon = () => <>BootstrapIconMock_JournalText</> +export const JournalX: Icon = () => <>BootstrapIconMock_JournalX</> +export const Journal: Icon = () => <>BootstrapIconMock_Journal</> +export const Journals: Icon = () => <>BootstrapIconMock_Journals</> +export const Joystick: Icon = () => <>BootstrapIconMock_Joystick</> +export const JustifyLeft: Icon = () => <>BootstrapIconMock_JustifyLeft</> +export const JustifyRight: Icon = () => <>BootstrapIconMock_JustifyRight</> +export const Justify: Icon = () => <>BootstrapIconMock_Justify</> +export const KanbanFill: Icon = () => <>BootstrapIconMock_KanbanFill</> +export const Kanban: Icon = () => <>BootstrapIconMock_Kanban</> +export const KeyFill: Icon = () => <>BootstrapIconMock_KeyFill</> +export const Key: Icon = () => <>BootstrapIconMock_Key</> +export const KeyboardFill: Icon = () => <>BootstrapIconMock_KeyboardFill</> +export const Keyboard: Icon = () => <>BootstrapIconMock_Keyboard</> +export const Ladder: Icon = () => <>BootstrapIconMock_Ladder</> +export const LampFill: Icon = () => <>BootstrapIconMock_LampFill</> +export const Lamp: Icon = () => <>BootstrapIconMock_Lamp</> +export const LaptopFill: Icon = () => <>BootstrapIconMock_LaptopFill</> +export const Laptop: Icon = () => <>BootstrapIconMock_Laptop</> +export const LayerBackward: Icon = () => <>BootstrapIconMock_LayerBackward</> +export const LayerForward: Icon = () => <>BootstrapIconMock_LayerForward</> +export const LayersFill: Icon = () => <>BootstrapIconMock_LayersFill</> +export const LayersHalf: Icon = () => <>BootstrapIconMock_LayersHalf</> +export const Layers: Icon = () => <>BootstrapIconMock_Layers</> +export const LayoutSidebarInsetReverse: Icon = () => <>BootstrapIconMock_LayoutSidebarInsetReverse</> +export const LayoutSidebarInset: Icon = () => <>BootstrapIconMock_LayoutSidebarInset</> +export const LayoutSidebarReverse: Icon = () => <>BootstrapIconMock_LayoutSidebarReverse</> +export const LayoutSidebar: Icon = () => <>BootstrapIconMock_LayoutSidebar</> +export const LayoutSplit: Icon = () => <>BootstrapIconMock_LayoutSplit</> +export const LayoutTextSidebarReverse: Icon = () => <>BootstrapIconMock_LayoutTextSidebarReverse</> +export const LayoutTextSidebar: Icon = () => <>BootstrapIconMock_LayoutTextSidebar</> +export const LayoutTextWindowReverse: Icon = () => <>BootstrapIconMock_LayoutTextWindowReverse</> +export const LayoutTextWindow: Icon = () => <>BootstrapIconMock_LayoutTextWindow</> +export const LayoutThreeColumns: Icon = () => <>BootstrapIconMock_LayoutThreeColumns</> +export const LayoutWtf: Icon = () => <>BootstrapIconMock_LayoutWtf</> +export const LifePreserver: Icon = () => <>BootstrapIconMock_LifePreserver</> +export const LightbulbFill: Icon = () => <>BootstrapIconMock_LightbulbFill</> +export const LightbulbOffFill: Icon = () => <>BootstrapIconMock_LightbulbOffFill</> +export const LightbulbOff: Icon = () => <>BootstrapIconMock_LightbulbOff</> +export const Lightbulb: Icon = () => <>BootstrapIconMock_Lightbulb</> +export const LightningChargeFill: Icon = () => <>BootstrapIconMock_LightningChargeFill</> +export const LightningCharge: Icon = () => <>BootstrapIconMock_LightningCharge</> +export const LightningFill: Icon = () => <>BootstrapIconMock_LightningFill</> +export const Lightning: Icon = () => <>BootstrapIconMock_Lightning</> +export const Line: Icon = () => <>BootstrapIconMock_Line</> +export const Link45deg: Icon = () => <>BootstrapIconMock_Link45deg</> +export const Link: Icon = () => <>BootstrapIconMock_Link</> +export const Linkedin: Icon = () => <>BootstrapIconMock_Linkedin</> +export const ListCheck: Icon = () => <>BootstrapIconMock_ListCheck</> +export const ListColumnsReverse: Icon = () => <>BootstrapIconMock_ListColumnsReverse</> +export const ListColumns: Icon = () => <>BootstrapIconMock_ListColumns</> +export const ListNested: Icon = () => <>BootstrapIconMock_ListNested</> +export const ListOl: Icon = () => <>BootstrapIconMock_ListOl</> +export const ListStars: Icon = () => <>BootstrapIconMock_ListStars</> +export const ListTask: Icon = () => <>BootstrapIconMock_ListTask</> +export const ListUl: Icon = () => <>BootstrapIconMock_ListUl</> +export const List: Icon = () => <>BootstrapIconMock_List</> +export const LockFill: Icon = () => <>BootstrapIconMock_LockFill</> +export const Lock: Icon = () => <>BootstrapIconMock_Lock</> +export const LungsFill: Icon = () => <>BootstrapIconMock_LungsFill</> +export const Lungs: Icon = () => <>BootstrapIconMock_Lungs</> +export const Magic: Icon = () => <>BootstrapIconMock_Magic</> +export const MagnetFill: Icon = () => <>BootstrapIconMock_MagnetFill</> +export const Magnet: Icon = () => <>BootstrapIconMock_Magnet</> +export const Mailbox: Icon = () => <>BootstrapIconMock_Mailbox</> +export const Mailbox2: Icon = () => <>BootstrapIconMock_Mailbox2</> +export const MapFill: Icon = () => <>BootstrapIconMock_MapFill</> +export const Map: Icon = () => <>BootstrapIconMock_Map</> +export const MarkdownFill: Icon = () => <>BootstrapIconMock_MarkdownFill</> +export const Markdown: Icon = () => <>BootstrapIconMock_Markdown</> +export const Mask: Icon = () => <>BootstrapIconMock_Mask</> +export const Mastodon: Icon = () => <>BootstrapIconMock_Mastodon</> +export const Medium: Icon = () => <>BootstrapIconMock_Medium</> +export const MegaphoneFill: Icon = () => <>BootstrapIconMock_MegaphoneFill</> +export const Megaphone: Icon = () => <>BootstrapIconMock_Megaphone</> +export const Memory: Icon = () => <>BootstrapIconMock_Memory</> +export const MenuAppFill: Icon = () => <>BootstrapIconMock_MenuAppFill</> +export const MenuApp: Icon = () => <>BootstrapIconMock_MenuApp</> +export const MenuButtonFill: Icon = () => <>BootstrapIconMock_MenuButtonFill</> +export const MenuButtonWideFill: Icon = () => <>BootstrapIconMock_MenuButtonWideFill</> +export const MenuButtonWide: Icon = () => <>BootstrapIconMock_MenuButtonWide</> +export const MenuButton: Icon = () => <>BootstrapIconMock_MenuButton</> +export const MenuDown: Icon = () => <>BootstrapIconMock_MenuDown</> +export const MenuUp: Icon = () => <>BootstrapIconMock_MenuUp</> +export const Messenger: Icon = () => <>BootstrapIconMock_Messenger</> +export const Meta: Icon = () => <>BootstrapIconMock_Meta</> +export const MicFill: Icon = () => <>BootstrapIconMock_MicFill</> +export const MicMuteFill: Icon = () => <>BootstrapIconMock_MicMuteFill</> +export const MicMute: Icon = () => <>BootstrapIconMock_MicMute</> +export const Mic: Icon = () => <>BootstrapIconMock_Mic</> +export const MicrosoftTeams: Icon = () => <>BootstrapIconMock_MicrosoftTeams</> +export const Microsoft: Icon = () => <>BootstrapIconMock_Microsoft</> +export const MinecartLoaded: Icon = () => <>BootstrapIconMock_MinecartLoaded</> +export const Minecart: Icon = () => <>BootstrapIconMock_Minecart</> +export const ModemFill: Icon = () => <>BootstrapIconMock_ModemFill</> +export const Modem: Icon = () => <>BootstrapIconMock_Modem</> +export const Moisture: Icon = () => <>BootstrapIconMock_Moisture</> +export const MoonFill: Icon = () => <>BootstrapIconMock_MoonFill</> +export const MoonStarsFill: Icon = () => <>BootstrapIconMock_MoonStarsFill</> +export const MoonStars: Icon = () => <>BootstrapIconMock_MoonStars</> +export const Moon: Icon = () => <>BootstrapIconMock_Moon</> +export const MortarboardFill: Icon = () => <>BootstrapIconMock_MortarboardFill</> +export const Mortarboard: Icon = () => <>BootstrapIconMock_Mortarboard</> +export const MotherboardFill: Icon = () => <>BootstrapIconMock_MotherboardFill</> +export const Motherboard: Icon = () => <>BootstrapIconMock_Motherboard</> +export const MouseFill: Icon = () => <>BootstrapIconMock_MouseFill</> +export const Mouse: Icon = () => <>BootstrapIconMock_Mouse</> +export const Mouse2Fill: Icon = () => <>BootstrapIconMock_Mouse2Fill</> +export const Mouse2: Icon = () => <>BootstrapIconMock_Mouse2</> +export const Mouse3Fill: Icon = () => <>BootstrapIconMock_Mouse3Fill</> +export const Mouse3: Icon = () => <>BootstrapIconMock_Mouse3</> +export const MusicNoteBeamed: Icon = () => <>BootstrapIconMock_MusicNoteBeamed</> +export const MusicNoteList: Icon = () => <>BootstrapIconMock_MusicNoteList</> +export const MusicNote: Icon = () => <>BootstrapIconMock_MusicNote</> +export const MusicPlayerFill: Icon = () => <>BootstrapIconMock_MusicPlayerFill</> +export const MusicPlayer: Icon = () => <>BootstrapIconMock_MusicPlayer</> +export const Newspaper: Icon = () => <>BootstrapIconMock_Newspaper</> +export const NintendoSwitch: Icon = () => <>BootstrapIconMock_NintendoSwitch</> +export const NodeMinusFill: Icon = () => <>BootstrapIconMock_NodeMinusFill</> +export const NodeMinus: Icon = () => <>BootstrapIconMock_NodeMinus</> +export const NodePlusFill: Icon = () => <>BootstrapIconMock_NodePlusFill</> +export const NodePlus: Icon = () => <>BootstrapIconMock_NodePlus</> +export const NutFill: Icon = () => <>BootstrapIconMock_NutFill</> +export const Nut: Icon = () => <>BootstrapIconMock_Nut</> +export const Nvidia: Icon = () => <>BootstrapIconMock_Nvidia</> +export const OctagonFill: Icon = () => <>BootstrapIconMock_OctagonFill</> +export const OctagonHalf: Icon = () => <>BootstrapIconMock_OctagonHalf</> +export const Octagon: Icon = () => <>BootstrapIconMock_Octagon</> +export const OpticalAudioFill: Icon = () => <>BootstrapIconMock_OpticalAudioFill</> +export const OpticalAudio: Icon = () => <>BootstrapIconMock_OpticalAudio</> +export const Option: Icon = () => <>BootstrapIconMock_Option</> +export const Outlet: Icon = () => <>BootstrapIconMock_Outlet</> +export const PCircleFill: Icon = () => <>BootstrapIconMock_PCircleFill</> +export const PCircle: Icon = () => <>BootstrapIconMock_PCircle</> +export const PSquareFill: Icon = () => <>BootstrapIconMock_PSquareFill</> +export const PSquare: Icon = () => <>BootstrapIconMock_PSquare</> +export const PaintBucket: Icon = () => <>BootstrapIconMock_PaintBucket</> +export const PaletteFill: Icon = () => <>BootstrapIconMock_PaletteFill</> +export const Palette: Icon = () => <>BootstrapIconMock_Palette</> +export const Palette2: Icon = () => <>BootstrapIconMock_Palette2</> +export const Paperclip: Icon = () => <>BootstrapIconMock_Paperclip</> +export const Paragraph: Icon = () => <>BootstrapIconMock_Paragraph</> +export const PassFill: Icon = () => <>BootstrapIconMock_PassFill</> +export const Pass: Icon = () => <>BootstrapIconMock_Pass</> +export const PatchCheckFill: Icon = () => <>BootstrapIconMock_PatchCheckFill</> +export const PatchCheck: Icon = () => <>BootstrapIconMock_PatchCheck</> +export const PatchExclamationFill: Icon = () => <>BootstrapIconMock_PatchExclamationFill</> +export const PatchExclamation: Icon = () => <>BootstrapIconMock_PatchExclamation</> +export const PatchMinusFill: Icon = () => <>BootstrapIconMock_PatchMinusFill</> +export const PatchMinus: Icon = () => <>BootstrapIconMock_PatchMinus</> +export const PatchPlusFill: Icon = () => <>BootstrapIconMock_PatchPlusFill</> +export const PatchPlus: Icon = () => <>BootstrapIconMock_PatchPlus</> +export const PatchQuestionFill: Icon = () => <>BootstrapIconMock_PatchQuestionFill</> +export const PatchQuestion: Icon = () => <>BootstrapIconMock_PatchQuestion</> +export const PauseBtnFill: Icon = () => <>BootstrapIconMock_PauseBtnFill</> +export const PauseBtn: Icon = () => <>BootstrapIconMock_PauseBtn</> +export const PauseCircleFill: Icon = () => <>BootstrapIconMock_PauseCircleFill</> +export const PauseCircle: Icon = () => <>BootstrapIconMock_PauseCircle</> +export const PauseFill: Icon = () => <>BootstrapIconMock_PauseFill</> +export const Pause: Icon = () => <>BootstrapIconMock_Pause</> +export const Paypal: Icon = () => <>BootstrapIconMock_Paypal</> +export const PcDisplayHorizontal: Icon = () => <>BootstrapIconMock_PcDisplayHorizontal</> +export const PcDisplay: Icon = () => <>BootstrapIconMock_PcDisplay</> +export const PcHorizontal: Icon = () => <>BootstrapIconMock_PcHorizontal</> +export const Pc: Icon = () => <>BootstrapIconMock_Pc</> +export const PciCard: Icon = () => <>BootstrapIconMock_PciCard</> +export const PeaceFill: Icon = () => <>BootstrapIconMock_PeaceFill</> +export const Peace: Icon = () => <>BootstrapIconMock_Peace</> +export const PenFill: Icon = () => <>BootstrapIconMock_PenFill</> +export const Pen: Icon = () => <>BootstrapIconMock_Pen</> +export const PencilFill: Icon = () => <>BootstrapIconMock_PencilFill</> +export const PencilSquare: Icon = () => <>BootstrapIconMock_PencilSquare</> +export const Pencil: Icon = () => <>BootstrapIconMock_Pencil</> +export const PentagonFill: Icon = () => <>BootstrapIconMock_PentagonFill</> +export const PentagonHalf: Icon = () => <>BootstrapIconMock_PentagonHalf</> +export const Pentagon: Icon = () => <>BootstrapIconMock_Pentagon</> +export const PeopleFill: Icon = () => <>BootstrapIconMock_PeopleFill</> +export const People: Icon = () => <>BootstrapIconMock_People</> +export const Percent: Icon = () => <>BootstrapIconMock_Percent</> +export const PersonAdd: Icon = () => <>BootstrapIconMock_PersonAdd</> +export const PersonBadgeFill: Icon = () => <>BootstrapIconMock_PersonBadgeFill</> +export const PersonBadge: Icon = () => <>BootstrapIconMock_PersonBadge</> +export const PersonBoundingBox: Icon = () => <>BootstrapIconMock_PersonBoundingBox</> +export const PersonCheckFill: Icon = () => <>BootstrapIconMock_PersonCheckFill</> +export const PersonCheck: Icon = () => <>BootstrapIconMock_PersonCheck</> +export const PersonCircle: Icon = () => <>BootstrapIconMock_PersonCircle</> +export const PersonDashFill: Icon = () => <>BootstrapIconMock_PersonDashFill</> +export const PersonDash: Icon = () => <>BootstrapIconMock_PersonDash</> +export const PersonDown: Icon = () => <>BootstrapIconMock_PersonDown</> +export const PersonExclamation: Icon = () => <>BootstrapIconMock_PersonExclamation</> +export const PersonFillAdd: Icon = () => <>BootstrapIconMock_PersonFillAdd</> +export const PersonFillCheck: Icon = () => <>BootstrapIconMock_PersonFillCheck</> +export const PersonFillDash: Icon = () => <>BootstrapIconMock_PersonFillDash</> +export const PersonFillDown: Icon = () => <>BootstrapIconMock_PersonFillDown</> +export const PersonFillExclamation: Icon = () => <>BootstrapIconMock_PersonFillExclamation</> +export const PersonFillGear: Icon = () => <>BootstrapIconMock_PersonFillGear</> +export const PersonFillLock: Icon = () => <>BootstrapIconMock_PersonFillLock</> +export const PersonFillSlash: Icon = () => <>BootstrapIconMock_PersonFillSlash</> +export const PersonFillUp: Icon = () => <>BootstrapIconMock_PersonFillUp</> +export const PersonFillX: Icon = () => <>BootstrapIconMock_PersonFillX</> +export const PersonFill: Icon = () => <>BootstrapIconMock_PersonFill</> +export const PersonGear: Icon = () => <>BootstrapIconMock_PersonGear</> +export const PersonHeart: Icon = () => <>BootstrapIconMock_PersonHeart</> +export const PersonHearts: Icon = () => <>BootstrapIconMock_PersonHearts</> +export const PersonLinesFill: Icon = () => <>BootstrapIconMock_PersonLinesFill</> +export const PersonLock: Icon = () => <>BootstrapIconMock_PersonLock</> +export const PersonPlusFill: Icon = () => <>BootstrapIconMock_PersonPlusFill</> +export const PersonPlus: Icon = () => <>BootstrapIconMock_PersonPlus</> +export const PersonRolodex: Icon = () => <>BootstrapIconMock_PersonRolodex</> +export const PersonSlash: Icon = () => <>BootstrapIconMock_PersonSlash</> +export const PersonSquare: Icon = () => <>BootstrapIconMock_PersonSquare</> +export const PersonUp: Icon = () => <>BootstrapIconMock_PersonUp</> +export const PersonVcardFill: Icon = () => <>BootstrapIconMock_PersonVcardFill</> +export const PersonVcard: Icon = () => <>BootstrapIconMock_PersonVcard</> +export const PersonVideo: Icon = () => <>BootstrapIconMock_PersonVideo</> +export const PersonVideo2: Icon = () => <>BootstrapIconMock_PersonVideo2</> +export const PersonVideo3: Icon = () => <>BootstrapIconMock_PersonVideo3</> +export const PersonWorkspace: Icon = () => <>BootstrapIconMock_PersonWorkspace</> +export const PersonXFill: Icon = () => <>BootstrapIconMock_PersonXFill</> +export const PersonX: Icon = () => <>BootstrapIconMock_PersonX</> +export const Person: Icon = () => <>BootstrapIconMock_Person</> +export const PhoneFill: Icon = () => <>BootstrapIconMock_PhoneFill</> +export const PhoneFlip: Icon = () => <>BootstrapIconMock_PhoneFlip</> +export const PhoneLandscapeFill: Icon = () => <>BootstrapIconMock_PhoneLandscapeFill</> +export const PhoneLandscape: Icon = () => <>BootstrapIconMock_PhoneLandscape</> +export const PhoneVibrateFill: Icon = () => <>BootstrapIconMock_PhoneVibrateFill</> +export const PhoneVibrate: Icon = () => <>BootstrapIconMock_PhoneVibrate</> +export const Phone: Icon = () => <>BootstrapIconMock_Phone</> +export const PieChartFill: Icon = () => <>BootstrapIconMock_PieChartFill</> +export const PieChart: Icon = () => <>BootstrapIconMock_PieChart</> +export const PiggyBankFill: Icon = () => <>BootstrapIconMock_PiggyBankFill</> +export const PiggyBank: Icon = () => <>BootstrapIconMock_PiggyBank</> +export const PinAngleFill: Icon = () => <>BootstrapIconMock_PinAngleFill</> +export const PinAngle: Icon = () => <>BootstrapIconMock_PinAngle</> +export const PinFill: Icon = () => <>BootstrapIconMock_PinFill</> +export const PinMapFill: Icon = () => <>BootstrapIconMock_PinMapFill</> +export const PinMap: Icon = () => <>BootstrapIconMock_PinMap</> +export const Pin: Icon = () => <>BootstrapIconMock_Pin</> +export const Pinterest: Icon = () => <>BootstrapIconMock_Pinterest</> +export const PipFill: Icon = () => <>BootstrapIconMock_PipFill</> +export const Pip: Icon = () => <>BootstrapIconMock_Pip</> +export const PlayBtnFill: Icon = () => <>BootstrapIconMock_PlayBtnFill</> +export const PlayBtn: Icon = () => <>BootstrapIconMock_PlayBtn</> +export const PlayCircleFill: Icon = () => <>BootstrapIconMock_PlayCircleFill</> +export const PlayCircle: Icon = () => <>BootstrapIconMock_PlayCircle</> +export const PlayFill: Icon = () => <>BootstrapIconMock_PlayFill</> +export const Play: Icon = () => <>BootstrapIconMock_Play</> +export const Playstation: Icon = () => <>BootstrapIconMock_Playstation</> +export const PlugFill: Icon = () => <>BootstrapIconMock_PlugFill</> +export const Plug: Icon = () => <>BootstrapIconMock_Plug</> +export const Plugin: Icon = () => <>BootstrapIconMock_Plugin</> +export const PlusCircleDotted: Icon = () => <>BootstrapIconMock_PlusCircleDotted</> +export const PlusCircleFill: Icon = () => <>BootstrapIconMock_PlusCircleFill</> +export const PlusCircle: Icon = () => <>BootstrapIconMock_PlusCircle</> +export const PlusLg: Icon = () => <>BootstrapIconMock_PlusLg</> +export const PlusSlashMinus: Icon = () => <>BootstrapIconMock_PlusSlashMinus</> +export const PlusSquareDotted: Icon = () => <>BootstrapIconMock_PlusSquareDotted</> +export const PlusSquareFill: Icon = () => <>BootstrapIconMock_PlusSquareFill</> +export const PlusSquare: Icon = () => <>BootstrapIconMock_PlusSquare</> +export const Plus: Icon = () => <>BootstrapIconMock_Plus</> +export const PostageFill: Icon = () => <>BootstrapIconMock_PostageFill</> +export const PostageHeartFill: Icon = () => <>BootstrapIconMock_PostageHeartFill</> +export const PostageHeart: Icon = () => <>BootstrapIconMock_PostageHeart</> +export const Postage: Icon = () => <>BootstrapIconMock_Postage</> +export const PostcardFill: Icon = () => <>BootstrapIconMock_PostcardFill</> +export const PostcardHeartFill: Icon = () => <>BootstrapIconMock_PostcardHeartFill</> +export const PostcardHeart: Icon = () => <>BootstrapIconMock_PostcardHeart</> +export const Postcard: Icon = () => <>BootstrapIconMock_Postcard</> +export const Power: Icon = () => <>BootstrapIconMock_Power</> +export const Prescription: Icon = () => <>BootstrapIconMock_Prescription</> +export const Prescription2: Icon = () => <>BootstrapIconMock_Prescription2</> +export const PrinterFill: Icon = () => <>BootstrapIconMock_PrinterFill</> +export const Printer: Icon = () => <>BootstrapIconMock_Printer</> +export const ProjectorFill: Icon = () => <>BootstrapIconMock_ProjectorFill</> +export const Projector: Icon = () => <>BootstrapIconMock_Projector</> +export const PuzzleFill: Icon = () => <>BootstrapIconMock_PuzzleFill</> +export const Puzzle: Icon = () => <>BootstrapIconMock_Puzzle</> +export const QrCodeScan: Icon = () => <>BootstrapIconMock_QrCodeScan</> +export const QrCode: Icon = () => <>BootstrapIconMock_QrCode</> +export const QuestionCircleFill: Icon = () => <>BootstrapIconMock_QuestionCircleFill</> +export const QuestionCircle: Icon = () => <>BootstrapIconMock_QuestionCircle</> +export const QuestionDiamondFill: Icon = () => <>BootstrapIconMock_QuestionDiamondFill</> +export const QuestionDiamond: Icon = () => <>BootstrapIconMock_QuestionDiamond</> +export const QuestionLg: Icon = () => <>BootstrapIconMock_QuestionLg</> +export const QuestionOctagonFill: Icon = () => <>BootstrapIconMock_QuestionOctagonFill</> +export const QuestionOctagon: Icon = () => <>BootstrapIconMock_QuestionOctagon</> +export const QuestionSquareFill: Icon = () => <>BootstrapIconMock_QuestionSquareFill</> +export const QuestionSquare: Icon = () => <>BootstrapIconMock_QuestionSquare</> +export const Question: Icon = () => <>BootstrapIconMock_Question</> +export const Quora: Icon = () => <>BootstrapIconMock_Quora</> +export const Quote: Icon = () => <>BootstrapIconMock_Quote</> +export const RCircleFill: Icon = () => <>BootstrapIconMock_RCircleFill</> +export const RCircle: Icon = () => <>BootstrapIconMock_RCircle</> +export const RSquareFill: Icon = () => <>BootstrapIconMock_RSquareFill</> +export const RSquare: Icon = () => <>BootstrapIconMock_RSquare</> +export const Radioactive: Icon = () => <>BootstrapIconMock_Radioactive</> +export const Rainbow: Icon = () => <>BootstrapIconMock_Rainbow</> +export const ReceiptCutoff: Icon = () => <>BootstrapIconMock_ReceiptCutoff</> +export const Receipt: Icon = () => <>BootstrapIconMock_Receipt</> +export const Reception0: Icon = () => <>BootstrapIconMock_Reception0</> +export const Reception1: Icon = () => <>BootstrapIconMock_Reception1</> +export const Reception2: Icon = () => <>BootstrapIconMock_Reception2</> +export const Reception3: Icon = () => <>BootstrapIconMock_Reception3</> +export const Reception4: Icon = () => <>BootstrapIconMock_Reception4</> +export const RecordBtnFill: Icon = () => <>BootstrapIconMock_RecordBtnFill</> +export const RecordBtn: Icon = () => <>BootstrapIconMock_RecordBtn</> +export const RecordCircleFill: Icon = () => <>BootstrapIconMock_RecordCircleFill</> +export const RecordCircle: Icon = () => <>BootstrapIconMock_RecordCircle</> +export const RecordFill: Icon = () => <>BootstrapIconMock_RecordFill</> +export const Record: Icon = () => <>BootstrapIconMock_Record</> +export const Record2Fill: Icon = () => <>BootstrapIconMock_Record2Fill</> +export const Record2: Icon = () => <>BootstrapIconMock_Record2</> +export const Recycle: Icon = () => <>BootstrapIconMock_Recycle</> +export const Reddit: Icon = () => <>BootstrapIconMock_Reddit</> +export const Regex: Icon = () => <>BootstrapIconMock_Regex</> +export const Repeat1: Icon = () => <>BootstrapIconMock_Repeat1</> +export const Repeat: Icon = () => <>BootstrapIconMock_Repeat</> +export const ReplyAllFill: Icon = () => <>BootstrapIconMock_ReplyAllFill</> +export const ReplyAll: Icon = () => <>BootstrapIconMock_ReplyAll</> +export const ReplyFill: Icon = () => <>BootstrapIconMock_ReplyFill</> +export const Reply: Icon = () => <>BootstrapIconMock_Reply</> +export const RewindBtnFill: Icon = () => <>BootstrapIconMock_RewindBtnFill</> +export const RewindBtn: Icon = () => <>BootstrapIconMock_RewindBtn</> +export const RewindCircleFill: Icon = () => <>BootstrapIconMock_RewindCircleFill</> +export const RewindCircle: Icon = () => <>BootstrapIconMock_RewindCircle</> +export const RewindFill: Icon = () => <>BootstrapIconMock_RewindFill</> +export const Rewind: Icon = () => <>BootstrapIconMock_Rewind</> +export const Robot: Icon = () => <>BootstrapIconMock_Robot</> +export const RocketFill: Icon = () => <>BootstrapIconMock_RocketFill</> +export const RocketTakeoffFill: Icon = () => <>BootstrapIconMock_RocketTakeoffFill</> +export const RocketTakeoff: Icon = () => <>BootstrapIconMock_RocketTakeoff</> +export const Rocket: Icon = () => <>BootstrapIconMock_Rocket</> +export const RouterFill: Icon = () => <>BootstrapIconMock_RouterFill</> +export const Router: Icon = () => <>BootstrapIconMock_Router</> +export const RssFill: Icon = () => <>BootstrapIconMock_RssFill</> +export const Rss: Icon = () => <>BootstrapIconMock_Rss</> +export const Rulers: Icon = () => <>BootstrapIconMock_Rulers</> +export const SafeFill: Icon = () => <>BootstrapIconMock_SafeFill</> +export const Safe: Icon = () => <>BootstrapIconMock_Safe</> +export const Safe2Fill: Icon = () => <>BootstrapIconMock_Safe2Fill</> +export const Safe2: Icon = () => <>BootstrapIconMock_Safe2</> +export const SaveFill: Icon = () => <>BootstrapIconMock_SaveFill</> +export const Save: Icon = () => <>BootstrapIconMock_Save</> +export const Save2Fill: Icon = () => <>BootstrapIconMock_Save2Fill</> +export const Save2: Icon = () => <>BootstrapIconMock_Save2</> +export const Scissors: Icon = () => <>BootstrapIconMock_Scissors</> +export const Scooter: Icon = () => <>BootstrapIconMock_Scooter</> +export const Screwdriver: Icon = () => <>BootstrapIconMock_Screwdriver</> +export const SdCardFill: Icon = () => <>BootstrapIconMock_SdCardFill</> +export const SdCard: Icon = () => <>BootstrapIconMock_SdCard</> +export const SearchHeartFill: Icon = () => <>BootstrapIconMock_SearchHeartFill</> +export const SearchHeart: Icon = () => <>BootstrapIconMock_SearchHeart</> +export const Search: Icon = () => <>BootstrapIconMock_Search</> +export const SegmentedNav: Icon = () => <>BootstrapIconMock_SegmentedNav</> +export const SendCheckFill: Icon = () => <>BootstrapIconMock_SendCheckFill</> +export const SendCheck: Icon = () => <>BootstrapIconMock_SendCheck</> +export const SendDashFill: Icon = () => <>BootstrapIconMock_SendDashFill</> +export const SendDash: Icon = () => <>BootstrapIconMock_SendDash</> +export const SendExclamationFill: Icon = () => <>BootstrapIconMock_SendExclamationFill</> +export const SendExclamation: Icon = () => <>BootstrapIconMock_SendExclamation</> +export const SendFill: Icon = () => <>BootstrapIconMock_SendFill</> +export const SendPlusFill: Icon = () => <>BootstrapIconMock_SendPlusFill</> +export const SendPlus: Icon = () => <>BootstrapIconMock_SendPlus</> +export const SendSlashFill: Icon = () => <>BootstrapIconMock_SendSlashFill</> +export const SendSlash: Icon = () => <>BootstrapIconMock_SendSlash</> +export const SendXFill: Icon = () => <>BootstrapIconMock_SendXFill</> +export const SendX: Icon = () => <>BootstrapIconMock_SendX</> +export const Send: Icon = () => <>BootstrapIconMock_Send</> +export const Server: Icon = () => <>BootstrapIconMock_Server</> +export const ShareFill: Icon = () => <>BootstrapIconMock_ShareFill</> +export const Share: Icon = () => <>BootstrapIconMock_Share</> +export const ShieldCheck: Icon = () => <>BootstrapIconMock_ShieldCheck</> +export const ShieldExclamation: Icon = () => <>BootstrapIconMock_ShieldExclamation</> +export const ShieldFillCheck: Icon = () => <>BootstrapIconMock_ShieldFillCheck</> +export const ShieldFillExclamation: Icon = () => <>BootstrapIconMock_ShieldFillExclamation</> +export const ShieldFillMinus: Icon = () => <>BootstrapIconMock_ShieldFillMinus</> +export const ShieldFillPlus: Icon = () => <>BootstrapIconMock_ShieldFillPlus</> +export const ShieldFillX: Icon = () => <>BootstrapIconMock_ShieldFillX</> +export const ShieldFill: Icon = () => <>BootstrapIconMock_ShieldFill</> +export const ShieldLockFill: Icon = () => <>BootstrapIconMock_ShieldLockFill</> +export const ShieldLock: Icon = () => <>BootstrapIconMock_ShieldLock</> +export const ShieldMinus: Icon = () => <>BootstrapIconMock_ShieldMinus</> +export const ShieldPlus: Icon = () => <>BootstrapIconMock_ShieldPlus</> +export const ShieldShaded: Icon = () => <>BootstrapIconMock_ShieldShaded</> +export const ShieldSlashFill: Icon = () => <>BootstrapIconMock_ShieldSlashFill</> +export const ShieldSlash: Icon = () => <>BootstrapIconMock_ShieldSlash</> +export const ShieldX: Icon = () => <>BootstrapIconMock_ShieldX</> +export const Shield: Icon = () => <>BootstrapIconMock_Shield</> +export const ShiftFill: Icon = () => <>BootstrapIconMock_ShiftFill</> +export const Shift: Icon = () => <>BootstrapIconMock_Shift</> +export const ShopWindow: Icon = () => <>BootstrapIconMock_ShopWindow</> +export const Shop: Icon = () => <>BootstrapIconMock_Shop</> +export const Shuffle: Icon = () => <>BootstrapIconMock_Shuffle</> +export const SignDeadEndFill: Icon = () => <>BootstrapIconMock_SignDeadEndFill</> +export const SignDeadEnd: Icon = () => <>BootstrapIconMock_SignDeadEnd</> +export const SignDoNotEnterFill: Icon = () => <>BootstrapIconMock_SignDoNotEnterFill</> +export const SignDoNotEnter: Icon = () => <>BootstrapIconMock_SignDoNotEnter</> +export const SignIntersectionFill: Icon = () => <>BootstrapIconMock_SignIntersectionFill</> +export const SignIntersectionSideFill: Icon = () => <>BootstrapIconMock_SignIntersectionSideFill</> +export const SignIntersectionSide: Icon = () => <>BootstrapIconMock_SignIntersectionSide</> +export const SignIntersectionTFill: Icon = () => <>BootstrapIconMock_SignIntersectionTFill</> +export const SignIntersectionT: Icon = () => <>BootstrapIconMock_SignIntersectionT</> +export const SignIntersectionYFill: Icon = () => <>BootstrapIconMock_SignIntersectionYFill</> +export const SignIntersectionY: Icon = () => <>BootstrapIconMock_SignIntersectionY</> +export const SignIntersection: Icon = () => <>BootstrapIconMock_SignIntersection</> +export const SignMergeLeftFill: Icon = () => <>BootstrapIconMock_SignMergeLeftFill</> +export const SignMergeLeft: Icon = () => <>BootstrapIconMock_SignMergeLeft</> +export const SignMergeRightFill: Icon = () => <>BootstrapIconMock_SignMergeRightFill</> +export const SignMergeRight: Icon = () => <>BootstrapIconMock_SignMergeRight</> +export const SignNoLeftTurnFill: Icon = () => <>BootstrapIconMock_SignNoLeftTurnFill</> +export const SignNoLeftTurn: Icon = () => <>BootstrapIconMock_SignNoLeftTurn</> +export const SignNoParkingFill: Icon = () => <>BootstrapIconMock_SignNoParkingFill</> +export const SignNoParking: Icon = () => <>BootstrapIconMock_SignNoParking</> +export const SignNoRightTurnFill: Icon = () => <>BootstrapIconMock_SignNoRightTurnFill</> +export const SignNoRightTurn: Icon = () => <>BootstrapIconMock_SignNoRightTurn</> +export const SignRailroadFill: Icon = () => <>BootstrapIconMock_SignRailroadFill</> +export const SignRailroad: Icon = () => <>BootstrapIconMock_SignRailroad</> +export const SignStopFill: Icon = () => <>BootstrapIconMock_SignStopFill</> +export const SignStopLightsFill: Icon = () => <>BootstrapIconMock_SignStopLightsFill</> +export const SignStopLights: Icon = () => <>BootstrapIconMock_SignStopLights</> +export const SignStop: Icon = () => <>BootstrapIconMock_SignStop</> +export const SignTurnLeftFill: Icon = () => <>BootstrapIconMock_SignTurnLeftFill</> +export const SignTurnLeft: Icon = () => <>BootstrapIconMock_SignTurnLeft</> +export const SignTurnRightFill: Icon = () => <>BootstrapIconMock_SignTurnRightFill</> +export const SignTurnRight: Icon = () => <>BootstrapIconMock_SignTurnRight</> +export const SignTurnSlightLeftFill: Icon = () => <>BootstrapIconMock_SignTurnSlightLeftFill</> +export const SignTurnSlightLeft: Icon = () => <>BootstrapIconMock_SignTurnSlightLeft</> +export const SignTurnSlightRightFill: Icon = () => <>BootstrapIconMock_SignTurnSlightRightFill</> +export const SignTurnSlightRight: Icon = () => <>BootstrapIconMock_SignTurnSlightRight</> +export const SignYieldFill: Icon = () => <>BootstrapIconMock_SignYieldFill</> +export const SignYield: Icon = () => <>BootstrapIconMock_SignYield</> +export const Signal: Icon = () => <>BootstrapIconMock_Signal</> +export const Signpost2Fill: Icon = () => <>BootstrapIconMock_Signpost2Fill</> +export const Signpost2: Icon = () => <>BootstrapIconMock_Signpost2</> +export const SignpostFill: Icon = () => <>BootstrapIconMock_SignpostFill</> +export const SignpostSplitFill: Icon = () => <>BootstrapIconMock_SignpostSplitFill</> +export const SignpostSplit: Icon = () => <>BootstrapIconMock_SignpostSplit</> +export const Signpost: Icon = () => <>BootstrapIconMock_Signpost</> +export const SimFill: Icon = () => <>BootstrapIconMock_SimFill</> +export const Sim: Icon = () => <>BootstrapIconMock_Sim</> +export const SinaWeibo: Icon = () => <>BootstrapIconMock_SinaWeibo</> +export const SkipBackwardBtnFill: Icon = () => <>BootstrapIconMock_SkipBackwardBtnFill</> +export const SkipBackwardBtn: Icon = () => <>BootstrapIconMock_SkipBackwardBtn</> +export const SkipBackwardCircleFill: Icon = () => <>BootstrapIconMock_SkipBackwardCircleFill</> +export const SkipBackwardCircle: Icon = () => <>BootstrapIconMock_SkipBackwardCircle</> +export const SkipBackwardFill: Icon = () => <>BootstrapIconMock_SkipBackwardFill</> +export const SkipBackward: Icon = () => <>BootstrapIconMock_SkipBackward</> +export const SkipEndBtnFill: Icon = () => <>BootstrapIconMock_SkipEndBtnFill</> +export const SkipEndBtn: Icon = () => <>BootstrapIconMock_SkipEndBtn</> +export const SkipEndCircleFill: Icon = () => <>BootstrapIconMock_SkipEndCircleFill</> +export const SkipEndCircle: Icon = () => <>BootstrapIconMock_SkipEndCircle</> +export const SkipEndFill: Icon = () => <>BootstrapIconMock_SkipEndFill</> +export const SkipEnd: Icon = () => <>BootstrapIconMock_SkipEnd</> +export const SkipForwardBtnFill: Icon = () => <>BootstrapIconMock_SkipForwardBtnFill</> +export const SkipForwardBtn: Icon = () => <>BootstrapIconMock_SkipForwardBtn</> +export const SkipForwardCircleFill: Icon = () => <>BootstrapIconMock_SkipForwardCircleFill</> +export const SkipForwardCircle: Icon = () => <>BootstrapIconMock_SkipForwardCircle</> +export const SkipForwardFill: Icon = () => <>BootstrapIconMock_SkipForwardFill</> +export const SkipForward: Icon = () => <>BootstrapIconMock_SkipForward</> +export const SkipStartBtnFill: Icon = () => <>BootstrapIconMock_SkipStartBtnFill</> +export const SkipStartBtn: Icon = () => <>BootstrapIconMock_SkipStartBtn</> +export const SkipStartCircleFill: Icon = () => <>BootstrapIconMock_SkipStartCircleFill</> +export const SkipStartCircle: Icon = () => <>BootstrapIconMock_SkipStartCircle</> +export const SkipStartFill: Icon = () => <>BootstrapIconMock_SkipStartFill</> +export const SkipStart: Icon = () => <>BootstrapIconMock_SkipStart</> +export const Skype: Icon = () => <>BootstrapIconMock_Skype</> +export const Slack: Icon = () => <>BootstrapIconMock_Slack</> +export const SlashCircleFill: Icon = () => <>BootstrapIconMock_SlashCircleFill</> +export const SlashCircle: Icon = () => <>BootstrapIconMock_SlashCircle</> +export const SlashLg: Icon = () => <>BootstrapIconMock_SlashLg</> +export const SlashSquareFill: Icon = () => <>BootstrapIconMock_SlashSquareFill</> +export const SlashSquare: Icon = () => <>BootstrapIconMock_SlashSquare</> +export const Slash: Icon = () => <>BootstrapIconMock_Slash</> +export const Sliders: Icon = () => <>BootstrapIconMock_Sliders</> +export const Sliders2Vertical: Icon = () => <>BootstrapIconMock_Sliders2Vertical</> +export const Sliders2: Icon = () => <>BootstrapIconMock_Sliders2</> +export const Smartwatch: Icon = () => <>BootstrapIconMock_Smartwatch</> +export const Snapchat: Icon = () => <>BootstrapIconMock_Snapchat</> +export const Snow: Icon = () => <>BootstrapIconMock_Snow</> +export const Snow2: Icon = () => <>BootstrapIconMock_Snow2</> +export const Snow3: Icon = () => <>BootstrapIconMock_Snow3</> +export const SortAlphaDownAlt: Icon = () => <>BootstrapIconMock_SortAlphaDownAlt</> +export const SortAlphaDown: Icon = () => <>BootstrapIconMock_SortAlphaDown</> +export const SortAlphaUpAlt: Icon = () => <>BootstrapIconMock_SortAlphaUpAlt</> +export const SortAlphaUp: Icon = () => <>BootstrapIconMock_SortAlphaUp</> +export const SortDownAlt: Icon = () => <>BootstrapIconMock_SortDownAlt</> +export const SortDown: Icon = () => <>BootstrapIconMock_SortDown</> +export const SortNumericDownAlt: Icon = () => <>BootstrapIconMock_SortNumericDownAlt</> +export const SortNumericDown: Icon = () => <>BootstrapIconMock_SortNumericDown</> +export const SortNumericUpAlt: Icon = () => <>BootstrapIconMock_SortNumericUpAlt</> +export const SortNumericUp: Icon = () => <>BootstrapIconMock_SortNumericUp</> +export const SortUpAlt: Icon = () => <>BootstrapIconMock_SortUpAlt</> +export const SortUp: Icon = () => <>BootstrapIconMock_SortUp</> +export const Soundwave: Icon = () => <>BootstrapIconMock_Soundwave</> +export const SpeakerFill: Icon = () => <>BootstrapIconMock_SpeakerFill</> +export const Speaker: Icon = () => <>BootstrapIconMock_Speaker</> +export const Speedometer: Icon = () => <>BootstrapIconMock_Speedometer</> +export const Speedometer2: Icon = () => <>BootstrapIconMock_Speedometer2</> +export const Spellcheck: Icon = () => <>BootstrapIconMock_Spellcheck</> +export const Spotify: Icon = () => <>BootstrapIconMock_Spotify</> +export const SquareFill: Icon = () => <>BootstrapIconMock_SquareFill</> +export const SquareHalf: Icon = () => <>BootstrapIconMock_SquareHalf</> +export const Square: Icon = () => <>BootstrapIconMock_Square</> +export const StackOverflow: Icon = () => <>BootstrapIconMock_StackOverflow</> +export const Stack: Icon = () => <>BootstrapIconMock_Stack</> +export const StarFill: Icon = () => <>BootstrapIconMock_StarFill</> +export const StarHalf: Icon = () => <>BootstrapIconMock_StarHalf</> +export const Star: Icon = () => <>BootstrapIconMock_Star</> +export const Stars: Icon = () => <>BootstrapIconMock_Stars</> +export const Steam: Icon = () => <>BootstrapIconMock_Steam</> +export const StickiesFill: Icon = () => <>BootstrapIconMock_StickiesFill</> +export const Stickies: Icon = () => <>BootstrapIconMock_Stickies</> +export const StickyFill: Icon = () => <>BootstrapIconMock_StickyFill</> +export const Sticky: Icon = () => <>BootstrapIconMock_Sticky</> +export const StopBtnFill: Icon = () => <>BootstrapIconMock_StopBtnFill</> +export const StopBtn: Icon = () => <>BootstrapIconMock_StopBtn</> +export const StopCircleFill: Icon = () => <>BootstrapIconMock_StopCircleFill</> +export const StopCircle: Icon = () => <>BootstrapIconMock_StopCircle</> +export const StopFill: Icon = () => <>BootstrapIconMock_StopFill</> +export const Stop: Icon = () => <>BootstrapIconMock_Stop</> +export const StoplightsFill: Icon = () => <>BootstrapIconMock_StoplightsFill</> +export const Stoplights: Icon = () => <>BootstrapIconMock_Stoplights</> +export const StopwatchFill: Icon = () => <>BootstrapIconMock_StopwatchFill</> +export const Stopwatch: Icon = () => <>BootstrapIconMock_Stopwatch</> +export const Strava: Icon = () => <>BootstrapIconMock_Strava</> +export const Stripe: Icon = () => <>BootstrapIconMock_Stripe</> +export const Subscript: Icon = () => <>BootstrapIconMock_Subscript</> +export const Subtract: Icon = () => <>BootstrapIconMock_Subtract</> +export const SuitClubFill: Icon = () => <>BootstrapIconMock_SuitClubFill</> +export const SuitClub: Icon = () => <>BootstrapIconMock_SuitClub</> +export const SuitDiamondFill: Icon = () => <>BootstrapIconMock_SuitDiamondFill</> +export const SuitDiamond: Icon = () => <>BootstrapIconMock_SuitDiamond</> +export const SuitHeartFill: Icon = () => <>BootstrapIconMock_SuitHeartFill</> +export const SuitHeart: Icon = () => <>BootstrapIconMock_SuitHeart</> +export const SuitSpadeFill: Icon = () => <>BootstrapIconMock_SuitSpadeFill</> +export const SuitSpade: Icon = () => <>BootstrapIconMock_SuitSpade</> +export const SunFill: Icon = () => <>BootstrapIconMock_SunFill</> +export const Sun: Icon = () => <>BootstrapIconMock_Sun</> +export const Sunglasses: Icon = () => <>BootstrapIconMock_Sunglasses</> +export const SunriseFill: Icon = () => <>BootstrapIconMock_SunriseFill</> +export const Sunrise: Icon = () => <>BootstrapIconMock_Sunrise</> +export const SunsetFill: Icon = () => <>BootstrapIconMock_SunsetFill</> +export const Sunset: Icon = () => <>BootstrapIconMock_Sunset</> +export const Superscript: Icon = () => <>BootstrapIconMock_Superscript</> +export const SymmetryHorizontal: Icon = () => <>BootstrapIconMock_SymmetryHorizontal</> +export const SymmetryVertical: Icon = () => <>BootstrapIconMock_SymmetryVertical</> +export const Table: Icon = () => <>BootstrapIconMock_Table</> +export const TabletFill: Icon = () => <>BootstrapIconMock_TabletFill</> +export const TabletLandscapeFill: Icon = () => <>BootstrapIconMock_TabletLandscapeFill</> +export const TabletLandscape: Icon = () => <>BootstrapIconMock_TabletLandscape</> +export const Tablet: Icon = () => <>BootstrapIconMock_Tablet</> +export const TagFill: Icon = () => <>BootstrapIconMock_TagFill</> +export const Tag: Icon = () => <>BootstrapIconMock_Tag</> +export const TagsFill: Icon = () => <>BootstrapIconMock_TagsFill</> +export const Tags: Icon = () => <>BootstrapIconMock_Tags</> +export const TaxiFrontFill: Icon = () => <>BootstrapIconMock_TaxiFrontFill</> +export const TaxiFront: Icon = () => <>BootstrapIconMock_TaxiFront</> +export const Telegram: Icon = () => <>BootstrapIconMock_Telegram</> +export const TelephoneFill: Icon = () => <>BootstrapIconMock_TelephoneFill</> +export const TelephoneForwardFill: Icon = () => <>BootstrapIconMock_TelephoneForwardFill</> +export const TelephoneForward: Icon = () => <>BootstrapIconMock_TelephoneForward</> +export const TelephoneInboundFill: Icon = () => <>BootstrapIconMock_TelephoneInboundFill</> +export const TelephoneInbound: Icon = () => <>BootstrapIconMock_TelephoneInbound</> +export const TelephoneMinusFill: Icon = () => <>BootstrapIconMock_TelephoneMinusFill</> +export const TelephoneMinus: Icon = () => <>BootstrapIconMock_TelephoneMinus</> +export const TelephoneOutboundFill: Icon = () => <>BootstrapIconMock_TelephoneOutboundFill</> +export const TelephoneOutbound: Icon = () => <>BootstrapIconMock_TelephoneOutbound</> +export const TelephonePlusFill: Icon = () => <>BootstrapIconMock_TelephonePlusFill</> +export const TelephonePlus: Icon = () => <>BootstrapIconMock_TelephonePlus</> +export const TelephoneXFill: Icon = () => <>BootstrapIconMock_TelephoneXFill</> +export const TelephoneX: Icon = () => <>BootstrapIconMock_TelephoneX</> +export const Telephone: Icon = () => <>BootstrapIconMock_Telephone</> +export const TencentQq: Icon = () => <>BootstrapIconMock_TencentQq</> +export const TerminalDash: Icon = () => <>BootstrapIconMock_TerminalDash</> +export const TerminalFill: Icon = () => <>BootstrapIconMock_TerminalFill</> +export const TerminalPlus: Icon = () => <>BootstrapIconMock_TerminalPlus</> +export const TerminalSplit: Icon = () => <>BootstrapIconMock_TerminalSplit</> +export const TerminalX: Icon = () => <>BootstrapIconMock_TerminalX</> +export const Terminal: Icon = () => <>BootstrapIconMock_Terminal</> +export const TextCenter: Icon = () => <>BootstrapIconMock_TextCenter</> +export const TextIndentLeft: Icon = () => <>BootstrapIconMock_TextIndentLeft</> +export const TextIndentRight: Icon = () => <>BootstrapIconMock_TextIndentRight</> +export const TextLeft: Icon = () => <>BootstrapIconMock_TextLeft</> +export const TextParagraph: Icon = () => <>BootstrapIconMock_TextParagraph</> +export const TextRight: Icon = () => <>BootstrapIconMock_TextRight</> +export const TextWrap: Icon = () => <>BootstrapIconMock_TextWrap</> +export const TextareaResize: Icon = () => <>BootstrapIconMock_TextareaResize</> +export const TextareaT: Icon = () => <>BootstrapIconMock_TextareaT</> +export const Textarea: Icon = () => <>BootstrapIconMock_Textarea</> +export const ThermometerHalf: Icon = () => <>BootstrapIconMock_ThermometerHalf</> +export const ThermometerHigh: Icon = () => <>BootstrapIconMock_ThermometerHigh</> +export const ThermometerLow: Icon = () => <>BootstrapIconMock_ThermometerLow</> +export const ThermometerSnow: Icon = () => <>BootstrapIconMock_ThermometerSnow</> +export const ThermometerSun: Icon = () => <>BootstrapIconMock_ThermometerSun</> +export const Thermometer: Icon = () => <>BootstrapIconMock_Thermometer</> +export const ThreeDotsVertical: Icon = () => <>BootstrapIconMock_ThreeDotsVertical</> +export const ThreeDots: Icon = () => <>BootstrapIconMock_ThreeDots</> +export const ThunderboltFill: Icon = () => <>BootstrapIconMock_ThunderboltFill</> +export const Thunderbolt: Icon = () => <>BootstrapIconMock_Thunderbolt</> +export const TicketDetailedFill: Icon = () => <>BootstrapIconMock_TicketDetailedFill</> +export const TicketDetailed: Icon = () => <>BootstrapIconMock_TicketDetailed</> +export const TicketFill: Icon = () => <>BootstrapIconMock_TicketFill</> +export const TicketPerforatedFill: Icon = () => <>BootstrapIconMock_TicketPerforatedFill</> +export const TicketPerforated: Icon = () => <>BootstrapIconMock_TicketPerforated</> +export const Ticket: Icon = () => <>BootstrapIconMock_Ticket</> +export const Tiktok: Icon = () => <>BootstrapIconMock_Tiktok</> +export const ToggleOff: Icon = () => <>BootstrapIconMock_ToggleOff</> +export const ToggleOn: Icon = () => <>BootstrapIconMock_ToggleOn</> +export const Toggle2Off: Icon = () => <>BootstrapIconMock_Toggle2Off</> +export const Toggle2On: Icon = () => <>BootstrapIconMock_Toggle2On</> +export const Toggles: Icon = () => <>BootstrapIconMock_Toggles</> +export const Toggles2: Icon = () => <>BootstrapIconMock_Toggles2</> +export const Tools: Icon = () => <>BootstrapIconMock_Tools</> +export const Tornado: Icon = () => <>BootstrapIconMock_Tornado</> +export const TrainFreightFrontFill: Icon = () => <>BootstrapIconMock_TrainFreightFrontFill</> +export const TrainFreightFront: Icon = () => <>BootstrapIconMock_TrainFreightFront</> +export const TrainFrontFill: Icon = () => <>BootstrapIconMock_TrainFrontFill</> +export const TrainFront: Icon = () => <>BootstrapIconMock_TrainFront</> +export const TrainLightrailFrontFill: Icon = () => <>BootstrapIconMock_TrainLightrailFrontFill</> +export const TrainLightrailFront: Icon = () => <>BootstrapIconMock_TrainLightrailFront</> +export const Translate: Icon = () => <>BootstrapIconMock_Translate</> +export const TrashFill: Icon = () => <>BootstrapIconMock_TrashFill</> +export const Trash: Icon = () => <>BootstrapIconMock_Trash</> +export const Trash2Fill: Icon = () => <>BootstrapIconMock_Trash2Fill</> +export const Trash2: Icon = () => <>BootstrapIconMock_Trash2</> +export const Trash3Fill: Icon = () => <>BootstrapIconMock_Trash3Fill</> +export const Trash3: Icon = () => <>BootstrapIconMock_Trash3</> +export const TreeFill: Icon = () => <>BootstrapIconMock_TreeFill</> +export const Tree: Icon = () => <>BootstrapIconMock_Tree</> +export const Trello: Icon = () => <>BootstrapIconMock_Trello</> +export const TriangleFill: Icon = () => <>BootstrapIconMock_TriangleFill</> +export const TriangleHalf: Icon = () => <>BootstrapIconMock_TriangleHalf</> +export const Triangle: Icon = () => <>BootstrapIconMock_Triangle</> +export const TrophyFill: Icon = () => <>BootstrapIconMock_TrophyFill</> +export const Trophy: Icon = () => <>BootstrapIconMock_Trophy</> +export const TropicalStorm: Icon = () => <>BootstrapIconMock_TropicalStorm</> +export const TruckFlatbed: Icon = () => <>BootstrapIconMock_TruckFlatbed</> +export const TruckFrontFill: Icon = () => <>BootstrapIconMock_TruckFrontFill</> +export const TruckFront: Icon = () => <>BootstrapIconMock_TruckFront</> +export const Truck: Icon = () => <>BootstrapIconMock_Truck</> +export const Tsunami: Icon = () => <>BootstrapIconMock_Tsunami</> +export const TvFill: Icon = () => <>BootstrapIconMock_TvFill</> +export const Tv: Icon = () => <>BootstrapIconMock_Tv</> +export const Twitch: Icon = () => <>BootstrapIconMock_Twitch</> +export const Twitter: Icon = () => <>BootstrapIconMock_Twitter</> +export const TypeBold: Icon = () => <>BootstrapIconMock_TypeBold</> +export const TypeH1: Icon = () => <>BootstrapIconMock_TypeH1</> +export const TypeH2: Icon = () => <>BootstrapIconMock_TypeH2</> +export const TypeH3: Icon = () => <>BootstrapIconMock_TypeH3</> +export const TypeItalic: Icon = () => <>BootstrapIconMock_TypeItalic</> +export const TypeStrikethrough: Icon = () => <>BootstrapIconMock_TypeStrikethrough</> +export const TypeUnderline: Icon = () => <>BootstrapIconMock_TypeUnderline</> +export const Type: Icon = () => <>BootstrapIconMock_Type</> +export const Ubuntu: Icon = () => <>BootstrapIconMock_Ubuntu</> +export const UiChecksGrid: Icon = () => <>BootstrapIconMock_UiChecksGrid</> +export const UiChecks: Icon = () => <>BootstrapIconMock_UiChecks</> +export const UiRadiosGrid: Icon = () => <>BootstrapIconMock_UiRadiosGrid</> +export const UiRadios: Icon = () => <>BootstrapIconMock_UiRadios</> +export const UmbrellaFill: Icon = () => <>BootstrapIconMock_UmbrellaFill</> +export const Umbrella: Icon = () => <>BootstrapIconMock_Umbrella</> +export const Unindent: Icon = () => <>BootstrapIconMock_Unindent</> +export const Union: Icon = () => <>BootstrapIconMock_Union</> +export const Unity: Icon = () => <>BootstrapIconMock_Unity</> +export const UniversalAccessCircle: Icon = () => <>BootstrapIconMock_UniversalAccessCircle</> +export const UniversalAccess: Icon = () => <>BootstrapIconMock_UniversalAccess</> +export const UnlockFill: Icon = () => <>BootstrapIconMock_UnlockFill</> +export const Unlock: Icon = () => <>BootstrapIconMock_Unlock</> +export const UpcScan: Icon = () => <>BootstrapIconMock_UpcScan</> +export const Upc: Icon = () => <>BootstrapIconMock_Upc</> +export const Upload: Icon = () => <>BootstrapIconMock_Upload</> +export const UsbCFill: Icon = () => <>BootstrapIconMock_UsbCFill</> +export const UsbC: Icon = () => <>BootstrapIconMock_UsbC</> +export const UsbDriveFill: Icon = () => <>BootstrapIconMock_UsbDriveFill</> +export const UsbDrive: Icon = () => <>BootstrapIconMock_UsbDrive</> +export const UsbFill: Icon = () => <>BootstrapIconMock_UsbFill</> +export const UsbMicroFill: Icon = () => <>BootstrapIconMock_UsbMicroFill</> +export const UsbMicro: Icon = () => <>BootstrapIconMock_UsbMicro</> +export const UsbMiniFill: Icon = () => <>BootstrapIconMock_UsbMiniFill</> +export const UsbMini: Icon = () => <>BootstrapIconMock_UsbMini</> +export const UsbPlugFill: Icon = () => <>BootstrapIconMock_UsbPlugFill</> +export const UsbPlug: Icon = () => <>BootstrapIconMock_UsbPlug</> +export const UsbSymbol: Icon = () => <>BootstrapIconMock_UsbSymbol</> +export const Usb: Icon = () => <>BootstrapIconMock_Usb</> +export const Valentine: Icon = () => <>BootstrapIconMock_Valentine</> +export const Valentine2: Icon = () => <>BootstrapIconMock_Valentine2</> +export const VectorPen: Icon = () => <>BootstrapIconMock_VectorPen</> +export const ViewList: Icon = () => <>BootstrapIconMock_ViewList</> +export const ViewStacked: Icon = () => <>BootstrapIconMock_ViewStacked</> +export const Vimeo: Icon = () => <>BootstrapIconMock_Vimeo</> +export const VinylFill: Icon = () => <>BootstrapIconMock_VinylFill</> +export const Vinyl: Icon = () => <>BootstrapIconMock_Vinyl</> +export const Virus: Icon = () => <>BootstrapIconMock_Virus</> +export const Virus2: Icon = () => <>BootstrapIconMock_Virus2</> +export const Voicemail: Icon = () => <>BootstrapIconMock_Voicemail</> +export const VolumeDownFill: Icon = () => <>BootstrapIconMock_VolumeDownFill</> +export const VolumeDown: Icon = () => <>BootstrapIconMock_VolumeDown</> +export const VolumeMuteFill: Icon = () => <>BootstrapIconMock_VolumeMuteFill</> +export const VolumeMute: Icon = () => <>BootstrapIconMock_VolumeMute</> +export const VolumeOffFill: Icon = () => <>BootstrapIconMock_VolumeOffFill</> +export const VolumeOff: Icon = () => <>BootstrapIconMock_VolumeOff</> +export const VolumeUpFill: Icon = () => <>BootstrapIconMock_VolumeUpFill</> +export const VolumeUp: Icon = () => <>BootstrapIconMock_VolumeUp</> +export const Vr: Icon = () => <>BootstrapIconMock_Vr</> +export const WalletFill: Icon = () => <>BootstrapIconMock_WalletFill</> +export const Wallet: Icon = () => <>BootstrapIconMock_Wallet</> +export const Wallet2: Icon = () => <>BootstrapIconMock_Wallet2</> +export const Watch: Icon = () => <>BootstrapIconMock_Watch</> +export const Water: Icon = () => <>BootstrapIconMock_Water</> +export const WebcamFill: Icon = () => <>BootstrapIconMock_WebcamFill</> +export const Webcam: Icon = () => <>BootstrapIconMock_Webcam</> +export const Wechat: Icon = () => <>BootstrapIconMock_Wechat</> +export const Whatsapp: Icon = () => <>BootstrapIconMock_Whatsapp</> +export const Wifi1: Icon = () => <>BootstrapIconMock_Wifi1</> +export const Wifi2: Icon = () => <>BootstrapIconMock_Wifi2</> +export const WifiOff: Icon = () => <>BootstrapIconMock_WifiOff</> +export const Wifi: Icon = () => <>BootstrapIconMock_Wifi</> +export const Wikipedia: Icon = () => <>BootstrapIconMock_Wikipedia</> +export const Wind: Icon = () => <>BootstrapIconMock_Wind</> +export const WindowDash: Icon = () => <>BootstrapIconMock_WindowDash</> +export const WindowDesktop: Icon = () => <>BootstrapIconMock_WindowDesktop</> +export const WindowDock: Icon = () => <>BootstrapIconMock_WindowDock</> +export const WindowFullscreen: Icon = () => <>BootstrapIconMock_WindowFullscreen</> +export const WindowPlus: Icon = () => <>BootstrapIconMock_WindowPlus</> +export const WindowSidebar: Icon = () => <>BootstrapIconMock_WindowSidebar</> +export const WindowSplit: Icon = () => <>BootstrapIconMock_WindowSplit</> +export const WindowStack: Icon = () => <>BootstrapIconMock_WindowStack</> +export const WindowX: Icon = () => <>BootstrapIconMock_WindowX</> +export const Window: Icon = () => <>BootstrapIconMock_Window</> +export const Windows: Icon = () => <>BootstrapIconMock_Windows</> +export const Wordpress: Icon = () => <>BootstrapIconMock_Wordpress</> +export const WrenchAdjustableCircleFill: Icon = () => <>BootstrapIconMock_WrenchAdjustableCircleFill</> +export const WrenchAdjustableCircle: Icon = () => <>BootstrapIconMock_WrenchAdjustableCircle</> +export const WrenchAdjustable: Icon = () => <>BootstrapIconMock_WrenchAdjustable</> +export const Wrench: Icon = () => <>BootstrapIconMock_Wrench</> +export const XCircleFill: Icon = () => <>BootstrapIconMock_XCircleFill</> +export const XCircle: Icon = () => <>BootstrapIconMock_XCircle</> +export const XDiamondFill: Icon = () => <>BootstrapIconMock_XDiamondFill</> +export const XDiamond: Icon = () => <>BootstrapIconMock_XDiamond</> +export const XLg: Icon = () => <>BootstrapIconMock_XLg</> +export const XOctagonFill: Icon = () => <>BootstrapIconMock_XOctagonFill</> +export const XOctagon: Icon = () => <>BootstrapIconMock_XOctagon</> +export const XSquareFill: Icon = () => <>BootstrapIconMock_XSquareFill</> +export const XSquare: Icon = () => <>BootstrapIconMock_XSquare</> +export const X: Icon = () => <>BootstrapIconMock_X</> +export const Xbox: Icon = () => <>BootstrapIconMock_Xbox</> +export const Yelp: Icon = () => <>BootstrapIconMock_Yelp</> +export const YinYang: Icon = () => <>BootstrapIconMock_YinYang</> +export const Youtube: Icon = () => <>BootstrapIconMock_Youtube</> +export const ZoomIn: Icon = () => <>BootstrapIconMock_ZoomIn</> +export const ZoomOut: Icon = () => <>BootstrapIconMock_ZoomOut</> diff --git a/frontend/src/test-utils/svg-mock.tsx b/frontend/src/test-utils/svg-mock.tsx new file mode 100644 index 000000000..4ee472b33 --- /dev/null +++ b/frontend/src/test-utils/svg-mock.tsx @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import React from 'react' + +export const ReactComponent: React.FC = (props) => <span data-svg-mock {...props} /> +export default ReactComponent diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index dddb57791..aef3daa9a 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,21 +1,39 @@ { - "compilerOptions": { - "target": "esnext", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "types": ["node", "@testing-library/jest-dom", "@types/jest"] + "compilerOptions" : { + "target" : "esnext", + "lib" : [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs" : true, + "skipLibCheck" : true, + "strict" : true, + "forceConsistentCasingInFileNames" : true, + "noEmit" : true, + "esModuleInterop" : true, + "module" : "esnext", + "moduleResolution" : "node", + "resolveJsonModule" : true, + "isolatedModules" : true, + "jsx" : "preserve", + "incremental" : true, + "types" : [ + "node", + "@testing-library/jest-dom", + "@types/jest" + ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules", "cypress", "cypress.config.ts", ".eslintrc.js"] + "include" : [ + "src/external-types/images/index.d.ts", + "next-env.d.ts", + "**/*.ts", + "**/*.tsx" + ], + "exclude" : [ + "node_modules", + "cypress", + "cypress.config.ts", + ".eslintrc.js" + ] } diff --git a/yarn.lock b/yarn.lock index 197547662..0f49dce09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2432,7 +2432,6 @@ __metadata: fast-deep-equal: 3.1.3 firacode: 6.2.0 flowchart.js: 1.17.1 - fork-awesome: 1.2.0 highlight.js: 11.7.0 htmlparser2: 8.0.1 i18next: 22.4.10 @@ -2463,6 +2462,7 @@ __metadata: prettier: 2.8.4 react: 18.2.0 react-bootstrap: 2.7.2 + react-bootstrap-icons: 1.10.2 react-bootstrap-typeahead: 6.0.0 react-diff-viewer: 3.1.1 react-dom: 18.2.0 @@ -10065,13 +10065,6 @@ __metadata: languageName: node linkType: hard -"fork-awesome@npm:1.2.0": - version: 1.2.0 - resolution: "fork-awesome@npm:1.2.0" - checksum: 473a6452d44020530b4f39d23c87ea3a3bba67390b08b4b9e279b2c79cd17288562403f9d4acdd640c978c7491bf3f3220f5bdbed06221104fee3aa77da84d40 - languageName: node - linkType: hard - "fork-ts-checker-webpack-plugin@npm:7.3.0": version: 7.3.0 resolution: "fork-ts-checker-webpack-plugin@npm:7.3.0" @@ -15390,6 +15383,17 @@ __metadata: languageName: node linkType: hard +"react-bootstrap-icons@npm:1.10.2": + version: 1.10.2 + resolution: "react-bootstrap-icons@npm:1.10.2" + dependencies: + prop-types: ^15.7.2 + peerDependencies: + react: ">=16.8.6" + checksum: eead5ae023a4b1d880fc1b33101fdd64a13b0411e62c4387c0443662be1c7c65f9c1d6ddcf7dc6ba5ee9f5d6a871f4f6b24073c2080e3a3ad901f1140f46abe4 + languageName: node + linkType: hard + "react-bootstrap-typeahead@npm:6.0.0": version: 6.0.0 resolution: "react-bootstrap-typeahead@npm:6.0.0"