# form.character-count The message under a text box with a limit, worded exactly as the GOV.UK Design System's character count: "You have 12 characters remaining", "You have 1 character remaining", "You have 0 characters remaining", "You have 3 characters too many", "You have 1 word too many". It returns the numbers as well, so a form can mark the box in error when `over`, and the server can refuse the same text with the same count: ```ts characterCount("Hello", 10, "characters", null) // { count: 5, remaining: 5, over: false, visible: true, // message: "You have 5 characters remaining", // description: "You can enter up to 10 characters" } ``` `react.form.textarea` shows it live as the person types. It is written in all three languages because the server has to enforce the same limit: a count the browser and the API disagree on is a form that says "0 remaining" and then rejects the post. ## Decisions - **Characters are Unicode code points.** An emoji is 1, not the 2 UTF-16 units JavaScript's `length` (and GOV.UK's own script) counts, so all three languages agree. A decomposed accent (`e` plus a combining acute) is 2. Text is counted as given: a browser posts a line break in a textarea as `\r\n`, which is 2 characters, so normalise line breaks before counting on the server if the limit must match the browser's. - **Words are runs of anything but whitespace**, like GOV.UK's `/\S+/g`, with whitespace spelled out as the Unicode White_Space set (tab to carriage return, space, U+0085, no-break space, U+1680, U+2000-U+200A, the line and paragraph separators, U+202F, U+205F, U+3000) so every language splits alike. Punctuation does not split: `two,three` is one word. - **The threshold** is a percentage of the limit below which the message is not shown (`visible` false), as GOV.UK's `threshold` option. The comparison is `count * 100 >= limit * threshold` in whole numbers, so 50% of 3 is 1.5 and one character stays below it. `null` shows the message always; so does being over the limit, whatever the threshold. The message is worked out even when not visible. - **remaining** goes negative when over; `message` says the positive number "too many". - **description** is GOV.UK's `textareaDescriptionText`, "You can enter up to 200 characters" (singular for a limit of 1), for a page before its script runs. Errors, identical in every language: `limit must be a whole number of at least 1`, `threshold must be a whole number from 0 to 100`, `unit must be characters or words`. Sources: GOV.UK Design System, "Character count" https://design-system.service.gov.uk/components/character-count/; the wording and the threshold rule from govuk-frontend's `character-count.mjs` (`charactersUnderLimit`, `charactersAtLimit`, `charactersOverLimit`, `wordsUnderLimit`, `wordsAtLimit`, `wordsOverLimit`, `isOverThreshold`) https://github.com/alphagov/govuk-frontend/blob/main/packages/govuk-frontend/src/govuk/components/character-count/character-count.mjs. ## Notices Portions derived from GOV.UK Frontend (https://github.com/alphagov/govuk-frontend), Copyright (c) 2017 Crown Copyright (Government Digital Service), under the MIT License; the full notice is in NOTICE. 1.0.1 adds its attribution notices (NOTICE). The code and the tests are unchanged.