Skip to content

Commit

Permalink
Add divider to Likert (#2765)
Browse files Browse the repository at this point in the history
  • Loading branch information
tina-ahm authored Dec 12, 2024
1 parent f7d8680 commit 95de927
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 13 deletions.
29 changes: 28 additions & 1 deletion src/codegen/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,34 @@ const common = {
maxHeight: 2,
},
}),

ILikertColumnProperties: () =>
new CG.obj(
new CG.prop(
'columns',
new CG.arr(
new CG.obj(
new CG.prop(
'value',
new CG.union(new CG.str().setPattern(/^\d+$/), new CG.num())
.setTitle('Value')
.setDescription('The value of the answer column'),
),
new CG.prop(
'divider',
new CG.enum('before', 'after', 'both')
.setTitle('Divider')
.setDescription(
"Choose if the divider should be shown 'before', 'after' or on 'both' sides of the column.",
)
.optional(),
),
),
)
.optional()
.setTitle('Columns')
.setDescription('Add customization to the columns of the likert component'),
),
),
// Types that component definitions extend:
ComponentBase: () =>
new CG.obj(
Expand Down
1 change: 1 addition & 0 deletions src/layout/Likert/Generator/LikertGeneratorChildren.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const GenerateRow = React.memo(function GenerateRow({ rowIndex, questionsBinding
hidden: parentItem.hidden,
pageBreak: parentItem.pageBreak,
renderAsSummary: parentItem.renderAsSummary,
columns: parentItem.columns,
}),
[parentItem, childId],
);
Expand Down
28 changes: 19 additions & 9 deletions src/layout/Likert/LikertComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const LikertComponent = ({ node }: LikertComponentProps) => {
const firstLikertNodeId = rowNodeIds[0];
const firstLikertNode = useNode(firstLikertNodeId) as LayoutNode<'LikertItem'> | undefined;
const { options: calculatedOptions, isFetching } = useNodeOptions(firstLikertNode);
const columns = useNodeItem(node, (item) => item.columns);

const id = node.id;

Expand Down Expand Up @@ -122,15 +123,24 @@ export const LikertComponent = ({ node }: LikertComponentProps) => {
<Lang id={textResourceBindings?.leftColumnHeader ?? 'likert.left_column_default_header_text'} />
</span>
</Table.HeaderCell>
{calculatedOptions.map((option, index) => (
<Table.HeaderCell
key={option.value}
scope='col'
id={`${id}-likert-columnheader-${index}`}
>
<Lang id={option.label} />
</Table.HeaderCell>
))}
{calculatedOptions.map((option, index) => {
const divider = columns?.find((column) => column.value == option.value)?.divider;

return (
<Table.HeaderCell
key={option.value}
scope='col'
id={`${id}-likert-columnheader-${index}`}
className={cn({
[classes.likertCellDividerStart]: divider === 'before',
[classes.likertCellDividerEnd]: divider === 'after',
[classes.likertCellDividerBoth]: divider === 'both',
})}
>
<Lang id={option.label} />
</Table.HeaderCell>
);
})}
</Table.Row>
</Table.Head>
<Table.Body>
Expand Down
1 change: 1 addition & 0 deletions src/layout/Likert/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,5 @@ export const Config = new CG.component({
.exportAs('ILikertFilter'),
),
)
.extends(CG.common('ILikertColumnProperties'))
.addPlugin(new OptionsPlugin({ supportsPreselection: false, type: 'single' }));
13 changes: 13 additions & 0 deletions src/layout/LikertItem/LikertItemComponent.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,16 @@ Altinn, and making sure they are consistent. */
margin: 0;
gap: 0;
}

.likertCellDividerStart {
border-inline-start: 1px solid #dde3e5;
}

.likertCellDividerEnd {
border-inline-end: 1px solid #dde3e5;
}

.likertCellDividerBoth {
border-inline-start: 1px solid #dde3e5;
border-inline-end: 1px solid #dde3e5;
}
16 changes: 13 additions & 3 deletions src/layout/LikertItem/LikertItemComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { forwardRef } from 'react';

import { Label, Radio, Table } from '@digdir/designsystemet-react';
import cn from 'classnames';

import { RequiredIndicator } from 'src/components/form/RequiredIndicator';
import { getLabelId } from 'src/components/label/Label';
Expand All @@ -14,7 +15,6 @@ import { useRadioButtons } from 'src/layout/RadioButtons/radioButtonsUtils';
import { BaseLayoutNode } from 'src/utils/layout/LayoutNode';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { PropsFromGenericComponent } from 'src/layout';
import type { IControlledRadioGroupProps } from 'src/layout/RadioButtons/ControlledRadioGroup';

export const LikertItemComponent = forwardRef<HTMLTableRowElement, PropsFromGenericComponent<'LikertItem'>>(
(props, ref) => {
Expand All @@ -36,7 +36,7 @@ export const LikertItemComponent = forwardRef<HTMLTableRowElement, PropsFromGene
);
LikertItemComponent.displayName = 'LikertItemComponent';

const RadioGroupTableRow = forwardRef<HTMLTableRowElement, IControlledRadioGroupProps>((props, ref) => {
const RadioGroupTableRow = forwardRef<HTMLTableRowElement, PropsFromGenericComponent<'LikertItem'>>((props, ref) => {
const { node } = props;
const { selectedValues, handleChange, calculatedOptions, fetchingOptions } = useRadioButtons(props);
const validations = useUnifiedValidationsForNode(node);
Expand All @@ -45,6 +45,8 @@ const RadioGroupTableRow = forwardRef<HTMLTableRowElement, IControlledRadioGroup
const groupContainer =
node.parent instanceof BaseLayoutNode && node.parent.isType('Likert') ? node.parent : undefined;

const columns = useNodeItem(props.node, (i) => i.columns);

return (
<Table.Row
data-componentid={node.id}
Expand Down Expand Up @@ -72,9 +74,17 @@ const RadioGroupTableRow = forwardRef<HTMLTableRowElement, IControlledRadioGroup
const isChecked = selectedValues[0] === option.value;
const rowLabelId = getLabelId(id);
const labelledby = `${rowLabelId} ${groupContainer?.baseId}-likert-columnheader-${index}`;
const divider = columns?.find((column) => column.value == option.value)?.divider;

return (
<Table.Cell key={option.value}>
<Table.Cell
key={option.value}
className={cn({
[classes.likertCellDividerStart]: divider === 'before',
[classes.likertCellDividerEnd]: divider === 'after',
[classes.likertCellDividerBoth]: divider === 'both',
})}
>
<Radio
checked={isChecked}
readOnly={readOnly}
Expand Down
1 change: 1 addition & 0 deletions src/layout/LikertItem/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export const Config = new CG.component({
.setDescription('Boolean value indicating if the label should be visible when only one option exists in table'),
),
)
.extends(CG.common('ILikertColumnProperties'))
.addPlugin(new OptionsPlugin({ supportsPreselection: true, type: 'single' }))
.addProperty(new CG.prop('layout', CG.common('LayoutStyle').optional()));

0 comments on commit 95de927

Please sign in to comment.