Skip to content

Commit 0f22908

Browse files
committed
CCMSPUI-466 | Add details component
1 parent 8e52869 commit 0f22908

File tree

6 files changed

+145
-26
lines changed

6 files changed

+145
-26
lines changed

laa-ccms-spring-boot-starters/laa-ccms-spring-boot-starter-govuk-dialect/src/main/java/uk/gov/laa/ccms/springboot/dialect/ButtonElementTagProcessor.java

+2-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package uk.gov.laa.ccms.springboot.dialect;
22

3-
import java.util.HashMap;
43
import java.util.Map;
54
import java.util.regex.Pattern;
65
import org.apache.logging.log4j.util.Strings;
@@ -10,11 +9,9 @@
109
import org.thymeleaf.model.IProcessableElementTag;
1110
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
1211
import org.thymeleaf.processor.element.IElementTagStructureHandler;
13-
import org.thymeleaf.standard.expression.IStandardExpression;
14-
import org.thymeleaf.standard.expression.IStandardExpressionParser;
15-
import org.thymeleaf.standard.expression.StandardExpressions;
1612
import org.thymeleaf.templatemode.TemplateMode;
1713

14+
1815
/**
1916
* Transforms <govuk:button/> elements into standard HTML button elements.
2017
*/
@@ -32,7 +29,7 @@ public ButtonElementTagProcessor() {
3229
protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
3330
IElementTagStructureHandler structureHandler) {
3431

35-
Map<String, String> attributes = parseAttributes(context, tag);
32+
Map<String, String> attributes = ProcessorUtils.parseAttributes(context, tag);
3633
String classNames = buildClassNames(attributes);
3734
String commonAttributes = buildCommonAttributes(classNames, attributes);
3835
String buttonAttributes = buildButtonAttributes(attributes);
@@ -43,26 +40,6 @@ protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
4340
replaceElementWithHtml(context, structureHandler, html);
4441
}
4542

46-
private Map<String, String> parseAttributes(ITemplateContext context,
47-
IProcessableElementTag tag) {
48-
Map<String, String> attributes = tag.getAttributeMap();
49-
Map<String, String> resolvedAttributes = new HashMap<>();
50-
IStandardExpressionParser parser =
51-
StandardExpressions.getExpressionParser(context.getConfiguration());
52-
53-
for (Map.Entry<String, String> entry : attributes.entrySet()) {
54-
String key = entry.getKey();
55-
String value = entry.getValue();
56-
if (key.startsWith("th:")) {
57-
IStandardExpression expression = parser.parseExpression(context, value);
58-
resolvedAttributes.put(key.replace("th:", ""), (String) expression.execute(context));
59-
} else {
60-
resolvedAttributes.put(key, value);
61-
}
62-
}
63-
64-
return resolvedAttributes;
65-
}
6643

6744
private String buildClassNames(Map<String, String> attributes) {
6845
String classNames = "govuk-button";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package uk.gov.laa.ccms.springboot.dialect;
2+
3+
import java.util.Map;
4+
import org.thymeleaf.context.ITemplateContext;
5+
import org.thymeleaf.model.IModel;
6+
import org.thymeleaf.model.IModelFactory;
7+
import org.thymeleaf.model.IProcessableElementTag;
8+
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
9+
import org.thymeleaf.processor.element.IElementTagStructureHandler;
10+
import org.thymeleaf.templatemode.TemplateMode;
11+
12+
/**
13+
* Transforms <govuk:button/> elements into standard HTML button elements.
14+
*/
15+
public class DetailsElementTagProcessor extends AbstractElementTagProcessor {
16+
17+
private static final String TAG_NAME = "details";
18+
private static final int PRECEDENCE = 900;
19+
20+
public DetailsElementTagProcessor() {
21+
super(TemplateMode.HTML, "govuk", TAG_NAME, true, null, false, PRECEDENCE);
22+
}
23+
24+
@Override
25+
protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
26+
IElementTagStructureHandler structureHandler) {
27+
28+
// Parse attributes
29+
Map<String, String> attributes = ProcessorUtils.parseAttributes(context, tag);
30+
String summaryText = attributes.getOrDefault("summaryText", "");
31+
String text = attributes.getOrDefault("text", "");
32+
33+
// Build the HTML structure
34+
String detailsHtml = buildDetailsHtml(summaryText, text);
35+
36+
// Create the model and replace the tag
37+
final IModelFactory modelFactory = context.getModelFactory();
38+
final IModel model = modelFactory.parse(context.getTemplateData(), detailsHtml);
39+
structureHandler.replaceWith(model, false);
40+
}
41+
42+
private String buildDetailsHtml(String summaryText, String text) {
43+
return new StringBuilder()
44+
.append("<details class=\"").append("govuk-details").append("\">")
45+
.append("<summary class=\"").append("govuk-details__summary").append("\">")
46+
.append("<span class=\"").append("govuk-details__summary-text").append("\">")
47+
.append(summaryText)
48+
.append("</span>")
49+
.append("</summary>")
50+
.append("<div class=\"").append("govuk-details__text").append("\">")
51+
.append(text)
52+
.append("</div>")
53+
.append("</details>")
54+
.toString();
55+
}
56+
}

laa-ccms-spring-boot-starters/laa-ccms-spring-boot-starter-govuk-dialect/src/main/java/uk/gov/laa/ccms/springboot/dialect/GovUkDialect.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ public GovUkDialect() {
1919

2020
@Override
2121
public Set<IProcessor> getProcessors(String dialectPrefix) {
22-
return Set.of(new ButtonElementTagProcessor());
22+
return Set.of(new ButtonElementTagProcessor(), new DetailsElementTagProcessor());
2323
}
2424
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package uk.gov.laa.ccms.springboot.dialect;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import org.thymeleaf.context.ITemplateContext;
6+
import org.thymeleaf.model.IProcessableElementTag;
7+
import org.thymeleaf.standard.expression.IStandardExpression;
8+
import org.thymeleaf.standard.expression.IStandardExpressionParser;
9+
import org.thymeleaf.standard.expression.StandardExpressions;
10+
11+
/**
12+
* ProcessorUtils for common code.
13+
*/
14+
public class ProcessorUtils {
15+
16+
private ProcessorUtils() {
17+
}
18+
19+
/**
20+
* Evaluate thymeleaf expressions.
21+
*/
22+
public static Map<String, String> parseAttributes(ITemplateContext context,
23+
IProcessableElementTag tag) {
24+
Map<String, String> attributes = tag.getAttributeMap();
25+
Map<String, String> resolvedAttributes = new HashMap<>();
26+
IStandardExpressionParser parser =
27+
StandardExpressions.getExpressionParser(context.getConfiguration());
28+
29+
for (Map.Entry<String, String> entry : attributes.entrySet()) {
30+
String key = entry.getKey();
31+
String value = entry.getValue();
32+
if (key.startsWith("th:")) {
33+
IStandardExpression expression = parser.parseExpression(context, value);
34+
resolvedAttributes.put(key.replace("th:", ""), (String) expression.execute(context));
35+
} else {
36+
resolvedAttributes.put(key, value);
37+
}
38+
}
39+
40+
return resolvedAttributes;
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package uk.gov.laa.ccms.springboot.dialect;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.boot.test.context.SpringBootTest;
8+
import org.thymeleaf.context.Context;
9+
import org.thymeleaf.spring6.SpringTemplateEngine;
10+
11+
@SpringBootTest(classes = ThymeleafTestConfig.class)
12+
class DetailsElementTagProcessorTest {
13+
14+
@Autowired
15+
private SpringTemplateEngine templateEngine;
16+
17+
@Test
18+
void shouldRenderGovukButton() {
19+
20+
Context context = new Context();
21+
String renderedHtml = templateEngine.process("test-details", context);
22+
assertThat(renderedHtml)
23+
.contains(
24+
"<details class=\"govuk-details\"><summary class=\"govuk-details__summary\">" +
25+
"<span class=\"govuk-details__summary-text\">Help with nationality</span>" +
26+
"</summary><div class=\"govuk-details__text\">We need to know your nationality " +
27+
"so we can work out which elections you're entitled to vote in.</div></details>");
28+
29+
}
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html xmlns:govuk="http://www.thymeleaf.org" lang="EN">
3+
<head>
4+
<title>Button Test</title>
5+
</head>
6+
<body>
7+
8+
<govuk:details summaryText="Help with nationality"
9+
text="We need to know your nationality so we can work out which elections you're entitled to vote in."/>
10+
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)