Skip to content

Commit

Permalink
Separate Nunjucks macro options from examples
Browse files Browse the repository at this point in the history
- Split the Nunjucks parameter table code from the example code
- Automatically insert parameter tables at the bottom of component pages
- If there is only one set of parameters, the table is output immediately; otherwise, an accordion is created
  • Loading branch information
querkmachine committed Aug 21, 2024
1 parent b56ee43 commit f86ab6b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 67 deletions.
3 changes: 2 additions & 1 deletion src/javascripts/application.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-new */

import { createAll, Button, NotificationBanner, SkipLink } from 'govuk-frontend'
import { createAll, Accordion, Button, NotificationBanner, SkipLink } from 'govuk-frontend'

import { loadAnalytics } from './components/analytics.mjs'
import BackToTop from './components/back-to-top.mjs'
Expand All @@ -19,6 +19,7 @@ import Search from './components/search.mjs'
import AppTabs from './components/tabs.mjs'

// Initialise GOV.UK Frontend
createAll(Accordion)
createAll(Button)
createAll(NotificationBanner)
createAll(SkipLink)
Expand Down
1 change: 1 addition & 0 deletions src/stylesheets/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ $govuk-new-typography-scale: true;
@import "govuk/core";
@import "govuk/objects";

@import "govuk/components/accordion";
@import "govuk/components/back-link";
@import "govuk/components/breadcrumbs";
@import "govuk/components/button";
Expand Down
2 changes: 2 additions & 0 deletions views/layouts/layout-pane.njk
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
{{ contents | safe }}
</div>

{% include "_nunjucks-params.njk" %}

{# No JS fallback to show overview #}
{% if showSubNav %}
{% include "_category-nav.njk" %}
Expand Down
68 changes: 2 additions & 66 deletions views/partials/_example.njk
Original file line number Diff line number Diff line change
Expand Up @@ -80,72 +80,8 @@
{% endif -%}
<div class="app-tabs__container js-tabs__container{{ " js-tabs__container--no-tabs" if (params.hideTab) }}" id="{{ exampleId }}-nunjucks" role="tabpanel">
{%- if (params.group == 'components') %}
{% set macroOptions = getMacroOptions(params.item) %}

{% set macroOptionsHTML %}
<p>
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
</p>
<p>
Some options are required for the macro to work; these are marked as "Required" in the option description.
</p>
<p>
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against <a href="https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting">cross-site scripting exploits</a>.
</p>
{% for table in macroOptions %}
<table class="govuk-table app-options__table" id="options-{{ exampleId }}--{{ table.slug }}">
<caption class="govuk-table__caption govuk-heading-m {% if table.slug == 'primary' %} govuk-visually-hidden{% endif %}">{{ table.name | safe }}</caption>
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th class="govuk-table__header app-options__limit-table-cell" scope="col">Name</th>
<th class="govuk-table__header app-options__limit-table-cell" scope="col">Type</th>
<th class="govuk-table__header" scope="col">Description</th>
</tr>
</thead>
<tbody class="govuk-table__body">
{% for option in table.options -%}
{# Option name only, without parent prefix -#}
{% set optionName = option.name.split(" ") | last %}
<tr class="govuk-table__row">
<th class="govuk-table__header" scope="row">{{ optionName | safe }}</th>
<td class="govuk-table__cell">{{ option.type }}</td>
<td class="govuk-table__cell">
{% if (option.required) %}
<strong>Required.</strong>
{% endif %}
{{ option.description | safe }}
{% if (option.params) or (option.isComponent and ["hint", "label"].includes(option.id)) %}
{% if option.isComponent and not ["hint", "label"].includes(option.id) %}
{# Link to subset of Nunjucks macro options table and Design System component page -#}
See supported <a href="#options-{{ exampleId }}--{{ option.slug }}">{{ option.name | safe }}</a> options for <a href="/components/{{ option.slug }}/#options-{{ option.slug }}-example">{{ optionName | safe }}</a>.
{% else %}
{# Link to Nunjucks macro options table only -#}
See <a href="#options-{{ exampleId }}--{{ option.slug }}">{{ option.name | safe }}</a>.
{% endif %}
{% elif option.isComponent %}
{# Link to Design System component page for nested components -#}
See <a href="/components/{{ option.slug }}/#options-{{ option.slug }}-example">{{ optionName | safe }}</a>.
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}

{%- endset %}

{%- from "govuk/components/details/macro.njk" import govukDetails %}

{{- govukDetails({
summaryHtml: '<span data-components="github-component-arguments">Nunjucks macro options</span>',
html: macroOptionsHTML,
classes: "app-options",
attributes:{
id: "options-" + exampleId + "-details"
}
})}}
{% endif -%}
<p><a href="#nunjucks-options"> Nunjucks options for this component</a></p>
{%- endif %}
<div class="app-example__code" data-module="app-copy">

```njk
Expand Down
81 changes: 81 additions & 0 deletions views/partials/_nunjucks-params.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{% if ["Components"].includes(section) %}
{% from "govuk/components/accordion/macro.njk" import govukAccordion %}

{% set macroOptions = getMacroOptions(item) %}
{% set accordionSections = [] %}

{# Utility macro for holding all the table code #}
{% macro _paramTable(table) %}
<table class="govuk-table app-options__table" id="options--{{ table.slug }}">
<thead class="govuk-table__head">
<tr class="govuk-table__row">
<th class="govuk-table__header app-options__limit-table-cell" scope="col">Name</th>
<th class="govuk-table__header app-options__limit-table-cell" scope="col">Type</th>
<th class="govuk-table__header" scope="col">Description</th>
</tr>
</thead>
<tbody class="govuk-table__body">
{% for option in table.options -%}
{# Option name only, without parent prefix -#}
{% set optionName = option.name.split(" ") | last %}
<tr class="govuk-table__row">
<th class="govuk-table__header" scope="row">{{ optionName | safe }}</th>
<td class="govuk-table__cell">{{ option.type }}</td>
<td class="govuk-table__cell">
{% if (option.required) %}
<strong>Required.</strong>
{% endif %}
{{ option.description | safe }}
{% if (option.params) or (option.isComponent and ["hint", "label"].includes(option.id)) %}
{% if option.isComponent and not ["hint", "label"].includes(option.id) %}
{# Link to subset of Nunjucks macro options table and Design System component page -#}
See supported <a href="#options--{{ option.slug }}">{{ option.name | safe }}</a> options for <a href="/components/{{ option.slug }}/#options-{{ option.slug }}-example">{{ optionName | safe }}</a>.
{% else %}
{# Link to Nunjucks macro options table only -#}
See <a href="#options--{{ option.slug }}">{{ option.name | safe }}</a>.
{% endif %}
{% elif option.isComponent %}
{# Link to Design System component page for nested components -#}
See <a href="/components/{{ option.slug }}/#options-{{ option.slug }}-example">{{ optionName | safe }}</a>.
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endmacro %}

<h2 class="govuk-heading-l govuk-!-padding-top-7" id="nunjucks-options">Nunjucks options for this component</h2>
<div class="app-prose-scope">
<p>Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.</p>
<p>Some options are required for the macro to work; these are marked as "Required" in the option description.</p>
<p>If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against <a href="https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting">cross-site scripting exploits</a>.</p>

{# If there is only one table, just output it to the page #}
{% if macroOptions.length === 1 %}
{{ _paramTable(macroOptions[0]) }}

{# Otherwise, loop through them all and build out an accordion #}
{% else %}
{% for table in macroOptions %}
{% set tableName %}{{ table.name | safe }}{% endset %}
{% set tableHtml %}
{{ _paramTable(table) }}
{% endset %}

{# Push content into an array, formatted as needed by the accordion #}
{% set accordionSections = (accordionSections.push({
heading: { html: tableName },
content: { html: tableHtml }
}), accordionSections)%}
{% endfor %}

{{ govukAccordion({
id: "nunjucks-options-accordion",
headingLevel: 3,
rememberExpanded: false,
items: accordionSections
}) }}
{% endif %}
</div>
{% endif %}

0 comments on commit f86ab6b

Please sign in to comment.