Enhance alignment and styling for RJSF components
- Updated LayoutObjectFieldTemplate to ensure consistent alignment of grid items with a minimum height and flex properties. - Improved TooltipFieldTemplate to center-align switch and checkbox widgets, enhancing overall layout consistency. - Refined CheckboxWidget and SwitchWidget styles for better alignment and text handling, ensuring labels do not overflow and maintain a single line.
This commit is contained in:
parent
76c6743537
commit
42cd1743e8
13912
application_events.json
13912
application_events.json
File diff suppressed because it is too large
Load Diff
|
@ -60,13 +60,21 @@ export default function LayoutObjectFieldTemplate(props) {
|
|||
)
|
||||
)}
|
||||
{layout.map((row, rowIdx) => (
|
||||
<SimpleGrid key={rowIdx} columns={12} spacing={3}>
|
||||
<SimpleGrid key={rowIdx} columns={12} spacing={3} alignItems="flex-end">
|
||||
{row.map((cell, cellIdx) => {
|
||||
const prop = propMap.get(cell.name)
|
||||
if (!prop) return null
|
||||
const col = Math.min(Math.max(cell.width || 12, 1), 12)
|
||||
return (
|
||||
<Box key={`${rowIdx}-${cellIdx}`} gridColumn={`span ${col}`}>{prop.content}</Box>
|
||||
<Box
|
||||
key={`${rowIdx}-${cellIdx}`}
|
||||
gridColumn={`span ${col}`}
|
||||
minH="40px" // Minimum height for consistent alignment
|
||||
display="flex"
|
||||
alignItems="flex-end"
|
||||
>
|
||||
{prop.content}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</SimpleGrid>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import React from 'react'
|
||||
import { Box, FormControl, FormErrorMessage, Tooltip as ChakraTooltip, useColorModeValue } from '@chakra-ui/react'
|
||||
import { Box, FormControl, FormErrorMessage, Tooltip as ChakraTooltip, useColorModeValue, Flex } from '@chakra-ui/react'
|
||||
|
||||
/**
|
||||
* Custom RJSF Field Template with integrated tooltips
|
||||
* Shows ui:description as tooltip on hover over the field
|
||||
* Removes the description text that normally appears below the field
|
||||
* Improves alignment for switches, checkboxes and handles long labels
|
||||
*/
|
||||
export default function TooltipFieldTemplate(props) {
|
||||
const {
|
||||
|
@ -36,6 +37,15 @@ export default function TooltipFieldTemplate(props) {
|
|||
// Only show tooltip if there's actual content (not empty string or whitespace)
|
||||
const hasTooltipContent = tooltipContent && typeof tooltipContent === 'string' && tooltipContent.trim().length > 0
|
||||
|
||||
// Detect if this is a switch or checkbox widget based on the schema type and widget
|
||||
const widgetType = uiSchema?.['ui:widget']
|
||||
const isBoolean = schema?.type === 'boolean'
|
||||
const isSwitchOrCheckbox = isBoolean && (widgetType === 'switch' || widgetType === 'checkbox' || widgetType === 'SwitchWidget' || widgetType === 'CheckboxWidget')
|
||||
|
||||
// For switch/checkbox widgets, we need special handling to center-align them with other fields
|
||||
// These widgets already include their label, so we don't need additional label handling
|
||||
const shouldCenterAlign = isSwitchOrCheckbox
|
||||
|
||||
// If there's tooltip content, wrap just the children (input/widget) in tooltip
|
||||
const wrappedChildren = hasTooltipContent ? (
|
||||
<ChakraTooltip
|
||||
|
@ -59,9 +69,22 @@ export default function TooltipFieldTemplate(props) {
|
|||
</ChakraTooltip>
|
||||
) : children
|
||||
|
||||
// Enhanced container for better alignment
|
||||
const containerProps = shouldCenterAlign ? {
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'flex-start',
|
||||
minH: '40px', // Standard input height for alignment
|
||||
w: 'full'
|
||||
} : {
|
||||
w: 'full'
|
||||
}
|
||||
|
||||
return (
|
||||
<FormControl isInvalid={!!errors} isRequired={required}>
|
||||
{wrappedChildren}
|
||||
<Box {...containerProps}>
|
||||
{wrappedChildren}
|
||||
</Box>
|
||||
{errors && (
|
||||
<FormErrorMessage>
|
||||
{errors}
|
||||
|
|
|
@ -138,6 +138,23 @@ export const CheckboxWidget = ({ id, label, value, required, disabled, readonly,
|
|||
isChecked={!!value}
|
||||
onChange={(e) => onChange(e.target.checked)}
|
||||
colorScheme="blue"
|
||||
alignItems="center"
|
||||
sx={{
|
||||
'& .chakra-checkbox__control': {
|
||||
alignSelf: 'flex-start',
|
||||
mt: '2px' // Small offset to align with text baseline
|
||||
},
|
||||
'& .chakra-checkbox__label': {
|
||||
fontSize: 'sm',
|
||||
lineHeight: '1.3',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
display: '-webkit-box',
|
||||
WebkitLineClamp: 1, // Force single line
|
||||
WebkitBoxOrient: 'vertical',
|
||||
wordBreak: 'break-word'
|
||||
}
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Checkbox>
|
||||
|
@ -148,8 +165,30 @@ export const CheckboxWidget = ({ id, label, value, required, disabled, readonly,
|
|||
)
|
||||
|
||||
export const SwitchWidget = ({ id, label, value, required, disabled, readonly, onChange, rawErrors = [] }) => (
|
||||
<FormControl display="flex" alignItems="center" isRequired={required} isDisabled={disabled} isReadOnly={readonly} isInvalid={rawErrors.length > 0}>
|
||||
<FormLabel htmlFor={id} mb="0" mr={3}>
|
||||
<FormControl
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
isRequired={required}
|
||||
isDisabled={disabled}
|
||||
isReadOnly={readonly}
|
||||
isInvalid={rawErrors.length > 0}
|
||||
minH="40px" // Standard height to match other inputs
|
||||
position="relative"
|
||||
>
|
||||
<FormLabel
|
||||
htmlFor={id}
|
||||
mb="0"
|
||||
mr={3}
|
||||
fontSize="sm"
|
||||
lineHeight="1.3"
|
||||
overflow="hidden"
|
||||
textOverflow="ellipsis"
|
||||
whiteSpace="nowrap" // Force single line
|
||||
wordBreak="break-word"
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
maxW="calc(100% - 60px)" // Reserve space for switch (approx 50px + margin)
|
||||
>
|
||||
{label}
|
||||
</FormLabel>
|
||||
<Switch
|
||||
|
@ -157,9 +196,12 @@ export const SwitchWidget = ({ id, label, value, required, disabled, readonly, o
|
|||
isChecked={!!value}
|
||||
onChange={(e) => onChange(e.target.checked)}
|
||||
colorScheme="blue"
|
||||
flexShrink={0} // Prevent switch from shrinking
|
||||
/>
|
||||
{rawErrors.length > 0 && (
|
||||
<FormHelperText color="red.500">{rawErrors[0]}</FormHelperText>
|
||||
<FormHelperText color="red.500" position="absolute" top="100%" left={0} mt={1}>
|
||||
{rawErrors[0]}
|
||||
</FormHelperText>
|
||||
)}
|
||||
</FormControl>
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue