/* * Copyright 2025 Commonwealth Scientific and Industrial Research * Organisation (CSIRO) ABN 41 687 119 230. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React, { memo } from 'react'; import type { QuestionnaireItem } from 'fhir/r4'; import Box from '@mui/material/Box'; import { useRendererConfigStore } from '../../../stores/rendererConfigStore'; import useRenderingExtensions from '../../../hooks/useRenderingExtensions'; import RequiredAsterisk from './RequiredAsterisk'; import { getContextDisplays } from '../../../utils/tabs'; import ContextDisplayItem from './ContextDisplayItem'; import ItemTextSwitcher from './ItemTextSwitcher'; import ItemPrefixSwitcher from './ItemPrefixSwitcher'; import Typography from '@mui/material/Typography'; import FlyoverItem from './FlyoverItem'; import type { PropsWithParentStylesAttribute } from '../../../interfaces/renderProps.interface'; interface ItemLabelProps extends PropsWithParentStylesAttribute { qItem: QuestionnaireItem; readOnly: boolean; isDisplayItem?: boolean; } const ItemLabel = memo(function ItemLabel(props: ItemLabelProps) { const { qItem, readOnly, isDisplayItem, parentStyles } = props; const readOnlyVisualStyle = useRendererConfigStore.use.readOnlyVisualStyle(); const requiredIndicatorPosition = useRendererConfigStore.use.requiredIndicatorPosition(); const { required, displayFlyover } = useRenderingExtensions(qItem); const contextDisplayItems = getContextDisplays(qItem); // is item is a display item, it should not use the "label" variant const component = isDisplayItem ? 'span' : 'label'; const variant = isDisplayItem ? undefined : 'label'; // Get text color from parent styles if available const readOnlyTextColor = readOnlyVisualStyle === 'disabled' ? 'text.disabled' : 'text.secondary'; const textColor = parentStyles?.color || (readOnly ? readOnlyTextColor : 'text.primary'); return ( {/* Label typography */} {/* Added 0.5 marginTop (4px) because item labels doesn't look in line with their fields */} {/* flexGrow: 1 is important if xhtml and markdown rendering has width: 100% */} {/* Required asterisk position is in front of text */} {required && requiredIndicatorPosition === 'start' ? ( * ) : null} {/* verticalAlign: top is required because an inline-flex box takes its baseline from its first flex item. Once the label text wraps onto multiple lines, that baseline sits well below the surrounding line box's baseline, which pushes the whole label down and away from its field. Aligning the box to the top of the line box keeps multi-line labels in line with their fields. */} {/* Required asterisk position is behind text */} {required && requiredIndicatorPosition === 'end' ? ( * ) : null} {/* Flyover */} {displayFlyover !== '' ? ( ) : null} {contextDisplayItems.map((item) => { return ; })} ); }); export default ItemLabel;