@hashicorp/design-system-components
Version:
Helios Design System Components
110 lines (107 loc) • 3.9 kB
JavaScript
import Component from '@glimmer/component';
import { hash } from '@ember/helper';
import didInsert from '@ember/render-modifiers/modifiers/did-insert';
import HdsTextBody from '../../text/body.js';
import { precompileTemplate } from '@ember/template-compilation';
import { setComponentTemplate } from '@ember/component';
/**
* Copyright IBM Corp. 2021, 2025
* SPDX-License-Identifier: MPL-2.0
*/
const ID_PREFIX = 'character-count-';
const NOOP = () => {};
class HdsFormCharacterCount extends Component {
// The current number of characters in @value
get currentLength() {
const {
value
} = this.args;
return value ? value.length : 0;
}
// Inflector utility function to determine plural or singular for 'character' noun
_pluralize(count, prefix = '', noun = 'character', suffix = 's') {
return `${count}${prefix ? ' ' + prefix : ''} ${noun}${count !== 1 ? suffix : ''}`;
}
get maxLength() {
const {
maxLength
} = this.args;
if (maxLength) {
return typeof maxLength === 'number' ? maxLength : parseInt(maxLength);
}
}
get minLength() {
const {
minLength
} = this.args;
if (minLength) {
return typeof minLength === 'number' ? minLength : parseInt(minLength);
}
}
get remaining() {
return this.maxLength ? this.maxLength - this.currentLength : undefined;
}
get shortfall() {
return this.minLength ? this.minLength - this.currentLength : undefined;
}
get message() {
let messageText = '';
if (this.minLength && this.currentLength === 0) {
messageText = `${this._pluralize(this.minLength)} required`;
} else if (this.minLength && this.currentLength < this.minLength) {
messageText = `${this._pluralize(this.shortfall, 'more')} required`;
} else if (this.maxLength && this.currentLength === 0) {
messageText = `${this._pluralize(this.maxLength)} allowed`;
} else if (this.maxLength && this.currentLength <= this.maxLength) {
messageText = `${this._pluralize(this.remaining)} remaining`;
} else if (this.maxLength && this.remaining && this.currentLength > this.maxLength) {
messageText = `Exceeded by ${this._pluralize(-this.remaining)}`;
} else {
messageText = `${this._pluralize(this.currentLength)} entered`;
}
return messageText;
}
get id() {
const {
controlId
} = this.args;
if (controlId) {
return `${ID_PREFIX}${controlId}`;
}
return null;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get onInsert() {
const {
onInsert
} = this.args;
// notice: this is a guard used to prevent triggering an error when the component is used as standalone element
if (typeof onInsert === 'function') {
return onInsert;
} else {
return NOOP;
}
}
get classNames() {
const classes = ['hds-form-character-count'];
// add a class based on the @contextualClass argument
// notice: this will *not* be documented for public use
// the reason for this is that the contextual component declarations don't pass attributes to the component
if (this.args.contextualClass) {
classes.push(this.args.contextualClass);
}
return classes.join(' ');
}
static {
setComponentTemplate(precompileTemplate("<HdsTextBody @tag=\"div\" @size=\"100\" class={{this.classNames}} id={{this.id}} {{didInsert this.onInsert}} ...attributes aria-live=\"polite\">\n {{#if (has-block)}}\n {{yield (hash minLength=this.minLength maxLength=this.maxLength currentLength=this.currentLength remaining=this.remaining shortfall=this.shortfall)}}\n {{else}}\n {{this.message}}\n {{/if}}\n</HdsTextBody>", {
strictMode: true,
scope: () => ({
HdsTextBody,
didInsert,
hash
})
}), this);
}
}
export { HdsFormCharacterCount as default };
//# sourceMappingURL=index.js.map