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.

Note: I have an open question w/our accessibility experts about the caption announcing twice on NVDA and whether or not this is expected behavior w/NVDA.

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.

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: 8dfc244

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

@dylanatsmith
Copy link
Member

FYI we have similar but different patterns implemented piecemeal in other places. I've done it so that the message is 50 / 100 characters remaining (show total limit, no period) and the count gets swapped out for the warning/error. There's also a warning threshold, so it goes yellow when the user gets close to the limit, then red when they're over the limit.

I like it a little better than stacking the count with another error and a caption — that's just a lot of text.

@lindseywild
Copy link
Contributor Author

@dylanatsmith What if instead of adding a new validation message, when a user types over the limit, the text changes to red and there's an error icon next to the "x characters over" message? We can still keep the error styling (red border) around the textarea. I am thinking from an accessibility perspective too, since the "x characters over" text is already read to screen reader users, adding an "error" to the message should suffice.

@lindseywild
Copy link
Contributor Author

I am making some updates to this so it might be best to hold off on reviewing; I will ping you all when it's ready again!

@lindseywild lindseywild marked this pull request as draft December 10, 2025 15:26
@lindseywild
Copy link
Contributor Author

@dylanatsmith an update for you :)

This is what it'd look like when you have an error message and you've exceeded the character limit.

screen shot of the character counter within a textarea showing an unrelated validation message and the character count text now in red with a danger icon

@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

llastflowers commented Dec 10, 2025

@lukasoppermann For design input from Primer 👀

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.

5 participants