@@ -61,6 +61,7 @@ export class CharacterCount extends ConfigurableComponent {
6161 const {
6262 i18n,
6363 maxlength,
64+ countFunction,
6465 countType,
6566 screenReaderCountMessageClass,
6667 textareaDescriptionClass,
@@ -72,9 +73,12 @@ export class CharacterCount extends ConfigurableComponent {
7273 locale : closestAttributeValue ( this . $root , 'lang' )
7374 } )
7475
75- if ( 'Segmenter' in Intl && countType === 'characters' ) {
76+ if (
77+ 'Segmenter' in Intl &&
78+ ( countType === 'characters' || ! ! countFunction )
79+ ) {
7680 this . segmenter = new Intl . Segmenter ( this . i18n . locale , {
77- granularity : 'grapheme'
81+ granularity : countType === 'words' ? 'word' : 'grapheme'
7882 } )
7983 }
8084
@@ -212,10 +216,11 @@ export class CharacterCount extends ConfigurableComponent {
212216 */
213217 updateCount ( text ) {
214218 const { $textarea, countFunctions } = this
215- const { countType = 'length' } = this . config
219+ let { countType = 'length' , countFunction } = this . config
216220
217221 text ??= $textarea . value
218- this . length = countFunctions [ countType ] . call ( this , text )
222+ countFunction ??= countFunctions [ countType ]
223+ this . length = countFunction . call ( this , text )
219224 }
220225
221226 /**
@@ -442,7 +447,7 @@ export class CharacterCount extends ConfigurableComponent {
442447 * Character count functions
443448 *
444449 * @constant
445- * @satisfies {Record<string, (this: CharacterCount, text: string) => number > }
450+ * @satisfies {Record<string, CharacterCountConfig['countFunction'] > }
446451 */
447452 countFunctions = Object . freeze ( {
448453 length ( text ) {
@@ -518,6 +523,7 @@ export class CharacterCount extends ConfigurableComponent {
518523 maxlength : { type : 'number' } ,
519524 threshold : { type : 'number' } ,
520525 countType : { type : 'string' } ,
526+ countFunction : { type : 'function' } ,
521527 textareaDescriptionClass : { type : 'string' } ,
522528 visibleCountMessageClass : { type : 'string' } ,
523529 screenReaderCountMessageClass : { type : 'string' } ,
@@ -564,6 +570,7 @@ export function initCharacterCounts(options) {
564570 * @property {number } [threshold=0] - The percentage value of the limit at which point the count message is displayed.
565571 * If this attribute is set, the count message will be hidden by default.
566572 * @property {'length' | 'characters' | 'words' } [countType] - The count type (`"characters"` or `"words"`) used to count the text.
573+ * @property {(this: CharacterCount, text: string) => number } [countFunction] - Custom character or word counting function.
567574 * @property {string } textareaDescriptionClass - Textarea description class
568575 * @property {string } visibleCountMessageClass - Visible count message class
569576 * @property {string } screenReaderCountMessageClass - Screen reader count message class
0 commit comments