/** @category Icons */ import React, { forwardRef, memo, useEffect, useImperativeHandle, useRef } from 'react'; import classNames, { type Argument } from 'classnames'; import { RenderIfValueIsTruthy } from '@openmrs/esm-react-utils'; import style from './icons.module.scss'; /** Array of all available OpenMRS icon IDs that can be used with the Icon component. */ export const iconIds = [ 'omrs-icon-activity', 'omrs-icon-add', 'omrs-icon-arrow-down', 'omrs-icon-arrow-left', 'omrs-icon-arrow-right', 'omrs-icon-arrow-up', 'omrs-icon-baby', 'omrs-icon-calendar-heat-map', 'omrs-icon-calendar', 'omrs-icon-caret-down', 'omrs-icon-caret-left', 'omrs-icon-caret-right', 'omrs-icon-caret-up', 'omrs-icon-chart-average', 'omrs-icon-checkmark-filled', 'omrs-icon-checkmark-outline', 'omrs-icon-chemistry', 'omrs-icon-chevron-down', 'omrs-icon-chevron-left', 'omrs-icon-chevron-right', 'omrs-icon-chevron-up', 'omrs-icon-close', 'omrs-icon-close-filled', 'omrs-icon-close-outline', 'omrs-icon-document', 'omrs-icon-document-attachment', 'omrs-icon-download', 'omrs-icon-drug-order', 'omrs-icon-edit', 'omrs-icon-event-schedule', 'omrs-icon-events', 'omrs-icon-gender-female', 'omrs-icon-gender-male', 'omrs-icon-gender-other', 'omrs-icon-gender-unknown', 'omrs-icon-generic-order-type', 'omrs-icon-group', 'omrs-icon-group-access', 'omrs-icon-hospital-bed', 'omrs-icon-image-medical', 'omrs-icon-information', 'omrs-icon-information-filled', 'omrs-icon-information-square', 'omrs-icon-inventory-management', 'omrs-icon-lab-order', 'omrs-icon-list-checked', 'omrs-icon-location', 'omrs-icon-material-order', 'omrs-icon-maximize', 'omrs-icon-medication', 'omrs-icon-message-queue', 'omrs-icon-microscope', 'omrs-icon-money', 'omrs-icon-mother', 'omrs-icon-movement', 'omrs-icon-overflow-menu--horizontal', 'omrs-icon-overflow-menu--vertical', 'omrs-icon-password', 'omrs-icon-pedestrian-family', 'omrs-icon-pen', 'omrs-icon-printer', 'omrs-icon-procedure-order', 'omrs-icon-programs', 'omrs-icon-renew', 'omrs-icon-referral-order', 'omrs-icon-report', 'omrs-icon-reset', 'omrs-icon-save', 'omrs-icon-search', 'omrs-icon-settings', 'omrs-icon-shopping-cart', 'omrs-icon-shopping-cart--arrow-down', 'omrs-icon-sticky-note-add', 'omrs-icon-switcher', 'omrs-icon-syringe', 'omrs-icon-table-of-contents', 'omrs-icon-table', 'omrs-icon-time', 'omrs-icon-tools', 'omrs-icon-translate', 'omrs-icon-trash-can', 'omrs-icon-tree-view--alt', 'omrs-icon-user-avatar', 'omrs-icon-user-follow', 'omrs-icon-user-xray', 'omrs-icon-user', 'omrs-icon-view-off', 'omrs-icon-view', 'omrs-icon-warning', ] as const; export type IconId = (typeof iconIds)[number]; export type IconProps = { className?: Argument; fill?: string; size?: number; }; /** */ export const ActivityIcon = memo( forwardRef(function ActivityIcon(props, ref) { return ; }), ); /** */ export const AddIcon = memo( forwardRef(function AddIcon(props, ref) { return ; }), ); /** */ export const ArrowDownIcon = memo( forwardRef(function ArrowDownIcon(props, ref) { return ; }), ); /** */ export const ArrowLeftIcon = memo( forwardRef(function ArrowLeftIcon(props, ref) { return ; }), ); /** */ export const ArrowRightIcon = memo( forwardRef(function ArrowRightIcon(props, ref) { return ; }), ); /** */ export const ArrowUpIcon = memo( forwardRef(function ArrowUpIcon(props: IconProps, ref) { return ; }), ); /** */ export const BabyIcon = memo( forwardRef(function BabyIcon(props: IconProps, ref) { return ; }), ); /** */ export const CalendarHeatMapIcon = memo( forwardRef(function CalendarHeatMap(props: IconProps, ref) { return ; }), ); /** */ export const CalendarIcon = memo( forwardRef(function Calendar(props: IconProps, ref) { return ; }), ); /** */ export const CaretDownIcon = memo( forwardRef(function CaretDownIcon(props: IconProps, ref) { return ; }), ); /** */ export const CaretLeftIcon = memo( forwardRef(function CaretLeftIcon(props: IconProps, ref) { return ; }), ); /** */ export const CaretRightIcon = memo( forwardRef(function CaretRightIcon(props: IconProps, ref) { return ; }), ); /** */ export const CaretUpIcon = memo( forwardRef(function CaretUpIcon(props: IconProps, ref) { return ; }), ); /** */ export const ChartAverageIcon = memo( forwardRef(function ChartAverageIcon(props, ref) { return ; }), ); /** */ export const CheckmarkFilledIcon = memo( forwardRef(function CheckmarkFilledIcon(props, ref) { return ; }), ); /** */ export const CheckmarkOutlineIcon = memo( forwardRef(function CheckmarkOutlineIcon(props, ref) { return ; }), ); /** */ export const ChemistryIcon = memo( forwardRef(function ChemistryIcon(props, ref) { return ; }), ); /** */ export const ChevronDownIcon = memo( forwardRef(function ChevronDownIcon(props, ref) { return ; }), ); /** */ export const ChevronLeftIcon = memo( forwardRef(function ChevronLeftIcon(props, ref) { return ; }), ); /** */ export const ChevronRightIcon = memo( forwardRef(function ChevronRightIcon(props, ref) { return ; }), ); /** */ export const ChevronUpIcon = memo( forwardRef(function ChevronUpIcon(props, ref) { return ; }), ); /** */ export const CloseIcon = memo( forwardRef(function CloseIcon(props, ref) { return ; }), ); /** */ export const CloseFilledIcon = memo( forwardRef(function CloseFilledIcon(props, ref) { return ; }), ); /** */ export const CloseOutlineIcon = memo( forwardRef(function CloseOutlineIcon(props, ref) { return ; }), ); /** */ export const DocumentIcon = memo( forwardRef(function DocumentIcon(props: IconProps, ref) { return ; }), ); /** */ export const DocumentAttachmentIcon = memo( forwardRef(function DocumentAttachmentIcon(props: IconProps, ref) { return ; }), ); /** */ export const DownloadIcon = memo( forwardRef(function DownloadIcon(props, ref) { return ; }), ); /** */ export const DrugOrderIcon = memo( forwardRef(function DrugOrderIcon(props, ref) { return ; }), ); /** */ export const EditIcon = memo( forwardRef(function EditIcon(props, ref) { return ; }), ); /** */ export const EventScheduleIcon = memo( forwardRef(function EventScheduleIcon(props, ref) { return ; }), ); /** */ export const EventsIcon = memo( forwardRef(function EventsIcon(props, ref) { return ; }), ); /** */ export const GenderFemaleIcon = memo( forwardRef(function GenderFemaleIcon(props, ref) { return ; }), ); /** */ export const GenderMaleIcon = memo( forwardRef(function GenderMaleIcon(props, ref) { return ; }), ); /** */ export const GenderOtherIcon = memo( forwardRef(function GenderOtherIcon(props, ref) { return ; }), ); /** */ export const GenderUnknownIcon = memo( forwardRef(function GenderUnknownIcon(props, ref) { return ; }), ); /** */ export const GenericOrderTypeIcon = memo( forwardRef(function GenericOrderTypeIcon(props, ref) { return ; }), ); /** */ export const GroupIcon = memo( forwardRef(function GroupIcon(props, ref) { return ; }), ); /** */ export const GroupAccessIcon = memo( forwardRef(function GroupAccessIcon(props, ref) { return ; }), ); /** */ export const HospitalBedIcon = memo( forwardRef(function HospitalBedIcon(props, ref) { return ; }), ); /** */ export const ImageMedicalIcon = memo( forwardRef(function ImageMedicalIcon(props, ref) { return ; }), ); /** */ export const InformationIcon = memo( forwardRef(function InformationIcon(props, ref) { return ; }), ); /** */ export const InformationFilledIcon = memo( forwardRef(function InformationFilledIcon(props, ref) { return ; }), ); /** */ export const InformationSquareIcon = memo( forwardRef(function InformationSquareIcon(props, ref) { return ; }), ); /** */ export const InventoryManagementIcon = memo( forwardRef(function InventoryManagementIcon(props, ref) { return ; }), ); /** */ export const LabOrderIcon = memo( forwardRef(function LabOrderIcon(props, ref) { return ; }), ); /** */ export const ListCheckedIcon = memo( forwardRef(function ListCheckedIcon(props, ref) { return ; }), ); /** */ export const LocationIcon = memo( forwardRef(function LocationIcon(props, ref) { return ; }), ); /** */ export const MaterialOrderIcon = memo( forwardRef(function MaterialOrderIcon(props, ref) { return ; }), ); /** */ export const MaximizeIcon = memo( forwardRef(function MaximizeIcon(props, ref) { return ; }), ); /** */ export const MedicationIcon = memo( forwardRef(function MedicationIcon(props, ref) { return ; }), ); /** */ export const MessageQueueIcon = memo( forwardRef(function MessageQueueIcon(props, ref) { return ; }), ); /** */ export const MicroscopeIcon = memo( forwardRef(function MicroscopeIcon(props, ref) { return ; }), ); /** * Billing */ export const MoneyIcon = memo( forwardRef(function MoneyIcon(props, ref) { return ; }), ); /** */ export const MotherIcon = memo( forwardRef(function MotherIcon(props, ref) { return ; }), ); /** */ export const MovementIcon = memo( forwardRef(function MovementIcon(props, ref) { return ; }), ); /** */ export const OverflowMenuHorizontalIcon = memo( forwardRef(function OverflowMenuHorizontalIcon(props, ref) { return ; }), ); /** */ export const OverflowMenuVerticalIcon = memo( forwardRef(function OverflowMenuVerticalIcon(props, ref) { return ; }), ); export const PasswordIcon = memo( forwardRef(function PasswordIcon(props, ref) { return ; }), ); /** */ export const PedestrianFamilyIcon = memo( forwardRef(function PedestrianFamilyIcon(props, ref) { return ; }), ); /** */ export const PenIcon = memo( forwardRef(function PenIcon(props, ref) { return ; }), ); /** */ export const PrinterIcon = memo( forwardRef(function PrinterIcon(props, ref) { return ; }), ); /** */ export const ProcedureOrderIcon = memo( forwardRef(function ProcedureOrderIcon(props, ref) { return ; }), ); /** */ export const ProgramsIcon = memo( forwardRef(function ProgramsIcon(props, ref) { return ; }), ); /** */ export const ReferralOrderIcon = memo( forwardRef(function ReferralOrderIcon(props, ref) { return ; }), ); /** */ export const RenewIcon = memo( forwardRef(function RenewIcon(props, ref) { return ; }), ); /** */ export const ReportIcon = memo( forwardRef(function ReportIcon(props, ref) { return ; }), ); /** */ export const ResetIcon = memo( forwardRef(function ResetIcon(props, ref) { return ; }), ); /** */ export const SaveIcon = memo( forwardRef(function SaveIcon(props, ref) { return ; }), ); /** */ export const SearchIcon = memo( forwardRef(function SearchIcon(props, ref) { return ; }), ); /** */ export const SettingsIcon = memo( forwardRef(function SaveIcon(props, ref) { return ; }), ); /** */ export const SwitcherIcon = memo( forwardRef(function SwitcherIcon(props, ref) { return ; }), ); /** * Order Basket, the UI to enter Orders for Medications, Referrals, Labs, Procedures and more */ export const ShoppingCartIcon = memo( forwardRef(function ShoppingCartIcon(props, ref) { return ; }), ); /** * Used as a button to add an item to the Order basket from a search */ export const ShoppingCartArrowDownIcon = memo( forwardRef(function ShoppingCartArrowDownIcon(props, ref) { return ; }), ); /** * Used as action button to open ward in-patient note workspace */ export const StickyNoteAddIcon = memo( forwardRef(function StickyNoteAddIcon(props, ref) { return ; }), ); /** */ export const SyringeIcon = memo( forwardRef(function SyringeIcon(props, ref) { return ; }), ); /** * Used as a button to add an item to the Order basket from a search */ export const TableOfContentsIcon = memo( forwardRef(function TableOfContentsIcon(props, ref) { return ; }), ); /** */ export const TableIcon = memo( forwardRef(function TableIcon(props, ref) { return ; }), ); /** * Lab investigations */ export const TimeIcon = memo( forwardRef(function TimeIcon(props, ref) { return ; }), ); /** */ export const ToolsIcon = memo( forwardRef(function ToolsIcon(props, ref) { return ; }), ); /** */ export const TranslateIcon = memo( forwardRef(function TranslateIcon(props, ref) { return ; }), ); /** */ export const TrashCanIcon = memo( forwardRef(function TrashCanIcon(props, ref) { return ; }), ); /** */ export const TreeViewAltIcon = memo( forwardRef(function TreeViewAltIcon(props, ref) { return ; }), ); /** * User of OpenMRS e.g. My Account */ export const UserAvatarIcon = memo( forwardRef(function UserAvatarIcon(props, ref) { return ; }), ); /** */ export const UserFollowIcon = memo( forwardRef(function UserFollowIcon(props, ref) { return ; }), ); /** * UserXray Icon * * `UserXrayIcon` is also used for imaging orders */ export const UserXrayIcon = memo( forwardRef(function UserXrayIcon(props, ref) { return ; }), ); /** */ export const UserIcon = memo( forwardRef(function UserIcon(props, ref) { return ; }), ); /** */ export const ViewOffIcon = memo( forwardRef(function ViewOffIcon(props, ref) { return ; }), ); /** */ export const ViewIcon = memo( forwardRef(function ViewIcon(props, ref) { return ; }), ); /** */ export const WarningIcon = memo( forwardRef(function WarningIcon(props, ref) { return ; }), ); // Icon aliases that are a little more aligned to specific use-cases // should all resolve to a defined React icon /** */ export const AllergiesIcon = WarningIcon; /** * */ export const AttachmentIcon = DocumentAttachmentIcon; /** * Conditions * * Note this is an alias for ListCheckedIcon */ export const ConditionsIcon = ListCheckedIcon; /** * */ export const RadiologyIcon = ImageMedicalIcon; /** * Used as a button to add an item to the Order basket from a search * * Note this is an alias for ShoppingCartArrowDownIcon */ export const ShoppingCartAddItemIcon = ShoppingCartArrowDownIcon; /** * This is a utility component that takes an `icon` and renders it if the sprite for the icon * is available. The goal is to make it easier to conditionally render configuration-specified icons. * * @example * ```tsx * * ``` */ export const MaybeIcon = memo( forwardRef(function MaybeIcon( { icon, fallback, ...iconProps }, ref, ) { const iconRef = useRef(icon ? document.getElementById(icon) : undefined); useEffect(() => { const container = document.getElementById('omrs-svgs-container'); const callback: MutationCallback = (mutationList) => { for (const mutation of mutationList) { if (mutation.type === 'childList') { iconRef.current = icon ? document.getElementById(icon) : undefined; } } }; const observer = new MutationObserver(callback); if (container) { observer.observe(container, { childList: true }); } return () => observer.disconnect(); }, [icon]); return ( ); }), ); export type SvgIconProps = { icon: IconId; iconProps: IconProps; }; /** * This is a utility type for custom icons that use the svg-sprite-loader to bundle custom icons */ export const Icon = memo( forwardRef(function Icon({ icon, iconProps }, ref) { let { className, fill, size } = Object.assign({}, { fill: 'currentColor', size: 20 }, iconProps); if (size <= 0 || size > 72) { console.error(`Invalid size '${size}' specified for ${icon}. Defaulting to 20.`); size = 20; } const iconRef = useRef(null); useImperativeHandle(ref, () => iconRef.current!); useEffect(() => { if (iconRef.current) { if (fill !== 'currentColor') { iconRef.current.style.setProperty('--omrs-icon-fill', fill); } } }, []); return ( ); }), );