Skip to content

Conversation

@lindseywild
Copy link
Contributor

@lindseywild lindseywild commented Dec 3, 2025

What are you trying to accomplish?

Adds character count functionality to the TextArea and TextField components.

Screenshots

Below is a video showcasing that TextArea and TextField components have an optional character_limit that can be passed in as an argument. When a user types, the field is updated with how many characters are left / how many are over. When a user exceeds the limit, the character count text changes to red and an error icon prepends the text.

There is also an aria-live region that updates after a slight delay (500ms) when a user finishes typing. This accurately tells screen reader users how many characters they have left / are over, as well as when the input is invalid if they have typed too many characters.

We are also including sr-only text that is associated with the input so that when a user focuses on the input, they hear "You can enter up to X character(s)". This was added because associating the "X character(s) remaining" message was causing duplicate announcements in NVDA and this is the recommended approach.

ominous-space-lamp-rrp7x5r5jg525www-4000.app.github.dev_lookbook_inspect_primer_alpha_text_area_playground_character_limit.10.validation_message.-.10.December.2025.mp4

Integration

No - users can migrate to this new API once it's finished but nothing needs to be done in dotcom.

List the issues that this change affects.

Related to https://github.com/github/primer/issues/5937.

Risk Assessment

  • Low risk the change is small, highly observable, and easily rolled back.

I chose low risk since we are only adding to the API.

What approach did you choose and why?

Some decisions made w/accessibility in mind:

  1. We have the character count on a separate line in the caption that allows a user to go over the limit, but errors when they do. This is helpful for users who copy / paste text that may be too long and will allow them to edit their content down rather than it stopping and cutting off the characters at the limit.
  2. The error messages and invalid state are read to screen readers, as well as a 500ms delay for the aria-live region to update with the amount of characters left or remaining.

Anything you want to highlight for special attention from reviewers?

  • Design-wise: thoughts? We've already implemented this in the "Blocked users UI" when adding a note, and have worked with accessibility experts on coming up with the best, accessible solution.
  • Are there any other areas that need to be updated or taken into account? I am not too familiar with the forms framework inner-workings and want to make sure I don't miss anything.

Accessibility

  • No new axe scan violation - This change does not introduce any new axe scan violations.

Merge checklist

  • Added/updated tests
  • Added/updated documentation
  • Added/updated previews (Lookbook)
  • Tested in Chrome
  • Tested in Firefox
  • Tested in Safari
  • Tested in Edge

Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.

@changeset-bot
Copy link

changeset-bot bot commented Dec 3, 2025

🦋 Changeset detected

Latest commit: 5a6201b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/view-components Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

<%= builder.text_area(@input.name, **@input.input_arguments) %>
<% end %>
<% if @input.character_limit? %>
<%= content_tag(:div, **character_limit_validation_arguments, data: { target: "primer-text-area.validationElement" }) do %>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to define validation because an error needs to appear as a user is making updates. My understanding is that current validation is designed to only show after form submission. Let me know if there is a better way to do this, though!

<% if @input.character_limit? %>
<%= content_tag(:div, **character_limit_validation_arguments, data: { target: "primer-text-area.validationElement" }) do %>
<span class="FormControl-inlineValidation--visual"><%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %></span>
<span data-target="primer-text-area.validationMessageElement"></span>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having our own defined validation message will also "stack" validation messages if there are multiple; thoughts? Is this ok?

Screen shot of a textarea with 2 error messages, stacked

@lindseywild lindseywild marked this pull request as ready for review December 10, 2025 17:17
@lindseywild
Copy link
Contributor Author

@jonrohan @dylanatsmith Ok this is ready again for review, PR description, video, & screenshots have been updated!

@llastflowers
Copy link
Contributor

llastflowers commented Dec 10, 2025

@lukasoppermann For design input from Primer 👀

@lukasoppermann
Copy link
Contributor

Hey, if it is off by default, it seems fine.

One nitpick, could we somehow wrap the count in a span or something so that it does not bounce so much?
I am thinking if there is a way to make sure it only changes from 9 → 10 and than 99 → 100, etc. instead of changing for every character update. I don't know if using ch or em could be helpful and increasing it to 2ch and afterwards 3ch?

@jonrohan jonrohan added this pull request to the merge queue Dec 16, 2025
@jonrohan jonrohan removed this pull request from the merge queue due to a manual request Dec 16, 2025
@lindseywild lindseywild added this pull request to the merge queue Dec 16, 2025
Merged via the queue into main with commit 7526370 Dec 16, 2025
30 of 31 checks passed
@lindseywild lindseywild deleted the lw/adds-character-counts branch December 16, 2025 15:15
@primer primer bot mentioned this pull request Dec 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants