Skip to content

Commit

Permalink
more stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
mimarz committed Sep 20, 2023
1 parent 72142c7 commit 0472e9f
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 28 deletions.
19 changes: 10 additions & 9 deletions packages/react/src/components/form/CharacterCounter.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import utilityClasses from '../../utils/utility.module.css';
import { ErrorMessage, Paragraph } from '../Typography';
import { ErrorMessage } from '../Typography';

export type CharacterLimitProps = Omit<
CharacterCounterProps,
Expand All @@ -10,9 +10,9 @@ export type CharacterLimitProps = Omit<

type CharacterCounterProps = {
/** The message indicating the remaining character limit. */
label: (count: number) => string;
label?: (count: number) => string;
/** The description of the maximum character limit for screen readers. */
srLabel: string;
srLabel?: string;
/** The maximum allowed character count. */
maxCount: number;
/** The current value. */
Expand All @@ -23,22 +23,23 @@ type CharacterCounterProps = {
size?: 'xsmall' | 'small' | 'medium' | 'large';
};

// const defaultLabel: CharacterCounterProps['label'] = (count) =>
// count > -1 ? `${count} tegn igjen` : `${Math.abs(count)} tegn for mye.`;
const defaultLabel: CharacterCounterProps['label'] = (count) =>
count > -1 ? `${count} tegn igjen` : `${Math.abs(count)} tegn for mye.`;

// const defaultSrLabel = (maxCount: number) =>
// `Tekstfelt med plass til ${maxCount} tegn.`;
const defaultSrLabel = (maxCount: number) =>
`Tekstfelt med plass til ${maxCount} tegn.`;

export const CharacterCounter = ({
label,
srLabel,
label = defaultLabel,
srLabel: propsSrLabel,
maxCount,
value,
id,
size,
}: CharacterCounterProps): JSX.Element => {
const currentCount = maxCount - value.length;
const hasExceededLimit = value.length > maxCount;
const srLabel = propsSrLabel ? propsSrLabel : defaultSrLabel(maxCount);

return (
<>
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/form/Textfield/Textfield.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ import * as TextfieldStories from './Textfield.stories';
<Controls />

<Canvas of={TextfieldStories.WithCharacterCounter} />
<Canvas of={TextfieldStories.Controlled} />
38 changes: 25 additions & 13 deletions packages/react/src/components/form/Textfield/Textfield.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { Meta, StoryObj } from '@storybook/react';
import type { Meta, StoryObj, StoryFn } from '@storybook/react';
import React, { useState } from 'react';

import { Button, Paragraph } from '../..';

import { Textfield } from '.';

Expand All @@ -12,28 +15,37 @@ export default {
export const Preview: Story = {
args: {
label: 'Label',
description: 'Description',
disabled: false,
readOnly: false,
error: 'Annen feilmelding her',
characterLimit: {
label: (count) =>
count > -1 ? `${count} tegn igjen` : `${Math.abs(count)} tegn for mye.`,
maxCount: 20,
srLabel: `Tekstfelt med plass til ${20} tegn.`,
},
description: '',
},
};

export const WithCharacterCounter: Story = {
args: {
label: 'Label',
error: 'Annen feilmelding her',
characterLimit: {
label: (count) =>
count > -1 ? `${count} tegn igjen` : `${Math.abs(count)} tegn for mye.`,
maxCount: 20,
srLabel: `Tekstfelt med plass til ${20} tegn.`,
count > -1
? `${count} character Left`
: `${Math.abs(count)} characters to many.`,
maxCount: 5,
srLabel: `Field with room for ${5} characters.`,
},
},
};

export const Controlled: StoryFn<typeof Textfield> = () => {
const [value, setValue] = useState<string>();
return (
<>
<Paragraph>Du har skrevet inn: {value}</Paragraph>
<Textfield
label='Kontroller meg!'
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<Button onClick={() => setValue('Kake 🎂')}>Jeg vil ha Kake 🎂</Button>
</>
);
};
39 changes: 33 additions & 6 deletions packages/react/src/components/form/Textfield/Textfield.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,51 @@ import classes from './Textfield.module.css';
import utilityClasses from './../../../utils/utility.module.css';

export type TextfieldProps = {
/** Label */
label?: ReactNode;
/** Visually hides `label` and `description` (still available for screen readers) */
hideLabel?: boolean;
/** Changes field size and paddings */
size?: 'xsmall' | 'small' | 'medium' | 'large';
/** Prefix for field. */
prefix?: string;
/** Sufix for field. */
sufix?: string;
/** Supported `input` types */
type?:
| 'text'
| 'password'
| 'date'
| 'datetime-local'
| 'email'
| 'file'
| 'month'
| 'number'
| 'password'
| 'search'
| 'tel'
| 'text'
| 'time'
| 'url'
| 'week';
/**
* The characterLimit function calculates remaining characters.
* The characterLimit function calculates remaining characters based on `maxCount`
*
* Provide a `label` function that takes count as parameter and returns a message.
*
* Use `srLabel` to describe `maxCount` for screen readers.
*
* Defaults to Norwegian if no labels are provided.
*/
characterLimit?: CharacterLimitProps;
} & Omit<FormFieldProps, 'size'> &
Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>;

/** Text input field
*
* @example
* ```tsx
* <Textfield label="Textfield label">
* ```
*/
export const Textfield = forwardRef<HTMLInputElement, TextfieldProps>(
(props, ref) => {
const {
Expand All @@ -49,8 +68,10 @@ export const Textfield = forwardRef<HTMLInputElement, TextfieldProps>(
prefix,
style,
characterLimit,
hideLabel,
...rest
} = props;

const {
inputProps,
descriptionId,
Expand All @@ -61,7 +82,7 @@ export const Textfield = forwardRef<HTMLInputElement, TextfieldProps>(
} = useTextfield(props);

const [inputValue, setInputValue] = useState(props.defaultValue);
const characterLimitId = `charactercount-${useId()}`;
const characterLimitId = `textfield-charactercount-${useId()}`;
const hasCharacterLimit = characterLimit != null;

const describedBy = cn(
Expand All @@ -83,7 +104,10 @@ export const Textfield = forwardRef<HTMLInputElement, TextfieldProps>(
>
{label && (
<Label
className={classes.label}
className={cn(
classes.label,
hideLabel && utilityClasses.visuallyHidden,
)}
htmlFor={inputProps.id}
size={size}
weight='regular'
Expand All @@ -102,7 +126,10 @@ export const Textfield = forwardRef<HTMLInputElement, TextfieldProps>(
id={descriptionId}
as='div'
size={size}
className={classes.description}
className={cn(
classes.description,
hideLabel && utilityClasses.visuallyHidden,
)}
>
{description}
</Paragraph>
Expand Down

0 comments on commit 0472e9f

Please sign in to comment.