/** @category Pictograms */ import React, { forwardRef, memo, useEffect, useRef } from 'react'; import classNames, { type Argument } from 'classnames'; import { RenderIfValueIsTruthy } from '@openmrs/esm-react-utils'; import style from './pictograms.module.scss'; /** Array of all available OpenMRS pictogram IDs that can be used with the Pictogram component. */ export const pictogramIds = [ 'omrs-pict-appointments', 'omrs-pict-assessment-1', 'omrs-pict-assessment-2', 'omrs-pict-blood-bank', 'omrs-pict-cardiology', 'omrs-pict-ct-scan', 'omrs-pict-dentistry', 'omrs-pict-emergency-department', 'omrs-pict-facility', 'omrs-pict-geriatrics', 'omrs-pict-gynaecology', 'omrs-pict-in-patient', 'omrs-pict-laboratory', 'omrs-pict-labs-2', 'omrs-pict-obstetrics', 'omrs-pict-patient-search', 'omrs-pict-patients', 'omrs-pict-payments-desk', 'omrs-pict-pharmacy', 'omrs-pict-pharmacy-2', 'omrs-pict-registration', 'omrs-pict-service-queues', 'omrs-pict-stock-management', 'omrs-pict-transfer', 'omrs-pict-triage', 'omrs-pict-x-ray', ] as const; export type PictogramId = (typeof pictogramIds)[number]; export type PictogramProps = { className?: Argument; size?: number; }; export const AppointmentsPictogram = memo( forwardRef(function AppointmentsPictogram(props, ref) { return ; }), ); /** * @deprecated use AppointmentsPictogram instead */ export const AppointmentsAltPictogram = AppointmentsPictogram; export const Assessment1Pictogram = memo( forwardRef(function Assessment1Pictogram(props, ref) { return ; }), ); export const Assessment2Pictogram = memo( forwardRef(function Assessment2Pictogram(props, ref) { return ; }), ); export const BloodBankPictogram = memo( forwardRef(function BloodBankPictogram(props, ref) { return ; }), ); export const CardiologyPictogram = memo( forwardRef(function CardiologyPictogram(props, ref) { return ; }), ); export const CtScanPictogram = memo( forwardRef(function CtScanPictogram(props, ref) { return ; }), ); export const DentistryPictogram = memo( forwardRef(function DentistryPictogram(props, ref) { return ; }), ); export const EmergencyDepartmentPictogram = memo( forwardRef(function EmergencyDepartmentPictogram(props, ref) { return ; }), ); export const FacilityPictogram = memo( forwardRef(function FacilityPictogram(props, ref) { return ; }), ); export const GeriatricsPictogram = memo( forwardRef(function GeriatricsPictogram(props, ref) { return ; }), ); export const GynaecologyPictogram = memo( forwardRef(function GynaecologyPictogram(props, ref) { return ; }), ); export const InPatientPictogram = memo( forwardRef(function InPatientPictogram(props, ref) { return ; }), ); export const LaboratoryPictogram = memo( forwardRef(function LaboratoryPictogram(props, ref) { return ; }), ); export const Labs2Pictogram = memo( forwardRef(function Labs2Pictogram(props, ref) { return ; }), ); export const ObstetricsPictogram = memo( forwardRef(function ObstetricsPictogram(props, ref) { return ; }), ); export const PatientSearchPictogram = memo( forwardRef(function PatientSearchPictogram(props, ref) { return ; }), ); export const PatientsPictogram = memo( forwardRef(function PatientsPictogram(props, ref) { return ; }), ); export const PaymentsDeskPictogram = memo( forwardRef(function PaymentsDeskPictogram(props, ref) { return ; }), ); export const PharmacyPictogram = memo( forwardRef(function PharmacyPictogram(props, ref) { return ; }), ); export const Pharmacy2Pictogram = memo( forwardRef(function Pharmacy2Pictogram(props, ref) { return ; }), ); export const RegistrationPictogram = memo( forwardRef(function RegistrationPictogram(props, ref) { return ; }), ); export const ServiceQueuesPictogram = memo( forwardRef(function ServiceQueuesPictogram(props, ref) { return ; }), ); export const StockManagementPictogram = memo( forwardRef(function StockManagementPictogram(props, ref) { return ; }), ); export const TransferPictogram = memo( forwardRef(function TransferPictogram(props, ref) { return ; }), ); export const TriagePictogram = memo( forwardRef(function TriagePictogram(props, ref) { return ; }), ); export const XrayPictogram = memo( forwardRef(function XrayPictogram(props, ref) { return ; }), ); // Pictogram aliases that are a little more aligned to specific use-cases // should all resolve to a defined React icon export const HomePictogram = FacilityPictogram; export const PatientListsPictogram = PatientsPictogram; /** * This is a utility component that takes an `pictogram` and render it if the sprite for the pictogram * is available. The goal is to make it easier to conditionally render configuration-specified pictograms. * * @example * ```tsx * * ``` */ export const MaybePictogram = memo( forwardRef(function MaybePictogram( { pictogram, fallback, ...pictogramProps }, ref, ) { const iconRef = useRef(document.getElementById(pictogram)); useEffect(() => { const container = document.getElementById('omrs-svgs-container'); const callback: MutationCallback = (mutationList) => { for (const mutation of mutationList) { if (mutation.type === 'childList') { iconRef.current = document.getElementById(pictogram); } } }; const observer = new MutationObserver(callback); if (container) { observer.observe(container, { childList: true }); } return () => observer.disconnect(); }, [pictogram]); return ( ); }), ); export type SvgPictogramProps = { /** the id of the pictogram */ pictogram: PictogramId; /** properties when using the pictogram */ pictogramProps: PictogramProps; }; /** * This is a utility type for custom pictograms. Please maintain alphabetical order when adding new pictograms for readability. */ export const Pictogram = memo( forwardRef(function Pictogram({ pictogram, pictogramProps }, ref) { let { className, size } = Object.assign({}, { size: 92 }, pictogramProps); if (size <= 26 || size > 144) { console.error(`Invalid size '${size}' specified for ${pictogram}. Defaulting to 92.`); size = 92; } return ( ); }), );