Skip to content

Implement character limit feature for inputs#7707

Merged
deleonio merged 45 commits intodevelopfrom
7162-rework-counter-v3
Jul 22, 2025
Merged

Implement character limit feature for inputs#7707
deleonio merged 45 commits intodevelopfrom
7162-rework-counter-v3

Conversation

@sdvg
Copy link
Copy Markdown
Contributor

@sdvg sdvg commented May 14, 2025

Refs: #7162

The A11y and PO reviews will only take place after all other DoD steps have been completed by the Developer:

  • Meaningful pull request title for the release notes
  • Pull request is linked to an issue and all changes relate to the issue
  • Tests to protect this code implemented (if applicable)
  • Manual test performed successfully (if applicable)
  • Documentation or migration has been updated (if applicable)

@sdvg sdvg linked an issue May 14, 2025 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented May 14, 2025

sdvg and others added 15 commits May 14, 2025 14:27
…rk-counter-v3

* 'develop' of github.com:public-ui/kolibri:
  chore: release 3.0.0-rc.10
  Update index.html
  Update index.html
  chore: release 3.0.0-rc.9
  fix: normal buttons hover effect
  Update all snapshots$ $ Refs: #7693
  fix: normal button styled
  Update all snapshots$ $ Refs: #7492
  chore: redefined snapshots
  feat: Add axe accessibility tests for input-checkbox, input-radio, single-select, tree, and scenarios
  Update all snapshots$ $ Refs: #7669
  refact: refactor snapshot tests to streamline options handling and skip unnecessary tests
  feat: switch secondary colour and add outline for contrast optimisation
  feat: change button hierarchy and introduce secondary colour variable
  Enhance DoD workflow to include 'ready_for_review' trigger and clarify draft PR handling
  add a stackblitz sample
  (#7651) Update Netlify configuration
  Document sticky header known issue
  Update all snapshots$ $ Refs: #7516
  Fix navigation style: Always left align labels
@sdvg sdvg marked this pull request as ready for review May 15, 2025 15:37
@deleonio deleonio requested a review from cbraehmig May 15, 2025 21:05
@deleonio deleonio added the a11y label May 16, 2025
…rk-counter-v3

* 'develop' of github.com:public-ui/kolibri: (139 commits)
  Set min-height for modal to have close button completely visible even with minimal content.
  chore: update deps on minor level and lock + move playwright install + fix npm-run-all2 execute
  Update all snapshots$ $ Refs: #7825
  Fix button hide label padding
  Fix Stylelint issue
  Update all snapshots$ $ Refs: #7825
  Unify toolbar styling
  Fix hover style for disabled link-button
  Update all snapshots$ $ Refs: #7825
  Remove border from vertical toolbar
  Add better spacing to sample
  chore: update benchmark-baseline.json [ci skip]
  Update component test and snapshots
  Fix linting issue
  Update all snapshots$ $ Refs: #7483
  Fix type import
  Update all snapshots$ $ Refs: #7825
  Implement vertical orientation for kol-toolbar
  chore: release 3.0.1-rc.0
  feat(benchmark-tests): enhance hydration benchmarks with batch processing and result tracking
  ...
Copy link
Copy Markdown
Contributor

@laske185 laske185 left a comment

Choose a reason for hiding this comment

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

Durch das Feature haben wir in die Textarea eine Fachlichkeit eingebaut. Denn die Anzeige, wie viele Zeichen übrig oder überschritten sind, ist ein hart gecodeter Validator. Außerdem steht die neue Property _character-limit im Konflikt zu _max-length:

<kol-textarea _label="Textara with charachter limit" _value="123213213123" _character-limit="20" class="hydrated mt" style="" _touched="" _max-length="12"></kol-textarea>

Bitte entferne das Feature wieder aus der Textarea und lasse nur das Debouncing drin (analog Version 2).

Erstelle dafür ein neues Sample (Story) unterhalb der Textarea, das genau dieses Feature mit React-Form-Hook umsetzt:

  • Info-Message, wenn noch Zeichen übrig sind.
  • Error-Message, wenn die maximale Anzahl überschritten ist.
  • max-length darf dann nicht gesetzt und die Validierung muss mit zod umgesetzt werden.

sdvg added 3 commits June 24, 2025 11:59
…rk-counter-v3

* 'develop' of github.com:public-ui/kolibri:
  7800 (feature) - SplitButton: Anpassung und Ergänzung von Props und Methoden zur API-Angleichung mit KolButton
  chore: release 3.0.2-rc.0
  Refactor package.json files list and add vite.config.ts for Vite configuration
  docs: translate theme readmes to english
  fix(components): move vibrate comment to helper (#7191)
  docs: update readmes for clarity (#7999)
  Add debug information when build fails
  Files files list
  7800 - test: update e2e to match new SplitButton behavior
  7800 - (feature) Split-Button immer mit Primäraktion
  docs(agent): require build before lint or test
  chore(tsconfig): remove compileOnSave and unify exclude
  feat(schema): add loading prop
  Remove Known Issues and add link to Readme
… into 7162-rework-counter-v3

* '7162-rework-counter-v3' of github.com:public-ui/kolibri:
  Update all snapshots$ $ Refs: #7162
@sdvg sdvg marked this pull request as ready for review June 24, 2025 10:16
…rk-counter-v3

* 'develop' of github.com:public-ui/kolibri: (32 commits)
  Fix generic type
  fix(number): replace Number with parseFloat for inline width parsing and remove Number #7603
  Refactor table component to use aria-sort attributes and add AriaSort type definition
  Remove deprecated code and update Jest snapshots
  Vite server: Remove strictPort option
  Heading: Change HTML-tag for secondary headline to <p>
  refactor(theme): comment out draft theme logic
  feat(samples-react): remove draft warnings
  style(kol-progress): replace inline style `width` with SVG `width` attribute in BarSvg #8006
  Skip all Axe failures
  Disable Axe tests failing in internal themes
  Simplify path transformation
  Provide platform correctly
  Fix theme import
  Transform theme import paths for window support
  Rename class name
  Add shadow.tsx
  Rename shadow.tsx to component.tsx
  Replace kol-pagination with kol-pagination-wc in table / Add kol-pagination-wc and remove Host wrapper
  7942 - fix: Tooltip-Überlagerung durch z-index in Sidebar behoben
  ...
@deleonio
Copy link
Copy Markdown
Contributor

Hi @laske185 und @sdvg,

ich möchte, dass wir diesen PR morgen früh als Erstes abhaken. Stefan hat, glaube schon x Mal die Konflikte gelöst.

Viele Grüße

@deleonio
Copy link
Copy Markdown
Contributor

deleonio commented Jul 16, 2025

Case _hasCounter _maxLength _maxLengthBehavior Ausgabe
1 - - - Zähler nicht sichtbar
2 + - - "n Zeichen"
3 + 5 - oder hard "n/5 Zeichen" - Behavior hard (max-length ist gesetzt)
4 + 5 soft "noch 3 Zeichen verfügbar" - Behavior soft (max-length ist nicht gesetzt)

https://stackblitz.com/edit/stackblitz-starters-7zvcawwd
Wir entscheiden uns bewusst dafür dass _maxLength nicht implizit _hasCounter aktiviert.

@deleonio deleonio removed the request for review from cbraehmig July 16, 2025 08:16
Copy link
Copy Markdown
Contributor

@deleonio deleonio left a comment

Choose a reason for hiding this comment

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

Hi @sdvg,

kannst Du bitte da noch einmal feintunen.

_hasCounter soll es weiterhin geben.

Comment thread packages/components/src/components/textarea/shadow.tsx
Comment thread docs/BREAKING_CHANGES.v3.md Outdated
- The property `_alert` has been removed. It's now being handled automatically based on `_msg` and the touched state. See #6138.
- The property `_error` has been removed. Use `_msg` instead.
- The property `_hideError` has bee renamed to `_hideMsg`.
- The property `_hasCounter` has been removed. To show a visual hint about allowed characters of an input, use `_maxLengthBehavior="soft"` instead. Consult documentation for more details.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

_hasCounter soll weiterhin den Text sichtbar oder nicht sichtbar schalten: #7707 (comment)

sdvg and others added 9 commits July 19, 2025 18:01
…rk-counter-v3

* 'develop' of github.com:public-ui/kolibri: (29 commits)
  Update all snapshots$ $ Refs: #7805
  Improve SplitButton sample
  chore: release 3.0.2-rc.2
  test: fix CLI unit tests
  docs: note KoliBri spelling and ESM imports
  Apply suggestions from code review
  Apply suggestions from code review
  test(cli): add e2e migration test
  docs(cli): add note about matching cli version
  test(cli): cover remaining migration tasks
  test(cli): cover command options
  test(cli): fix remove task import
  chore(cli): remove local gitignore and add unit test script
  test(cli): add coverage for remaining migration tasks
  test(cli): cover additional migration tasks
  Fix: selecting typed value on blur in single-select
  test(cli): add code migration example
  test(cli): add mocha setup
  Fix: Clear button causes crash in Singleselect
  fix(kol-select): add snapshot tests for single and multiple value selections  #7758
  ...
…rk-counter-v3

* 'develop' of github.com:public-ui/kolibri: (33 commits)
  feat: add GitHub Actions workflow to handle PR labels
  docs: clarify component property guidelines
  chore: run benchmark workflows manually
  test(cli): extend CLI interface timeout
  fix(cli): avoid floating promise in entry
  test: fix cli interface async parsing
  chore: remove barrel files from component wrappers
  fix(input-file): initialize filename state with translated text
  Apply suggestions from code review
  refactor(pagination): cache pagination translation
  docs(agent): clarify constant ordering
  refactor: cache translations in components
  Fix theme selection
  Update Snapshots
  Revert Stencil versions
  feat(table-stateless): update sorting accessibility text and localization
  Update Jest snapshots
  fix(cli): enhance version retrieval for yarn and improve test structure
  fix(cli): clarify streaming tag detection
  fix(cli): improve tag detection
  ...
…2-rework-counter-v3

* origin/7162-rework-counter-v3:
  Update all snapshots$ $ Refs: #7162
@sdvg sdvg requested a review from Copilot July 22, 2025 10:19

This comment was marked as outdated.

@deleonio deleonio requested a review from Copilot July 22, 2025 11:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a comprehensive character limit feature for input components (textarea, input-text, input-password, input-email) with enhanced user feedback and accessibility. The implementation adds new character counting behaviors, internationalization support, and improved styling for character limit states.

Key changes:

  • Added _maxLengthBehavior property with 'hard' (default) and 'soft' modes for character limit enforcement
  • Implemented debounced character counting for better screen reader accessibility
  • Enhanced counter component with visual and ARIA feedback for exceeded limits

Reviewed Changes

Copilot reviewed 43 out of 47 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/components/src/schema/props/max-length-behavior.ts New schema definition for maxLengthBehavior property
packages/components/src/functional-components/FormFieldCounter/FormFieldCounter.tsx Redesigned counter component with visual/ARIA text separation and exceeded state handling
packages/components/src/functional-components/FormFieldCharacterLimitHint/FormFieldCharacterLimitHint.tsx New component providing accessible character limit hints
packages/components/src/locales/*.ts Added internationalized strings for character limit feedback
packages/components/src/components/input-*/shadow.tsx Updated input components to support new character limit behaviors
packages/themes/*/mixins/form-field.scss Added styling for exceeded character limit state
Comments suppressed due to low confidence (1)

packages/samples/react/src/components/input-text/partials/cases.tsx:45

  • The removal of _hasCounter property from this test case suggests that the counter behavior has changed. Ensure there are adequate tests covering the new automatic counter behavior when _maxLength is set.
			<KolInputText {...props} _placeholder="Placeholder" _label="With counter" _maxLength={10} _value="Lorem Ipsum" />

counterClasses.push('kol-form-field__counter--exceeded');
}
} else {
return null;
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider returning an empty fragment (<></>) instead of null for consistency with JSX patterns and to avoid potential issues with conditional rendering.

Suggested change
return null;
return <></>;

Copilot uses AI. Check for mistakes.
Comment on lines +42 to 43
import { debounce } from 'lodash-es';

Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

Consider using a lightweight debounce implementation instead of importing the entire lodash-es library to reduce bundle size. A simple setTimeout-based debounce function would be sufficient for this use case.

Suggested change
import { debounce } from 'lodash-es';
function debounce(func: (...args: any[]) => void, wait: number): (...args: any[]) => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
return function (...args: any[]) {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => func(...args), wait);
};
}

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +16
let visualText: string | undefined;
let ariaText: string | undefined;
const counterClasses = ['kol-form-field__counter'];
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

[nitpick] The function has multiple responsibilities (calculating visual text, aria text, and CSS classes). Consider extracting the text calculation logic into separate utility functions to improve readability and testability.

Suggested change
let visualText: string | undefined;
let ariaText: string | undefined;
const counterClasses = ['kol-form-field__counter'];
const counterClasses = ['kol-form-field__counter'];
const { visualText, ariaText, exceededLive } = calculateCounterTexts(currentLength, currentLengthDebounced, maxLength, hasCounter);
if (exceededLive) {
counterClasses.push('kol-form-field__counter--exceeded');
}
if (!visualText || !ariaText) {
return null;
}
return (
<>
<span class={clsx(counterClasses)} aria-hidden="true" data-testid="input-counter">
{visualText}
</span>
<span aria-live="polite" class="visually-hidden" data-testid="input-counter-aria">
{ariaText}
</span>
</>
);
};
const calculateCounterTexts = (
currentLength: number,
currentLengthDebounced: number,
maxLength?: number,
hasCounter?: boolean
): { visualText: string | undefined; ariaText: string | undefined; exceededLive: boolean } => {
let visualText: string | undefined;
let ariaText: string | undefined;
let exceededLive = false;

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +38
&__hint {
@include kol-typography-hint;
}
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

The &__hint block was moved from lines 11-13 to lines 36-38. Ensure this relocation doesn't affect CSS specificity or cascade behavior in existing implementations.

Suggested change
&__hint {
@include kol-typography-hint;
}
// Removed &__hint block from here as it was relocated to its original position.

Copilot uses AI. Check for mistakes.
@deleonio deleonio merged commit 5ed6a8f into develop Jul 22, 2025
9 checks passed
@deleonio deleonio deleted the 7162-rework-counter-v3 branch July 22, 2025 11:23
@publicuibot publicuibot bot locked and limited conversation to collaborators Jul 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Screenreader-Output Input-/Textarea-Counter optimieren

4 participants