@nationalarchives/frontend 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/nationalarchives/all+analytics.js +1 -1
- package/nationalarchives/all+analytics.js.map +1 -1
- package/nationalarchives/all.css +1 -1
- package/nationalarchives/all.css.map +1 -1
- package/nationalarchives/all.js +1 -1
- package/nationalarchives/all.js.map +1 -1
- package/nationalarchives/all.mjs +11 -1
- package/nationalarchives/assets/images/favicon.ico +0 -0
- package/nationalarchives/assets/images/favicon.svg +7 -0
- package/nationalarchives/assets/images/mstile-150x150.png +0 -0
- package/nationalarchives/assets/images/nationalarchives-opengraph-image.png +0 -0
- package/nationalarchives/components/TextAreaCharacterCount/TextAreaCharacterCount.js +2 -0
- package/nationalarchives/components/TextAreaCharacterCount/TextAreaCharacterCount.js.map +1 -0
- package/nationalarchives/components/TextAreaItemisedRows/TextAreaItemisedRows.js +2 -0
- package/nationalarchives/components/TextAreaItemisedRows/TextAreaItemisedRows.js.map +1 -0
- package/nationalarchives/components/button/fixtures.json +1 -1
- package/nationalarchives/components/button/template.njk +1 -1
- package/nationalarchives/components/card/fixtures.json +1 -1
- package/nationalarchives/components/card/template.njk +1 -1
- package/nationalarchives/components/code-block/fixtures.json +1 -1
- package/nationalarchives/components/date-input/macro-options.json +2 -1
- package/nationalarchives/components/footer/fixtures.json +1 -1
- package/nationalarchives/components/hero/fixtures.json +1 -1
- package/nationalarchives/components/pagination/fixtures.json +4 -4
- package/nationalarchives/components/textarea/TextAreaCharacterCount.mjs +160 -0
- package/nationalarchives/components/textarea/TextAreaItemisedRows.mjs +202 -0
- package/nationalarchives/components/textarea/fixtures.json +43 -2
- package/nationalarchives/components/textarea/macro-options.json +36 -1
- package/nationalarchives/components/textarea/template.njk +15 -2
- package/nationalarchives/components/textarea/textarea.css +1 -1
- package/nationalarchives/components/textarea/textarea.css.map +1 -1
- package/nationalarchives/components/textarea/textarea.js +1 -1
- package/nationalarchives/components/textarea/textarea.js.map +1 -1
- package/nationalarchives/components/textarea/textarea.mjs +3 -197
- package/nationalarchives/components/textarea/textarea.scss +12 -1
- package/nationalarchives/prototype-kit.css +1 -1
- package/nationalarchives/prototype-kit.css.map +1 -1
- package/nationalarchives/templates/fixtures.json +3 -3
- package/nationalarchives/templates/layouts/_generic.njk +2 -14
- package/nationalarchives/templates/macros/title.njk +63 -0
- package/package.json +4 -4
- package/nationalarchives/assets/images/nationalarchives-opengraph-image-dark.png +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
export default class TextAreaItemisedRows {
|
|
2
|
+
constructor($module, options = {}) {
|
|
3
|
+
this.$module = $module;
|
|
4
|
+
this.$formFieldInput =
|
|
5
|
+
this.$module && this.$module.querySelector(".tna-textarea");
|
|
6
|
+
this.$formFieldInputHint =
|
|
7
|
+
this.$module && this.$module.querySelector(".tna-form-item__hint");
|
|
8
|
+
this.$formFieldBody =
|
|
9
|
+
this.$module && this.$module.querySelector(".tna-form-item__body");
|
|
10
|
+
|
|
11
|
+
if (
|
|
12
|
+
!this.$module ||
|
|
13
|
+
!this.$formFieldInput ||
|
|
14
|
+
!this.$formFieldBody ||
|
|
15
|
+
this.$formFieldInput.getAttribute("hidden") !== null
|
|
16
|
+
) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!(this.$formFieldInput instanceof HTMLTextAreaElement)) {
|
|
21
|
+
throw new Error("Expected a textarea element");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { enhancedHint } = options;
|
|
25
|
+
this.enhancedHint = enhancedHint || "Enter an item and press enter";
|
|
26
|
+
|
|
27
|
+
this.values = this.$formFieldInput.value
|
|
28
|
+
.split("\n")
|
|
29
|
+
.map((value) => value.trim())
|
|
30
|
+
.filter((value) => value);
|
|
31
|
+
|
|
32
|
+
this.id = this.$formFieldInput.id;
|
|
33
|
+
|
|
34
|
+
this.init();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
init() {
|
|
38
|
+
this.$formFieldNewInput = document.createElement("input");
|
|
39
|
+
this.$formFieldNewInput.classList.add("tna-text-input");
|
|
40
|
+
["id", "aria-describedby"].forEach((attribute) => {
|
|
41
|
+
this.$formFieldNewInput.setAttribute(
|
|
42
|
+
attribute,
|
|
43
|
+
this.$formFieldInput.getAttribute(attribute),
|
|
44
|
+
);
|
|
45
|
+
this.$formFieldInput.removeAttribute(attribute);
|
|
46
|
+
});
|
|
47
|
+
this.$formFieldBody.appendChild(this.$formFieldNewInput);
|
|
48
|
+
this.$formFieldInput.setAttribute("hidden", "");
|
|
49
|
+
this.$formFieldInput.addEventListener("keyup", () => this.updateList());
|
|
50
|
+
this.$formFieldNewInput.addEventListener("keypress", (event) => {
|
|
51
|
+
if (event.key === "Enter") {
|
|
52
|
+
this.appendValue(event.target.value);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this.$formFieldNewInputAddButton = document.createElement("button");
|
|
57
|
+
this.$formFieldNewInputAddButton.setAttribute("type", "button");
|
|
58
|
+
this.$formFieldNewInputAddButton.classList.add(
|
|
59
|
+
"tna-button",
|
|
60
|
+
"tna-button--small",
|
|
61
|
+
);
|
|
62
|
+
this.$formFieldNewInputAddButtonInner = document.createElement("span");
|
|
63
|
+
this.$formFieldNewInputAddButtonInner.innerText = "Add";
|
|
64
|
+
this.$formFieldNewInputAddButtonInnerExtra = document.createElement("span");
|
|
65
|
+
this.$formFieldNewInputAddButtonInnerExtra.classList.add(
|
|
66
|
+
"tna-visually-hidden",
|
|
67
|
+
);
|
|
68
|
+
this.$formFieldNewInputAddButtonInnerExtra.innerText = " to list";
|
|
69
|
+
this.$formFieldNewInputAddButtonInner.appendChild(
|
|
70
|
+
this.$formFieldNewInputAddButtonInnerExtra,
|
|
71
|
+
);
|
|
72
|
+
this.$formFieldNewInputAddButton.appendChild(
|
|
73
|
+
this.$formFieldNewInputAddButtonInner,
|
|
74
|
+
);
|
|
75
|
+
this.$formFieldBody.appendChild(this.$formFieldNewInputAddButton);
|
|
76
|
+
this.$formFieldNewInputAddButton.addEventListener("click", () => {
|
|
77
|
+
this.appendValue(this.$formFieldNewInput.value);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
this.$formFieldLiveAria = document.createElement("div");
|
|
81
|
+
this.$formFieldLiveAria.setAttribute("aria-live", "polite");
|
|
82
|
+
this.$formFieldLiveAria.classList.add("tna-visually-hidden");
|
|
83
|
+
this.$module.appendChild(this.$formFieldLiveAria);
|
|
84
|
+
|
|
85
|
+
this.$formFieldCounter = document.createElement("p");
|
|
86
|
+
this.$formFieldCounter.id = `${this.id}-list-helper`;
|
|
87
|
+
this.$formFieldCounter.classList.add("tna-!--margin-top-xs");
|
|
88
|
+
this.$module.appendChild(this.$formFieldCounter);
|
|
89
|
+
|
|
90
|
+
this.$formFieldNewInput.setAttribute(
|
|
91
|
+
"aria-describedby",
|
|
92
|
+
`${this.$formFieldNewInput.getAttribute("aria-describedby")} ${
|
|
93
|
+
this.$formFieldCounter.id
|
|
94
|
+
}`,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
this.$valuesList = document.createElement("ul");
|
|
98
|
+
this.$valuesList.classList.add(
|
|
99
|
+
"tna-compound-filters",
|
|
100
|
+
"tna-!--margin-top-xs",
|
|
101
|
+
);
|
|
102
|
+
this.$valuesList.addEventListener("blur", () => {
|
|
103
|
+
this.$valuesList.removeAttribute("tabindex");
|
|
104
|
+
this.updateAriaText("");
|
|
105
|
+
});
|
|
106
|
+
this.$module.appendChild(this.$valuesList);
|
|
107
|
+
|
|
108
|
+
if (!this.$formFieldInputHint) {
|
|
109
|
+
this.$formFieldInputHint = document.createElement("p");
|
|
110
|
+
this.$formFieldInputHint.classList.add("tna-form-item__hint");
|
|
111
|
+
this.$formFieldBody.parentNode.insertBefore(
|
|
112
|
+
this.$formFieldInputHint,
|
|
113
|
+
this.$formFieldBody,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
this.$formFieldInputHint.innerText = this.enhancedHint;
|
|
117
|
+
|
|
118
|
+
this.updateList();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
updateAriaText(content) {
|
|
122
|
+
this.$formFieldLiveAria.innerText = content;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* eslint-disable-next-line class-methods-use-this */
|
|
126
|
+
normaliseValue(value) {
|
|
127
|
+
return value.replace(/\s{2,}/u, " ").trim();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
isValueInList(value) {
|
|
131
|
+
return this.values
|
|
132
|
+
.map((eachValue) => this.normaliseValue(eachValue).toLowerCase())
|
|
133
|
+
.includes(value.toLowerCase().trim());
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
appendValue(value) {
|
|
137
|
+
const newValue = this.normaliseValue(value);
|
|
138
|
+
if (newValue) {
|
|
139
|
+
if (this.isValueInList(newValue)) {
|
|
140
|
+
this.updateAriaText(`'${newValue}' already added`);
|
|
141
|
+
} else {
|
|
142
|
+
this.values.push(newValue);
|
|
143
|
+
this.$formFieldInput.value = this.values.join("\n");
|
|
144
|
+
this.updateList();
|
|
145
|
+
this.updateAriaText(`'${newValue}' added`);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
this.updateAriaText("Enter an item to add");
|
|
149
|
+
}
|
|
150
|
+
this.$formFieldNewInput.value = "";
|
|
151
|
+
this.$formFieldNewInput.focus();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
removeValue(value) {
|
|
155
|
+
const removeValue = this.normaliseValue(value);
|
|
156
|
+
if (removeValue && this.isValueInList(removeValue)) {
|
|
157
|
+
this.values = this.values.filter(
|
|
158
|
+
(existingValue) => existingValue !== removeValue,
|
|
159
|
+
);
|
|
160
|
+
this.$formFieldInput.value = this.values.join("\n");
|
|
161
|
+
this.updateList();
|
|
162
|
+
this.updateAriaText(`'${removeValue}' removed`);
|
|
163
|
+
}
|
|
164
|
+
if (this.values.length) {
|
|
165
|
+
this.$valuesList.setAttribute("tabindex", "0");
|
|
166
|
+
this.$valuesList.focus();
|
|
167
|
+
} else {
|
|
168
|
+
this.$formFieldNewInput.focus();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
updateList() {
|
|
173
|
+
this.$valuesList.innerHTML = "";
|
|
174
|
+
this.values
|
|
175
|
+
.map((value) => {
|
|
176
|
+
const $item = document.createElement("li");
|
|
177
|
+
$item.classList.add("tna-compound-filters__item");
|
|
178
|
+
const $itemLabel = document.createElement("span");
|
|
179
|
+
$itemLabel.innerText = value;
|
|
180
|
+
$item.appendChild($itemLabel);
|
|
181
|
+
|
|
182
|
+
const $removeItemButton = document.createElement("button");
|
|
183
|
+
$removeItemButton.innerText = `Remove '${value}'`;
|
|
184
|
+
$removeItemButton.setAttribute("type", "button");
|
|
185
|
+
$removeItemButton.classList.add("tna-compound-filters__link");
|
|
186
|
+
$removeItemButton.addEventListener("click", () => {
|
|
187
|
+
this.removeValue(value);
|
|
188
|
+
});
|
|
189
|
+
$item.appendChild($removeItemButton);
|
|
190
|
+
return $item;
|
|
191
|
+
})
|
|
192
|
+
.forEach(($item) => this.$valuesList.appendChild($item));
|
|
193
|
+
|
|
194
|
+
let innerTextItemValue = "item";
|
|
195
|
+
/* eslint-disable-next-line no-magic-numbers */
|
|
196
|
+
if (this.values.length !== 1) {
|
|
197
|
+
innerTextItemValue += "s";
|
|
198
|
+
}
|
|
199
|
+
const innerTextValue = `${new Intl.NumberFormat().format(this.values.length)} ${innerTextItemValue} added`;
|
|
200
|
+
this.$formFieldCounter.innerText = innerTextValue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"name": "feedback",
|
|
32
32
|
"hint": "What did you think?"
|
|
33
33
|
},
|
|
34
|
-
"html": "<div class=\"tna-form-item\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><p id=\"feedback-hint\" class=\"tna-form-item__hint\">What did you think?</p><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\"feedback-hint
|
|
34
|
+
"html": "<div class=\"tna-form-item\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><p id=\"feedback-hint\" class=\"tna-form-item__hint\">What did you think?</p><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\"feedback-hint \"></textarea></div></div>"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"name": "with an error",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"text": "Enter some feedback"
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
-
"html": "<div class=\"tna-form-item tna-form-item--error\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><p id=\"feedback-error\" class=\"tna-form-item__error\"><span class=\"tna-visually-hidden\">Error:</span> Enter some feedback</p><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\" feedback-error\"></textarea></div></div>"
|
|
47
|
+
"html": "<div class=\"tna-form-item tna-form-item--error\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><p id=\"feedback-error\" class=\"tna-form-item__error\"><span class=\"tna-visually-hidden\">Error:</span> Enter some feedback</p><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\" feedback-error \"></textarea></div></div>"
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
"name": "textarea size",
|
|
@@ -123,6 +123,47 @@
|
|
|
123
123
|
},
|
|
124
124
|
"html": "<div class=\"tna-form-item\" data-module=\"tna-textarea-itemised-rows\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\"></textarea></div></div>"
|
|
125
125
|
},
|
|
126
|
+
{
|
|
127
|
+
"name": "with character count",
|
|
128
|
+
"options": {
|
|
129
|
+
"label": "Enter your feedback",
|
|
130
|
+
"headingSize": "m",
|
|
131
|
+
"id": "feedback",
|
|
132
|
+
"name": "feedback",
|
|
133
|
+
"characterCount": {
|
|
134
|
+
"max": 200
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"html": "<div class=\"tna-form-item\" data-module=\"tna-textarea-character-count\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\" feedback-count\" data-max-length=\"200\"></textarea><div id=\"feedback-count\" class=\"tna-visually-hidden\">You can enter up to 200 characters</div><p class=\"tna-textarea-count\" aria-hidden=\"true\">You can enter up to 200 characters</p><div class=\"tna-textarea-count__screen-reader-status tna-visually-hidden\" aria-live=\"polite\">You can enter up to 200 characters</div></div></div>"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "with word count",
|
|
141
|
+
"options": {
|
|
142
|
+
"label": "Enter your feedback",
|
|
143
|
+
"headingSize": "m",
|
|
144
|
+
"id": "feedback",
|
|
145
|
+
"name": "feedback",
|
|
146
|
+
"characterCount": {
|
|
147
|
+
"max": 200,
|
|
148
|
+
"countType": "words"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"html": "<div class=\"tna-form-item\" data-module=\"tna-textarea-character-count\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\" feedback-count\" data-max-length=\"200\" data-count-type=\"words\"></textarea><div id=\"feedback-count\" class=\"tna-visually-hidden\">You can enter up to 200 words</div><p class=\"tna-textarea-count\" aria-hidden=\"true\">You can enter up to 200 words</p><div class=\"tna-textarea-count__screen-reader-status tna-visually-hidden\" aria-live=\"polite\">You can enter up to 200 words</div></div></div>"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"name": "with character count and custom debounce duration",
|
|
155
|
+
"options": {
|
|
156
|
+
"label": "Enter your feedback",
|
|
157
|
+
"headingSize": "m",
|
|
158
|
+
"id": "feedback",
|
|
159
|
+
"name": "feedback",
|
|
160
|
+
"characterCount": {
|
|
161
|
+
"max": 200,
|
|
162
|
+
"debounceDuration": 500
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"html": "<div class=\"tna-form-item\" data-module=\"tna-textarea-character-count\"><div class=\"tna-form-item__header\"><label class=\"tna-form-item__label tna-heading-m\" for=\"feedback\">Enter your feedback</label></div><div class=\"tna-form-item__body\"><textarea id=\"feedback\" class=\"tna-textarea\" name=\"feedback\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" rows=\"5\" aria-describedby=\" feedback-count\" data-max-length=\"200\" data-debounce-duration=\"500\"></textarea><div id=\"feedback-count\" class=\"tna-visually-hidden\">You can enter up to 200 characters</div><p class=\"tna-textarea-count\" aria-hidden=\"true\">You can enter up to 200 characters</p><div class=\"tna-textarea-count__screen-reader-status tna-visually-hidden\" aria-live=\"polite\">You can enter up to 200 characters</div></div></div>"
|
|
166
|
+
},
|
|
126
167
|
{
|
|
127
168
|
"name": "with classes",
|
|
128
169
|
"options": {
|
|
@@ -56,6 +56,41 @@
|
|
|
56
56
|
}
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
|
+
{
|
|
60
|
+
"name": "characterCount",
|
|
61
|
+
"type": "object",
|
|
62
|
+
"required": false,
|
|
63
|
+
"description": "Configuration for the character count feature. Can not be used with `itemiseRows`.",
|
|
64
|
+
"params": [
|
|
65
|
+
{
|
|
66
|
+
"name": "max",
|
|
67
|
+
"type": "number",
|
|
68
|
+
"required": true,
|
|
69
|
+
"description": "The maximum number of characters (or words if countType is set to `words`)."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "countType",
|
|
73
|
+
"type": "string",
|
|
74
|
+
"required": false,
|
|
75
|
+
"description": "The type of character count to display. Can be `characters` or `words`.",
|
|
76
|
+
"default": "characters"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "threshold",
|
|
80
|
+
"type": "number",
|
|
81
|
+
"required": false,
|
|
82
|
+
"description": "The character count threshold in percent at which to start displaying a warning.",
|
|
83
|
+
"default": 80
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "debounceDuration",
|
|
87
|
+
"type": "number",
|
|
88
|
+
"required": false,
|
|
89
|
+
"description": "The debounce duration in milliseconds for updating the character count.",
|
|
90
|
+
"default": 1000
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
59
94
|
{
|
|
60
95
|
"name": "spellcheck",
|
|
61
96
|
"type": "boolean",
|
|
@@ -94,7 +129,7 @@
|
|
|
94
129
|
"name": "itemiseRows",
|
|
95
130
|
"type": "boolean",
|
|
96
131
|
"required": false,
|
|
97
|
-
"description": "If `true`, when JavaScript is available, parse each row of the textarea content into a list of items.",
|
|
132
|
+
"description": "If `true`, when JavaScript is available, parse each row of the textarea content into a list of items. Ignored if `characterCount` is enabled.",
|
|
98
133
|
"default": false
|
|
99
134
|
},
|
|
100
135
|
{
|
|
@@ -9,8 +9,21 @@
|
|
|
9
9
|
error: params.error,
|
|
10
10
|
classes: params.formItemClasses,
|
|
11
11
|
attributes: params.formItemAttributes
|
|
12
|
-
}, 'tna-textarea-itemised-rows' if params.itemiseRows else '') %}
|
|
12
|
+
}, 'tna-textarea-character-count' if params.characterCount else ('tna-textarea-itemised-rows' if params.itemiseRows else '')) %}
|
|
13
13
|
<textarea id="{{ params.id }}" class="tna-textarea{% if params.size %} tna-textarea--{{ params.size }}{% endif %}{% if params.classes %} {{ params.classes }}{% endif %}" name="{{ params.name }}" spellcheck="{{ params.spellcheck if params.spellcheck else false }}" autocapitalize="{{ params.autocapitalize if params.autocapitalize else 'off' }}" autocorrect="{{ 'on' if params.autocorrect else 'off' }}" rows="{{ params.rows if params.rows else 5 }}"
|
|
14
|
-
{%- if params.hint or params.error %} aria-describedby="{%- if params.hint -%}{{ params.id }}-hint{%- endif %} {% if params.error -%}{{ params.id }}-error{%- endif -%}"{%- endif %}
|
|
14
|
+
{%- if params.hint or params.error or params.characterCount %} aria-describedby="{%- if params.hint -%}{{ params.id }}-hint{%- endif %} {% if params.error -%}{{ params.id }}-error{%- endif %} {% if params.characterCount -%}{{ params.id }}-count{%- endif -%}"{%- endif %}
|
|
15
|
+
{%- if params.characterCount %} data-max-length="{{ params.characterCount.max }}"
|
|
16
|
+
{%- if params.characterCount.countType %} data-count-type="{{ params.characterCount.countType }}"{%- endif %}
|
|
17
|
+
{%- if params.characterCount.threshold %} data-count-threshold="{{ params.characterCount.threshold }}"{%- endif %}
|
|
18
|
+
{%- if params.characterCount.debounceDuration %} data-debounce-duration="{{ params.characterCount.debounceDuration }}"{%- endif %}
|
|
19
|
+
{%- endif %}
|
|
15
20
|
{%- for attribute, value in params.attributes %} {{ attribute }}{% if value !== '' %}="{{ value }}"{% endif %}{% endfor %}>{{ params.value }}</textarea>
|
|
21
|
+
{%- if params.characterCount %}
|
|
22
|
+
{%- set characterCountMessage %}
|
|
23
|
+
You can enter up to {{ params.characterCount.max }} {{ params.characterCount.countType | default('characters') }}
|
|
24
|
+
{%- endset %}
|
|
25
|
+
<div id="{{ params.id }}-count" class="tna-visually-hidden">{{ characterCountMessage }}</div>
|
|
26
|
+
<p class="tna-textarea-count" aria-hidden="true">{{ characterCountMessage }}</p>
|
|
27
|
+
<div class="tna-textarea-count__screen-reader-status tna-visually-hidden" aria-live="polite">{{ characterCountMessage }}</div>
|
|
28
|
+
{%- endif %}
|
|
16
29
|
{%- endcall %}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.tna-textarea{color:var(--input-foreground, rgb(1, 1, 1));background-color:var(--input-background, rgb(255, 255, 255));border:2px var(--input-border, rgb(1, 1, 1)) solid}.tna-textarea:hover{outline:4px var(--keyline) solid}.tna-textarea{width:100%;min-height:calc(7.5rem + 0.5rem);padding:0.25rem 0.5rem;display:block;box-sizing:border-box;resize:vertical;line-height:1.5;border-radius:2px}.tna-form-item--error .tna-textarea{border-color:var(--form-error-border, #c20000)}.tna-textarea--m{max-width:20rem}.tna-textarea--l{max-width:40rem}.tna-textarea--xl{max-width:80rem}[data-module=tna-textarea-itemised-rows] .tna-form-item__body{display:flex;align-items:stretch;gap:2px}[data-module=tna-textarea-itemised-rows] .tna-form-item__body .tna-text-input{flex:1}[data-module=tna-textarea-itemised-rows] .tna-form-item__body .tna-button{align-items:center}/*# sourceMappingURL=textarea.css.map */
|
|
1
|
+
.tna-textarea{color:var(--input-foreground, rgb(1, 1, 1));background-color:var(--input-background, rgb(255, 255, 255));border:2px var(--input-border, rgb(1, 1, 1)) solid}.tna-textarea:hover{outline:4px var(--keyline) solid}.tna-textarea{width:100%;min-height:calc(7.5rem + 0.5rem);padding:0.25rem 0.5rem;display:block;box-sizing:border-box;resize:vertical;line-height:1.5;border-radius:2px}.tna-form-item--error .tna-textarea,.tna-textarea--error{border-color:var(--form-error-border, #c20000)}.tna-textarea--m{max-width:20rem}.tna-textarea--l{max-width:40rem}.tna-textarea--xl{max-width:80rem}[data-module=tna-textarea-itemised-rows] .tna-form-item__body{display:flex;align-items:stretch;gap:2px}[data-module=tna-textarea-itemised-rows] .tna-form-item__body .tna-text-input{flex:1}[data-module=tna-textarea-itemised-rows] .tna-form-item__body .tna-button{align-items:center}.tna-textarea-count{margin-top:0.5rem}.tna-textarea-count--error{color:var(--form-error-text, #c20000);font-weight:700}/*# sourceMappingURL=textarea.css.map */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../../../../src/nationalarchives/tools/_colour.scss","../../../../src/nationalarchives/components/textarea/textarea.scss","../../../../src/nationalarchives/tools/_borders.scss","../../../../src/nationalarchives/variables/_borders.scss"],"names":[],"mappings":"AA4IA,cA9DE,4CAIA,6DA4BI,mDAmCJ,oBACE,iCCzIJ,cACE,WACA,iCAIA,uBAEA,cACA,sBAEA,gBAEA,gBCnBA,cCDsB,IF0BtB,oCDuFI,+CCnFJ,iBACE,gBAGF,iBACE,gBAGF,kBACE,gBAKF,8DACE,aACA,oBACA,QAEA,8EACE,OAGF,0EACE","file":"textarea.css","sourcesContent":["@use \"sass:list\";\n@use \"sass:map\";\n@use \"sass:meta\";\n@use \"../variables/a11y\";\n@use \"../variables/borders\";\n@use \"../variables/forms\";\n@use \"../variables/colour\";\n@use \"../variables/features\";\n@use \"../tools/media\";\n\n$base-colours: (\n \"background\",\n \"font-base\",\n \"font-dark\",\n \"font-light\",\n \"icon-light\",\n \"link\",\n \"link-visited\",\n \"keyline\",\n \"keyline-dark\"\n);\n\n@function brand-colour($colour, $opacity: 1) {\n @return colour.brand-colour($colour, $opacity);\n}\n\n@mixin colour-css-vars($excludes...) {\n @each $name, $value in colour.$colour-palette-default {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index($base-colours, $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@mixin colour-css-vars-dark($excludes...) {\n @each $name, $value in colour.$colour-palette-dark {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index($base-colours, $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@mixin colour-css-vars-high-contrast($excludes...) {\n @each $name, $value in colour.$colour-palette-high-contrast {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index($base-colours, $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@mixin colour-css-vars-high-contrast-dark($excludes...) {\n @each $name, $value in colour.$colour-palette-high-contrast-dark {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index((\"keyline\", \"keyline-dark\"), $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@function colour-var($colour) {\n @return var(\n --#{$colour},\n #{map.get(colour.$colour-palette-default, $colour)}\n );\n}\n\n@mixin colour-font($colour, $important: false) {\n color: colour-var($colour) if(sass($important): !important; else: null);\n}\n\n@mixin colour-background($colour, $important: false) {\n background-color: colour-var($colour)\n if(sass($important): !important; else: null);\n}\n\n@mixin colour-background-brand($brandColour, $important: false) {\n background-color: #{brand-colour($brandColour)}\n if(sass($important): !important; else: null);\n}\n\n@mixin colour-border(\n $colour,\n $width: \"\",\n $style: solid,\n $direction: \"\",\n $important: false\n) {\n @if $direction != \"\" {\n @if $width != \"\" {\n border-#{$direction}: $width\n colour-var($colour)\n $style\n if(sass($important): !important; else: null);\n } @else {\n border-#{$direction}-color: colour-var($colour)\n if(sass($important): !important; else: null);\n }\n } @else {\n @if $width != \"\" {\n border: $width\n colour-var($colour)\n $style\n if(sass($important): !important; else: null);\n } @else {\n border-color: var(\n --#{$colour},\n #{map.get(colour.$colour-palette-default, $colour)}\n )\n if(sass($important): !important; else: null);\n }\n }\n}\n\n@mixin colour-outline($colour, $width: \"\", $style: solid, $important: false) {\n @if $width != \"\" {\n outline: $width\n colour-var($colour)\n $style\n if(sass($important): !important; else: null);\n } @else {\n outline-color: colour-var($colour)\n if(sass($important): !important; else: null);\n }\n}\n\n@mixin colour-fill($colour, $important: false) {\n fill: colour-var($colour) if(sass($important): !important; else: null);\n}\n\n%colour-input {\n @include colour-font(\"input-foreground\");\n @include colour-background(\"input-background\");\n @include colour-border(\"input-border\", forms.$form-field-border-width);\n\n &:hover {\n outline: a11y.$focus-outline-active-total-width var(--keyline) solid;\n }\n}\n\n@mixin colour-input() {\n @extend %colour-input;\n}\n\n@mixin thick-keyline($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\"keyline\", $border-width, solid, $direction);\n } @else {\n @include colour-border(\"keyline\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-dark($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\"keyline-dark\", $border-width, solid, $direction);\n } @else {\n @include colour-border(\"keyline-dark\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-accent($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\"accent-border\", $border-width, solid, $direction);\n } @else {\n @include colour-border(\"accent-border\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-error($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\n \"form-error-border\",\n $border-width,\n solid,\n $direction\n );\n } @else {\n @include colour-border(\"form-error-border\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-brand($direction: \"\", $brandColour, $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n border-#{$direction}: $border-width #{brand-colour($brandColour)} solid;\n } @else {\n border: $border-width #{brand-colour($brandColour)} solid;\n }\n}\n\n@mixin thick-keyline-transparent($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n border-#{$direction}: $border-width transparent solid;\n } @else {\n border: $border-width transparent solid;\n }\n}\n\n%always-light {\n @include colour-css-vars;\n\n @media (prefers-contrast: more) {\n @include colour-css-vars-high-contrast;\n }\n}\n\n@mixin always-light {\n @extend %always-light;\n}\n\n%contrast {\n --background: var(--contrast-background);\n --font-base: var(--contrast-font-base);\n --font-dark: var(--contrast-font-dark);\n --font-light: var(--contrast-font-light);\n --icon-light: var(--contrast-icon-light);\n --link: var(--contrast-link);\n --link-visited: var(--contrast-link-visited);\n --keyline: var(--contrast-keyline);\n --keyline-dark: var(--contrast-keyline-dark);\n --button-text: var(--contrast-button-text);\n --button-background: var(--contrast-button-background);\n --button-hover-text: var(--contrast-button-hover-text);\n --button-hover-background: var(--contrast-button-hover-background);\n --accent-border: var(--accent-border-bright);\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n}\n\n@mixin contrast {\n @extend %contrast;\n}\n\n%contrast-on-mobile {\n @include media.on-mobile {\n --background: var(--contrast-background);\n --font-base: var(--contrast-font-base);\n --font-dark: var(--contrast-font-dark);\n --font-light: var(--contrast-font-light);\n --icon-light: var(--contrast-icon-light);\n --link: var(--contrast-link);\n --link-visited: var(--contrast-link-visited);\n --keyline: var(--contrast-keyline);\n --keyline-dark: var(--contrast-keyline-dark);\n --button-text: var(--contrast-button-text);\n --button-background: var(--contrast-button-background);\n --button-hover-text: var(--contrast-button-hover-text);\n --button-hover-background: var(--contrast-button-hover-background);\n --accent-border: var(--accent-border-bright);\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n }\n}\n\n@mixin contrast-on-mobile {\n @extend %contrast-on-mobile;\n}\n\n%base {\n @each $name, $value in $base-colours {\n --#{$name}: var(--base-#{$value});\n }\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n}\n\n@mixin base {\n @extend %base;\n}\n\n%tint {\n --background: var(--background-tint);\n\n @include colour-background(\"background\");\n}\n\n@mixin tint {\n @extend %tint;\n}\n\n%accent {\n --background: var(--accent-background);\n --font-base: var(--accent-font-base);\n --font-dark: var(--accent-font-dark);\n --font-light: var(--accent-font-light);\n --icon-light: var(--accent-icon-light);\n --link: var(--accent-link);\n --link-visited: var(--accent-link);\n --keyline: var(--accent-keyline);\n --keyline-dark: var(--accent-keyline-dark);\n --accent-border: var(--accent-font-dark);\n --button-text: var(--accent-button-text);\n --button-background: var(--accent-button-background);\n --button-hover-text: var(--accent-button-hover-text);\n --button-hover-background: var(--accent-button-hover-background);\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n}\n\n@mixin accent {\n @extend %accent;\n}\n\n%accent-light {\n --background: var(--accent-background-light);\n --font-base: #{map.get(colour.$colour-palette-default, \"font-base\")};\n --font-dark: #{map.get(colour.$colour-palette-default, \"font-dark\")};\n --font-light: #{map.get(colour.$colour-palette-default, \"font-light\")};\n --icon-light: #{map.get(colour.$colour-palette-default, \"icon-light\")};\n --keyline: #{map.get(colour.$colour-palette-default, \"keyline\")};\n --keyline-dark: #{map.get(colour.$colour-palette-default, \"keyline-dark\")};\n --button-text: #{map.get(colour.$colour-palette-default, \"button-text\")};\n --button-background: #{map.get(\n colour.$colour-palette-default,\n \"button-background\"\n )};\n --button-hover-text: #{map.get(\n colour.$colour-palette-default,\n \"button-hover-text\"\n )};\n --button-hover-background: #{map.get(\n colour.$colour-palette-default,\n \"button-hover-background\"\n )};\n --accent-border: var(--accent-background);\n\n @include colour-background(\"background\");\n @include colour-font(\"font-base\");\n\n .tna-template--system-theme & {\n @media (prefers-color-scheme: dark) {\n // --link: #{map.get(colour.$colour-palette-default, \"link\")};\n // --link-visited: #{map.get(colour.$colour-palette-default, \"link-visited\")};\n\n --background: var(--accent-background);\n --font-base: var(--accent-font-base);\n --font-dark: var(--accent-font-dark);\n --font-light: var(--accent-font-light);\n --icon-light: var(--accent-icon-light);\n --link: var(--accent-link);\n --link-visited: var(--accent-link);\n --keyline: var(--accent-keyline);\n --keyline-dark: var(--accent-keyline-dark);\n --accent-border: var(--accent-font-dark);\n --button-text: var(--accent-button-text);\n --button-background: var(--accent-button-background);\n --button-hover-text: var(--accent-button-hover-text);\n --button-hover-background: var(--accent-button-hover-background);\n }\n }\n\n .tna-template--dark-theme & {\n // --link: #{map.get(colour.$colour-palette-default, \"link\")};\n // --link-visited: #{map.get(colour.$colour-palette-default, \"link-visited\")};\n\n --background: var(--accent-background);\n --font-base: var(--accent-font-base);\n --font-dark: var(--accent-font-dark);\n --font-light: var(--accent-font-light);\n --icon-light: var(--accent-icon-light);\n --link: var(--accent-link);\n --link-visited: var(--accent-link);\n --keyline: var(--accent-keyline);\n --keyline-dark: var(--accent-keyline-dark);\n --accent-border: var(--accent-font-dark);\n --button-text: var(--accent-button-text);\n --button-background: var(--accent-button-background);\n --button-hover-text: var(--accent-button-hover-text);\n --button-hover-background: var(--accent-button-hover-background);\n }\n}\n\n@mixin accent-light {\n @extend %accent-light;\n}\n\n%yellow-accent {\n --accent-background: #{colour.brand-colour(\"yellow\")} !important;\n --accent-background-light: #{colour.brand-colour(\"cream\")} !important;\n --accent-border: #{colour.brand-colour(\"yellow\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"yellow\")} !important;\n --accent-font-base: #{colour.brand-colour(\"black\")} !important;\n --accent-font-dark: #{colour.brand-colour(\"black\")} !important;\n --accent-font-light: #{colour.brand-colour(\"black\", 0.7)} !important;\n --accent-icon-light: #{colour.brand-colour(\"black\", 0.7)} !important;\n --accent-link: #{colour.brand-colour(\"black\")} !important;\n --accent-link-visited: #{colour.brand-colour(\"black\")} !important;\n --accent-keyline: #{colour.brand-colour(\"black\", 0.5)} !important;\n --accent-keyline-dark: #{colour.brand-colour(\"black\", 0.8)} !important;\n --button-accented-text: #{colour.brand-colour(\"black\")} !important;\n --button-accented-background: #{colour.brand-colour(\"yellow\")} !important;\n}\n\n@mixin yellow-accent {\n @extend %yellow-accent;\n}\n\n%accent-lighter-text {\n --accent-font-base: #{colour.brand-colour(\"white\")} !important;\n --accent-font-dark: #{colour.brand-colour(\"white\")} !important;\n --accent-font-light: #{colour.brand-colour(\"white\", 0.7)} !important;\n --accent-icon-light: #{colour.brand-colour(\"white\", 0.7)} !important;\n --accent-link: #{colour.brand-colour(\"white\")} !important;\n --accent-link-visited: #{colour.brand-colour(\"white\")} !important;\n --accent-keyline: #{colour.brand-colour(\"white\", 0.5)} !important;\n --accent-keyline-dark: #{colour.brand-colour(\"white\", 0.8)} !important;\n --button-accented-text: #{colour.brand-colour(\"white\")} !important;\n}\n\n%black-accent {\n --accent-background: #{colour.brand-colour(\"black\")} !important;\n --accent-background-light: #{colour.brand-colour(\"light-grey\")} !important;\n --accent-border: #{colour.brand-colour(\"black\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"grey\")} !important;\n --button-accented-text: #{colour.brand-colour(\"black\")} !important;\n --button-accented-background: #{colour.brand-colour(\"grey\")} !important;\n}\n\n@mixin black-accent {\n @extend %accent-lighter-text;\n @extend %black-accent;\n}\n\n%pink-accent {\n --accent-background: #{colour.brand-colour(\"maroon\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-pink\")} !important;\n --accent-border: #{colour.brand-colour(\"maroon\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"pink\")} !important;\n --button-accented-background: #{colour.brand-colour(\"maroon\")} !important;\n}\n\n@mixin pink-accent {\n @extend %accent-lighter-text;\n @extend %pink-accent;\n}\n\n%orange-accent {\n --accent-background: #{colour.brand-colour(\"chestnut\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-orange\")} !important;\n --accent-border: #{colour.brand-colour(\"chestnut\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"orange\")} !important;\n --button-accented-background: #{colour.brand-colour(\"chestnut\")} !important;\n}\n\n@mixin orange-accent {\n @extend %accent-lighter-text;\n @extend %orange-accent;\n}\n\n%green-accent {\n --accent-background: #{colour.brand-colour(\"forest\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-green\")} !important;\n --accent-border: #{colour.brand-colour(\"forest\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"green\")} !important;\n --button-accented-background: #{colour.brand-colour(\"forest\")} !important;\n}\n\n@mixin green-accent {\n @extend %accent-lighter-text;\n @extend %green-accent;\n}\n\n%blue-accent {\n --accent-background: #{colour.brand-colour(\"navy\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-blue\")} !important;\n --accent-border: #{colour.brand-colour(\"navy\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"blue\")} !important;\n --button-accented-background: #{colour.brand-colour(\"navy\")} !important;\n}\n\n@mixin blue-accent {\n @extend %accent-lighter-text;\n @extend %blue-accent;\n}\n\n@mixin on-high-contrast {\n @media (prefers-contrast: more) {\n @content;\n }\n}\n\n@mixin on-forced-colours {\n @media (forced-colors: active) {\n @content;\n }\n}\n\n@mixin on-high-contrast-and-forced-colours {\n @include on-forced-colours {\n @content;\n }\n\n @include on-high-contrast {\n @content;\n }\n}\n\n%image-loader-background {\n background: linear-gradient(\n -45deg,\n rgb(0 0 0 / 25%),\n rgb(255 255 255 / 25%),\n rgb(0 0 0 / 25%)\n );\n background-size: 500% 500%;\n background-position: 0 50%;\n\n animation: image-loader-background ease-in-out 1.2s infinite;\n\n @media (prefers-reduced-motion) {\n animation: none !important;\n }\n}\n\n@mixin image-loader-background {\n @if features.$image-loader-animations {\n @extend %image-loader-background;\n }\n}\n","@use \"../../variables/forms\" as formsVars;\n@use \"../../tools/borders\";\n@use \"../../tools/colour\";\n@use \"../../tools/spacing\";\n\n$textarea-minimum-lines-visible: 5 !default;\n$textarea-line-height: 1.5rem !default;\n$textarea-vertical-padding: 0.25 !default;\n\n.tna-textarea {\n width: 100%;\n min-height: calc(\n #{$textarea-line-height * $textarea-minimum-lines-visible} +\n #{spacing.space($textarea-vertical-padding * 2)}\n );\n padding: spacing.space($textarea-vertical-padding) spacing.space(0.5);\n\n display: block;\n box-sizing: border-box;\n\n resize: vertical;\n\n line-height: 1.5;\n\n @include colour.colour-input;\n\n @include borders.rounded-border;\n\n .tna-form-item--error & {\n @include colour.colour-border(\"form-error-border\");\n }\n\n &--m {\n max-width: 20rem;\n }\n\n &--l {\n max-width: 40rem;\n }\n\n &--xl {\n max-width: 80rem;\n }\n}\n\n[data-module=\"tna-textarea-itemised-rows\"] {\n .tna-form-item__body {\n display: flex;\n align-items: stretch;\n gap: 2px;\n\n .tna-text-input {\n flex: 1;\n }\n\n .tna-button {\n align-items: center;\n }\n }\n}\n","@use \"../variables/borders\";\n\n@mixin rounded-border {\n border-radius: borders.$rounded-border-radius;\n}\n","$thick-border-width: 5px !default;\n$very-thick-border-width: 8px !default;\n$rounded-border-radius: 2px !default;\n"]}
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../../../../src/nationalarchives/tools/_colour.scss","../../../../src/nationalarchives/components/textarea/textarea.scss","../../../../src/nationalarchives/tools/_borders.scss","../../../../src/nationalarchives/variables/_borders.scss","../../../../src/nationalarchives/tools/_typography.scss","../../../../src/nationalarchives/variables/_typography.scss"],"names":[],"mappings":"AA4IA,cA9DE,4CAIA,6DA4BI,mDAmCJ,oBACE,iCCxIJ,cACE,WACA,iCAIA,uBAEA,cACA,sBAEA,gBAEA,gBCpBA,cCDsB,IF2BtB,yDDsFI,+CCjFJ,iBACE,gBAGF,iBACE,gBAGF,kBACE,gBAKF,8DACE,aACA,oBACA,QAEA,8EACE,OAGF,0EACE,mBAKN,oBACE,kBAEA,2BDYA,sCIvDA,YCiBsB","file":"textarea.css","sourcesContent":["@use \"sass:list\";\n@use \"sass:map\";\n@use \"sass:meta\";\n@use \"../variables/a11y\";\n@use \"../variables/borders\";\n@use \"../variables/forms\";\n@use \"../variables/colour\";\n@use \"../variables/features\";\n@use \"../tools/media\";\n\n$base-colours: (\n \"background\",\n \"font-base\",\n \"font-dark\",\n \"font-light\",\n \"icon-light\",\n \"link\",\n \"link-visited\",\n \"keyline\",\n \"keyline-dark\"\n);\n\n@function brand-colour($colour, $opacity: 1) {\n @return colour.brand-colour($colour, $opacity);\n}\n\n@mixin colour-css-vars($excludes...) {\n @each $name, $value in colour.$colour-palette-default {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index($base-colours, $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@mixin colour-css-vars-dark($excludes...) {\n @each $name, $value in colour.$colour-palette-dark {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index($base-colours, $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@mixin colour-css-vars-high-contrast($excludes...) {\n @each $name, $value in colour.$colour-palette-high-contrast {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index($base-colours, $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@mixin colour-css-vars-high-contrast-dark($excludes...) {\n @each $name, $value in colour.$colour-palette-high-contrast-dark {\n @if not list.index($excludes, $name) {\n --#{$name}: #{$value};\n @if list.index((\"keyline\", \"keyline-dark\"), $name) {\n --base-#{$name}: #{$value};\n }\n }\n }\n}\n\n@function colour-var($colour) {\n @return var(\n --#{$colour},\n #{map.get(colour.$colour-palette-default, $colour)}\n );\n}\n\n@mixin colour-font($colour, $important: false) {\n color: colour-var($colour) if(sass($important): !important; else: null);\n}\n\n@mixin colour-background($colour, $important: false) {\n background-color: colour-var($colour)\n if(sass($important): !important; else: null);\n}\n\n@mixin colour-background-brand($brandColour, $important: false) {\n background-color: #{brand-colour($brandColour)}\n if(sass($important): !important; else: null);\n}\n\n@mixin colour-border(\n $colour,\n $width: \"\",\n $style: solid,\n $direction: \"\",\n $important: false\n) {\n @if $direction != \"\" {\n @if $width != \"\" {\n border-#{$direction}: $width\n colour-var($colour)\n $style\n if(sass($important): !important; else: null);\n } @else {\n border-#{$direction}-color: colour-var($colour)\n if(sass($important): !important; else: null);\n }\n } @else {\n @if $width != \"\" {\n border: $width\n colour-var($colour)\n $style\n if(sass($important): !important; else: null);\n } @else {\n border-color: var(\n --#{$colour},\n #{map.get(colour.$colour-palette-default, $colour)}\n )\n if(sass($important): !important; else: null);\n }\n }\n}\n\n@mixin colour-outline($colour, $width: \"\", $style: solid, $important: false) {\n @if $width != \"\" {\n outline: $width\n colour-var($colour)\n $style\n if(sass($important): !important; else: null);\n } @else {\n outline-color: colour-var($colour)\n if(sass($important): !important; else: null);\n }\n}\n\n@mixin colour-fill($colour, $important: false) {\n fill: colour-var($colour) if(sass($important): !important; else: null);\n}\n\n%colour-input {\n @include colour-font(\"input-foreground\");\n @include colour-background(\"input-background\");\n @include colour-border(\"input-border\", forms.$form-field-border-width);\n\n &:hover {\n outline: a11y.$focus-outline-active-total-width var(--keyline) solid;\n }\n}\n\n@mixin colour-input() {\n @extend %colour-input;\n}\n\n@mixin thick-keyline($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\"keyline\", $border-width, solid, $direction);\n } @else {\n @include colour-border(\"keyline\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-dark($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\"keyline-dark\", $border-width, solid, $direction);\n } @else {\n @include colour-border(\"keyline-dark\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-accent($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\"accent-border\", $border-width, solid, $direction);\n } @else {\n @include colour-border(\"accent-border\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-error($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n @include colour-border(\n \"form-error-border\",\n $border-width,\n solid,\n $direction\n );\n } @else {\n @include colour-border(\"form-error-border\", $border-width, solid);\n }\n}\n\n@mixin thick-keyline-brand($direction: \"\", $brandColour, $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n border-#{$direction}: $border-width #{brand-colour($brandColour)} solid;\n } @else {\n border: $border-width #{brand-colour($brandColour)} solid;\n }\n}\n\n@mixin thick-keyline-transparent($direction: \"\", $veryThick: false) {\n $border-width: borders.$thick-border-width;\n @if $veryThick {\n $border-width: borders.$very-thick-border-width;\n }\n @if $direction != \"\" {\n border-#{$direction}: $border-width transparent solid;\n } @else {\n border: $border-width transparent solid;\n }\n}\n\n%always-light {\n @include colour-css-vars;\n\n @media (prefers-contrast: more) {\n @include colour-css-vars-high-contrast;\n }\n}\n\n@mixin always-light {\n @extend %always-light;\n}\n\n%contrast {\n --background: var(--contrast-background);\n --font-base: var(--contrast-font-base);\n --font-dark: var(--contrast-font-dark);\n --font-light: var(--contrast-font-light);\n --icon-light: var(--contrast-icon-light);\n --link: var(--contrast-link);\n --link-visited: var(--contrast-link-visited);\n --keyline: var(--contrast-keyline);\n --keyline-dark: var(--contrast-keyline-dark);\n --button-text: var(--contrast-button-text);\n --button-background: var(--contrast-button-background);\n --button-hover-text: var(--contrast-button-hover-text);\n --button-hover-background: var(--contrast-button-hover-background);\n --accent-border: var(--accent-border-bright);\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n}\n\n@mixin contrast {\n @extend %contrast;\n}\n\n%contrast-on-mobile {\n @include media.on-mobile {\n --background: var(--contrast-background);\n --font-base: var(--contrast-font-base);\n --font-dark: var(--contrast-font-dark);\n --font-light: var(--contrast-font-light);\n --icon-light: var(--contrast-icon-light);\n --link: var(--contrast-link);\n --link-visited: var(--contrast-link-visited);\n --keyline: var(--contrast-keyline);\n --keyline-dark: var(--contrast-keyline-dark);\n --button-text: var(--contrast-button-text);\n --button-background: var(--contrast-button-background);\n --button-hover-text: var(--contrast-button-hover-text);\n --button-hover-background: var(--contrast-button-hover-background);\n --accent-border: var(--accent-border-bright);\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n }\n}\n\n@mixin contrast-on-mobile {\n @extend %contrast-on-mobile;\n}\n\n%base {\n @each $name, $value in $base-colours {\n --#{$name}: var(--base-#{$value});\n }\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n}\n\n@mixin base {\n @extend %base;\n}\n\n%tint {\n --background: var(--background-tint);\n\n @include colour-background(\"background\");\n}\n\n@mixin tint {\n @extend %tint;\n}\n\n%accent {\n --background: var(--accent-background);\n --font-base: var(--accent-font-base);\n --font-dark: var(--accent-font-dark);\n --font-light: var(--accent-font-light);\n --icon-light: var(--accent-icon-light);\n --link: var(--accent-link);\n --link-visited: var(--accent-link);\n --keyline: var(--accent-keyline);\n --keyline-dark: var(--accent-keyline-dark);\n --accent-border: var(--accent-font-dark);\n --button-text: var(--accent-button-text);\n --button-background: var(--accent-button-background);\n --button-hover-text: var(--accent-button-hover-text);\n --button-hover-background: var(--accent-button-hover-background);\n\n @include colour-background(\"background\");\n\n @include colour-font(\"font-base\");\n}\n\n@mixin accent {\n @extend %accent;\n}\n\n%accent-light {\n --background: var(--accent-background-light);\n --font-base: #{map.get(colour.$colour-palette-default, \"font-base\")};\n --font-dark: #{map.get(colour.$colour-palette-default, \"font-dark\")};\n --font-light: #{map.get(colour.$colour-palette-default, \"font-light\")};\n --icon-light: #{map.get(colour.$colour-palette-default, \"icon-light\")};\n --keyline: #{map.get(colour.$colour-palette-default, \"keyline\")};\n --keyline-dark: #{map.get(colour.$colour-palette-default, \"keyline-dark\")};\n --button-text: #{map.get(colour.$colour-palette-default, \"button-text\")};\n --button-background: #{map.get(\n colour.$colour-palette-default,\n \"button-background\"\n )};\n --button-hover-text: #{map.get(\n colour.$colour-palette-default,\n \"button-hover-text\"\n )};\n --button-hover-background: #{map.get(\n colour.$colour-palette-default,\n \"button-hover-background\"\n )};\n --accent-border: var(--accent-background);\n\n @include colour-background(\"background\");\n @include colour-font(\"font-base\");\n\n .tna-template--system-theme & {\n @media (prefers-color-scheme: dark) {\n // --link: #{map.get(colour.$colour-palette-default, \"link\")};\n // --link-visited: #{map.get(colour.$colour-palette-default, \"link-visited\")};\n\n --background: var(--accent-background);\n --font-base: var(--accent-font-base);\n --font-dark: var(--accent-font-dark);\n --font-light: var(--accent-font-light);\n --icon-light: var(--accent-icon-light);\n --link: var(--accent-link);\n --link-visited: var(--accent-link);\n --keyline: var(--accent-keyline);\n --keyline-dark: var(--accent-keyline-dark);\n --accent-border: var(--accent-font-dark);\n --button-text: var(--accent-button-text);\n --button-background: var(--accent-button-background);\n --button-hover-text: var(--accent-button-hover-text);\n --button-hover-background: var(--accent-button-hover-background);\n }\n }\n\n .tna-template--dark-theme & {\n // --link: #{map.get(colour.$colour-palette-default, \"link\")};\n // --link-visited: #{map.get(colour.$colour-palette-default, \"link-visited\")};\n\n --background: var(--accent-background);\n --font-base: var(--accent-font-base);\n --font-dark: var(--accent-font-dark);\n --font-light: var(--accent-font-light);\n --icon-light: var(--accent-icon-light);\n --link: var(--accent-link);\n --link-visited: var(--accent-link);\n --keyline: var(--accent-keyline);\n --keyline-dark: var(--accent-keyline-dark);\n --accent-border: var(--accent-font-dark);\n --button-text: var(--accent-button-text);\n --button-background: var(--accent-button-background);\n --button-hover-text: var(--accent-button-hover-text);\n --button-hover-background: var(--accent-button-hover-background);\n }\n}\n\n@mixin accent-light {\n @extend %accent-light;\n}\n\n%yellow-accent {\n --accent-background: #{colour.brand-colour(\"yellow\")} !important;\n --accent-background-light: #{colour.brand-colour(\"cream\")} !important;\n --accent-border: #{colour.brand-colour(\"yellow\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"yellow\")} !important;\n --accent-font-base: #{colour.brand-colour(\"black\")} !important;\n --accent-font-dark: #{colour.brand-colour(\"black\")} !important;\n --accent-font-light: #{colour.brand-colour(\"black\", 0.7)} !important;\n --accent-icon-light: #{colour.brand-colour(\"black\", 0.7)} !important;\n --accent-link: #{colour.brand-colour(\"black\")} !important;\n --accent-link-visited: #{colour.brand-colour(\"black\")} !important;\n --accent-keyline: #{colour.brand-colour(\"black\", 0.5)} !important;\n --accent-keyline-dark: #{colour.brand-colour(\"black\", 0.8)} !important;\n --button-accented-text: #{colour.brand-colour(\"black\")} !important;\n --button-accented-background: #{colour.brand-colour(\"yellow\")} !important;\n}\n\n@mixin yellow-accent {\n @extend %yellow-accent;\n}\n\n%accent-lighter-text {\n --accent-font-base: #{colour.brand-colour(\"white\")} !important;\n --accent-font-dark: #{colour.brand-colour(\"white\")} !important;\n --accent-font-light: #{colour.brand-colour(\"white\", 0.7)} !important;\n --accent-icon-light: #{colour.brand-colour(\"white\", 0.7)} !important;\n --accent-link: #{colour.brand-colour(\"white\")} !important;\n --accent-link-visited: #{colour.brand-colour(\"white\")} !important;\n --accent-keyline: #{colour.brand-colour(\"white\", 0.5)} !important;\n --accent-keyline-dark: #{colour.brand-colour(\"white\", 0.8)} !important;\n --button-accented-text: #{colour.brand-colour(\"white\")} !important;\n}\n\n%black-accent {\n --accent-background: #{colour.brand-colour(\"black\")} !important;\n --accent-background-light: #{colour.brand-colour(\"light-grey\")} !important;\n --accent-border: #{colour.brand-colour(\"black\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"grey\")} !important;\n --button-accented-text: #{colour.brand-colour(\"black\")} !important;\n --button-accented-background: #{colour.brand-colour(\"grey\")} !important;\n}\n\n@mixin black-accent {\n @extend %accent-lighter-text;\n @extend %black-accent;\n}\n\n%pink-accent {\n --accent-background: #{colour.brand-colour(\"maroon\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-pink\")} !important;\n --accent-border: #{colour.brand-colour(\"maroon\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"pink\")} !important;\n --button-accented-background: #{colour.brand-colour(\"maroon\")} !important;\n}\n\n@mixin pink-accent {\n @extend %accent-lighter-text;\n @extend %pink-accent;\n}\n\n%orange-accent {\n --accent-background: #{colour.brand-colour(\"chestnut\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-orange\")} !important;\n --accent-border: #{colour.brand-colour(\"chestnut\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"orange\")} !important;\n --button-accented-background: #{colour.brand-colour(\"chestnut\")} !important;\n}\n\n@mixin orange-accent {\n @extend %accent-lighter-text;\n @extend %orange-accent;\n}\n\n%green-accent {\n --accent-background: #{colour.brand-colour(\"forest\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-green\")} !important;\n --accent-border: #{colour.brand-colour(\"forest\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"green\")} !important;\n --button-accented-background: #{colour.brand-colour(\"forest\")} !important;\n}\n\n@mixin green-accent {\n @extend %accent-lighter-text;\n @extend %green-accent;\n}\n\n%blue-accent {\n --accent-background: #{colour.brand-colour(\"navy\")} !important;\n --accent-background-light: #{colour.brand-colour(\"pastel-blue\")} !important;\n --accent-border: #{colour.brand-colour(\"navy\")} !important;\n --accent-border-bright: #{colour.brand-colour(\"blue\")} !important;\n --button-accented-background: #{colour.brand-colour(\"navy\")} !important;\n}\n\n@mixin blue-accent {\n @extend %accent-lighter-text;\n @extend %blue-accent;\n}\n\n@mixin on-high-contrast {\n @media (prefers-contrast: more) {\n @content;\n }\n}\n\n@mixin on-forced-colours {\n @media (forced-colors: active) {\n @content;\n }\n}\n\n@mixin on-high-contrast-and-forced-colours {\n @include on-forced-colours {\n @content;\n }\n\n @include on-high-contrast {\n @content;\n }\n}\n\n%image-loader-background {\n background: linear-gradient(\n -45deg,\n rgb(0 0 0 / 25%),\n rgb(255 255 255 / 25%),\n rgb(0 0 0 / 25%)\n );\n background-size: 500% 500%;\n background-position: 0 50%;\n\n animation: image-loader-background ease-in-out 1.2s infinite;\n\n @media (prefers-reduced-motion) {\n animation: none !important;\n }\n}\n\n@mixin image-loader-background {\n @if features.$image-loader-animations {\n @extend %image-loader-background;\n }\n}\n","@use \"../../variables/forms\" as formsVars;\n@use \"../../tools/borders\";\n@use \"../../tools/colour\";\n@use \"../../tools/spacing\";\n@use \"../../tools/typography\";\n\n$textarea-minimum-lines-visible: 5 !default;\n$textarea-line-height: 1.5rem !default;\n$textarea-vertical-padding: 0.25 !default;\n\n.tna-textarea {\n width: 100%;\n min-height: calc(\n #{$textarea-line-height * $textarea-minimum-lines-visible} +\n #{spacing.space($textarea-vertical-padding * 2)}\n );\n padding: spacing.space($textarea-vertical-padding) spacing.space(0.5);\n\n display: block;\n box-sizing: border-box;\n\n resize: vertical;\n\n line-height: 1.5;\n\n @include colour.colour-input;\n\n @include borders.rounded-border;\n\n .tna-form-item--error &,\n &--error {\n @include colour.colour-border(\"form-error-border\");\n }\n\n &--m {\n max-width: 20rem;\n }\n\n &--l {\n max-width: 40rem;\n }\n\n &--xl {\n max-width: 80rem;\n }\n}\n\n[data-module=\"tna-textarea-itemised-rows\"] {\n .tna-form-item__body {\n display: flex;\n align-items: stretch;\n gap: 2px;\n\n .tna-text-input {\n flex: 1;\n }\n\n .tna-button {\n align-items: center;\n }\n }\n}\n\n.tna-textarea-count {\n margin-top: spacing.space(0.5);\n\n &--error {\n @include colour.colour-font(\"form-error-text\");\n @include typography.main-font-weight-bold;\n }\n}\n","@use \"../variables/borders\";\n\n@mixin rounded-border {\n border-radius: borders.$rounded-border-radius;\n}\n","$thick-border-width: 5px !default;\n$very-thick-border-width: 8px !default;\n$rounded-border-radius: 2px !default;\n","@use \"sass:math\";\n@use \"../variables/typography\";\n@use \"colour\";\n@use \"media\";\n\n@mixin font-size($font-size-px) {\n font-size: #{math.div($font-size-px, typography.$relative-1rem-px)}rem;\n}\n\n@mixin relative-font-size($font-size-px) {\n @warn \"relative-font-size() will soon be deprecated in favour of font-size().\";\n @include font-size($font-size-px);\n}\n\n@mixin main-font-weight {\n font-weight: typography.$main-font-weight;\n}\n\n@mixin main-font-weight-medium {\n font-weight: typography.$main-font-weight-medium;\n}\n\n@mixin main-font-weight-bold {\n font-weight: typography.$main-font-weight-bold;\n}\n\n@mixin main-font($bold: false) {\n font-family: typography.$main-font-family;\n font-variation-settings: \"wdth\" 100;\n font-style: normal;\n font-optical-sizing: auto;\n @if $bold {\n @include main-font-weight-bold;\n } @else {\n @include main-font-weight;\n }\n}\n\n@mixin heading-font {\n font-family: typography.$heading-font-family;\n font-weight: typography.$heading-font-weight;\n}\n\n@mixin detail-font($bold: false) {\n font-family: typography.$detail-font-family;\n font-style: normal;\n font-optical-sizing: auto;\n @if $bold {\n font-weight: typography.$detail-font-weight-bold;\n } @else {\n font-weight: typography.$detail-font-weight;\n }\n}\n\n@mixin detail-font-small {\n @include detail-font;\n @include font-size(14);\n line-height: 1.1;\n text-transform: uppercase;\n}\n\n@mixin interactable-text-decoration {\n text-decoration-thickness: typography.$interactable-text-decoration-thickness;\n text-underline-offset: typography.$interactable-text-decoration-offset;\n}\n\n@mixin interacted-text-decoration {\n text-decoration: underline;\n text-decoration-thickness: typography.$interactive-text-decoration-thickness;\n text-underline-offset: typography.$interactable-text-decoration-offset;\n}\n\n@mixin heading-generator(\n $font-size-default,\n $font-size-medium,\n $font-size-small,\n $font-size-tiny,\n $line-height\n) {\n $small-and-tiny-identical: $font-size-small == $font-size-tiny;\n $medium-small-and-tiny-identical: $font-size-medium == $font-size-small and\n $small-and-tiny-identical;\n $all-identical: $font-size-default == $font-size-medium and\n $medium-small-and-tiny-identical and $small-and-tiny-identical;\n line-height: $line-height;\n @include font-size($font-size-default);\n\n @if $all-identical != true {\n @if $medium-small-and-tiny-identical != true {\n @include media.on-medium {\n @include font-size($font-size-medium);\n }\n\n @if $small-and-tiny-identical != true {\n @include media.on-small {\n @include font-size($font-size-small);\n }\n\n @include media.on-tiny {\n @include font-size($font-size-tiny);\n }\n } @else {\n @include media.on-mobile {\n @include font-size($font-size-small);\n }\n }\n } @else {\n @include media.on-smaller-than-large {\n @include font-size($font-size-medium);\n }\n }\n }\n}\n","@use \"sass:math\";\n\n/*\n * ------------------------------------------\n * The typefaces, sizes and spacings that are\n * defined in this file have been selected to\n * ensure 100% match with the latest National\n * Archives brand guidelines - avoid changing\n * or overwriting any of these values without\n * signing off with the Digital Services team\n * first\n * ------------------------------------------\n */\n\n$relative-1rem-px: 16; // 16px = 1rem\n\n/*\n * ------------------------------------------\n * When true, use the included font files for\n * Open Sans and Roboto Mono, rather than the\n * versions hosted by Google Fonts\n * ------------------------------------------\n */\n$use-local-fonts: false !default;\n\n$body-font-size-px: 19 !default;\n$body-font-size-px-medium: 18 !default;\n$body-font-size-px-mobile: 17 !default;\n$body-line-height: 1.75 !default;\n\n$interactable-text-decoration-offset: 0.125em !default;\n$interactable-text-decoration-thickness: #{math.div(1.5, $relative-1rem-px)}rem !default;\n$interactive-text-decoration-thickness: #{math.div(4, $relative-1rem-px)}rem !default;\n\n$main-font-family-name: \"Open Sans\" !default;\n$main-font-family:\n #{$main-font-family-name},\n sans-serif;\n$main-font-weight: 400 !default;\n$main-font-weight-medium: 600 !default;\n$main-font-weight-bold: 700 !default;\n$main-font-file: \"OpenSans-Regular.ttf\" !default;\n$main-font-file-medium: \"OpenSans-SemiBold.ttf\" !default;\n$main-font-file-bold: \"OpenSans-Bold.ttf\" !default;\n\n/*\n * ------------------------------------------\n * To use Supria Sans Condensed (which is the\n * approved heading typeface for The National\n * Archives), you need to obtain a licence to\n * properly embed the CSS files with the font\n * definitions in your service - check with a\n * member of the Digital Services team on how\n * to get a licence\n * ------------------------------------------\n */\n$heading-font-family-name: \"supria-sans-condensed\" !default;\n$heading-font-family:\n #{$heading-font-family-name},\n \"Arial Narrow\",\n sans-serif;\n$heading-font-weight: 500 !default;\n\n/*\n * ------------------------------------------\n * The detail font should be a monospace font\n * and is used for chips, supertitles as well\n * as the date search component\n * ------------------------------------------\n */\n$detail-font-family-name: \"Roboto Mono\" !default;\n$detail-font-family:\n #{$detail-font-family-name},\n monospace;\n$detail-font-weight: 400 !default;\n$detail-font-weight-bold: 500 !default;\n$detail-font-file: \"RobotoMono-Regular.ttf\" !default;\n$detail-font-file-bold: \"RobotoMono-Medium.ttf\" !default;\n\n$heading-xl-font-size-default: 64 !default;\n$heading-xl-font-size-medium: 48 !default;\n$heading-xl-font-size-small: 36 !default;\n$heading-xl-font-size-tiny: $heading-xl-font-size-small !default;\n$heading-xl-line-height: 1.1 !default;\n\n$heading-l-font-size-default: 36 !default;\n$heading-l-font-size-medium: 32 !default;\n$heading-l-font-size-small: 29 !default;\n$heading-l-font-size-tiny: $heading-l-font-size-small !default;\n$heading-l-line-height: 1.15 !default;\n\n$heading-m-font-size-default: 22 !default;\n$heading-m-font-size-medium: $heading-m-font-size-default !default;\n$heading-m-font-size-small: 21 !default;\n$heading-m-font-size-tiny: $heading-m-font-size-small !default;\n$heading-m-line-height: 1.4 !default;\n\n$heading-s-font-size-default: 19 !default;\n$heading-s-font-size-medium: $heading-s-font-size-default !default;\n$heading-s-font-size-small: $heading-s-font-size-default !default;\n$heading-s-font-size-tiny: $heading-s-font-size-default !default;\n$heading-s-line-height: 1.5 !default;\n\n$code-font-family: Consolas, Monaco, \"Ubuntu Mono\", monospace !default;\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("TNAFrontend",[],e):"object"==typeof exports?exports.TNAFrontend=e():t.TNAFrontend=e()}(self,()=>(()=>{"use strict";
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("TNAFrontend",[],e):"object"==typeof exports?exports.TNAFrontend=e():t.TNAFrontend=e()}(self,()=>(()=>{"use strict";var t={740(t,e,i){i.d(e,{default:()=>r});class r{constructor(t,e={}){this.$module=t,this.$formFieldInput=this.$module&&this.$module.querySelector(".tna-textarea"),this.$formFieldCharacterCount=this.$module&&this.$module.querySelector(".tna-textarea-count"),this.$formFieldCharacterCountScreenReader=this.$module&&this.$module.querySelector(".tna-textarea-count__screen-reader-status"),this.max=parseInt(this.$formFieldInput?.dataset?.maxLength,10),this.countType=this.$formFieldInput?.dataset?.countType||"characters",this.$module&&this.$formFieldInput&&this.$formFieldCharacterCount&&this.$formFieldCharacterCountScreenReader&&this.max&&this.init(e)}init(t){this.threshold=t.threshold||parseInt(this.$formFieldInput?.dataset?.countThreshold,10)||0,this.debounceDuration=t.debounceDuration||parseInt(this.$formFieldInput?.dataset?.debounceDuration,10)||1e3,this.intervalChecker=t.intervalChecker||1e3,this.debounceTimeout=null,this.lastInputValue="",this.$formFieldInput.addEventListener("input",()=>{this.handleInput(),this.lastInputTimestamp=Date.now()}),this.$formFieldInput.addEventListener("focus",()=>{this.handleFocus()}),this.$formFieldInput.addEventListener("blur",()=>{this.handleBlur()}),this.updateVisualCharacterCount(),this.updateScreenReaderCharacterCount()}handleFocus(){this.valueChecker=window.setInterval(()=>{(!this.lastInputTimestamp||Date.now()-this.intervalChecker/2>=this.lastInputTimestamp)&&this.updateIfValueChanged()},this.intervalChecker)}handleBlur(){this.valueChecker&&window.clearInterval(this.valueChecker),this.updateScreenReaderCharacterCount()}updateIfValueChanged(){this.$formFieldInput.value!==this.lastInputValue&&(this.lastInputValue=this.$formFieldInput.value,this.updateVisualCharacterCount(),this.updateScreenReaderCharacterCount())}handleInput(){this.updateVisualCharacterCount(),clearTimeout(this.debounceTimeout),this.debounceTimeout=setTimeout(()=>{this.updateScreenReaderCharacterCount()},this.debounceDuration)}getCurrentLength(){if("words"===this.countType){const t=this.$formFieldInput.value.trim();return""===t?0:t.split(/\s+/).length}return this.$formFieldInput.value.length}getCurrentLengthMessage(){const t=this.getCurrentLength();let e=this.countType;return 1===Math.abs(this.max-t)&&(e=e.replace(/s$/,"")),t>this.max?`You have ${(new Intl.NumberFormat).format(t-this.max)} ${e} too many`:`You have ${(new Intl.NumberFormat).format(this.max-t)} ${e} remaining`}isOverThreshold(){return this.getCurrentLength()>this.max}updateVisualCharacterCount(){this.threshold&&(this.getCurrentLength()>this.max*(this.threshold/100)?this.showCharacterCount():this.hideCharacterCount()),this.$formFieldCharacterCount.innerText=this.getCurrentLengthMessage(),this.isOverThreshold()?(this.$formFieldInput.classList.add("tna-textarea--error"),this.$formFieldCharacterCount.classList.add("tna-textarea-count--error")):(this.$formFieldInput.classList.remove("tna-textarea--error"),this.$formFieldCharacterCount.classList.remove("tna-textarea-count--error"))}updateScreenReaderCharacterCount(){const t=this.getCurrentLengthMessage();this.$formFieldCharacterCountScreenReader.innerText=t}showCharacterCount(){this.$formFieldCharacterCount.removeAttribute("hidden"),this.$formFieldCharacterCountScreenReader.removeAttribute("aria-hidden")}hideCharacterCount(){this.$formFieldCharacterCount.setAttribute("hidden",""),this.$formFieldCharacterCountScreenReader.setAttribute("aria-hidden","true")}}},371(t,e,i){i.d(e,{default:()=>r});class r{constructor(t,e={}){if(this.$module=t,this.$formFieldInput=this.$module&&this.$module.querySelector(".tna-textarea"),this.$formFieldInputHint=this.$module&&this.$module.querySelector(".tna-form-item__hint"),this.$formFieldBody=this.$module&&this.$module.querySelector(".tna-form-item__body"),!this.$module||!this.$formFieldInput||!this.$formFieldBody||null!==this.$formFieldInput.getAttribute("hidden"))return;if(!(this.$formFieldInput instanceof HTMLTextAreaElement))throw new Error("Expected a textarea element");const{enhancedHint:i}=e;this.enhancedHint=i||"Enter an item and press enter",this.values=this.$formFieldInput.value.split("\n").map(t=>t.trim()).filter(t=>t),this.id=this.$formFieldInput.id,this.init()}init(){this.$formFieldNewInput=document.createElement("input"),this.$formFieldNewInput.classList.add("tna-text-input"),["id","aria-describedby"].forEach(t=>{this.$formFieldNewInput.setAttribute(t,this.$formFieldInput.getAttribute(t)),this.$formFieldInput.removeAttribute(t)}),this.$formFieldBody.appendChild(this.$formFieldNewInput),this.$formFieldInput.setAttribute("hidden",""),this.$formFieldInput.addEventListener("keyup",()=>this.updateList()),this.$formFieldNewInput.addEventListener("keypress",t=>{"Enter"===t.key&&this.appendValue(t.target.value)}),this.$formFieldNewInputAddButton=document.createElement("button"),this.$formFieldNewInputAddButton.setAttribute("type","button"),this.$formFieldNewInputAddButton.classList.add("tna-button","tna-button--small"),this.$formFieldNewInputAddButtonInner=document.createElement("span"),this.$formFieldNewInputAddButtonInner.innerText="Add",this.$formFieldNewInputAddButtonInnerExtra=document.createElement("span"),this.$formFieldNewInputAddButtonInnerExtra.classList.add("tna-visually-hidden"),this.$formFieldNewInputAddButtonInnerExtra.innerText=" to list",this.$formFieldNewInputAddButtonInner.appendChild(this.$formFieldNewInputAddButtonInnerExtra),this.$formFieldNewInputAddButton.appendChild(this.$formFieldNewInputAddButtonInner),this.$formFieldBody.appendChild(this.$formFieldNewInputAddButton),this.$formFieldNewInputAddButton.addEventListener("click",()=>{this.appendValue(this.$formFieldNewInput.value)}),this.$formFieldLiveAria=document.createElement("div"),this.$formFieldLiveAria.setAttribute("aria-live","polite"),this.$formFieldLiveAria.classList.add("tna-visually-hidden"),this.$module.appendChild(this.$formFieldLiveAria),this.$formFieldCounter=document.createElement("p"),this.$formFieldCounter.id=`${this.id}-list-helper`,this.$formFieldCounter.classList.add("tna-!--margin-top-xs"),this.$module.appendChild(this.$formFieldCounter),this.$formFieldNewInput.setAttribute("aria-describedby",`${this.$formFieldNewInput.getAttribute("aria-describedby")} ${this.$formFieldCounter.id}`),this.$valuesList=document.createElement("ul"),this.$valuesList.classList.add("tna-compound-filters","tna-!--margin-top-xs"),this.$valuesList.addEventListener("blur",()=>{this.$valuesList.removeAttribute("tabindex"),this.updateAriaText("")}),this.$module.appendChild(this.$valuesList),this.$formFieldInputHint||(this.$formFieldInputHint=document.createElement("p"),this.$formFieldInputHint.classList.add("tna-form-item__hint"),this.$formFieldBody.parentNode.insertBefore(this.$formFieldInputHint,this.$formFieldBody)),this.$formFieldInputHint.innerText=this.enhancedHint,this.updateList()}updateAriaText(t){this.$formFieldLiveAria.innerText=t}normaliseValue(t){return t.replace(/\s{2,}/u," ").trim()}isValueInList(t){return this.values.map(t=>this.normaliseValue(t).toLowerCase()).includes(t.toLowerCase().trim())}appendValue(t){const e=this.normaliseValue(t);e?this.isValueInList(e)?this.updateAriaText(`'${e}' already added`):(this.values.push(e),this.$formFieldInput.value=this.values.join("\n"),this.updateList(),this.updateAriaText(`'${e}' added`)):this.updateAriaText("Enter an item to add"),this.$formFieldNewInput.value="",this.$formFieldNewInput.focus()}removeValue(t){const e=this.normaliseValue(t);e&&this.isValueInList(e)&&(this.values=this.values.filter(t=>t!==e),this.$formFieldInput.value=this.values.join("\n"),this.updateList(),this.updateAriaText(`'${e}' removed`)),this.values.length?(this.$valuesList.setAttribute("tabindex","0"),this.$valuesList.focus()):this.$formFieldNewInput.focus()}updateList(){this.$valuesList.innerHTML="",this.values.map(t=>{const e=document.createElement("li");e.classList.add("tna-compound-filters__item");const i=document.createElement("span");i.innerText=t,e.appendChild(i);const r=document.createElement("button");return r.innerText=`Remove '${t}'`,r.setAttribute("type","button"),r.classList.add("tna-compound-filters__link"),r.addEventListener("click",()=>{this.removeValue(t)}),e.appendChild(r),e}).forEach(t=>this.$valuesList.appendChild(t));let t="item";1!==this.values.length&&(t+="s");const e=`${(new Intl.NumberFormat).format(this.values.length)} ${t} added`;this.$formFieldCounter.innerText=e}}}};const e={};function i(r){const n=e[r];if(void 0!==n)return n.exports;const s=e[r]={exports:{}};return t[r](s,s.exports,i),s.exports}i.d=(t,e)=>{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};let r={};i.r(r),i.d(r,{TextAreaCharacterCount:()=>n.default,TextAreaItemisedRows:()=>s.default});var n=i(740),s=i(371);return r})());
|
|
2
2
|
//# sourceMappingURL=textarea.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/textarea/textarea.js","mappings":"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","sources":["webpack://TNAFrontend/webpack/universalModuleDefinition","webpack://TNAFrontend/webpack/bootstrap","webpack://TNAFrontend/webpack/runtime/define property getters","webpack://TNAFrontend/webpack/runtime/hasOwnProperty shorthand","webpack://TNAFrontend/webpack/runtime/make namespace object","webpack://TNAFrontend/./src/nationalarchives/components/textarea/textarea.mjs"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"TNAFrontend\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"TNAFrontend\"] = factory();\n\telse\n\t\troot[\"TNAFrontend\"] = factory();\n})(self, () => {\nreturn ","// The require scope\nconst __webpack_require__ = {};\n\n","// define getter/value functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop));","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export class TextAreaItemisedRows {\n constructor($module, options = {}) {\n this.$module = $module;\n this.$formFieldInput =\n this.$module && this.$module.querySelector(\".tna-textarea\");\n this.$formFieldInputHint =\n this.$module && this.$module.querySelector(\".tna-form-item__hint\");\n this.$formFieldBody =\n this.$module && this.$module.querySelector(\".tna-form-item__body\");\n\n if (\n !this.$module ||\n !this.$formFieldInput ||\n !this.$formFieldBody ||\n this.$formFieldInput.getAttribute(\"hidden\") !== null\n ) {\n return;\n }\n\n const { enhancedHint } = options;\n this.enhancedHint = enhancedHint || \"Enter an item and press enter\";\n\n this.init();\n }\n\n init() {\n this.values = this.$formFieldInput.value\n .split(\"\\n\")\n .map((value) => value.trim())\n .filter((value) => value);\n\n this.id = this.$formFieldInput.id;\n\n this.$formFieldNewInput = document.createElement(\"input\");\n this.$formFieldNewInput.classList.add(\"tna-text-input\");\n [\"id\", \"aria-describedby\"].forEach((attribute) => {\n this.$formFieldNewInput.setAttribute(\n attribute,\n this.$formFieldInput.getAttribute(attribute),\n );\n this.$formFieldInput.removeAttribute(attribute);\n });\n this.$formFieldBody.appendChild(this.$formFieldNewInput);\n this.$formFieldInput.setAttribute(\"hidden\", \"\");\n this.$formFieldInput.addEventListener(\"keyup\", () => this.updateList());\n this.$formFieldNewInput.addEventListener(\"keypress\", (event) => {\n if (event.key === \"Enter\") {\n this.appendValue(event.target.value);\n }\n });\n\n this.$formFieldNewInputAddButton = document.createElement(\"button\");\n this.$formFieldNewInputAddButton.setAttribute(\"type\", \"button\");\n this.$formFieldNewInputAddButton.classList.add(\n \"tna-button\",\n \"tna-button--small\",\n );\n this.$formFieldNewInputAddButtonInner = document.createElement(\"span\");\n this.$formFieldNewInputAddButtonInner.innerText = \"Add\";\n this.$formFieldNewInputAddButtonInnerExtra = document.createElement(\"span\");\n this.$formFieldNewInputAddButtonInnerExtra.classList.add(\n \"tna-visually-hidden\",\n );\n this.$formFieldNewInputAddButtonInnerExtra.innerText = \" to list\";\n this.$formFieldNewInputAddButtonInner.appendChild(\n this.$formFieldNewInputAddButtonInnerExtra,\n );\n this.$formFieldNewInputAddButton.appendChild(\n this.$formFieldNewInputAddButtonInner,\n );\n this.$formFieldBody.appendChild(this.$formFieldNewInputAddButton);\n this.$formFieldNewInputAddButton.addEventListener(\"click\", () => {\n this.appendValue(this.$formFieldNewInput.value);\n });\n\n this.$formFieldLiveAria = document.createElement(\"div\");\n this.$formFieldLiveAria.setAttribute(\"aria-live\", \"assertive\");\n this.$formFieldLiveAria.classList.add(\"tna-visually-hidden\");\n this.$module.appendChild(this.$formFieldLiveAria);\n\n this.$formFieldCounter = document.createElement(\"p\");\n this.$formFieldCounter.id = `${this.id}-list-helper`;\n this.$formFieldCounter.classList.add(\"tna-!--margin-top-xs\");\n this.$module.appendChild(this.$formFieldCounter);\n\n this.$formFieldNewInput.setAttribute(\n \"aria-describedby\",\n `${this.$formFieldNewInput.getAttribute(\"aria-describedby\")} ${\n this.$formFieldCounter.id\n }`,\n );\n\n this.$valuesList = document.createElement(\"ul\");\n this.$valuesList.classList.add(\n \"tna-compound-filters\",\n \"tna-!--margin-top-xs\",\n );\n this.$valuesList.addEventListener(\"blur\", () => {\n this.$valuesList.removeAttribute(\"tabindex\");\n this.updateAriaText(\"\");\n });\n this.$module.appendChild(this.$valuesList);\n\n if (!this.$formFieldInputHint) {\n this.$formFieldInputHint = document.createElement(\"p\");\n this.$formFieldInputHint.classList.add(\"tna-form-item__hint\");\n this.$formFieldBody.parentNode.insertBefore(\n this.$formFieldInputHint,\n this.$formFieldBody,\n );\n }\n this.$formFieldInputHint.innerText = this.enhancedHint;\n\n this.updateList();\n }\n\n updateAriaText(content) {\n this.$formFieldLiveAria.innerText = content;\n }\n\n /* eslint-disable-next-line class-methods-use-this */\n normaliseValue(value) {\n return value.replace(/\\s{2,}/u, \" \").trim();\n }\n\n isValueInList(value) {\n return this.values\n .map((eachValue) => this.normaliseValue(eachValue).toLowerCase())\n .includes(value.toLowerCase().trim());\n }\n\n appendValue(value) {\n const newValue = this.normaliseValue(value);\n if (newValue) {\n if (this.isValueInList(newValue)) {\n this.updateAriaText(`'${newValue}' already added`);\n } else {\n this.values.push(newValue);\n this.$formFieldInput.value = this.values.join(\"\\n\");\n this.updateList();\n this.updateAriaText(`'${newValue}' added`);\n }\n } else {\n this.updateAriaText(\"Enter an item to add\");\n }\n this.$formFieldNewInput.value = \"\";\n this.$formFieldNewInput.focus();\n }\n\n removeValue(value) {\n const removeValue = this.normaliseValue(value);\n if (removeValue && this.isValueInList(removeValue)) {\n this.values = this.values.filter(\n (existingValue) => existingValue !== removeValue,\n );\n this.$formFieldInput.value = this.values.join(\"\\n\");\n this.updateList();\n this.updateAriaText(`'${removeValue}' removed`);\n }\n if (this.values.length) {\n this.$valuesList.setAttribute(\"tabindex\", \"0\");\n this.$valuesList.focus();\n } else {\n this.$formFieldNewInput.focus();\n }\n }\n\n updateList() {\n this.$valuesList.innerHTML = \"\";\n this.values\n .map((value) => {\n const $item = document.createElement(\"li\");\n $item.classList.add(\"tna-compound-filters__item\");\n const $itemLabel = document.createElement(\"span\");\n $itemLabel.innerText = value;\n $item.appendChild($itemLabel);\n\n const $removeItemButton = document.createElement(\"button\");\n $removeItemButton.innerText = `Remove '${value}'`;\n $removeItemButton.setAttribute(\"type\", \"button\");\n $removeItemButton.classList.add(\"tna-compound-filters__link\");\n $removeItemButton.addEventListener(\"click\", () => {\n this.removeValue(value);\n });\n $item.appendChild($removeItemButton);\n return $item;\n })\n .forEach(($item) => this.$valuesList.appendChild($item));\n\n let innerTextItemValue = \"item\";\n /* eslint-disable-next-line no-magic-numbers */\n if (this.values.length !== 1) {\n innerTextItemValue += \"s\";\n }\n const innerTextValue = `${this.values.length} ${innerTextItemValue} added`;\n this.$formFieldCounter.innerText = innerTextValue;\n }\n}\n"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","TextAreaItemisedRows","constructor","$module","options","this","$formFieldInput","querySelector","$formFieldInputHint","$formFieldBody","getAttribute","enhancedHint","init","values","split","map","trim","filter","id","$formFieldNewInput","document","createElement","classList","add","forEach","attribute","setAttribute","removeAttribute","appendChild","addEventListener","updateList","event","appendValue","target","$formFieldNewInputAddButton","$formFieldNewInputAddButtonInner","innerText","$formFieldNewInputAddButtonInnerExtra","$formFieldLiveAria","$formFieldCounter","$valuesList","updateAriaText","parentNode","insertBefore","content","normaliseValue","replace","isValueInList","eachValue","toLowerCase","includes","newValue","push","join","focus","removeValue","existingValue","length","innerHTML","$item","$itemLabel","$removeItemButton","innerTextItemValue","innerTextValue"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"components/textarea/textarea.js","mappings":"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","sources":["webpack://TNAFrontend/webpack/universalModuleDefinition","webpack://TNAFrontend/./src/nationalarchives/components/textarea/TextAreaCharacterCount.mjs","webpack://TNAFrontend/./src/nationalarchives/components/textarea/TextAreaItemisedRows.mjs","webpack://TNAFrontend/webpack/bootstrap","webpack://TNAFrontend/webpack/runtime/define property getters","webpack://TNAFrontend/webpack/runtime/hasOwnProperty shorthand","webpack://TNAFrontend/webpack/runtime/make namespace object"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"TNAFrontend\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"TNAFrontend\"] = factory();\n\telse\n\t\troot[\"TNAFrontend\"] = factory();\n})(self, () => {\nreturn ","export default class TextAreaCharacterCount {\n constructor($module, options = {}) {\n this.$module = $module;\n this.$formFieldInput =\n this.$module && this.$module.querySelector(\".tna-textarea\");\n this.$formFieldCharacterCount =\n this.$module && this.$module.querySelector(\".tna-textarea-count\");\n this.$formFieldCharacterCountScreenReader =\n this.$module &&\n this.$module.querySelector(\".tna-textarea-count__screen-reader-status\");\n this.max = parseInt(this.$formFieldInput?.dataset?.maxLength, 10);\n this.countType = this.$formFieldInput?.dataset?.countType || \"characters\";\n\n if (\n !this.$module ||\n !this.$formFieldInput ||\n !this.$formFieldCharacterCount ||\n !this.$formFieldCharacterCountScreenReader ||\n !this.max\n ) {\n return;\n }\n\n this.init(options);\n }\n\n init(options) {\n this.threshold =\n options.threshold ||\n parseInt(this.$formFieldInput?.dataset?.countThreshold, 10) ||\n /* eslint-disable-next-line no-magic-numbers */\n 0;\n this.debounceDuration =\n options.debounceDuration ||\n parseInt(this.$formFieldInput?.dataset?.debounceDuration, 10) ||\n /* eslint-disable-next-line no-magic-numbers */\n 1000;\n /* eslint-disable-next-line no-magic-numbers */\n this.intervalChecker = options.intervalChecker || 1000;\n this.debounceTimeout = null;\n this.lastInputValue = \"\";\n\n this.$formFieldInput.addEventListener(\"input\", () => {\n this.handleInput();\n this.lastInputTimestamp = Date.now();\n });\n this.$formFieldInput.addEventListener(\"focus\", () => {\n this.handleFocus();\n });\n this.$formFieldInput.addEventListener(\"blur\", () => {\n this.handleBlur();\n });\n this.updateVisualCharacterCount();\n this.updateScreenReaderCharacterCount();\n }\n\n handleFocus() {\n this.valueChecker = window.setInterval(() => {\n if (\n !this.lastInputTimestamp ||\n /* eslint-disable-next-line no-magic-numbers */\n Date.now() - this.intervalChecker / 2 >= this.lastInputTimestamp\n ) {\n this.updateIfValueChanged();\n }\n }, this.intervalChecker);\n }\n\n handleBlur() {\n if (this.valueChecker) {\n window.clearInterval(this.valueChecker);\n }\n this.updateScreenReaderCharacterCount();\n }\n\n updateIfValueChanged() {\n if (this.$formFieldInput.value !== this.lastInputValue) {\n this.lastInputValue = this.$formFieldInput.value;\n this.updateVisualCharacterCount();\n this.updateScreenReaderCharacterCount();\n }\n }\n\n handleInput() {\n this.updateVisualCharacterCount();\n clearTimeout(this.debounceTimeout);\n this.debounceTimeout = setTimeout(() => {\n this.updateScreenReaderCharacterCount();\n }, this.debounceDuration);\n }\n\n getCurrentLength() {\n if (this.countType === \"words\") {\n const trimmedValue = this.$formFieldInput.value.trim();\n if (trimmedValue === \"\") {\n /* eslint-disable-next-line no-magic-numbers */\n return 0;\n }\n return trimmedValue.split(/\\s+/).length;\n }\n return this.$formFieldInput.value.length;\n }\n\n getCurrentLengthMessage() {\n const currentLength = this.getCurrentLength();\n let typeLabel = this.countType;\n /* eslint-disable-next-line no-magic-numbers */\n if (Math.abs(this.max - currentLength) === 1) {\n typeLabel = typeLabel.replace(/s$/, \"\");\n }\n if (currentLength > this.max) {\n return `You have ${new Intl.NumberFormat().format(currentLength - this.max)} ${typeLabel} too many`;\n }\n return `You have ${new Intl.NumberFormat().format(this.max - currentLength)} ${typeLabel} remaining`;\n }\n\n isOverThreshold() {\n return this.getCurrentLength() > this.max;\n }\n\n updateVisualCharacterCount() {\n if (this.threshold) {\n /* eslint-disable-next-line no-magic-numbers */\n if (this.getCurrentLength() > this.max * (this.threshold / 100)) {\n this.showCharacterCount();\n } else {\n this.hideCharacterCount();\n }\n }\n\n this.$formFieldCharacterCount.innerText = this.getCurrentLengthMessage();\n if (this.isOverThreshold()) {\n this.$formFieldInput.classList.add(\"tna-textarea--error\");\n this.$formFieldCharacterCount.classList.add(\"tna-textarea-count--error\");\n } else {\n this.$formFieldInput.classList.remove(\"tna-textarea--error\");\n this.$formFieldCharacterCount.classList.remove(\n \"tna-textarea-count--error\",\n );\n }\n }\n\n updateScreenReaderCharacterCount() {\n const currentLengthMessage = this.getCurrentLengthMessage();\n this.$formFieldCharacterCountScreenReader.innerText = currentLengthMessage;\n }\n\n showCharacterCount() {\n this.$formFieldCharacterCount.removeAttribute(\"hidden\");\n this.$formFieldCharacterCountScreenReader.removeAttribute(\"aria-hidden\");\n }\n\n hideCharacterCount() {\n this.$formFieldCharacterCount.setAttribute(\"hidden\", \"\");\n this.$formFieldCharacterCountScreenReader.setAttribute(\n \"aria-hidden\",\n \"true\",\n );\n }\n}\n","export default class TextAreaItemisedRows {\n constructor($module, options = {}) {\n this.$module = $module;\n this.$formFieldInput =\n this.$module && this.$module.querySelector(\".tna-textarea\");\n this.$formFieldInputHint =\n this.$module && this.$module.querySelector(\".tna-form-item__hint\");\n this.$formFieldBody =\n this.$module && this.$module.querySelector(\".tna-form-item__body\");\n\n if (\n !this.$module ||\n !this.$formFieldInput ||\n !this.$formFieldBody ||\n this.$formFieldInput.getAttribute(\"hidden\") !== null\n ) {\n return;\n }\n\n if (!(this.$formFieldInput instanceof HTMLTextAreaElement)) {\n throw new Error(\"Expected a textarea element\");\n }\n\n const { enhancedHint } = options;\n this.enhancedHint = enhancedHint || \"Enter an item and press enter\";\n\n this.values = this.$formFieldInput.value\n .split(\"\\n\")\n .map((value) => value.trim())\n .filter((value) => value);\n\n this.id = this.$formFieldInput.id;\n\n this.init();\n }\n\n init() {\n this.$formFieldNewInput = document.createElement(\"input\");\n this.$formFieldNewInput.classList.add(\"tna-text-input\");\n [\"id\", \"aria-describedby\"].forEach((attribute) => {\n this.$formFieldNewInput.setAttribute(\n attribute,\n this.$formFieldInput.getAttribute(attribute),\n );\n this.$formFieldInput.removeAttribute(attribute);\n });\n this.$formFieldBody.appendChild(this.$formFieldNewInput);\n this.$formFieldInput.setAttribute(\"hidden\", \"\");\n this.$formFieldInput.addEventListener(\"keyup\", () => this.updateList());\n this.$formFieldNewInput.addEventListener(\"keypress\", (event) => {\n if (event.key === \"Enter\") {\n this.appendValue(event.target.value);\n }\n });\n\n this.$formFieldNewInputAddButton = document.createElement(\"button\");\n this.$formFieldNewInputAddButton.setAttribute(\"type\", \"button\");\n this.$formFieldNewInputAddButton.classList.add(\n \"tna-button\",\n \"tna-button--small\",\n );\n this.$formFieldNewInputAddButtonInner = document.createElement(\"span\");\n this.$formFieldNewInputAddButtonInner.innerText = \"Add\";\n this.$formFieldNewInputAddButtonInnerExtra = document.createElement(\"span\");\n this.$formFieldNewInputAddButtonInnerExtra.classList.add(\n \"tna-visually-hidden\",\n );\n this.$formFieldNewInputAddButtonInnerExtra.innerText = \" to list\";\n this.$formFieldNewInputAddButtonInner.appendChild(\n this.$formFieldNewInputAddButtonInnerExtra,\n );\n this.$formFieldNewInputAddButton.appendChild(\n this.$formFieldNewInputAddButtonInner,\n );\n this.$formFieldBody.appendChild(this.$formFieldNewInputAddButton);\n this.$formFieldNewInputAddButton.addEventListener(\"click\", () => {\n this.appendValue(this.$formFieldNewInput.value);\n });\n\n this.$formFieldLiveAria = document.createElement(\"div\");\n this.$formFieldLiveAria.setAttribute(\"aria-live\", \"polite\");\n this.$formFieldLiveAria.classList.add(\"tna-visually-hidden\");\n this.$module.appendChild(this.$formFieldLiveAria);\n\n this.$formFieldCounter = document.createElement(\"p\");\n this.$formFieldCounter.id = `${this.id}-list-helper`;\n this.$formFieldCounter.classList.add(\"tna-!--margin-top-xs\");\n this.$module.appendChild(this.$formFieldCounter);\n\n this.$formFieldNewInput.setAttribute(\n \"aria-describedby\",\n `${this.$formFieldNewInput.getAttribute(\"aria-describedby\")} ${\n this.$formFieldCounter.id\n }`,\n );\n\n this.$valuesList = document.createElement(\"ul\");\n this.$valuesList.classList.add(\n \"tna-compound-filters\",\n \"tna-!--margin-top-xs\",\n );\n this.$valuesList.addEventListener(\"blur\", () => {\n this.$valuesList.removeAttribute(\"tabindex\");\n this.updateAriaText(\"\");\n });\n this.$module.appendChild(this.$valuesList);\n\n if (!this.$formFieldInputHint) {\n this.$formFieldInputHint = document.createElement(\"p\");\n this.$formFieldInputHint.classList.add(\"tna-form-item__hint\");\n this.$formFieldBody.parentNode.insertBefore(\n this.$formFieldInputHint,\n this.$formFieldBody,\n );\n }\n this.$formFieldInputHint.innerText = this.enhancedHint;\n\n this.updateList();\n }\n\n updateAriaText(content) {\n this.$formFieldLiveAria.innerText = content;\n }\n\n /* eslint-disable-next-line class-methods-use-this */\n normaliseValue(value) {\n return value.replace(/\\s{2,}/u, \" \").trim();\n }\n\n isValueInList(value) {\n return this.values\n .map((eachValue) => this.normaliseValue(eachValue).toLowerCase())\n .includes(value.toLowerCase().trim());\n }\n\n appendValue(value) {\n const newValue = this.normaliseValue(value);\n if (newValue) {\n if (this.isValueInList(newValue)) {\n this.updateAriaText(`'${newValue}' already added`);\n } else {\n this.values.push(newValue);\n this.$formFieldInput.value = this.values.join(\"\\n\");\n this.updateList();\n this.updateAriaText(`'${newValue}' added`);\n }\n } else {\n this.updateAriaText(\"Enter an item to add\");\n }\n this.$formFieldNewInput.value = \"\";\n this.$formFieldNewInput.focus();\n }\n\n removeValue(value) {\n const removeValue = this.normaliseValue(value);\n if (removeValue && this.isValueInList(removeValue)) {\n this.values = this.values.filter(\n (existingValue) => existingValue !== removeValue,\n );\n this.$formFieldInput.value = this.values.join(\"\\n\");\n this.updateList();\n this.updateAriaText(`'${removeValue}' removed`);\n }\n if (this.values.length) {\n this.$valuesList.setAttribute(\"tabindex\", \"0\");\n this.$valuesList.focus();\n } else {\n this.$formFieldNewInput.focus();\n }\n }\n\n updateList() {\n this.$valuesList.innerHTML = \"\";\n this.values\n .map((value) => {\n const $item = document.createElement(\"li\");\n $item.classList.add(\"tna-compound-filters__item\");\n const $itemLabel = document.createElement(\"span\");\n $itemLabel.innerText = value;\n $item.appendChild($itemLabel);\n\n const $removeItemButton = document.createElement(\"button\");\n $removeItemButton.innerText = `Remove '${value}'`;\n $removeItemButton.setAttribute(\"type\", \"button\");\n $removeItemButton.classList.add(\"tna-compound-filters__link\");\n $removeItemButton.addEventListener(\"click\", () => {\n this.removeValue(value);\n });\n $item.appendChild($removeItemButton);\n return $item;\n })\n .forEach(($item) => this.$valuesList.appendChild($item));\n\n let innerTextItemValue = \"item\";\n /* eslint-disable-next-line no-magic-numbers */\n if (this.values.length !== 1) {\n innerTextItemValue += \"s\";\n }\n const innerTextValue = `${new Intl.NumberFormat().format(this.values.length)} ${innerTextItemValue} added`;\n this.$formFieldCounter.innerText = innerTextValue;\n }\n}\n","// The module cache\nconst __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tconst cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tconst module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter/value functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop));","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};"],"names":["root","factory","exports","module","define","amd","self","TextAreaCharacterCount","constructor","$module","options","this","$formFieldInput","querySelector","$formFieldCharacterCount","$formFieldCharacterCountScreenReader","max","parseInt","dataset","maxLength","countType","init","threshold","countThreshold","debounceDuration","intervalChecker","debounceTimeout","lastInputValue","addEventListener","handleInput","lastInputTimestamp","Date","now","handleFocus","handleBlur","updateVisualCharacterCount","updateScreenReaderCharacterCount","valueChecker","window","setInterval","updateIfValueChanged","clearInterval","value","clearTimeout","setTimeout","getCurrentLength","trimmedValue","trim","split","length","getCurrentLengthMessage","currentLength","typeLabel","Math","abs","replace","Intl","NumberFormat","format","isOverThreshold","showCharacterCount","hideCharacterCount","innerText","classList","add","remove","currentLengthMessage","removeAttribute","setAttribute","TextAreaItemisedRows","$formFieldInputHint","$formFieldBody","getAttribute","HTMLTextAreaElement","Error","enhancedHint","values","map","filter","id","$formFieldNewInput","document","createElement","forEach","attribute","appendChild","updateList","event","key","appendValue","target","$formFieldNewInputAddButton","$formFieldNewInputAddButtonInner","$formFieldNewInputAddButtonInnerExtra","$formFieldLiveAria","$formFieldCounter","$valuesList","updateAriaText","parentNode","insertBefore","content","normaliseValue","isValueInList","eachValue","toLowerCase","includes","newValue","push","join","focus","removeValue","existingValue","innerHTML","$item","$itemLabel","$removeItemButton","innerTextItemValue","innerTextValue","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag"],"sourceRoot":""}
|