-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Created new `Field.Counter` to replace `CharacterCounter` - Will delete old `CharacterCounter` in #2710 when use is replaced with `Field.Counter` there - [Example story](https://pr-2717.storybook.designsystemet.no/?path=/story/komponenter-field--counter) --------- Co-authored-by: Eirik Backer <[email protected]>
- Loading branch information
1 parent
f71573f
commit af03291
Showing
4 changed files
with
83 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { forwardRef, useEffect, useRef, useState } from 'react'; | ||
import { | ||
ValidationMessage, | ||
type ValidationMessageProps, | ||
} from '../../ValidationMessage'; | ||
|
||
export type FieldCounterProps = { | ||
/** Label template for when `maxCount` is exceeded | ||
* @default '%d tegn for mye' | ||
*/ | ||
over?: string; | ||
/** Label template for count | ||
* @default '%d tegn igjen' | ||
*/ | ||
under?: string; | ||
/** The maximum allowed characters. */ | ||
limit: number; | ||
} & ValidationMessageProps; | ||
|
||
const label = (text: string, count: number) => | ||
text.replace('%d', Math.abs(count).toString()); | ||
|
||
export const FieldCounter = forwardRef<HTMLParagraphElement, FieldCounterProps>( | ||
function FieldCounter( | ||
{ limit, under = '%d tegn igjen', over = '%d tegn for mye', ...rest }, | ||
ref, | ||
) { | ||
const [count, setCount] = useState(0); | ||
const counterRef = useRef<HTMLDivElement>(null); | ||
const hasExceededLimit = count > limit; | ||
const remainder = limit - count; | ||
|
||
useEffect(() => { | ||
const onInput = ({ target }: Event) => { | ||
if ( | ||
target instanceof HTMLInputElement || | ||
target instanceof HTMLTextAreaElement | ||
) { | ||
setCount(target.value.length); | ||
} | ||
}; | ||
|
||
const field = counterRef.current?.closest('.ds-field'); | ||
|
||
field?.addEventListener('input', onInput); | ||
|
||
return () => field?.removeEventListener('input', onInput); | ||
}, [setCount]); | ||
|
||
return ( | ||
<> | ||
<div | ||
data-field='description' | ||
className='ds-sr-only' | ||
aria-live={'polite'} | ||
ref={counterRef} | ||
> | ||
{hasExceededLimit && label(over, remainder)} | ||
</div> | ||
<ValidationMessage error={hasExceededLimit} ref={ref} {...rest}> | ||
{label(hasExceededLimit ? over : under, remainder)} | ||
</ValidationMessage> | ||
</> | ||
); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters