Skip to content

Commit

Permalink
feat: add text-input component (#1786)
Browse files Browse the repository at this point in the history
  • Loading branch information
frshwtr authored Aug 23, 2024
1 parent a18ae52 commit fdbadfe
Show file tree
Hide file tree
Showing 19 changed files with 473 additions and 5 deletions.
1 change: 1 addition & 0 deletions apps/dictionary/tokens/$metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"whitelabel/components/o3-button",
"whitelabel/components/o3-tooltip",
"whitelabel/components/o3-typography",
"whitelabel/components/o3-form",
"whitelabel/components/o3-editorial-typography",
"whitelabel/whitelabel",
"utility-tokens",
Expand Down
3 changes: 2 additions & 1 deletion apps/dictionary/tokens/$themes.json
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,8 @@
"whitelabel/components/o3-tooltip": "source",
"whitelabel/use-case/focus": "enabled",
"whitelabel/components/o3-typography": "source",
"whitelabel/components/o3-editorial-typography": "source"
"whitelabel/components/o3-editorial-typography": "source",
"whitelabel/components/o3-form": "source"
},
"$figmaCollectionId": "VariableCollectionId:4842:355",
"$figmaModeId": "4842:3",
Expand Down
40 changes: 40 additions & 0 deletions apps/dictionary/tokens/whitelabel/components/o3-form.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"o3": {
"form": {
"text-input": {
"border": {
"@": {
"value": {
"color": "{o3.color.palette.black-30}",
"width": "2px",
"style": "solid"
},
"type": "border"
},
"error": {
"value": {
"color": "{o3.color.use-case.alert-text}",
"width": "2px",
"style": "solid"
},
"type": "border"
}
},
"background-color": {
"@": {
"value": "{o3.color.palette.white}",
"type": "color"
},
"error": {
"value": "rgba(204, 0, 0, 0.06)",
"type": "color"
}
},
"border-radius": {
"value": "6px",
"type": "borderRadius"
}
}
}
}
}
10 changes: 9 additions & 1 deletion apps/dictionary/tokens/whitelabel/use-case/color.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,16 @@
"value": "{o3.color.palette.white}",
"type": "color"
}
},
"alert-text": {
"value": "{o3.color.palette.crimson}",
"type": "color"
},
"error": {
"value": "{o3.color.palette.crimson}",
"type": "color"
}
}
}
}
}
}
107 changes: 107 additions & 0 deletions components/o3-form/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,108 @@
# o3-form[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](#licence)

Provides components to construct forms.

## Overview

o3-form provides UI form elements with consistent labelling, descriptions, and error styles and interfaces.

## Components

### Text Input

A standard text input for collecting text values.
label: 'Full name',
description: 'Your full name as printed on your driving license',

```tsx
<TextInput label='Full name'
disabled={false}
description='Your full name as printed on your driving license'
/>
```

**HTML**

```
<div data-o3-brand="whitelabel">
<div class="o3-form-field">
<label for="my-input-field">Full name</label>
<span
class="o3-form-input-description"
>
Your full name as printed on your driving license
</span>
<input id="my-input-field" class="o3-form o3-form-text-input" type="text" />
</div>
</div>
```

#### Short text input

The size and max length of the text input can be limited with the `length` property.

```html

<TextInput label="Security code"
description="3 digit security code as printed on the back of your credit card."
length={3} />;
```

**HTML**

```html
<div class="o3-form-field">
<label for="my-input-field">Security Code</label>
<span
class="o3-form-input-description"
>
3 digit security code as printed on the back of your credit card.
</span>
<input
id="my-input-field"
class="o3-form o3-form-text-input o3-form-text-input--short-3"
maxlength="3"
type="text"
/>
```

This will provide a text box 3 characters wide and only allow 3 characters to be typed.

If you prefer to limit the length without styling, use the `maxLength` attribute instead.

```tsx
<TextInput label="Security code"
description="3 digit security code as printed on the back of your credit card."
feedback={args.feedback}
attributes={{
maxLength: 3
}} />;
```

**HTML**

```html
<div class="o3-form-field">
<label for="my-input-field">Security Code</label>
<span
class="o3-form-input-description"
>
3 digit security code as printed on the back of your credit card.
</span>
<input
id="my-input-field"
class="o3-form o3-form-text-input"
maxlength="3"
type="text"
/>
```

## Contact

If you have any questions or comments about this component, or need help using it, please either [raise an issue](https://github.com/Financial-Times/o3-editorial-typography/issues), visit [#origami-support](https://financialtimes.slack.com/messages/origami-support/) or email [Origami Support](mailto:[email protected]).

---

## Licence

This software is published by the Financial Times under the [MIT licence](http://opensource.org/licenses/MIT).
1 change: 1 addition & 0 deletions components/o3-form/main.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import './src/css/components/form.css';
@import './src/css/components/form-field.css';
@import './src/css/components/feedback.css';
@import './src/css/components/text-input.css';
@import './src/css/components/checkbox.css';
1 change: 1 addition & 0 deletions components/o3-form/src/css/brands/whitelabel.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
@import '@financial-times/o3-foundation/css/whitelabel.css';
@import '../tokens/whitelabel/o3-form/_variables.css';
@import '../../../main.css';
28 changes: 28 additions & 0 deletions components/o3-form/src/css/components/text-input.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

.o3-form-text-input {
border: var(--_o3-form-text-input-border);
padding: var(--o3-spacing-3xs) var(--o3-spacing-2xs);
background-color: var(--_o3-form-text-input-background-color);
border-radius: var(--_o3-form-text-input-border-radius);
max-width: var(--_o3-form-text-input-max-width);
}

.o3-form-text-input--short-2 {
--_o3-form-text-input-max-width: 1.5em;
}

.o3-form-text-input--short-3 {
--_o3-form-text-input-max-width: 2.5em;
}

.o3-form-text-input--short-4 {
--_o3-form-text-input-max-width: 3.5em;
}

.o3-form-text-input--short-5 {
--_o3-form-text-input-max-width: 4.5em;
}
.o3-form-text-input--error {
border: var(--_o3-form-text-input-border-error);
background-color: var(--_o3-form-text-input-background-color-error);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Do not edit directly
*/


[data-o3-brand="whitelabel"] .o3-form {
--_o3-form-text-input-border: 2px solid var(--o3-color-palette-black-30);
--_o3-form-text-input-border-error: 2px solid var(--o3-color-use-case-alert-text);
--_o3-form-text-input-background-color: var(--o3-color-palette-white);
--_o3-form-text-input-background-color-error: rgba(204, 0, 0, 0.06);
--_o3-form-text-input-border-radius: 0.375rem;
}
2 changes: 1 addition & 1 deletion components/o3-form/src/tsx/CheckBox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {LabeledFormField, FormFieldset} from './fieldComponents/FormField';
import type {CheckBoxProps, FormFieldsetProps} from '../types';
import type {CheckBoxProps, FormFieldsetProps} from '../types/index';

export const CheckBoxItem = (props: CheckBoxProps) => {
let {inputId, attributes, optional, error} = props;
Expand Down
41 changes: 41 additions & 0 deletions components/o3-form/src/tsx/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {TextInputProps} from '../types/index';
import '../../main.css';
import {LabeledFormField} from './fieldComponents/FormField';

export const TextInput = ({
label,
feedback,
description,
disabled,
length,
attributes,
inputId,
optional,
}: TextInputProps) => {
const inputClasses = ['o3-form', 'o3-form-text-input'];

if (feedback && feedback.type === 'error') {
inputClasses.push('o3-form-text-input--error');
}
if (length) {
inputClasses.push(`o3-form-text-input--short-${length}`);
}

return (
<LabeledFormField
label={label}
feedback={feedback}
description={description}>
<input
{...attributes}
id={inputId}
disabled={disabled}
className={inputClasses.join(' ')}
required={optional}
aria-required={optional}
maxLength={length}
type="text"
/>
</LabeledFormField>
);
};
7 changes: 6 additions & 1 deletion components/o3-form/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ export type BaseInputProps = {
attributes?: JSX.IntrinsicElements['input'];
};

export interface TextInputProps extends FormFieldProps{
disabled?: boolean,
length?: 2 | 3 | 4 | 5,
feedback?: FeedbackProps
};

export interface CheckBoxProps extends BaseInputProps {
inputId: string;
checkboxLabel: string; // Label specifically for the checkbox
}

export interface FormFieldsetProps {
label: string;
description?: string;
Expand Down
86 changes: 86 additions & 0 deletions components/o3-form/stories/whitelabel/textInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type {Meta} from '@storybook/react';
import links from '@financial-times/o3-figma-sb-links';

import {TextInput as TextInputTsx} from '../../src/tsx/TextInput';
import '../../src/css/brands/whitelabel.css';

const meta: Meta<typeof TextInputTsx> = {
title: 'Whitelabel/o3-form',
component: TextInputTsx,
decorators: [
Story => (
<div data-o3-brand="whitelabel">
<Story />
</div>
),
],
parameters: {
backgrounds: {disable: true},
},
} as Meta;

export const TextInput = {
args: {
label: 'Full name',
description: 'Your full name as printed on your driving license',
feedback: {},
},
parameters: {
design: {
type: 'figma',
url: links['whitelabel-o3-form--text-input'].figma,
},
},
render: (args) => {
return (
<TextInputTsx label={args.label} disabled={args.disabled} description={args.description} feedback={args.feedback}
/>);
},
};

export const TextInputErrorState = {
args: {
label: 'Full name',
description: 'Your full name as printed on your driving license',
feedback: {message: 'Something went wrong', type: 'error'},
},
parameters: {
design: {
type: 'figma',
url: links['whitelabel-o3-form--text-input-error-state'].figma,
},
},
render: (args) => {
return (
<TextInputTsx label={args.label} disabled={args.disabled} description={args.description} length={args.length}
feedback={args.feedback}
/>);
},
};

export const ShortTextInput = (args) => {
return (
<>
<TextInputTsx label="Day" description="Two digit day of the month" feedback={args.feedback} length={2}
/>
<TextInputTsx label="Security code"
description="3 digit security code as printed on the back of your credit card."
feedback={args.feedback} length={3} />
<TextInputTsx label="Date of Bith" description="The year you were born" feedback={args.feedback} length={4}
/>
<TextInputTsx label="Passcode" description="A 5-digin code to authenticate you on login"
feedback={args.feedback} length={5} />
</>
);
};
ShortTextInput.parameters = {
controls: {
disable: true
},
design: {
type: 'figma',
url: links['whitelabel-o3-form--text-input'].figma,
},
}

export default meta;
Loading

0 comments on commit fdbadfe

Please sign in to comment.