diff --git a/.changeset/hungry-cups-applaud.md b/.changeset/hungry-cups-applaud.md new file mode 100644 index 000000000..49ca1ea92 --- /dev/null +++ b/.changeset/hungry-cups-applaud.md @@ -0,0 +1,5 @@ +--- +"@hyperdx/app": patch +--- + +Swap out bootstrap icons for tabler icons across app diff --git a/agent_docs/tech_stack.md b/agent_docs/tech_stack.md index 9540a44c1..403e2cc60 100644 --- a/agent_docs/tech_stack.md +++ b/agent_docs/tech_stack.md @@ -8,6 +8,7 @@ - **Charts/Visualization**: Recharts, uPlot - **Code Editor**: CodeMirror (for SQL/JSON editing) - **Styling**: Mantine's built-in system, SCSS modules when needed +- **Icons**: Use `@tabler/icons-react` **UI Component Priority**: Mantine components first → Custom components on Mantine primitives → Custom SCSS modules as last resort diff --git a/packages/app/.storybook/preview-head.html b/packages/app/.storybook/preview-head.html index fb4d6a073..452c506f9 100644 --- a/packages/app/.storybook/preview-head.html +++ b/packages/app/.storybook/preview-head.html @@ -1,7 +1,3 @@ - {/* eslint-disable-next-line @next/next/no-sync-scripts */} -
diff --git a/packages/app/src/AlertsPage.tsx b/packages/app/src/AlertsPage.tsx index e7ab030f4..bc7ddfdc3 100644 --- a/packages/app/src/AlertsPage.tsx +++ b/packages/app/src/AlertsPage.tsx @@ -20,7 +20,17 @@ import { Tooltip, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; -import { IconBell } from '@tabler/icons-react'; +import { + IconAlertTriangle, + IconBell, + IconBrandSlack, + IconChartLine, + IconCheck, + IconChevronRight, + IconHelpCircle, + IconInfoCircleFilled, + IconTableRow, +} from '@tabler/icons-react'; import { useQueryClient } from '@tanstack/react-query'; import { ErrorBoundary } from '@/components/ErrorBoundary'; @@ -312,7 +322,7 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) { {alert.dashboard?.name} {tileName ? ( <> - + {tileName} ) : null} @@ -338,11 +348,11 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) { const alertIcon = (() => { switch (alert.source) { case AlertSource.TILE: - return 'bi-graph-up'; + return ; case AlertSource.SAVED_SEARCH: - return 'bi-layout-text-sidebar-reverse'; + return ; default: - return 'bi-question'; + return ; } })(); @@ -359,9 +369,9 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) { const notificationMethod = React.useMemo(() => { if (alert.channel.type === 'webhook') { return ( - - Notify via Webhook - + + Notify via Webhook + ); } }, [alert]); @@ -400,8 +410,10 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) { className={styles.alertLink} title={linkTitle} > - - {alertName} + + {alertIcon} + {alertName} +
@@ -435,18 +447,18 @@ function AlertCardList({ alerts }: { alerts: AlertsPageItem[] }) {
{alarmAlerts.length > 0 && (
-
- Triggered -
+ + Triggered + {alarmAlerts.map((alert, index) => ( ))}
)}
-
- OK -
+ + OK + {okData.length === 0 && (
No alerts
)} @@ -472,7 +484,7 @@ export default function AlertsPage() {
} + icon={} color="gray" py="xs" mt="md" diff --git a/packages/app/src/AppNav.components.tsx b/packages/app/src/AppNav.components.tsx index 3a4ec5bf1..994e18bfe 100644 --- a/packages/app/src/AppNav.components.tsx +++ b/packages/app/src/AppNav.components.tsx @@ -14,8 +14,19 @@ import { UnstyledButton, } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; +import { + IconBook, + IconBrandDiscord, + IconBulb, + IconChevronDown, + IconChevronRight, + IconChevronUp, + IconHelp, + IconLogout, + IconSettings, + IconUserCog, +} from '@tabler/icons-react'; -import { Icon } from '@/components/Icon'; import InstallInstructionModal from '@/InstallInstructionsModal'; import { useSources } from '@/source'; @@ -132,7 +143,7 @@ export const AppNavUserMenu = ({
- + )} @@ -146,14 +157,14 @@ export const AppNavUserMenu = ({ data-testid="team-settings-menu-item" href="/team" component={Link} - leftSection={} + leftSection={} > Team Settings )} } + leftSection={} onClick={onClickUserPreferences} > User Preferences @@ -164,7 +175,7 @@ export const AppNavUserMenu = ({ } + leftSection={} component={Link} href={logoutUrl} > @@ -221,7 +232,7 @@ export const AppNavHelpMenu = ({ - + @@ -239,13 +250,13 @@ export const AppNavHelpMenu = ({ data-testid="documentation-menu-item" href="https://clickhouse.com/docs/use-cases/observability/clickstack" component="a" - leftSection={} + leftSection={} > Documentation } + leftSection={} component="a" href="https://hyperdx.io/discord" target="_blank" @@ -254,7 +265,7 @@ export const AppNavHelpMenu = ({ } + leftSection={} onClick={onAddDataClick} > Setup Instructions @@ -321,11 +332,11 @@ export const AppNavLink = ({ size="sm" onClick={onToggle} > - + {isExpanded ? ( + + ) : ( + + )} )} diff --git a/packages/app/src/AppNav.tsx b/packages/app/src/AppNav.tsx index 31de4307d..6bf5f7029 100644 --- a/packages/app/src/AppNav.tsx +++ b/packages/app/src/AppNav.tsx @@ -27,10 +27,15 @@ import { import { useDisclosure, useLocalStorage } from '@mantine/hooks'; import { IconBell, + IconBellFilled, IconChartDots, + IconChevronDown, + IconChevronRight, + IconCommand, IconDeviceLaptop, IconLayoutGrid, IconLayoutSidebarLeftCollapse, + IconSearch, IconSettings, IconSitemap, IconTable, @@ -135,7 +140,7 @@ function SearchInput({ return (
{window.navigator.platform?.toUpperCase().includes('MAC') ? ( - + ) : ( Ctrl )} @@ -161,7 +166,7 @@ function SearchInput({ onChange={(e: React.ChangeEvent) => onChange(e.currentTarget.value) } - leftSection={} + leftSection={} onKeyDown={handleKeyDown} rightSection={ value ? ( @@ -208,7 +213,11 @@ const AppNavGroupLabel = ({ }) => { return (
- + {collapsed ? ( + + ) : ( + + )}
{name}
); @@ -486,20 +495,25 @@ export default function AppNav({ fixed = false }: { fixed?: boolean }) { draggable data-savedsearchid={savedSearch.id} > -
{savedSearch.name}
- {Array.isArray(savedSearch.alerts) && savedSearch.alerts.length > 0 ? ( - savedSearch.alerts.some(a => a.state === AlertState.ALERT) ? ( - - ) : ( - - ) - ) : null} + +
{savedSearch.name}
+ {Array.isArray(savedSearch.alerts) && + savedSearch.alerts.length > 0 ? ( + savedSearch.alerts.some(a => a.state === AlertState.ALERT) ? ( + + ) : ( + + ) + ) : null} +
), [ diff --git a/packages/app/src/AuthPage.tsx b/packages/app/src/AuthPage.tsx index 70f03870f..6434a6177 100644 --- a/packages/app/src/AuthPage.tsx +++ b/packages/app/src/AuthPage.tsx @@ -14,6 +14,7 @@ import { Stack, TextInput, } from '@mantine/core'; +import { IconAt, IconLock } from '@tabler/icons-react'; import api from './api'; import * as config from './config'; @@ -150,7 +151,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) { withAsterisk={false} placeholder="you@company.com" type="email" - leftSection={} + leftSection={} error={errors.email?.message} required {...form.email} @@ -159,7 +160,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) { size="md" label="Password" withAsterisk={false} - leftSection={} + leftSection={} error={errors.password?.message} required placeholder="Password" @@ -179,7 +180,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) { size="md" required withAsterisk={false} - leftSection={} + leftSection={} error={errors.confirmPassword?.message} placeholder="Confirm Password" {...form.confirmPassword} diff --git a/packages/app/src/ClickhousePage.tsx b/packages/app/src/ClickhousePage.tsx index 88585ffeb..2f0e2d439 100644 --- a/packages/app/src/ClickhousePage.tsx +++ b/packages/app/src/ClickhousePage.tsx @@ -22,6 +22,7 @@ import { Text, Tooltip, } from '@mantine/core'; +import { IconRefresh } from '@tabler/icons-react'; import ReactCodeMirror from '@uiw/react-codemirror'; import { ConnectionSelectControlled } from '@/components/ConnectionSelect'; @@ -529,7 +530,7 @@ function ClickhousePage() { aria-label="Refresh dashboard" px="xs" > - + diff --git a/packages/app/src/DBChartPage.tsx b/packages/app/src/DBChartPage.tsx index 44dab3b7a..61ea08710 100644 --- a/packages/app/src/DBChartPage.tsx +++ b/packages/app/src/DBChartPage.tsx @@ -17,6 +17,11 @@ import { Text, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; +import { + IconChevronDown, + IconChevronUp, + IconInfoCircle, +} from '@tabler/icons-react'; import api from '@/api'; import { DEFAULT_CHART_CONFIG, Granularity } from '@/ChartUtils'; @@ -120,7 +125,7 @@ function AIAssistant({ } + icon={} variant="outline" withCloseButton onClose={() => setAlertDismissed(true)} @@ -150,9 +155,9 @@ function AIAssistant({ > {opened ? ( - + ) : ( - + )} AI Assistant [A] diff --git a/packages/app/src/DBDashboardPage.tsx b/packages/app/src/DBDashboardPage.tsx index 5acff88a2..5e16fed07 100644 --- a/packages/app/src/DBDashboardPage.tsx +++ b/packages/app/src/DBDashboardPage.tsx @@ -46,7 +46,19 @@ import { } from '@mantine/core'; import { useHover } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; -import { IconBell, IconFilterEdit, IconPlayerPlay } from '@tabler/icons-react'; +import { + IconBell, + IconCopy, + IconDotsVertical, + IconDownload, + IconFilterEdit, + IconPencil, + IconPlayerPlay, + IconRefresh, + IconTags, + IconTrash, + IconUpload, +} from '@tabler/icons-react'; import { ContactSupportText } from '@/components/ContactSupportText'; import EditTimeChartForm from '@/components/DBEditTimeChartForm'; @@ -277,7 +289,7 @@ const Tile = forwardRef( onClick={onDuplicateClick} title="Duplicate" > - + ) : ( @@ -505,7 +517,7 @@ function DashboardName({ size="xs" onClick={() => setEditing(true)} > - + )}
@@ -944,7 +956,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) { size="xs" style={{ flexShrink: 0 }} > - + {dashboard?.tags?.length || 0}{' '} {dashboard?.tags?.length === 1 ? 'Tag' : 'Tags'} @@ -954,14 +966,14 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) { {hasTiles && ( } + leftSection={} onClick={() => { if (!sources || !dashboard) { notifications.show({ @@ -984,7 +996,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) { )} } + leftSection={} onClick={() => { if (dashboard && !dashboard.tiles.length) { router.push( @@ -998,7 +1010,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) { {hasTiles ? 'Import New Dashboard' : 'Import Dashboard'} } + leftSection={} color="red" onClick={() => deleteDashboard.mutate(dashboard?.id ?? '', { @@ -1097,7 +1109,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) { title="Refresh dashboard" px="xs" > - + diff --git a/packages/app/src/DBSearchPage.tsx b/packages/app/src/DBSearchPage.tsx index 3873e8e94..66d02b747 100644 --- a/packages/app/src/DBSearchPage.tsx +++ b/packages/app/src/DBSearchPage.tsx @@ -60,7 +60,15 @@ import { useDocumentVisibility, } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; -import { IconPlayerPlay } from '@tabler/icons-react'; +import { + IconBolt, + IconCirclePlus, + IconPlayerPlay, + IconPlus, + IconSettings, + IconTags, + IconX, +} from '@tabler/icons-react'; import { useIsFetching } from '@tanstack/react-query'; import { SortingState } from '@tanstack/react-table'; import CodeMirror from '@uiw/react-codemirror'; @@ -381,7 +389,7 @@ function SaveSearchModal({ }} size="xs" > - + } > @@ -395,7 +403,7 @@ function SaveSearchModal({ color="gray" size="xs" > - + Add Tag @@ -1376,7 +1384,7 @@ function DBSearchPage() { title="Edit Source" > - + @@ -1384,7 +1392,7 @@ function DBSearchPage() { Sources } + leftSection={} onClick={() => setNewSourceModalOpened(true)} > Create New Source @@ -1392,7 +1400,7 @@ function DBSearchPage() { {IS_LOCAL_MODE ? ( } + leftSection={} onClick={() => setModelFormExpanded(v => !v)} > Edit Source @@ -1400,7 +1408,7 @@ function DBSearchPage() { ) : ( } + leftSection={} component={Link} href="/team" > @@ -1485,7 +1493,7 @@ function DBSearchPage() { size="xs" style={{ flexShrink: 0 }} > - + {savedSearch.tags?.length || 0} @@ -1755,7 +1763,10 @@ function DBSearchPage() { variant="outline" onClick={handleResumeLiveTail} > - + Resume Live Tail )} diff --git a/packages/app/src/DBSearchPageAlertModal.tsx b/packages/app/src/DBSearchPageAlertModal.tsx index 900a43176..1beb95475 100644 --- a/packages/app/src/DBSearchPageAlertModal.tsx +++ b/packages/app/src/DBSearchPageAlertModal.tsx @@ -28,6 +28,12 @@ import { Text, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; +import { + IconBrandSlack, + IconChartLine, + IconInfoCircleFilled, + IconPlus, +} from '@tabler/icons-react'; import { useQueryClient } from '@tanstack/react-query'; import { useCreateSavedSearch } from '@/savedSearch'; @@ -56,7 +62,7 @@ const SavedSearchAlertFormSchema = z .passthrough(); const CHANNEL_ICONS = { - webhook: , + webhook: , }; const AlertForm = ({ @@ -166,7 +172,7 @@ const AlertForm = ({ {groupBy && thresholdType === AlertThresholdType.BELOW && ( } + icon={} bg="dark" py="xs" > @@ -181,7 +187,7 @@ const AlertForm = ({ - }> + }> Threshold chart @@ -417,7 +423,7 @@ export const DBSearchPageAlertModal = ({ ))} - + New Alert diff --git a/packages/app/src/DOMPlayer.tsx b/packages/app/src/DOMPlayer.tsx index adf79c781..5d50c821e 100644 --- a/packages/app/src/DOMPlayer.tsx +++ b/packages/app/src/DOMPlayer.tsx @@ -4,6 +4,14 @@ import throttle from 'lodash/throttle'; import { useHotkeys } from 'react-hotkeys-hook'; import { Replayer } from 'rrweb'; import { ActionIcon, CopyButton, HoverCard } from '@mantine/core'; +import { + IconArrowsMaximize, + IconCheck, + IconCopy, + IconGlobe, + IconLink, + IconList, +} from '@tabler/icons-react'; import { useRRWebEventStream } from '@/sessions'; import { useDebugMode } from '@/utils'; @@ -43,13 +51,13 @@ const URLHoverCard = memo(({ url }: { url: string }) => { @@ -474,9 +482,9 @@ export default function DOMPlayer({ color="gray" > {playerFullWidth ? ( - + ) : ( - + )} @@ -490,11 +498,7 @@ export default function DOMPlayer({ size="sm" color="gray" > - {copied ? ( - - ) : ( - - )} + {copied ? : } )} diff --git a/packages/app/src/DashboardFiltersModal.tsx b/packages/app/src/DashboardFiltersModal.tsx index 0f75ce13a..eb9e2f820 100644 --- a/packages/app/src/DashboardFiltersModal.tsx +++ b/packages/app/src/DashboardFiltersModal.tsx @@ -20,7 +20,13 @@ import { Tooltip, UnstyledButton, } from '@mantine/core'; -import { IconFilter, IconPencil, IconTrash } from '@tabler/icons-react'; +import { + IconFilter, + IconInfoCircle, + IconPencil, + IconStack, + IconTrash, +} from '@tabler/icons-react'; import SourceSchemaPreview from './components/SourceSchemaPreview'; import { SourceSelectControlled } from './components/SourceSelect'; @@ -55,7 +61,7 @@ const CustomInputWrapper = ({ {label} {tooltipText && ( - + )} {errorMessage && ( @@ -280,7 +286,7 @@ const DashboardFiltersList = ({ - + {sources?.find(s => s.id === filter.source)?.name} @@ -329,7 +335,6 @@ const DashboardFiltersModal = ({ if (opened) { setSelectedFilter(undefined); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [opened]); const handleRemoveFilter = (id: string) => { diff --git a/packages/app/src/HDXMultiSeriesTableChart.tsx b/packages/app/src/HDXMultiSeriesTableChart.tsx index 7bf2662d1..0bd7348ff 100644 --- a/packages/app/src/HDXMultiSeriesTableChart.tsx +++ b/packages/app/src/HDXMultiSeriesTableChart.tsx @@ -1,8 +1,8 @@ -import { memo, useCallback, useMemo, useRef, useState } from 'react'; +import { useCallback, useMemo, useRef, useState } from 'react'; import Link from 'next/link'; import cx from 'classnames'; -import { Flex, Text, UnstyledButton } from '@mantine/core'; -import { IconGripVertical } from '@tabler/icons-react'; +import { UnstyledButton } from '@mantine/core'; +import { IconDownload, IconTextWrap } from '@tabler/icons-react'; import { flexRender, getCoreRowModel, @@ -228,7 +228,7 @@ export const Table = ({ setWrapLinesEnabled(prev => !prev)} > - + - + )} diff --git a/packages/app/src/InstallInstructionsModal.tsx b/packages/app/src/InstallInstructionsModal.tsx index 99fee6046..8f420ca82 100644 --- a/packages/app/src/InstallInstructionsModal.tsx +++ b/packages/app/src/InstallInstructionsModal.tsx @@ -1,5 +1,6 @@ import cx from 'classnames'; -import { Button, Modal } from '@mantine/core'; +import { Button, Group, Modal } from '@mantine/core'; +import { IconClipboard, IconClipboardCheck } from '@tabler/icons-react'; import api from './api'; import Clipboard from './Clipboard'; @@ -29,15 +30,14 @@ function CopyableValue({ {value} -
- + + {isCopied ? ( + + ) : ( + + )} {isCopied ? 'Copied!' : 'Copy'} -
+
); }} diff --git a/packages/app/src/KubernetesDashboardPage.tsx b/packages/app/src/KubernetesDashboardPage.tsx index d9411b92e..05d03946a 100644 --- a/packages/app/src/KubernetesDashboardPage.tsx +++ b/packages/app/src/KubernetesDashboardPage.tsx @@ -24,6 +24,11 @@ import { Tooltip, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; +import { + IconCaretDownFilled, + IconCaretUpFilled, + IconRefresh, +} from '@tabler/icons-react'; import { useVirtualizer } from '@tanstack/react-virtual'; import { TimePicker } from '@/components/TimePicker'; @@ -81,13 +86,12 @@ const Th = React.memo<{ onClick={() => onSort?.(sort === 'asc' ? 'desc' : 'asc')} > {children} - {!!sort && ( - - )} + {!!sort && + (sort === 'asc' ? ( + + ) : ( + + ))} ); }); @@ -1213,7 +1217,7 @@ function KubernetesDashboardPage() { aria-label="Refresh dashboard" px="xs" > - + @@ -1350,7 +1354,7 @@ function KubernetesDashboardPage() { legacyBehavior > - Search + Search */} diff --git a/packages/app/src/LogSidePanelElements.tsx b/packages/app/src/LogSidePanelElements.tsx index 01f5c2a9c..23a4f0a94 100644 --- a/packages/app/src/LogSidePanelElements.tsx +++ b/packages/app/src/LogSidePanelElements.tsx @@ -5,10 +5,15 @@ import cx from 'classnames'; import { format } from 'date-fns'; import { JSONTree } from 'react-json-tree'; import { Alert, Button, CloseButton, Kbd, Text, Tooltip } from '@mantine/core'; +import { + IconChevronDown, + IconChevronRight, + IconCode, + IconPackage, +} from '@tabler/icons-react'; import { ColumnDef, Row, Table } from '@tanstack/react-table'; import HyperJson from './components/HyperJson'; -import { Icon } from './components/Icon'; import { StacktraceFrame as StacktraceFrameCmp } from './components/StacktraceFrame'; import { TableCellButton } from './components/Table'; import { UNDEFINED_WIDTH } from './tableUtils'; @@ -37,7 +42,11 @@ export const CollapsibleSection = ({ role="button" onClick={() => setCollapsed(!collapsed)} > - + {collapsed ? ( + + ) : ( + + )}
{title}
{collapsed ? null :
{children}
} @@ -137,7 +146,11 @@ export const StacktraceRow = ({ withArrow color="gray" > - + )} {augmentedFrame && ( @@ -526,9 +539,9 @@ export const SourceMapsFtux = () => { onClose={() => setIsDismissed(true)} > - Some of the stack frames are pointing to - minified files. Use hyperdx-cli to upload your source maps and see the - original code. + Some of the stack frames are pointing to minified + files. Use hyperdx-cli to upload your source maps and see the original + code. @@ -1491,7 +1497,7 @@ function ServicesDashboardPage() { aria-label="Refresh dashboard" px="xs" > - + diff --git a/packages/app/src/SessionSubpanel.tsx b/packages/app/src/SessionSubpanel.tsx index a38ba6126..ac619af8f 100644 --- a/packages/app/src/SessionSubpanel.tsx +++ b/packages/app/src/SessionSubpanel.tsx @@ -20,6 +20,15 @@ import { SegmentedControl, Tooltip, } from '@mantine/core'; +import { + IconArrowBackUp, + IconArrowForwardUp, + IconArrowsMinimize, + IconPlayerPause, + IconPlayerPlay, + IconToggleLeft, + IconToggleRight, +} from '@tabler/icons-react'; import DBRowSidePanel from '@/components/DBRowSidePanel'; @@ -531,7 +540,7 @@ export default function SessionSubpanel({ setEventsFollowPlayerPosition(!eventsFollowPlayerPosition) } > - + @@ -631,7 +640,7 @@ export default function SessionSubpanel({ onClick={skipBackward} disabled={(focus?.ts || 0) <= minTs} > - + - + {playerState === 'paused' ? ( + + ) : ( + + )} @@ -661,7 +670,7 @@ export default function SessionSubpanel({ onClick={skipForward} disabled={(focus?.ts || 0) >= maxTs} > - + @@ -672,11 +681,11 @@ export default function SessionSubpanel({ variant="light" fw="normal" rightSection={ - + skipInactive ? ( + + ) : ( + + ) } onClick={() => setSkipInactive(!skipInactive)} > diff --git a/packages/app/src/SessionsPage.tsx b/packages/app/src/SessionsPage.tsx index 6a975e2e4..ffad0f7ef 100644 --- a/packages/app/src/SessionsPage.tsx +++ b/packages/app/src/SessionsPage.tsx @@ -36,7 +36,11 @@ import { Text, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; -import { IconPlayerPlay } from '@tabler/icons-react'; +import { + IconDeviceLaptop, + IconInfoCircleFilled, + IconPlayerPlay, +} from '@tabler/icons-react'; import { useVirtualizer } from '@tanstack/react-virtual'; import { SourceSelectControlled } from '@/components/SourceSelect'; @@ -511,7 +515,7 @@ export default function SessionsPage() { <> {sessionSource && sessionSource.kind !== SourceKind.Session && ( } + icon={} color="gray" py="xs" mt="md" @@ -545,7 +549,7 @@ function SessionSetupInstructions() { return ( <> - + Instructions diff --git a/packages/app/src/Spotlights.tsx b/packages/app/src/Spotlights.tsx index 369d1f26b..0cd9b40f9 100644 --- a/packages/app/src/Spotlights.tsx +++ b/packages/app/src/Spotlights.tsx @@ -3,6 +3,19 @@ import * as React from 'react'; import { useRouter } from 'next/router'; import { Spotlight, SpotlightActionData } from '@mantine/spotlight'; +import { + IconActivityHeartbeat, + IconBell, + IconChartLine, + IconDeviceLaptop, + IconGridDots, + IconHelpCircle, + IconLayout, + IconLayoutSidebar, + IconLogs, + IconSearch, + IconSettings, +} from '@tabler/icons-react'; import api from './api'; import Logo from './Icon'; @@ -27,7 +40,7 @@ export const useSpotlightActions = () => { logViewActions.push({ id: logView._id, group: 'Saved searches', - leftSection: , + leftSection: , description: logView.query, label: logView.name, keywords: ['search', 'log', 'saved'], @@ -42,7 +55,7 @@ export const useSpotlightActions = () => { logViewActions.push({ id: dashboard._id, group: 'Dashboards', - leftSection: , + leftSection: , label: dashboard.name, keywords: ['dashboard'], onClick: () => { @@ -55,7 +68,7 @@ export const useSpotlightActions = () => { { id: 'search', group: 'Menu', - leftSection: , + leftSection: , label: 'Search', description: 'Start a new search', keywords: ['log', 'events', 'logs'], @@ -66,7 +79,7 @@ export const useSpotlightActions = () => { { id: 'chart-explorer', group: 'Menu', - leftSection: , + leftSection: , label: 'Chart Explorer', description: 'Explore your data', keywords: ['graph', 'metrics'], @@ -77,7 +90,7 @@ export const useSpotlightActions = () => { { id: 'new-dashboard', group: 'Menu', - leftSection: , + leftSection: , label: 'New Dashboard', description: 'Create a new dashboard', keywords: ['graph'], @@ -88,7 +101,7 @@ export const useSpotlightActions = () => { { id: 'sessions', group: 'Menu', - leftSection: , + leftSection: , label: 'Client Sessions', description: 'View client sessions', keywords: ['browser', 'web'], @@ -99,7 +112,7 @@ export const useSpotlightActions = () => { { id: 'alerts', group: 'Menu', - leftSection: , + leftSection: , label: 'Alerts', description: 'View and manage alerts', onClick: () => { @@ -110,7 +123,7 @@ export const useSpotlightActions = () => { id: 'service-health', group: 'Menu', label: 'Service Health', - leftSection: , + leftSection: , description: 'HTTP, Database and Infrastructure metrics', onClick: () => { router.push('/services'); @@ -119,7 +132,7 @@ export const useSpotlightActions = () => { { id: 'team-settings', group: 'Menu', - leftSection: , + leftSection: , label: 'Team Settings', onClick: () => { @@ -129,7 +142,7 @@ export const useSpotlightActions = () => { { id: 'documentation', group: 'Menu', - leftSection: , + leftSection: , label: 'Documentation', keywords: ['help', 'docs'], onClick: () => { @@ -170,7 +183,7 @@ export const HDXSpotlightProvider = ({ , + leftSection: , placeholder: 'Search', }} nothingFound="Nothing found" diff --git a/packages/app/src/TeamPage.tsx b/packages/app/src/TeamPage.tsx index 3e6972875..c12ec3309 100644 --- a/packages/app/src/TeamPage.tsx +++ b/packages/app/src/TeamPage.tsx @@ -28,7 +28,17 @@ import { } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; -import { IconPencil } from '@tabler/icons-react'; +import { + IconCheck, + IconChevronDown, + IconChevronUp, + IconClipboard, + IconDatabase, + IconHelpCircle, + IconPencil, + IconServer, + IconX, +} from '@tabler/icons-react'; import { ConnectionForm } from '@/components/ConnectionForm'; import SelectControlled from '@/components/SelectControlled'; @@ -84,7 +94,7 @@ function ConnectionsSection() { onClick={() => setEditedConnectionId(c.id)} size="sm" > - Edit + Edit )} {editedConnectionId === c.id && ( @@ -93,7 +103,7 @@ function ConnectionsSection() { onClick={() => setEditedConnectionId(null)} size="sm" > - Cancel + Cancel )} @@ -162,23 +172,27 @@ function SourcesSection() {
{s.name} - {capitalizeFirstLetter(s.kind)} - - - {connections?.find(c => c.id === s.connection)?.name} - - {s.from && ( - <> - - {s.from.databaseName} - { - s.kind === SourceKind.Metric - ? '' - : '.' /** Metrics dont have table names */ - } - {s.from.tableName} - - )} + + {capitalizeFirstLetter(s.kind)} + + + {connections?.find(c => c.id === s.connection)?.name} + + + {s.from && ( + <> + + {s.from.databaseName} + { + s.kind === SourceKind.Metric + ? '' + : '.' /** Metrics dont have table names */ + } + {s.from.tableName} + + )} + +
{editedSourceId !== s.id && ( @@ -187,7 +201,7 @@ function SourcesSection() { onClick={() => setEditedSourceId(s.id)} size="sm" > - + )} {editedSourceId === s.id && ( @@ -196,7 +210,7 @@ function SourcesSection() { onClick={() => setEditedSourceId(null)} size="sm" > - + )} @@ -348,7 +362,7 @@ function IntegrationsSection() { onClick={() => setEditedWebhookId(null)} size="compact-xs" > - Cancel + Cancel )} @@ -472,7 +486,7 @@ function TeamNameSection() { - } - onClick={onDelete} - > + } onClick={onDelete}> Confirm Delete diff --git a/packages/app/src/components/ConnectionSelect.tsx b/packages/app/src/components/ConnectionSelect.tsx index f61dbc7d5..476f25439 100644 --- a/packages/app/src/components/ConnectionSelect.tsx +++ b/packages/app/src/components/ConnectionSelect.tsx @@ -1,5 +1,6 @@ import { useMemo } from 'react'; import { UseControllerProps } from 'react-hook-form'; +import { IconServer } from '@tabler/icons-react'; import SelectControlled from '@/components/SelectControlled'; import { useConnections } from '@/connection'; @@ -28,7 +29,7 @@ export function ConnectionSelectControlled({ comboboxProps={{ withinPortal: false }} searchable placeholder="Connection" - leftSection={} + leftSection={} maxDropdownHeight={280} size={size} /> diff --git a/packages/app/src/components/DBEditTimeChartForm.tsx b/packages/app/src/components/DBEditTimeChartForm.tsx index 35d11017d..cc0ce2847 100644 --- a/packages/app/src/components/DBEditTimeChartForm.tsx +++ b/packages/app/src/components/DBEditTimeChartForm.tsx @@ -40,7 +40,22 @@ import { Text, Textarea, } from '@mantine/core'; -import { IconPlayerPlay } from '@tabler/icons-react'; +import { + IconArrowDown, + IconArrowUp, + IconBell, + IconChartLine, + IconCirclePlus, + IconCode, + IconDotsVertical, + IconLayoutGrid, + IconList, + IconMarkdown, + IconNumbers, + IconPlayerPlay, + IconTable, + IconTrash, +} from '@tabler/icons-react'; import { SortingState } from '@tanstack/react-table'; import { @@ -216,7 +231,7 @@ function ChartSeriesEditorComponent({ onClick={() => onSwapSeries(index, index - 1)} title="Move up" > - + )} {(index ?? -1) < length - 1 && ( @@ -227,7 +242,7 @@ function ChartSeriesEditorComponent({ onClick={() => onSwapSeries(index, index + 1)} title="Move down" > - + )} {((index ?? -1) > 0 || length > 1) && ( @@ -237,7 +252,7 @@ function ChartSeriesEditorComponent({ size="xs" onClick={() => onRemoveSeries(index)} > - + Remove Series )} @@ -700,31 +715,31 @@ export default function EditTimeChartForm({ } + leftSection={} > Line/Bar } + leftSection={} > Table } + leftSection={} > Number } + leftSection={} > Search } + leftSection={} > Markdown @@ -851,7 +866,7 @@ export default function EditTimeChartForm({ }); }} > - + Add Series )} @@ -885,7 +900,7 @@ export default function EditTimeChartForm({ ) } > - + {!alert ? 'Add Alert' : 'Remove Alert'} )} @@ -1070,12 +1085,12 @@ export default function EditTimeChartForm({ } + leftSection={} onClick={() => setSaveToDashboardModalOpen(true)} > Save to Dashboard @@ -1221,7 +1236,7 @@ export default function EditTimeChartForm({ {showSampleEvents && ( - }> + }> Sample Matched Events @@ -1247,7 +1262,7 @@ export default function EditTimeChartForm({ )} - }> + }> Generated SQL diff --git a/packages/app/src/components/DBRowJsonViewer.tsx b/packages/app/src/components/DBRowJsonViewer.tsx index 5cac71a1a..36b705504 100644 --- a/packages/app/src/components/DBRowJsonViewer.tsx +++ b/packages/app/src/components/DBRowJsonViewer.tsx @@ -15,6 +15,17 @@ import { } from '@mantine/core'; import { useDebouncedValue } from '@mantine/hooks'; import { notifications } from '@mantine/notifications'; +import { + IconChartLine, + IconCheck, + IconCopy, + IconFilter, + IconMinus, + IconPlus, + IconSearch, + IconSettings, + IconTextWrap, +} from '@tabler/icons-react'; import HyperJson, { GetLineActions, LineAction } from '@/components/HyperJson'; import { mergePath } from '@/utils'; @@ -81,12 +92,12 @@ function HyperJsonMenu() { setJsonOptions({ ...jsonOptions, lineWrap: !jsonOptions.lineWrap }) } > - + - + @@ -104,7 +115,7 @@ function HyperJsonMenu() { py={8} rightSection={ jsonOptions.normallyExpanded ? ( - + ) : null } > @@ -114,7 +125,9 @@ function HyperJsonMenu() { lh="1" py={8} rightSection={ - jsonOptions.tabulate ? : null + jsonOptions.tabulate ? ( + + ) : null } onClick={() => setJsonOptions({ @@ -183,10 +196,10 @@ export function DBRowJsonViewer({ actions.push({ key: 'add-to-search', label: ( - <> - + + Add to Filters - + ), title: 'Add to Filters', onClick: () => { @@ -226,10 +239,10 @@ export function DBRowJsonViewer({ actions.push({ key: 'search', label: ( - <> - + + Search - + ), title: 'Search for this value only', onClick: () => { @@ -271,7 +284,7 @@ export function DBRowJsonViewer({ if (generateChartUrl && typeof value === 'number') { actions.push({ key: 'chart', - label: , + label: , title: 'Chart', onClick: () => { let chartFieldPath = fieldPath; @@ -317,15 +330,15 @@ export function DBRowJsonViewer({ actions.push({ key: 'toggle-column', label: isIncluded ? ( - <> - + + Column - + ) : ( - <> - + + Column - + ), title: isIncluded ? `Remove ${fieldPath} column from results table` @@ -372,7 +385,12 @@ export function DBRowJsonViewer({ } else { actions.push({ key: 'copy-value', - label: 'Copy Value', + label: ( + + + Copy Value + + ), onClick: () => { window.navigator.clipboard.writeText( typeof value === 'string' @@ -415,7 +433,7 @@ export function DBRowJsonViewer({ onChange={(e: React.ChangeEvent) => setFilter(e.currentTarget.value) } - leftSection={} + leftSection={} /> {filter && ( )} diff --git a/packages/app/src/components/DBRowTable.tsx b/packages/app/src/components/DBRowTable.tsx index 681f58555..a1df3e2ad 100644 --- a/packages/app/src/components/DBRowTable.tsx +++ b/packages/app/src/components/DBRowTable.tsx @@ -49,6 +49,7 @@ import { import { IconCode, IconDownload, + IconRefresh, IconRotateClockwise, IconSettings, IconTextWrap, @@ -272,8 +273,8 @@ const SqlModal = ({ ) : isLoadingSql ? (
-
- +
+
Loading SQL...
@@ -956,8 +957,8 @@ export const RawLogTable = memo(
{isLoading ? (
-
- +
+
{' '} {loadingDate != null && ( <> diff --git a/packages/app/src/components/DBSearchPageFilters.tsx b/packages/app/src/components/DBSearchPageFilters.tsx index 57daea01b..624b497c3 100644 --- a/packages/app/src/components/DBSearchPageFilters.tsx +++ b/packages/app/src/components/DBSearchPageFilters.tsx @@ -29,7 +29,19 @@ import { UnstyledButton, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; -import { IconSearch } from '@tabler/icons-react'; +import { + IconChartBar, + IconChartBarOff, + IconChevronDown, + IconChevronRight, + IconChevronUp, + IconPin, + IconPinFilled, + IconRefresh, + IconSearch, + IconShadow, + IconSitemap, +} from '@tabler/icons-react'; import { useAllFields, @@ -229,13 +241,13 @@ export const FilterCheckbox = ({ )}
} + label={pinned ? : } data-testid={`filter-pin-${label}`} />
{pinned && ( - + )}
@@ -602,9 +614,13 @@ export const FilterGroup = ({ aria-checked={showDistributions} role="checkbox" > - + {isFetchingDistribution ? ( + + ) : showDistributions ? ( + + ) : ( + + )} {onFieldPinClick && ( - + {isFieldPinned ? ( + + ) : ( + + )} )} @@ -729,11 +747,11 @@ export const FilterGroup = ({ label={ shouldShowMore ? ( <> - Less + Less ) : ( <> - Show more + Show more ) } @@ -757,7 +775,7 @@ export const FilterGroup = ({ display={hasLoadedMore ? 'none' : undefined} label={ <> - Load more + Load more } onClick={() => onLoadMore(name)} @@ -1143,8 +1161,9 @@ const DBSearchPageFiltersComponent = ({ {showRefreshButton && ( setDateRange(chartConfig.dateRange)} /> } @@ -1174,8 +1193,14 @@ const DBSearchPageFiltersComponent = ({ withArrow label="Denoise results will visually remove events matching common event patterns from the results table." > - - Denoise Results + + + + Denoise Results + } @@ -1197,8 +1222,14 @@ const DBSearchPageFiltersComponent = ({ withArrow label="Only show root spans (spans with no parent span)." > - - Root Spans Only + + + + Root Spans Only + } @@ -1344,7 +1375,11 @@ const DBSearchPageFiltersComponent = ({ size="compact-xs" loading={isFacetsFetching} rightSection={ - + showMoreFields ? ( + + ) : ( + + ) } onClick={() => setShowMoreFields(!showMoreFields)} > diff --git a/packages/app/src/components/DBTableSelect.tsx b/packages/app/src/components/DBTableSelect.tsx index a9e66002d..2db5cf4d9 100644 --- a/packages/app/src/components/DBTableSelect.tsx +++ b/packages/app/src/components/DBTableSelect.tsx @@ -1,5 +1,6 @@ import { useController, UseControllerProps } from 'react-hook-form'; import { Flex, Select } from '@mantine/core'; +import { IconTable } from '@tabler/icons-react'; import { useTablesDirect } from '@/clickhouse'; @@ -55,7 +56,7 @@ export default function DBTableSelect({ } + leftSection={} maxDropdownHeight={280} data={data} disabled={isDatabasesLoading} diff --git a/packages/app/src/components/ErrorBoundary.tsx b/packages/app/src/components/ErrorBoundary.tsx index bb252f311..29c25c13f 100644 --- a/packages/app/src/components/ErrorBoundary.tsx +++ b/packages/app/src/components/ErrorBoundary.tsx @@ -1,8 +1,7 @@ import React from 'react'; import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary'; import { Alert, Button, Stack, Text } from '@mantine/core'; - -import { Icon } from './Icon'; +import { IconInfoCircleFilled } from '@tabler/icons-react'; type ErrorBoundaryProps = { children: React.ReactNode; @@ -33,7 +32,7 @@ export const ErrorBoundary = ({ } + icon={} title={message || 'Something went wrong'} > {(showErrorMessage || showRetry) && ( diff --git a/packages/app/src/components/EventTag.tsx b/packages/app/src/components/EventTag.tsx index ec2315bed..318e597c6 100644 --- a/packages/app/src/components/EventTag.tsx +++ b/packages/app/src/components/EventTag.tsx @@ -3,7 +3,7 @@ import Link from 'next/link'; import SqlString from 'sqlstring'; import { SearchConditionLanguage } from '@hyperdx/common-utils/dist/types'; import { Button, Group, Popover, Stack, Text, Tooltip } from '@mantine/core'; -import { IconLink } from '@tabler/icons-react'; +import { IconCirclePlus, IconLink, IconSearch } from '@tabler/icons-react'; import { isLinkableUrl } from '@/utils/highlightedAttributes'; @@ -103,7 +103,7 @@ export default function EventTag({ color="gray" variant="subtle" size="xs" - rightSection={} + rightSection={} onClick={() => { onPropertyAddClick(sqlExpression, value); setOpened(false); @@ -123,7 +123,7 @@ export default function EventTag({ color="gray" variant="subtle" size="xs" - rightSection={} + rightSection={} > Search This Value diff --git a/packages/app/src/components/ExceptionSubpanel.tsx b/packages/app/src/components/ExceptionSubpanel.tsx index 8d78b0343..5f590282a 100644 --- a/packages/app/src/components/ExceptionSubpanel.tsx +++ b/packages/app/src/components/ExceptionSubpanel.tsx @@ -3,6 +3,12 @@ import cx from 'classnames'; import { ErrorBoundary } from 'react-error-boundary'; import { Button, Text, Tooltip } from '@mantine/core'; import { Group, Loader } from '@mantine/core'; +import { + IconChevronDown, + IconChevronRight, + IconChevronUp, + IconLogs, +} from '@tabler/icons-react'; import { ColumnDef, Row, Table as TanstackTable } from '@tanstack/react-table'; import { StacktraceFrame as TStacktraceFrame } from '@/types'; @@ -126,7 +132,11 @@ export const CollapsibleSection = ({ role="button" onClick={() => setCollapsed(!collapsed)} > - + {collapsed ? ( + + ) : ( + + )}
{title}
{collapsed ? null :
{children}
} @@ -226,7 +236,7 @@ export const StacktraceRow = ({ withArrow color="gray" > - + )} {augmentedFrame && ( @@ -618,11 +628,11 @@ export const ExceptionSubpanel = ({ > {stacktraceExpanded ? ( <> - Hide stack trace + Hide stack trace ) : ( <> - + Show {stacktraceHiddenRowsCount} more frames )} @@ -647,11 +657,12 @@ export const ExceptionSubpanel = ({ > {breadcrumbExpanded ? ( <> - Hide breadcrumbs + Hide + breadcrumbs ) : ( <> - + Show {breadcrumbHiddenRowsCount} more breadcrumbs )} diff --git a/packages/app/src/components/ExpandableRowTable.tsx b/packages/app/src/components/ExpandableRowTable.tsx index a2ac254b2..1eab24b2a 100644 --- a/packages/app/src/components/ExpandableRowTable.tsx +++ b/packages/app/src/components/ExpandableRowTable.tsx @@ -2,7 +2,7 @@ import React, { memo, useCallback, useState } from 'react'; import cx from 'classnames'; import { useQueryState } from 'nuqs'; import { TSource } from '@hyperdx/common-utils/dist/types'; -import { IconChevronRight } from '@tabler/icons-react'; +import { IconArrowsMaximize, IconChevronRight } from '@tabler/icons-react'; import styles from '../../styles/LogTable.module.scss'; @@ -68,7 +68,7 @@ export const ExpandedLogRow = memo( lineHeight: 1, }} > - + )} {children} diff --git a/packages/app/src/components/HyperJson.tsx b/packages/app/src/components/HyperJson.tsx index a691afeff..ac214bb96 100644 --- a/packages/app/src/components/HyperJson.tsx +++ b/packages/app/src/components/HyperJson.tsx @@ -11,6 +11,11 @@ import { isString, } from 'lodash'; import { useHover } from '@mantine/hooks'; +import { + IconCaretDownFilled, + IconCaretRightFilled, + IconClipboard, +} from '@tabler/icons-react'; import styles from './HyperJson.module.scss'; @@ -264,13 +269,13 @@ const Line = React.memo(
{isExpandable && (isExpanded ? ( - + ) : ( - + ))} {keyName}
- +
diff --git a/packages/app/src/components/Icon.tsx b/packages/app/src/components/Icon.tsx deleted file mode 100644 index 2f3812984..000000000 --- a/packages/app/src/components/Icon.tsx +++ /dev/null @@ -1,2064 +0,0 @@ -import React from 'react'; - -type IconName = - | '0-circle-fill' - | '0-circle' - | '0-square-fill' - | '0-square' - | '1-circle-fill' - | '1-circle' - | '1-square-fill' - | '1-square' - | '123' - | '2-circle-fill' - | '2-circle' - | '2-square-fill' - | '2-square' - | '3-circle-fill' - | '3-circle' - | '3-square-fill' - | '3-square' - | '4-circle-fill' - | '4-circle' - | '4-square-fill' - | '4-square' - | '5-circle-fill' - | '5-circle' - | '5-square-fill' - | '5-square' - | '6-circle-fill' - | '6-circle' - | '6-square-fill' - | '6-square' - | '7-circle-fill' - | '7-circle' - | '7-square-fill' - | '7-square' - | '8-circle-fill' - | '8-circle' - | '8-square-fill' - | '8-square' - | '9-circle-fill' - | '9-circle' - | '9-square-fill' - | '9-square' - | 'activity' - | 'airplane-engines-fill' - | 'airplane-engines' - | 'airplane-fill' - | 'airplane' - | 'alarm-fill' - | 'alarm' - | 'alexa' - | 'align-bottom' - | 'align-center' - | 'align-end' - | 'align-middle' - | 'align-start' - | 'align-top' - | 'alipay' - | 'alphabet-uppercase' - | 'alphabet' - | 'alt' - | 'amazon' - | 'amd' - | 'android' - | 'android2' - | 'app-indicator' - | 'app' - | 'apple' - | 'archive-fill' - | 'archive' - | 'arrow-90deg-down' - | 'arrow-90deg-left' - | 'arrow-90deg-right' - | 'arrow-90deg-up' - | 'arrow-bar-down' - | 'arrow-bar-left' - | 'arrow-bar-right' - | 'arrow-bar-up' - | 'arrow-clockwise' - | 'arrow-counterclockwise' - | 'arrow-down-circle-fill' - | 'arrow-down-circle' - | 'arrow-down-left-circle-fill' - | 'arrow-down-left-circle' - | 'arrow-down-left-square-fill' - | 'arrow-down-left-square' - | 'arrow-down-left' - | 'arrow-down-right-circle-fill' - | 'arrow-down-right-circle' - | 'arrow-down-right-square-fill' - | 'arrow-down-right-square' - | 'arrow-down-right' - | 'arrow-down-short' - | 'arrow-down-square-fill' - | 'arrow-down-square' - | 'arrow-down-up' - | 'arrow-down' - | 'arrow-left-circle-fill' - | 'arrow-left-circle' - | 'arrow-left-right' - | 'arrow-left-short' - | 'arrow-left-square-fill' - | 'arrow-left-square' - | 'arrow-left' - | 'arrow-repeat' - | 'arrow-return-left' - | 'arrow-return-right' - | 'arrow-right-circle-fill' - | 'arrow-right-circle' - | 'arrow-right-short' - | 'arrow-right-square-fill' - | 'arrow-right-square' - | 'arrow-right' - | 'arrow-through-heart-fill' - | 'arrow-through-heart' - | 'arrow-up-circle-fill' - | 'arrow-up-circle' - | 'arrow-up-left-circle-fill' - | 'arrow-up-left-circle' - | 'arrow-up-left-square-fill' - | 'arrow-up-left-square' - | 'arrow-up-left' - | 'arrow-up-right-circle-fill' - | 'arrow-up-right-circle' - | 'arrow-up-right-square-fill' - | 'arrow-up-right-square' - | 'arrow-up-right' - | 'arrow-up-short' - | 'arrow-up-square-fill' - | 'arrow-up-square' - | 'arrow-up' - | 'arrows-angle-contract' - | 'arrows-angle-expand' - | 'arrows-collapse-vertical' - | 'arrows-collapse' - | 'arrows-expand-vertical' - | 'arrows-expand' - | 'arrows-fullscreen' - | 'arrows-move' - | 'arrows-vertical' - | 'arrows' - | 'aspect-ratio-fill' - | 'aspect-ratio' - | 'asterisk' - | 'at' - | 'award-fill' - | 'award' - | 'back' - | 'backpack-fill' - | 'backpack' - | 'backpack2-fill' - | 'backpack2' - | 'backpack3-fill' - | 'backpack3' - | 'backpack4-fill' - | 'backpack4' - | 'backspace-fill' - | 'backspace-reverse-fill' - | 'backspace-reverse' - | 'backspace' - | 'badge-3d-fill' - | 'badge-3d' - | 'badge-4k-fill' - | 'badge-4k' - | 'badge-8k-fill' - | 'badge-8k' - | 'badge-ad-fill' - | 'badge-ad' - | 'badge-ar-fill' - | 'badge-ar' - | 'badge-cc-fill' - | 'badge-cc' - | 'badge-hd-fill' - | 'badge-hd' - | 'badge-sd-fill' - | 'badge-sd' - | 'badge-tm-fill' - | 'badge-tm' - | 'badge-vo-fill' - | 'badge-vo' - | 'badge-vr-fill' - | 'badge-vr' - | 'badge-wc-fill' - | 'badge-wc' - | 'bag-check-fill' - | 'bag-check' - | 'bag-dash-fill' - | 'bag-dash' - | 'bag-fill' - | 'bag-heart-fill' - | 'bag-heart' - | 'bag-plus-fill' - | 'bag-plus' - | 'bag-x-fill' - | 'bag-x' - | 'bag' - | 'balloon-fill' - | 'balloon-heart-fill' - | 'balloon-heart' - | 'balloon' - | 'ban-fill' - | 'ban' - | 'bandaid-fill' - | 'bandaid' - | 'bank' - | 'bank2' - | 'bar-chart-fill' - | 'bar-chart-line-fill' - | 'bar-chart-line' - | 'bar-chart-steps' - | 'bar-chart' - | 'basket-fill' - | 'basket' - | 'basket2-fill' - | 'basket2' - | 'basket3-fill' - | 'basket3' - | 'battery-charging' - | 'battery-full' - | 'battery-half' - | 'battery' - | 'behance' - | 'bell-fill' - | 'bell-slash-fill' - | 'bell-slash' - | 'bell' - | 'bezier' - | 'bezier2' - | 'bicycle' - | 'bing' - | 'binoculars-fill' - | 'binoculars' - | 'blockquote-left' - | 'blockquote-right' - | 'bluetooth' - | 'body-text' - | 'book-fill' - | 'book-half' - | 'book' - | 'bookmark-check-fill' - | 'bookmark-check' - | 'bookmark-dash-fill' - | 'bookmark-dash' - | 'bookmark-fill' - | 'bookmark-heart-fill' - | 'bookmark-heart' - | 'bookmark-plus-fill' - | 'bookmark-plus' - | 'bookmark-star-fill' - | 'bookmark-star' - | 'bookmark-x-fill' - | 'bookmark-x' - | 'bookmark' - | 'bookmarks-fill' - | 'bookmarks' - | 'bookshelf' - | 'boombox-fill' - | 'boombox' - | 'bootstrap-fill' - | 'bootstrap-reboot' - | 'bootstrap' - | 'border-all' - | 'border-bottom' - | 'border-center' - | 'border-inner' - | 'border-left' - | 'border-middle' - | 'border-outer' - | 'border-right' - | 'border-style' - | 'border-top' - | 'border-width' - | 'border' - | 'bounding-box-circles' - | 'bounding-box' - | 'box-arrow-down-left' - | 'box-arrow-down-right' - | 'box-arrow-down' - | 'box-arrow-in-down-left' - | 'box-arrow-in-down-right' - | 'box-arrow-in-down' - | 'box-arrow-in-left' - | 'box-arrow-in-right' - | 'box-arrow-in-up-left' - | 'box-arrow-in-up-right' - | 'box-arrow-in-up' - | 'box-arrow-left' - | 'box-arrow-right' - | 'box-arrow-up-left' - | 'box-arrow-up-right' - | 'box-arrow-up' - | 'box-fill' - | 'box-seam-fill' - | 'box-seam' - | 'box' - | 'box2-fill' - | 'box2-heart-fill' - | 'box2-heart' - | 'box2' - | 'boxes' - | 'braces-asterisk' - | 'braces' - | 'bricks' - | 'briefcase-fill' - | 'briefcase' - | 'brightness-alt-high-fill' - | 'brightness-alt-high' - | 'brightness-alt-low-fill' - | 'brightness-alt-low' - | 'brightness-high-fill' - | 'brightness-high' - | 'brightness-low-fill' - | 'brightness-low' - | 'brilliance' - | 'broadcast-pin' - | 'broadcast' - | 'browser-chrome' - | 'browser-edge' - | 'browser-firefox' - | 'browser-safari' - | 'brush-fill' - | 'brush' - | 'bucket-fill' - | 'bucket' - | 'bug-fill' - | 'bug' - | 'building-add' - | 'building-check' - | 'building-dash' - | 'building-down' - | 'building-exclamation' - | 'building-fill-add' - | 'building-fill-check' - | 'building-fill-dash' - | 'building-fill-down' - | 'building-fill-exclamation' - | 'building-fill-gear' - | 'building-fill-lock' - | 'building-fill-slash' - | 'building-fill-up' - | 'building-fill-x' - | 'building-fill' - | 'building-gear' - | 'building-lock' - | 'building-slash' - | 'building-up' - | 'building-x' - | 'building' - | 'buildings-fill' - | 'buildings' - | 'bullseye' - | 'bus-front-fill' - | 'bus-front' - | 'c-circle-fill' - | 'c-circle' - | 'c-square-fill' - | 'c-square' - | 'cake-fill' - | 'cake' - | 'cake2-fill' - | 'cake2' - | 'calculator-fill' - | 'calculator' - | 'calendar-check-fill' - | 'calendar-check' - | 'calendar-date-fill' - | 'calendar-date' - | 'calendar-day-fill' - | 'calendar-day' - | 'calendar-event-fill' - | 'calendar-event' - | 'calendar-fill' - | 'calendar-heart-fill' - | 'calendar-heart' - | 'calendar-minus-fill' - | 'calendar-minus' - | 'calendar-month-fill' - | 'calendar-month' - | 'calendar-plus-fill' - | 'calendar-plus' - | 'calendar-range-fill' - | 'calendar-range' - | 'calendar-week-fill' - | 'calendar-week' - | 'calendar-x-fill' - | 'calendar-x' - | 'calendar' - | 'calendar2-check-fill' - | 'calendar2-check' - | 'calendar2-date-fill' - | 'calendar2-date' - | 'calendar2-day-fill' - | 'calendar2-day' - | 'calendar2-event-fill' - | 'calendar2-event' - | 'calendar2-fill' - | 'calendar2-heart-fill' - | 'calendar2-heart' - | 'calendar2-minus-fill' - | 'calendar2-minus' - | 'calendar2-month-fill' - | 'calendar2-month' - | 'calendar2-plus-fill' - | 'calendar2-plus' - | 'calendar2-range-fill' - | 'calendar2-range' - | 'calendar2-week-fill' - | 'calendar2-week' - | 'calendar2-x-fill' - | 'calendar2-x' - | 'calendar2' - | 'calendar3-event-fill' - | 'calendar3-event' - | 'calendar3-fill' - | 'calendar3-range-fill' - | 'calendar3-range' - | 'calendar3-week-fill' - | 'calendar3-week' - | 'calendar3' - | 'calendar4-event' - | 'calendar4-range' - | 'calendar4-week' - | 'calendar4' - | 'camera-fill' - | 'camera-reels-fill' - | 'camera-reels' - | 'camera-video-fill' - | 'camera-video-off-fill' - | 'camera-video-off' - | 'camera-video' - | 'camera' - | 'camera2' - | 'capslock-fill' - | 'capslock' - | 'capsule-pill' - | 'capsule' - | 'car-front-fill' - | 'car-front' - | 'card-checklist' - | 'card-heading' - | 'card-image' - | 'card-list' - | 'card-text' - | 'caret-down-fill' - | 'caret-down-square-fill' - | 'caret-down-square' - | 'caret-down' - | 'caret-left-fill' - | 'caret-left-square-fill' - | 'caret-left-square' - | 'caret-left' - | 'caret-right-fill' - | 'caret-right-square-fill' - | 'caret-right-square' - | 'caret-right' - | 'caret-up-fill' - | 'caret-up-square-fill' - | 'caret-up-square' - | 'caret-up' - | 'cart-check-fill' - | 'cart-check' - | 'cart-dash-fill' - | 'cart-dash' - | 'cart-fill' - | 'cart-plus-fill' - | 'cart-plus' - | 'cart-x-fill' - | 'cart-x' - | 'cart' - | 'cart2' - | 'cart3' - | 'cart4' - | 'cash-coin' - | 'cash-stack' - | 'cash' - | 'cassette-fill' - | 'cassette' - | 'cast' - | 'cc-circle-fill' - | 'cc-circle' - | 'cc-square-fill' - | 'cc-square' - | 'chat-dots-fill' - | 'chat-dots' - | 'chat-fill' - | 'chat-heart-fill' - | 'chat-heart' - | 'chat-left-dots-fill' - | 'chat-left-dots' - | 'chat-left-fill' - | 'chat-left-heart-fill' - | 'chat-left-heart' - | 'chat-left-quote-fill' - | 'chat-left-quote' - | 'chat-left-text-fill' - | 'chat-left-text' - | 'chat-left' - | 'chat-quote-fill' - | 'chat-quote' - | 'chat-right-dots-fill' - | 'chat-right-dots' - | 'chat-right-fill' - | 'chat-right-heart-fill' - | 'chat-right-heart' - | 'chat-right-quote-fill' - | 'chat-right-quote' - | 'chat-right-text-fill' - | 'chat-right-text' - | 'chat-right' - | 'chat-square-dots-fill' - | 'chat-square-dots' - | 'chat-square-fill' - | 'chat-square-heart-fill' - | 'chat-square-heart' - | 'chat-square-quote-fill' - | 'chat-square-quote' - | 'chat-square-text-fill' - | 'chat-square-text' - | 'chat-square' - | 'chat-text-fill' - | 'chat-text' - | 'chat' - | 'check-all' - | 'check-circle-fill' - | 'check-circle' - | 'check-lg' - | 'check-square-fill' - | 'check-square' - | 'check' - | 'check2-all' - | 'check2-circle' - | 'check2-square' - | 'check2' - | 'chevron-bar-contract' - | 'chevron-bar-down' - | 'chevron-bar-expand' - | 'chevron-bar-left' - | 'chevron-bar-right' - | 'chevron-bar-up' - | 'chevron-compact-down' - | 'chevron-compact-left' - | 'chevron-compact-right' - | 'chevron-compact-up' - | 'chevron-contract' - | 'chevron-double-down' - | 'chevron-double-left' - | 'chevron-double-right' - | 'chevron-double-up' - | 'chevron-down' - | 'chevron-expand' - | 'chevron-left' - | 'chevron-right' - | 'chevron-up' - | 'circle-fill' - | 'circle-half' - | 'circle-square' - | 'circle' - | 'clipboard-check-fill' - | 'clipboard-check' - | 'clipboard-data-fill' - | 'clipboard-data' - | 'clipboard-fill' - | 'clipboard-heart-fill' - | 'clipboard-heart' - | 'clipboard-minus-fill' - | 'clipboard-minus' - | 'clipboard-plus-fill' - | 'clipboard-plus' - | 'clipboard-pulse' - | 'clipboard-x-fill' - | 'clipboard-x' - | 'clipboard' - | 'clipboard2-check-fill' - | 'clipboard2-check' - | 'clipboard2-data-fill' - | 'clipboard2-data' - | 'clipboard2-fill' - | 'clipboard2-heart-fill' - | 'clipboard2-heart' - | 'clipboard2-minus-fill' - | 'clipboard2-minus' - | 'clipboard2-plus-fill' - | 'clipboard2-plus' - | 'clipboard2-pulse-fill' - | 'clipboard2-pulse' - | 'clipboard2-x-fill' - | 'clipboard2-x' - | 'clipboard2' - | 'clock-fill' - | 'clock-history' - | 'clock' - | 'cloud-arrow-down-fill' - | 'cloud-arrow-down' - | 'cloud-arrow-up-fill' - | 'cloud-arrow-up' - | 'cloud-check-fill' - | 'cloud-check' - | 'cloud-download-fill' - | 'cloud-download' - | 'cloud-drizzle-fill' - | 'cloud-drizzle' - | 'cloud-fill' - | 'cloud-fog-fill' - | 'cloud-fog' - | 'cloud-fog2-fill' - | 'cloud-fog2' - | 'cloud-hail-fill' - | 'cloud-hail' - | 'cloud-haze-fill' - | 'cloud-haze' - | 'cloud-haze2-fill' - | 'cloud-haze2' - | 'cloud-lightning-fill' - | 'cloud-lightning-rain-fill' - | 'cloud-lightning-rain' - | 'cloud-lightning' - | 'cloud-minus-fill' - | 'cloud-minus' - | 'cloud-moon-fill' - | 'cloud-moon' - | 'cloud-plus-fill' - | 'cloud-plus' - | 'cloud-rain-fill' - | 'cloud-rain-heavy-fill' - | 'cloud-rain-heavy' - | 'cloud-rain' - | 'cloud-slash-fill' - | 'cloud-slash' - | 'cloud-sleet-fill' - | 'cloud-sleet' - | 'cloud-snow-fill' - | 'cloud-snow' - | 'cloud-sun-fill' - | 'cloud-sun' - | 'cloud-upload-fill' - | 'cloud-upload' - | 'cloud' - | 'clouds-fill' - | 'clouds' - | 'cloudy-fill' - | 'cloudy' - | 'code-slash' - | 'code-square' - | 'code' - | 'coin' - | 'collection-fill' - | 'collection-play-fill' - | 'collection-play' - | 'collection' - | 'columns-gap' - | 'columns' - | 'command' - | 'compass-fill' - | 'compass' - | 'cone-striped' - | 'cone' - | 'controller' - | 'cookie' - | 'copy' - | 'cpu-fill' - | 'cpu' - | 'credit-card-2-back-fill' - | 'credit-card-2-back' - | 'credit-card-2-front-fill' - | 'credit-card-2-front' - | 'credit-card-fill' - | 'credit-card' - | 'crop' - | 'crosshair' - | 'crosshair2' - | 'cup-fill' - | 'cup-hot-fill' - | 'cup-hot' - | 'cup-straw' - | 'cup' - | 'currency-bitcoin' - | 'currency-dollar' - | 'currency-euro' - | 'currency-exchange' - | 'currency-pound' - | 'currency-rupee' - | 'currency-yen' - | 'cursor-fill' - | 'cursor-text' - | 'cursor' - | 'dash-circle-dotted' - | 'dash-circle-fill' - | 'dash-circle' - | 'dash-lg' - | 'dash-square-dotted' - | 'dash-square-fill' - | 'dash-square' - | 'dash' - | 'database-add' - | 'database-check' - | 'database-dash' - | 'database-down' - | 'database-exclamation' - | 'database-fill-add' - | 'database-fill-check' - | 'database-fill-dash' - | 'database-fill-down' - | 'database-fill-exclamation' - | 'database-fill-gear' - | 'database-fill-lock' - | 'database-fill-slash' - | 'database-fill-up' - | 'database-fill-x' - | 'database-fill' - | 'database-gear' - | 'database-lock' - | 'database-slash' - | 'database-up' - | 'database-x' - | 'database' - | 'device-hdd-fill' - | 'device-hdd' - | 'device-ssd-fill' - | 'device-ssd' - | 'diagram-2-fill' - | 'diagram-2' - | 'diagram-3-fill' - | 'diagram-3' - | 'diamond-fill' - | 'diamond-half' - | 'diamond' - | 'dice-1-fill' - | 'dice-1' - | 'dice-2-fill' - | 'dice-2' - | 'dice-3-fill' - | 'dice-3' - | 'dice-4-fill' - | 'dice-4' - | 'dice-5-fill' - | 'dice-5' - | 'dice-6-fill' - | 'dice-6' - | 'disc-fill' - | 'disc' - | 'discord' - | 'display-fill' - | 'display' - | 'displayport-fill' - | 'displayport' - | 'distribute-horizontal' - | 'distribute-vertical' - | 'door-closed-fill' - | 'door-closed' - | 'door-open-fill' - | 'door-open' - | 'dot' - | 'download' - | 'dpad-fill' - | 'dpad' - | 'dribbble' - | 'dropbox' - | 'droplet-fill' - | 'droplet-half' - | 'droplet' - | 'duffle-fill' - | 'duffle' - | 'ear-fill' - | 'ear' - | 'earbuds' - | 'easel-fill' - | 'easel' - | 'easel2-fill' - | 'easel2' - | 'easel3-fill' - | 'easel3' - | 'egg-fill' - | 'egg-fried' - | 'egg' - | 'eject-fill' - | 'eject' - | 'emoji-angry-fill' - | 'emoji-angry' - | 'emoji-astonished-fill' - | 'emoji-astonished' - | 'emoji-dizzy-fill' - | 'emoji-dizzy' - | 'emoji-expressionless-fill' - | 'emoji-expressionless' - | 'emoji-frown-fill' - | 'emoji-frown' - | 'emoji-grimace-fill' - | 'emoji-grimace' - | 'emoji-grin-fill' - | 'emoji-grin' - | 'emoji-heart-eyes-fill' - | 'emoji-heart-eyes' - | 'emoji-kiss-fill' - | 'emoji-kiss' - | 'emoji-laughing-fill' - | 'emoji-laughing' - | 'emoji-neutral-fill' - | 'emoji-neutral' - | 'emoji-smile-fill' - | 'emoji-smile-upside-down-fill' - | 'emoji-smile-upside-down' - | 'emoji-smile' - | 'emoji-sunglasses-fill' - | 'emoji-sunglasses' - | 'emoji-surprise-fill' - | 'emoji-surprise' - | 'emoji-tear-fill' - | 'emoji-tear' - | 'emoji-wink-fill' - | 'emoji-wink' - | 'envelope-arrow-down-fill' - | 'envelope-arrow-down' - | 'envelope-arrow-up-fill' - | 'envelope-arrow-up' - | 'envelope-at-fill' - | 'envelope-at' - | 'envelope-check-fill' - | 'envelope-check' - | 'envelope-dash-fill' - | 'envelope-dash' - | 'envelope-exclamation-fill' - | 'envelope-exclamation' - | 'envelope-fill' - | 'envelope-heart-fill' - | 'envelope-heart' - | 'envelope-open-fill' - | 'envelope-open-heart-fill' - | 'envelope-open-heart' - | 'envelope-open' - | 'envelope-paper-fill' - | 'envelope-paper-heart-fill' - | 'envelope-paper-heart' - | 'envelope-paper' - | 'envelope-plus-fill' - | 'envelope-plus' - | 'envelope-slash-fill' - | 'envelope-slash' - | 'envelope-x-fill' - | 'envelope-x' - | 'envelope' - | 'eraser-fill' - | 'eraser' - | 'escape' - | 'ethernet' - | 'ev-front-fill' - | 'ev-front' - | 'ev-station-fill' - | 'ev-station' - | 'exclamation-circle-fill' - | 'exclamation-circle' - | 'exclamation-diamond-fill' - | 'exclamation-diamond' - | 'exclamation-lg' - | 'exclamation-octagon-fill' - | 'exclamation-octagon' - | 'exclamation-square-fill' - | 'exclamation-square' - | 'exclamation-triangle-fill' - | 'exclamation-triangle' - | 'exclamation' - | 'exclude' - | 'explicit-fill' - | 'explicit' - | 'exposure' - | 'eye-fill' - | 'eye-slash-fill' - | 'eye-slash' - | 'eye' - | 'eyedropper' - | 'eyeglasses' - | 'facebook' - | 'fan' - | 'fast-forward-btn-fill' - | 'fast-forward-btn' - | 'fast-forward-circle-fill' - | 'fast-forward-circle' - | 'fast-forward-fill' - | 'fast-forward' - | 'feather' - | 'feather2' - | 'file-arrow-down-fill' - | 'file-arrow-down' - | 'file-arrow-up-fill' - | 'file-arrow-up' - | 'file-bar-graph-fill' - | 'file-bar-graph' - | 'file-binary-fill' - | 'file-binary' - | 'file-break-fill' - | 'file-break' - | 'file-check-fill' - | 'file-check' - | 'file-code-fill' - | 'file-code' - | 'file-diff-fill' - | 'file-diff' - | 'file-earmark-arrow-down-fill' - | 'file-earmark-arrow-down' - | 'file-earmark-arrow-up-fill' - | 'file-earmark-arrow-up' - | 'file-earmark-bar-graph-fill' - | 'file-earmark-bar-graph' - | 'file-earmark-binary-fill' - | 'file-earmark-binary' - | 'file-earmark-break-fill' - | 'file-earmark-break' - | 'file-earmark-check-fill' - | 'file-earmark-check' - | 'file-earmark-code-fill' - | 'file-earmark-code' - | 'file-earmark-diff-fill' - | 'file-earmark-diff' - | 'file-earmark-easel-fill' - | 'file-earmark-easel' - | 'file-earmark-excel-fill' - | 'file-earmark-excel' - | 'file-earmark-fill' - | 'file-earmark-font-fill' - | 'file-earmark-font' - | 'file-earmark-image-fill' - | 'file-earmark-image' - | 'file-earmark-lock-fill' - | 'file-earmark-lock' - | 'file-earmark-lock2-fill' - | 'file-earmark-lock2' - | 'file-earmark-medical-fill' - | 'file-earmark-medical' - | 'file-earmark-minus-fill' - | 'file-earmark-minus' - | 'file-earmark-music-fill' - | 'file-earmark-music' - | 'file-earmark-pdf-fill' - | 'file-earmark-pdf' - | 'file-earmark-person-fill' - | 'file-earmark-person' - | 'file-earmark-play-fill' - | 'file-earmark-play' - | 'file-earmark-plus-fill' - | 'file-earmark-plus' - | 'file-earmark-post-fill' - | 'file-earmark-post' - | 'file-earmark-ppt-fill' - | 'file-earmark-ppt' - | 'file-earmark-richtext-fill' - | 'file-earmark-richtext' - | 'file-earmark-ruled-fill' - | 'file-earmark-ruled' - | 'file-earmark-slides-fill' - | 'file-earmark-slides' - | 'file-earmark-spreadsheet-fill' - | 'file-earmark-spreadsheet' - | 'file-earmark-text-fill' - | 'file-earmark-text' - | 'file-earmark-word-fill' - | 'file-earmark-word' - | 'file-earmark-x-fill' - | 'file-earmark-x' - | 'file-earmark-zip-fill' - | 'file-earmark-zip' - | 'file-earmark' - | 'file-easel-fill' - | 'file-easel' - | 'file-excel-fill' - | 'file-excel' - | 'file-fill' - | 'file-font-fill' - | 'file-font' - | 'file-image-fill' - | 'file-image' - | 'file-lock-fill' - | 'file-lock' - | 'file-lock2-fill' - | 'file-lock2' - | 'file-medical-fill' - | 'file-medical' - | 'file-minus-fill' - | 'file-minus' - | 'file-music-fill' - | 'file-music' - | 'file-pdf-fill' - | 'file-pdf' - | 'file-person-fill' - | 'file-person' - | 'file-play-fill' - | 'file-play' - | 'file-plus-fill' - | 'file-plus' - | 'file-post-fill' - | 'file-post' - | 'file-ppt-fill' - | 'file-ppt' - | 'file-richtext-fill' - | 'file-richtext' - | 'file-ruled-fill' - | 'file-ruled' - | 'file-slides-fill' - | 'file-slides' - | 'file-spreadsheet-fill' - | 'file-spreadsheet' - | 'file-text-fill' - | 'file-text' - | 'file-word-fill' - | 'file-word' - | 'file-x-fill' - | 'file-x' - | 'file-zip-fill' - | 'file-zip' - | 'file' - | 'files-alt' - | 'files' - | 'filetype-aac' - | 'filetype-ai' - | 'filetype-bmp' - | 'filetype-cs' - | 'filetype-css' - | 'filetype-csv' - | 'filetype-doc' - | 'filetype-docx' - | 'filetype-exe' - | 'filetype-gif' - | 'filetype-heic' - | 'filetype-html' - | 'filetype-java' - | 'filetype-jpg' - | 'filetype-js' - | 'filetype-json' - | 'filetype-jsx' - | 'filetype-key' - | 'filetype-m4p' - | 'filetype-md' - | 'filetype-mdx' - | 'filetype-mov' - | 'filetype-mp3' - | 'filetype-mp4' - | 'filetype-otf' - | 'filetype-pdf' - | 'filetype-php' - | 'filetype-png' - | 'filetype-ppt' - | 'filetype-pptx' - | 'filetype-psd' - | 'filetype-py' - | 'filetype-raw' - | 'filetype-rb' - | 'filetype-sass' - | 'filetype-scss' - | 'filetype-sh' - | 'filetype-sql' - | 'filetype-svg' - | 'filetype-tiff' - | 'filetype-tsx' - | 'filetype-ttf' - | 'filetype-txt' - | 'filetype-wav' - | 'filetype-woff' - | 'filetype-xls' - | 'filetype-xlsx' - | 'filetype-xml' - | 'filetype-yml' - | 'film' - | 'filter-circle-fill' - | 'filter-circle' - | 'filter-left' - | 'filter-right' - | 'filter-square-fill' - | 'filter-square' - | 'filter' - | 'fingerprint' - | 'fire' - | 'flag-fill' - | 'flag' - | 'floppy-fill' - | 'floppy' - | 'floppy2-fill' - | 'floppy2' - | 'flower1' - | 'flower2' - | 'flower3' - | 'folder-check' - | 'folder-fill' - | 'folder-minus' - | 'folder-plus' - | 'folder-symlink-fill' - | 'folder-symlink' - | 'folder-x' - | 'folder' - | 'folder2-open' - | 'folder2' - | 'fonts' - | 'forward-fill' - | 'forward' - | 'front' - | 'fuel-pump-diesel-fill' - | 'fuel-pump-diesel' - | 'fuel-pump-fill' - | 'fuel-pump' - | 'fullscreen-exit' - | 'fullscreen' - | 'funnel-fill' - | 'funnel' - | 'gear-fill' - | 'gear-wide-connected' - | 'gear-wide' - | 'gear' - | 'gem' - | 'gender-ambiguous' - | 'gender-female' - | 'gender-male' - | 'gender-neuter' - | 'gender-trans' - | 'geo-alt-fill' - | 'geo-alt' - | 'geo-fill' - | 'geo' - | 'gift-fill' - | 'gift' - | 'git' - | 'github' - | 'gitlab' - | 'globe-americas' - | 'globe-asia-australia' - | 'globe-central-south-asia' - | 'globe-europe-africa' - | 'globe' - | 'globe2' - | 'google-play' - | 'google' - | 'gpu-card' - | 'graph-down-arrow' - | 'graph-down' - | 'graph-up-arrow' - | 'graph-up' - | 'grid-1x2-fill' - | 'grid-1x2' - | 'grid-3x2-gap-fill' - | 'grid-3x2-gap' - | 'grid-3x2' - | 'grid-3x3-gap-fill' - | 'grid-3x3-gap' - | 'grid-3x3' - | 'grid-fill' - | 'grid' - | 'grip-horizontal' - | 'grip-vertical' - | 'h-circle-fill' - | 'h-circle' - | 'h-square-fill' - | 'h-square' - | 'hammer' - | 'hand-index-fill' - | 'hand-index-thumb-fill' - | 'hand-index-thumb' - | 'hand-index' - | 'hand-thumbs-down-fill' - | 'hand-thumbs-down' - | 'hand-thumbs-up-fill' - | 'hand-thumbs-up' - | 'handbag-fill' - | 'handbag' - | 'hash' - | 'hdd-fill' - | 'hdd-network-fill' - | 'hdd-network' - | 'hdd-rack-fill' - | 'hdd-rack' - | 'hdd-stack-fill' - | 'hdd-stack' - | 'hdd' - | 'hdmi-fill' - | 'hdmi' - | 'headphones' - | 'headset-vr' - | 'headset' - | 'heart-arrow' - | 'heart-fill' - | 'heart-half' - | 'heart-pulse-fill' - | 'heart-pulse' - | 'heart' - | 'heartbreak-fill' - | 'heartbreak' - | 'hearts' - | 'heptagon-fill' - | 'heptagon-half' - | 'heptagon' - | 'hexagon-fill' - | 'hexagon-half' - | 'hexagon' - | 'highlighter' - | 'highlights' - | 'hospital-fill' - | 'hospital' - | 'hourglass-bottom' - | 'hourglass-split' - | 'hourglass-top' - | 'hourglass' - | 'house-add-fill' - | 'house-add' - | 'house-check-fill' - | 'house-check' - | 'house-dash-fill' - | 'house-dash' - | 'house-door-fill' - | 'house-door' - | 'house-down-fill' - | 'house-down' - | 'house-exclamation-fill' - | 'house-exclamation' - | 'house-fill' - | 'house-gear-fill' - | 'house-gear' - | 'house-heart-fill' - | 'house-heart' - | 'house-lock-fill' - | 'house-lock' - | 'house-slash-fill' - | 'house-slash' - | 'house-up-fill' - | 'house-up' - | 'house-x-fill' - | 'house-x' - | 'house' - | 'houses-fill' - | 'houses' - | 'hr' - | 'hurricane' - | 'hypnotize' - | 'image-alt' - | 'image-fill' - | 'image' - | 'images' - | 'inbox-fill' - | 'inbox' - | 'inboxes-fill' - | 'inboxes' - | 'incognito' - | 'indent' - | 'infinity' - | 'info-circle-fill' - | 'info-circle' - | 'info-lg' - | 'info-square-fill' - | 'info-square' - | 'info' - | 'input-cursor-text' - | 'input-cursor' - | 'instagram' - | 'intersect' - | 'journal-album' - | 'journal-arrow-down' - | 'journal-arrow-up' - | 'journal-bookmark-fill' - | 'journal-bookmark' - | 'journal-check' - | 'journal-code' - | 'journal-medical' - | 'journal-minus' - | 'journal-plus' - | 'journal-richtext' - | 'journal-text' - | 'journal-x' - | 'journal' - | 'journals' - | 'joystick' - | 'justify-left' - | 'justify-right' - | 'justify' - | 'kanban-fill' - | 'kanban' - | 'key-fill' - | 'key' - | 'keyboard-fill' - | 'keyboard' - | 'ladder' - | 'lamp-fill' - | 'lamp' - | 'laptop-fill' - | 'laptop' - | 'layer-backward' - | 'layer-forward' - | 'layers-fill' - | 'layers-half' - | 'layers' - | 'layout-sidebar-inset-reverse' - | 'layout-sidebar-inset' - | 'layout-sidebar-reverse' - | 'layout-sidebar' - | 'layout-split' - | 'layout-text-sidebar-reverse' - | 'layout-text-sidebar' - | 'layout-text-window-reverse' - | 'layout-text-window' - | 'layout-three-columns' - | 'layout-wtf' - | 'life-preserver' - | 'lightbulb-fill' - | 'lightbulb-off-fill' - | 'lightbulb-off' - | 'lightbulb' - | 'lightning-charge-fill' - | 'lightning-charge' - | 'lightning-fill' - | 'lightning' - | 'line' - | 'link-45deg' - | 'link' - | 'linkedin' - | 'list-check' - | 'list-columns-reverse' - | 'list-columns' - | 'list-nested' - | 'list-ol' - | 'list-stars' - | 'list-task' - | 'list-ul' - | 'list' - | 'lock-fill' - | 'lock' - | 'luggage-fill' - | 'luggage' - | 'lungs-fill' - | 'lungs' - | 'magic' - | 'magnet-fill' - | 'magnet' - | 'mailbox-flag' - | 'mailbox' - | 'mailbox2-flag' - | 'mailbox2' - | 'map-fill' - | 'map' - | 'markdown-fill' - | 'markdown' - | 'marker-tip' - | 'mask' - | 'mastodon' - | 'medium' - | 'megaphone-fill' - | 'megaphone' - | 'memory' - | 'menu-app-fill' - | 'menu-app' - | 'menu-button-fill' - | 'menu-button-wide-fill' - | 'menu-button-wide' - | 'menu-button' - | 'menu-down' - | 'menu-up' - | 'messenger' - | 'meta' - | 'mic-fill' - | 'mic-mute-fill' - | 'mic-mute' - | 'mic' - | 'microsoft-teams' - | 'microsoft' - | 'minecart-loaded' - | 'minecart' - | 'modem-fill' - | 'modem' - | 'moisture' - | 'moon-fill' - | 'moon-stars-fill' - | 'moon-stars' - | 'moon' - | 'mortarboard-fill' - | 'mortarboard' - | 'motherboard-fill' - | 'motherboard' - | 'mouse-fill' - | 'mouse' - | 'mouse2-fill' - | 'mouse2' - | 'mouse3-fill' - | 'mouse3' - | 'music-note-beamed' - | 'music-note-list' - | 'music-note' - | 'music-player-fill' - | 'music-player' - | 'newspaper' - | 'nintendo-switch' - | 'node-minus-fill' - | 'node-minus' - | 'node-plus-fill' - | 'node-plus' - | 'noise-reduction' - | 'nut-fill' - | 'nut' - | 'nvidia' - | 'nvme-fill' - | 'nvme' - | 'octagon-fill' - | 'octagon-half' - | 'octagon' - | 'opencollective' - | 'optical-audio-fill' - | 'optical-audio' - | 'option' - | 'outlet' - | 'p-circle-fill' - | 'p-circle' - | 'p-square-fill' - | 'p-square' - | 'paint-bucket' - | 'palette-fill' - | 'palette' - | 'palette2' - | 'paperclip' - | 'paragraph' - | 'pass-fill' - | 'pass' - | 'passport-fill' - | 'passport' - | 'patch-check-fill' - | 'patch-check' - | 'patch-exclamation-fill' - | 'patch-exclamation' - | 'patch-minus-fill' - | 'patch-minus' - | 'patch-plus-fill' - | 'patch-plus' - | 'patch-question-fill' - | 'patch-question' - | 'pause-btn-fill' - | 'pause-btn' - | 'pause-circle-fill' - | 'pause-circle' - | 'pause-fill' - | 'pause' - | 'paypal' - | 'pc-display-horizontal' - | 'pc-display' - | 'pc-horizontal' - | 'pc' - | 'pci-card-network' - | 'pci-card-sound' - | 'pci-card' - | 'peace-fill' - | 'peace' - | 'pen-fill' - | 'pen' - | 'pencil-fill' - | 'pencil-square' - | 'pencil' - | 'pentagon-fill' - | 'pentagon-half' - | 'pentagon' - | 'people-fill' - | 'people' - | 'percent' - | 'person-add' - | 'person-arms-up' - | 'person-badge-fill' - | 'person-badge' - | 'person-bounding-box' - | 'person-check-fill' - | 'person-check' - | 'person-circle' - | 'person-dash-fill' - | 'person-dash' - | 'person-down' - | 'person-exclamation' - | 'person-fill-add' - | 'person-fill-check' - | 'person-fill-dash' - | 'person-fill-down' - | 'person-fill-exclamation' - | 'person-fill-gear' - | 'person-fill-lock' - | 'person-fill-slash' - | 'person-fill-up' - | 'person-fill-x' - | 'person-fill' - | 'person-gear' - | 'person-heart' - | 'person-hearts' - | 'person-lines-fill' - | 'person-lock' - | 'person-plus-fill' - | 'person-plus' - | 'person-raised-hand' - | 'person-rolodex' - | 'person-slash' - | 'person-square' - | 'person-standing-dress' - | 'person-standing' - | 'person-up' - | 'person-vcard-fill' - | 'person-vcard' - | 'person-video' - | 'person-video2' - | 'person-video3' - | 'person-walking' - | 'person-wheelchair' - | 'person-workspace' - | 'person-x-fill' - | 'person-x' - | 'person' - | 'phone-fill' - | 'phone-flip' - | 'phone-landscape-fill' - | 'phone-landscape' - | 'phone-vibrate-fill' - | 'phone-vibrate' - | 'phone' - | 'pie-chart-fill' - | 'pie-chart' - | 'piggy-bank-fill' - | 'piggy-bank' - | 'pin-angle-fill' - | 'pin-angle' - | 'pin-fill' - | 'pin-map-fill' - | 'pin-map' - | 'pin' - | 'pinterest' - | 'pip-fill' - | 'pip' - | 'play-btn-fill' - | 'play-btn' - | 'play-circle-fill' - | 'play-circle' - | 'play-fill' - | 'play' - | 'playstation' - | 'plug-fill' - | 'plug' - | 'plugin' - | 'plus-circle-dotted' - | 'plus-circle-fill' - | 'plus-circle' - | 'plus-lg' - | 'plus-slash-minus' - | 'plus-square-dotted' - | 'plus-square-fill' - | 'plus-square' - | 'plus' - | 'postage-fill' - | 'postage-heart-fill' - | 'postage-heart' - | 'postage' - | 'postcard-fill' - | 'postcard-heart-fill' - | 'postcard-heart' - | 'postcard' - | 'power' - | 'prescription' - | 'prescription2' - | 'printer-fill' - | 'printer' - | 'projector-fill' - | 'projector' - | 'puzzle-fill' - | 'puzzle' - | 'qr-code-scan' - | 'qr-code' - | 'question-circle-fill' - | 'question-circle' - | 'question-diamond-fill' - | 'question-diamond' - | 'question-lg' - | 'question-octagon-fill' - | 'question-octagon' - | 'question-square-fill' - | 'question-square' - | 'question' - | 'quora' - | 'quote' - | 'r-circle-fill' - | 'r-circle' - | 'r-square-fill' - | 'r-square' - | 'radar' - | 'radioactive' - | 'rainbow' - | 'receipt-cutoff' - | 'receipt' - | 'reception-0' - | 'reception-1' - | 'reception-2' - | 'reception-3' - | 'reception-4' - | 'record-btn-fill' - | 'record-btn' - | 'record-circle-fill' - | 'record-circle' - | 'record-fill' - | 'record' - | 'record2-fill' - | 'record2' - | 'recycle' - | 'reddit' - | 'regex' - | 'repeat-1' - | 'repeat' - | 'reply-all-fill' - | 'reply-all' - | 'reply-fill' - | 'reply' - | 'rewind-btn-fill' - | 'rewind-btn' - | 'rewind-circle-fill' - | 'rewind-circle' - | 'rewind-fill' - | 'rewind' - | 'robot' - | 'rocket-fill' - | 'rocket-takeoff-fill' - | 'rocket-takeoff' - | 'rocket' - | 'router-fill' - | 'router' - | 'rss-fill' - | 'rss' - | 'rulers' - | 'safe-fill' - | 'safe' - | 'safe2-fill' - | 'safe2' - | 'save-fill' - | 'save' - | 'save2-fill' - | 'save2' - | 'scissors' - | 'scooter' - | 'screwdriver' - | 'sd-card-fill' - | 'sd-card' - | 'search-heart-fill' - | 'search-heart' - | 'search' - | 'segmented-nav' - | 'send-arrow-down-fill' - | 'send-arrow-down' - | 'send-arrow-up-fill' - | 'send-arrow-up' - | 'send-check-fill' - | 'send-check' - | 'send-dash-fill' - | 'send-dash' - | 'send-exclamation-fill' - | 'send-exclamation' - | 'send-fill' - | 'send-plus-fill' - | 'send-plus' - | 'send-slash-fill' - | 'send-slash' - | 'send-x-fill' - | 'send-x' - | 'send' - | 'server' - | 'shadows' - | 'share-fill' - | 'share' - | 'shield-check' - | 'shield-exclamation' - | 'shield-fill-check' - | 'shield-fill-exclamation' - | 'shield-fill-minus' - | 'shield-fill-plus' - | 'shield-fill-x' - | 'shield-fill' - | 'shield-lock-fill' - | 'shield-lock' - | 'shield-minus' - | 'shield-plus' - | 'shield-shaded' - | 'shield-slash-fill' - | 'shield-slash' - | 'shield-x' - | 'shield' - | 'shift-fill' - | 'shift' - | 'shop-window' - | 'shop' - | 'shuffle' - | 'sign-dead-end-fill' - | 'sign-dead-end' - | 'sign-do-not-enter-fill' - | 'sign-do-not-enter' - | 'sign-intersection-fill' - | 'sign-intersection-side-fill' - | 'sign-intersection-side' - | 'sign-intersection-t-fill' - | 'sign-intersection-t' - | 'sign-intersection-y-fill' - | 'sign-intersection-y' - | 'sign-intersection' - | 'sign-merge-left-fill' - | 'sign-merge-left' - | 'sign-merge-right-fill' - | 'sign-merge-right' - | 'sign-no-left-turn-fill' - | 'sign-no-left-turn' - | 'sign-no-parking-fill' - | 'sign-no-parking' - | 'sign-no-right-turn-fill' - | 'sign-no-right-turn' - | 'sign-railroad-fill' - | 'sign-railroad' - | 'sign-stop-fill' - | 'sign-stop-lights-fill' - | 'sign-stop-lights' - | 'sign-stop' - | 'sign-turn-left-fill' - | 'sign-turn-left' - | 'sign-turn-right-fill' - | 'sign-turn-right' - | 'sign-turn-slight-left-fill' - | 'sign-turn-slight-left' - | 'sign-turn-slight-right-fill' - | 'sign-turn-slight-right' - | 'sign-yield-fill' - | 'sign-yield' - | 'signal' - | 'signpost-2-fill' - | 'signpost-2' - | 'signpost-fill' - | 'signpost-split-fill' - | 'signpost-split' - | 'signpost' - | 'sim-fill' - | 'sim-slash-fill' - | 'sim-slash' - | 'sim' - | 'sina-weibo' - | 'skip-backward-btn-fill' - | 'skip-backward-btn' - | 'skip-backward-circle-fill' - | 'skip-backward-circle' - | 'skip-backward-fill' - | 'skip-backward' - | 'skip-end-btn-fill' - | 'skip-end-btn' - | 'skip-end-circle-fill' - | 'skip-end-circle' - | 'skip-end-fill' - | 'skip-end' - | 'skip-forward-btn-fill' - | 'skip-forward-btn' - | 'skip-forward-circle-fill' - | 'skip-forward-circle' - | 'skip-forward-fill' - | 'skip-forward' - | 'skip-start-btn-fill' - | 'skip-start-btn' - | 'skip-start-circle-fill' - | 'skip-start-circle' - | 'skip-start-fill' - | 'skip-start' - | 'skype' - | 'slack' - | 'slash-circle-fill' - | 'slash-circle' - | 'slash-lg' - | 'slash-square-fill' - | 'slash-square' - | 'slash' - | 'sliders' - | 'sliders2-vertical' - | 'sliders2' - | 'smartwatch' - | 'snapchat' - | 'snow' - | 'snow2' - | 'snow3' - | 'sort-alpha-down-alt' - | 'sort-alpha-down' - | 'sort-alpha-up-alt' - | 'sort-alpha-up' - | 'sort-down-alt' - | 'sort-down' - | 'sort-numeric-down-alt' - | 'sort-numeric-down' - | 'sort-numeric-up-alt' - | 'sort-numeric-up' - | 'sort-up-alt' - | 'sort-up' - | 'soundwave' - | 'sourceforge' - | 'speaker-fill' - | 'speaker' - | 'speedometer' - | 'speedometer2' - | 'spellcheck' - | 'spotify' - | 'square-fill' - | 'square-half' - | 'square' - | 'stack-overflow' - | 'stack' - | 'star-fill' - | 'star-half' - | 'star' - | 'stars' - | 'steam' - | 'stickies-fill' - | 'stickies' - | 'sticky-fill' - | 'sticky' - | 'stop-btn-fill' - | 'stop-btn' - | 'stop-circle-fill' - | 'stop-circle' - | 'stop-fill' - | 'stop' - | 'stoplights-fill' - | 'stoplights' - | 'stopwatch-fill' - | 'stopwatch' - | 'strava' - | 'stripe' - | 'subscript' - | 'substack' - | 'subtract' - | 'suit-club-fill' - | 'suit-club' - | 'suit-diamond-fill' - | 'suit-diamond' - | 'suit-heart-fill' - | 'suit-heart' - | 'suit-spade-fill' - | 'suit-spade' - | 'suitcase-fill' - | 'suitcase-lg-fill' - | 'suitcase-lg' - | 'suitcase' - | 'suitcase2-fill' - | 'suitcase2' - | 'sun-fill' - | 'sun' - | 'sunglasses' - | 'sunrise-fill' - | 'sunrise' - | 'sunset-fill' - | 'sunset' - | 'superscript' - | 'symmetry-horizontal' - | 'symmetry-vertical' - | 'table' - | 'tablet-fill' - | 'tablet-landscape-fill' - | 'tablet-landscape' - | 'tablet' - | 'tag-fill' - | 'tag' - | 'tags-fill' - | 'tags' - | 'taxi-front-fill' - | 'taxi-front' - | 'telegram' - | 'telephone-fill' - | 'telephone-forward-fill' - | 'telephone-forward' - | 'telephone-inbound-fill' - | 'telephone-inbound' - | 'telephone-minus-fill' - | 'telephone-minus' - | 'telephone-outbound-fill' - | 'telephone-outbound' - | 'telephone-plus-fill' - | 'telephone-plus' - | 'telephone-x-fill' - | 'telephone-x' - | 'telephone' - | 'tencent-qq' - | 'terminal-dash' - | 'terminal-fill' - | 'terminal-plus' - | 'terminal-split' - | 'terminal-x' - | 'terminal' - | 'text-center' - | 'text-indent-left' - | 'text-indent-right' - | 'text-left' - | 'text-paragraph' - | 'text-right' - | 'text-wrap' - | 'textarea-resize' - | 'textarea-t' - | 'textarea' - | 'thermometer-half' - | 'thermometer-high' - | 'thermometer-low' - | 'thermometer-snow' - | 'thermometer-sun' - | 'thermometer' - | 'threads-fill' - | 'threads' - | 'three-dots-vertical' - | 'three-dots' - | 'thunderbolt-fill' - | 'thunderbolt' - | 'ticket-detailed-fill' - | 'ticket-detailed' - | 'ticket-fill' - | 'ticket-perforated-fill' - | 'ticket-perforated' - | 'ticket' - | 'tiktok' - | 'toggle-off' - | 'toggle-on' - | 'toggle2-off' - | 'toggle2-on' - | 'toggles' - | 'toggles2' - | 'tools' - | 'tornado' - | 'train-freight-front-fill' - | 'train-freight-front' - | 'train-front-fill' - | 'train-front' - | 'train-lightrail-front-fill' - | 'train-lightrail-front' - | 'translate' - | 'transparency' - | 'trash-fill' - | 'trash' - | 'trash2-fill' - | 'trash2' - | 'trash3-fill' - | 'trash3' - | 'tree-fill' - | 'tree' - | 'trello' - | 'triangle-fill' - | 'triangle-half' - | 'triangle' - | 'trophy-fill' - | 'trophy' - | 'tropical-storm' - | 'truck-flatbed' - | 'truck-front-fill' - | 'truck-front' - | 'truck' - | 'tsunami' - | 'tv-fill' - | 'tv' - | 'twitch' - | 'twitter-x' - | 'twitter' - | 'type-bold' - | 'type-h1' - | 'type-h2' - | 'type-h3' - | 'type-h4' - | 'type-h5' - | 'type-h6' - | 'type-italic' - | 'type-strikethrough' - | 'type-underline' - | 'type' - | 'ubuntu' - | 'ui-checks-grid' - | 'ui-checks' - | 'ui-radios-grid' - | 'ui-radios' - | 'umbrella-fill' - | 'umbrella' - | 'unindent' - | 'union' - | 'unity' - | 'universal-access-circle' - | 'universal-access' - | 'unlock-fill' - | 'unlock' - | 'upc-scan' - | 'upc' - | 'upload' - | 'usb-c-fill' - | 'usb-c' - | 'usb-drive-fill' - | 'usb-drive' - | 'usb-fill' - | 'usb-micro-fill' - | 'usb-micro' - | 'usb-mini-fill' - | 'usb-mini' - | 'usb-plug-fill' - | 'usb-plug' - | 'usb-symbol' - | 'usb' - | 'valentine' - | 'valentine2' - | 'vector-pen' - | 'view-list' - | 'view-stacked' - | 'vignette' - | 'vimeo' - | 'vinyl-fill' - | 'vinyl' - | 'virus' - | 'virus2' - | 'voicemail' - | 'volume-down-fill' - | 'volume-down' - | 'volume-mute-fill' - | 'volume-mute' - | 'volume-off-fill' - | 'volume-off' - | 'volume-up-fill' - | 'volume-up' - | 'vr' - | 'wallet-fill' - | 'wallet' - | 'wallet2' - | 'watch' - | 'water' - | 'webcam-fill' - | 'webcam' - | 'wechat' - | 'whatsapp' - | 'wifi-1' - | 'wifi-2' - | 'wifi-off' - | 'wifi' - | 'wikipedia' - | 'wind' - | 'window-dash' - | 'window-desktop' - | 'window-dock' - | 'window-fullscreen' - | 'window-plus' - | 'window-sidebar' - | 'window-split' - | 'window-stack' - | 'window-x' - | 'window' - | 'windows' - | 'wordpress' - | 'wrench-adjustable-circle-fill' - | 'wrench-adjustable-circle' - | 'wrench-adjustable' - | 'wrench' - | 'x-circle-fill' - | 'x-circle' - | 'x-diamond-fill' - | 'x-diamond' - | 'x-lg' - | 'x-octagon-fill' - | 'x-octagon' - | 'x-square-fill' - | 'x-square' - | 'x' - | 'xbox' - | 'yelp' - | 'yin-yang' - | 'youtube' - | 'zoom-in' - | 'zoom-out'; - -export const Icon = ({ - name, - className, - ...props -}: { - name: IconName; - className?: string; -}) => { - return ; -}; diff --git a/packages/app/src/components/NetworkPropertyPanel.tsx b/packages/app/src/components/NetworkPropertyPanel.tsx index 47870407a..c8874028e 100644 --- a/packages/app/src/components/NetworkPropertyPanel.tsx +++ b/packages/app/src/components/NetworkPropertyPanel.tsx @@ -3,15 +3,9 @@ import Link from 'next/link'; import { pickBy } from 'lodash'; import CopyToClipboard from 'react-copy-to-clipboard'; import { JSONTree } from 'react-json-tree'; -import { - Accordion, - Box, - Button, - CopyButton, - TableData, - Text, -} from '@mantine/core'; +import { Accordion, Box, Button, CopyButton, TableData } from '@mantine/core'; import { notifications } from '@mantine/notifications'; +import { IconTerminal } from '@tabler/icons-react'; import HyperJson from '@/components/HyperJson'; import { Table } from '@/components/Table'; @@ -229,7 +223,7 @@ export function NetworkPropertySubpanel({ }} > @@ -240,7 +234,7 @@ export function NetworkPropertySubpanel({ size="sm" as="a" > - + Endpoint Trends */} diff --git a/packages/app/src/components/NumberFormat.tsx b/packages/app/src/components/NumberFormat.tsx index f794e51f6..d6a9727e4 100644 --- a/packages/app/src/components/NumberFormat.tsx +++ b/packages/app/src/components/NumberFormat.tsx @@ -11,6 +11,14 @@ import { TextInput, } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; +import { + IconClock, + IconCurrencyDollar, + IconDatabase, + IconNumbers, + IconPercentage, + IconX, +} from '@tabler/icons-react'; import { NumberFormat } from '../types'; import { formatNumber } from '../utils'; @@ -23,12 +31,12 @@ const FORMAT_NAMES: Record = { time: 'Time', }; -const FORMAT_ICONS: Record = { - number: '123', - currency: 'currency-dollar', - percent: 'percent', - byte: 'database', - time: 'clock', +const FORMAT_ICONS: Record = { + number: , + currency: , + percent: , + byte: , + time: , }; export const NumberFormatForm: React.FC<{ @@ -83,11 +91,7 @@ export const NumberFormatForm: React.FC<{ > - ) - } + leftSection={values.output && FORMAT_ICONS[values.output]} style={{ flex: 1 }} data={[ { value: 'number', label: 'Number' }, @@ -234,11 +238,7 @@ export const NumberFormatInput: React.FC<{ size="compact-sm" color="dark" variant="default" - leftSection={ - value?.output && ( - - ) - } + leftSection={value?.output && FORMAT_ICONS[value.output]} > {value?.output ? FORMAT_NAMES[value.output] : 'Set number format'} @@ -250,7 +250,7 @@ export const NumberFormatInput: React.FC<{ px="xs" onClick={() => handleApply(undefined)} > - + )} diff --git a/packages/app/src/components/OnboardingModal.tsx b/packages/app/src/components/OnboardingModal.tsx index 964069d99..9575e96ac 100644 --- a/packages/app/src/components/OnboardingModal.tsx +++ b/packages/app/src/components/OnboardingModal.tsx @@ -6,6 +6,7 @@ import { } from '@hyperdx/common-utils/dist/types'; import { Button, Divider, Modal, Text } from '@mantine/core'; import { notifications } from '@mantine/notifications'; +import { IconArrowLeft } from '@tabler/icons-react'; import { ConnectionForm } from '@/components/ConnectionForm'; import { IS_LOCAL_MODE } from '@/config'; @@ -400,7 +401,7 @@ export default function OnboardingModal({ p="xs" mb="md" > - Back + Back Lets set up a source table to query telemetry from. diff --git a/packages/app/src/components/SearchPageActionBar.tsx b/packages/app/src/components/SearchPageActionBar.tsx index ea62adb55..8eaa8e44c 100644 --- a/packages/app/src/components/SearchPageActionBar.tsx +++ b/packages/app/src/components/SearchPageActionBar.tsx @@ -1,4 +1,5 @@ import { Button, Menu, Text } from '@mantine/core'; +import { IconDotsVertical, IconForms, IconTrash } from '@tabler/icons-react'; export default function SearchPageActionBar({ onClickDeleteSavedSearch, @@ -17,19 +18,19 @@ export default function SearchPageActionBar({ size="xs" style={{ flexShrink: 0 }} > - + } + leftSection={} onClick={onClickDeleteSavedSearch} > Delete Saved Search } + leftSection={} onClick={onClickRenameSavedSearch} > Rename Saved Search diff --git a/packages/app/src/components/ServiceDashboardDbQuerySidePanel.tsx b/packages/app/src/components/ServiceDashboardDbQuerySidePanel.tsx index dd6c9b735..35a773944 100644 --- a/packages/app/src/components/ServiceDashboardDbQuerySidePanel.tsx +++ b/packages/app/src/components/ServiceDashboardDbQuerySidePanel.tsx @@ -2,6 +2,7 @@ import { useCallback, useMemo } from 'react'; import { parseAsString, useQueryState } from 'nuqs'; import type { Filter } from '@hyperdx/common-utils/dist/types'; import { Drawer, Grid, Group, Text } from '@mantine/core'; +import { IconServer } from '@tabler/icons-react'; import { INTEGER_NUMBER_FORMAT, MS_NUMBER_FORMAT } from '@/ChartUtils'; import { ChartBox } from '@/components/ChartBox'; @@ -76,7 +77,7 @@ export default function ServiceDashboardDbQuerySidePanel({ Details for {dbQuery} {service && ( - + {service} )} diff --git a/packages/app/src/components/ServiceDashboardEndpointSidePanel.tsx b/packages/app/src/components/ServiceDashboardEndpointSidePanel.tsx index 6d6d9b0ee..2aa5d72df 100644 --- a/packages/app/src/components/ServiceDashboardEndpointSidePanel.tsx +++ b/packages/app/src/components/ServiceDashboardEndpointSidePanel.tsx @@ -2,6 +2,7 @@ import { useCallback, useMemo } from 'react'; import { parseAsString, useQueryState } from 'nuqs'; import type { Filter } from '@hyperdx/common-utils/dist/types'; import { Drawer, Grid, Group, Text } from '@mantine/core'; +import { IconServer } from '@tabler/icons-react'; import { ERROR_RATE_PERCENTAGE_NUMBER_FORMAT, @@ -83,7 +84,7 @@ export default function ServiceDashboardEndpointSidePanel({ Details for {endpoint} {service && ( - + {service} )} diff --git a/packages/app/src/components/SourceForm.tsx b/packages/app/src/components/SourceForm.tsx index e50811349..b8fc63cf6 100644 --- a/packages/app/src/components/SourceForm.tsx +++ b/packages/app/src/components/SourceForm.tsx @@ -20,6 +20,7 @@ import { Anchor, Box, Button, + Center, Divider, Flex, Grid, @@ -31,7 +32,12 @@ import { Tooltip, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; -import { IconTrash } from '@tabler/icons-react'; +import { + IconCirclePlus, + IconHelpCircle, + IconSettings, + IconTrash, +} from '@tabler/icons-react'; import { SourceSelectControlled } from '@/components/SourceSelect'; import { IS_METRICS_ENABLED, IS_SESSIONS_ENABLED } from '@/config'; @@ -125,16 +131,17 @@ function FormRow({ label )} - - + - + - + @@ -250,7 +257,7 @@ function HighlightedAttributeExpressionsFormRow({ }); }} > - + Add expression @@ -313,10 +320,10 @@ export function LogTableModelForm(props: TableModelProps) { onClick={() => setShowOptionalFields(true)} size="xs" > - - - - Configure Optional Fields + + + Configure Optional Fields + )} {showOptionalFields && ( diff --git a/packages/app/src/components/SourceSchemaPreview.tsx b/packages/app/src/components/SourceSchemaPreview.tsx index 9aa01aa22..a727ffafc 100644 --- a/packages/app/src/components/SourceSchemaPreview.tsx +++ b/packages/app/src/components/SourceSchemaPreview.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { MetricsDataType, TSource } from '@hyperdx/common-utils/dist/types'; import { Modal, Paper, Tabs, Text, TextProps, Tooltip } from '@mantine/core'; -import { IconCode } from '@tabler/icons-react'; +import { IconCode, IconRefresh } from '@tabler/icons-react'; import { useTableMetadata } from '@/hooks/useMetadata'; @@ -77,8 +77,8 @@ const TableSchemaPreview = ({ style={{ overflow: 'hidden' }} > {isLoading ? ( -
- +
+
) : (
} + leftSection={} maxDropdownHeight={280} size={size} onCreate={onCreate} diff --git a/packages/app/src/components/SpanEventsSubpanel.tsx b/packages/app/src/components/SpanEventsSubpanel.tsx index 65f5c7bbb..e0bfd9bf4 100644 --- a/packages/app/src/components/SpanEventsSubpanel.tsx +++ b/packages/app/src/components/SpanEventsSubpanel.tsx @@ -1,6 +1,7 @@ import React, { useMemo } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import { Box, Button, Text } from '@mantine/core'; +import { IconChevronDown, IconChevronUp } from '@tabler/icons-react'; import { ColumnDef } from '@tanstack/react-table'; import { FormatTime } from '@/useFormatTime'; @@ -128,11 +129,11 @@ export const SpanEventsSubpanel = ({ > {isExpanded ? ( <> - Hide events + Hide events ) : ( <> - + Show {hiddenRowsCount} more events )} diff --git a/packages/app/src/components/Table.tsx b/packages/app/src/components/Table.tsx index c83962dfc..f2422bdf1 100644 --- a/packages/app/src/components/Table.tsx +++ b/packages/app/src/components/Table.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import cx from 'classnames'; +import { IconChevronDown, IconChevronUp } from '@tabler/icons-react'; import { ColumnDef, flexRender, @@ -108,13 +109,14 @@ export const Table = | string[]>({ export const TableCellButton: React.FC<{ title?: string; label: React.ReactNode; - biIcon?: string; + biIcon?: 'chevron-up' | 'chevron-down'; onClick: VoidFunction; }> = ({ onClick, title, label, biIcon }) => { return ( ); }; diff --git a/packages/app/src/components/Tags.tsx b/packages/app/src/components/Tags.tsx index 2589a2dca..46a23ab29 100644 --- a/packages/app/src/components/Tags.tsx +++ b/packages/app/src/components/Tags.tsx @@ -10,6 +10,7 @@ import { ScrollArea, Stack, } from '@mantine/core'; +import { IconSearch, IconTags } from '@tabler/icons-react'; import api from '@/api'; @@ -101,7 +102,7 @@ export const Tags = React.memo( color="gray" style={{ cursor: 'pointer' }} > - + )} @@ -112,7 +113,7 @@ export const Tags = React.memo( size="xs" placeholder={allowCreate ? 'Search or create tag' : 'Search tag'} variant="filled" - leftSection={} + leftSection={} autoFocus m={8} mb={0} diff --git a/packages/app/src/components/TeamSettings/TeamMembersSection.tsx b/packages/app/src/components/TeamSettings/TeamMembersSection.tsx index 0c8e33c11..4b1cb01e6 100644 --- a/packages/app/src/components/TeamSettings/TeamMembersSection.tsx +++ b/packages/app/src/components/TeamSettings/TeamMembersSection.tsx @@ -15,6 +15,7 @@ import { TextInput, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; +import { IconLock, IconUserPlus } from '@tabler/icons-react'; import api from '@/api'; @@ -215,7 +216,7 @@ export default function TeamMembersSection() {
Team Members
, } + icon={} key="5" className="mb-4" color="gray" diff --git a/packages/app/src/stories/Button.stories.tsx b/packages/app/src/stories/Button.stories.tsx index e701abd7e..54193f0a0 100644 --- a/packages/app/src/stories/Button.stories.tsx +++ b/packages/app/src/stories/Button.stories.tsx @@ -1,5 +1,6 @@ import { Button } from '@mantine/core'; import type { Meta } from '@storybook/nextjs'; +import { IconStarFilled } from '@tabler/icons-react'; // Just a test story, can be deleted @@ -14,7 +15,7 @@ const meta: Meta = { export const Default = () => (
- + {parsedUrl?.host}
- + {parsedUrl?.pathname}