feat: add horizontal radio

This commit is contained in:
David Nguyen
2025-10-15 11:17:57 +11:00
parent f48813bb3c
commit a26a740fe5
11 changed files with 196 additions and 58 deletions

View File

@ -107,6 +107,11 @@ type CalculateMultiItemPositionOptions = {
*/
fieldPadding: number;
/**
* The direction of the items.
*/
direction: 'horizontal' | 'vertical';
type: 'checkbox' | 'radio';
};
@ -122,6 +127,7 @@ export const calculateMultiItemPosition = (options: CalculateMultiItemPositionOp
itemSize,
spacingBetweenItemAndText,
fieldPadding,
direction,
type,
} = options;
@ -130,6 +136,39 @@ export const calculateMultiItemPosition = (options: CalculateMultiItemPositionOp
const innerFieldX = fieldPadding;
const innerFieldY = fieldPadding;
if (direction === 'horizontal') {
const itemHeight = innerFieldHeight;
const itemWidth = innerFieldWidth / itemCount;
const y = innerFieldY;
const x = itemIndex * itemWidth + innerFieldX;
let itemInputY = y + itemHeight / 2 - itemSize / 2;
let itemInputX = x;
// We need a little different logic to center the radio circle icon.
if (type === 'radio') {
itemInputX = x + itemSize / 2;
itemInputY = y + itemHeight / 2;
}
const textX = x + itemSize + spacingBetweenItemAndText;
const textY = y;
// Multiplied by 2 for extra padding on the right hand side of the text and the next item.
const textWidth = itemWidth - itemSize - spacingBetweenItemAndText * 2;
const textHeight = itemHeight;
return {
itemInputX,
itemInputY,
textX,
textY,
textWidth,
textHeight,
};
}
const itemHeight = innerFieldHeight / itemCount;
const y = itemIndex * itemHeight + innerFieldY;
@ -137,6 +176,7 @@ export const calculateMultiItemPosition = (options: CalculateMultiItemPositionOp
let itemInputY = y + itemHeight / 2 - itemSize / 2;
let itemInputX = innerFieldX;
// We need a little different logic to center the radio circle icon.
if (type === 'radio') {
itemInputX = innerFieldX + itemSize / 2;
itemInputY = y + itemHeight / 2;

View File

@ -26,6 +26,9 @@ export const renderCheckboxFieldElement = (
fieldGroup.add(upsertFieldRect(field, options));
const checkboxMeta: TCheckboxFieldMeta | null = (field.fieldMeta as TCheckboxFieldMeta) || null;
const checkboxValues = checkboxMeta?.values || [];
if (isFirstRender) {
pageLayer.add(fieldGroup);
@ -72,6 +75,7 @@ export const renderCheckboxFieldElement = (
itemSize: checkboxSize,
spacingBetweenItemAndText: spacingBetweenCheckboxAndText,
fieldPadding: checkboxFieldPadding,
direction: checkboxMeta?.direction || 'vertical',
type: 'checkbox',
});
@ -113,9 +117,6 @@ export const renderCheckboxFieldElement = (
});
}
const checkboxMeta: TCheckboxFieldMeta | null = (field.fieldMeta as TCheckboxFieldMeta) || null;
const checkboxValues = checkboxMeta?.values || [];
const { fieldWidth, fieldHeight } = calculateFieldPosition(field, pageWidth, pageHeight);
checkboxValues.forEach(({ id, value, checked }, index) => {
@ -128,6 +129,7 @@ export const renderCheckboxFieldElement = (
itemSize: checkboxSize,
spacingBetweenItemAndText: spacingBetweenCheckboxAndText,
fieldPadding: checkboxFieldPadding,
direction: checkboxMeta?.direction || 'vertical',
type: 'checkbox',
});

View File

@ -26,6 +26,9 @@ export const renderRadioFieldElement = (
fieldGroup.add(upsertFieldRect(field, options));
const radioMeta: TRadioFieldMeta | null = (field.fieldMeta as TRadioFieldMeta) || null;
const radioValues = radioMeta?.values || [];
if (isFirstRender) {
pageLayer.add(fieldGroup);
@ -66,6 +69,7 @@ export const renderRadioFieldElement = (
spacingBetweenItemAndText: spacingBetweenRadioAndText,
fieldPadding: radioFieldPadding,
type: 'radio',
direction: radioMeta?.direction || 'vertical',
});
circleElement.setAttrs({
@ -104,9 +108,6 @@ export const renderRadioFieldElement = (
});
}
const radioMeta: TRadioFieldMeta | null = (field.fieldMeta as TRadioFieldMeta) || null;
const radioValues = radioMeta?.values || [];
const { fieldWidth, fieldHeight } = calculateFieldPosition(field, pageWidth, pageHeight);
radioValues.forEach(({ value, checked }, index) => {
@ -120,6 +121,7 @@ export const renderRadioFieldElement = (
spacingBetweenItemAndText: spacingBetweenRadioAndText,
fieldPadding: radioFieldPadding,
type: 'radio',
direction: radioMeta?.direction || 'vertical',
});
// Circle which represents the radio button.