Skip to content

Commit

Permalink
fix: updated docs for custom text fields
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinGhadyani-Okta committed Apr 11, 2023
1 parent 617ff81 commit 9a8de6f
Show file tree
Hide file tree
Showing 12 changed files with 235 additions and 133 deletions.
61 changes: 1 addition & 60 deletions packages/odyssey-react-mui/src/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,7 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import { InputBaseProps } from "@mui/material";
import {
ChangeEventHandler,
FocusEventHandler,
InputHTMLAttributes,
memo,
ReactElement,
ReactNode,
useMemo,
} from "react";
import { memo, ReactElement, useMemo } from "react";

import {
FieldError,
Expand All @@ -30,20 +21,6 @@ import {
} from "./";

export type FieldProps = {
/**
* If `true`, the component will receive focus automatically.
*/
autoFocus?: boolean;
/**
* This prop helps users to fill forms faster, especially on mobile devices.
* The name can be confusing, as it's more like an autofill.
* You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
*/
autoCompleteType?: InputHTMLAttributes<HTMLInputElement>["autoComplete"];
/**
* End `InputAdornment` for this component.
*/
endAdornment?: ReactNode;
/**
* If `error` is not undefined, the `input` will indicate an error.
*/
Expand All @@ -57,22 +34,10 @@ export type FieldProps = {
* The id of the `input` element.
*/
id?: string;
/**
* Props that go onto the HTML `input` element.
*/
inputProps?: InputBaseProps["inputProps"];
/**
* If `true`, the component is disabled.
*/
isDisabled?: boolean;
/**
* If `true`, a [TextareaAutosize](/material-ui/react-textarea-autosize/) element is rendered.
*/
isMultiline?: boolean;
/**
* It prevents the user from changing the value of the field
*/
isReadOnly?: boolean;
/**
* If `true`, the `input` element is required.
*/
Expand All @@ -81,18 +46,6 @@ export type FieldProps = {
* The label for the `input` element.
*/
label: string;
/**
* Callback fired when the `input` element loses focus.
*/
onBlur?: FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
/**
* Callback fired when the value is changed.
*/
onChange?: ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>;
/**
* Callback fired when the `input` element get focus.
*/
onFocus?: FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
/**
* The label for the `input` element if the it's not optional
*/
Expand All @@ -108,18 +61,6 @@ export type FieldProps = {
ariaDescribedBy?: string;
id: string;
}) => ReactElement;
/**
* Start `InputAdornment` for this component.
*/
startAdornment?: ReactNode;
/**
* Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
*/
type?: string;
/**
* The value of the `input` element, required for a controlled component.
*/
value?: string;
};

const Field = ({
Expand Down
1 change: 1 addition & 0 deletions packages/odyssey-react-mui/src/SearchField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ const SearchField = forwardRef<HTMLInputElement, SearchFieldProps>(
hint={hint}
id={idOverride}
isDisabled={isDisabled}
isRequired={false}
label={label}
renderFieldComponent={renderFieldComponent}
/>
Expand Down
2 changes: 1 addition & 1 deletion packages/odyssey-react-mui/src/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export type TextFieldProps = {
/**
* Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
*/
type?: string;
type?: "email" | "number" | "tel" | "text" | "url";
/**
* The value of the `input` element, required for a controlled component.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ArgsTable, Canvas, Meta, Story } from "@storybook/addon-docs";

<Meta anchor />

# Password Field

Password inputs ensure that sensitive content is safely obscured.

<Canvas>
<Story id="mui-components-forms-passwordfield--default" />
</Canvas>
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*!
* Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/

import { ComponentMeta, ComponentStory } from "@storybook/react";
import { PasswordField } from "@okta/odyssey-react-mui";

import { MuiThemeDecorator } from "../../../../.storybook/components";
import PasswordFieldMdx from "./PasswordField.mdx";

const storybookMeta: ComponentMeta<typeof PasswordField> = {
title: `MUI Components/Forms/PasswordField`,
component: PasswordField,
parameters: {
docs: {
page: PasswordFieldMdx,
},
},
argTypes: {
autoCompleteType: {
control: "text",
defaultValue: "name",
},
autoFocus: {
control: "boolean",
defaultValue: false,
},
isDisabled: {
control: "boolean",
defaultValue: false,
},
errorMessage: {
control: "text",
},
hint: {
control: "text",
},
id: {
control: "text",
},
label: {
control: "text",
defaultValue: "Destination",
},
onBlur: {
control: "function",
},
onChange: {
control: "function",
},
onFocus: {
control: "function",
},
placeholder: {
control: "text",
},
isReadOnly: {
control: "boolean",
defaultValue: false,
},
isRequired: {
control: "boolean",
defaultValue: true,
},
value: {
control: "text",
},
},
decorators: [MuiThemeDecorator],
};

export default storybookMeta;

const Template: ComponentStory<typeof PasswordField> = (args) => {
return <PasswordField {...args} />;
};

export const Default = Template.bind({});
Default.args = {
autoCompleteType: "current-password",
label: "Password",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ArgsTable, Canvas, Meta, Story } from "@storybook/addon-docs";

<Meta anchor />

# Search Field

Search inputs allow the user to submit queries. This is the only input type where `placeholder` may be used.

<Canvas>
<Story id="mui-components-forms-searchfield--default" />
</Canvas>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*!
* Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/

import { ComponentMeta, ComponentStory } from "@storybook/react";
import { SearchField } from "@okta/odyssey-react-mui";

import { MuiThemeDecorator } from "../../../../.storybook/components";
import SearchFieldMdx from "./SearchField.mdx";

const storybookMeta: ComponentMeta<typeof SearchField> = {
title: `MUI Components/Forms/SearchField`,
component: SearchField,
parameters: {
docs: {
page: SearchFieldMdx,
},
},
argTypes: {
autoCompleteType: {
control: "text",
defaultValue: "name",
},
autoFocus: {
control: "boolean",
defaultValue: false,
},
isDisabled: {
control: "boolean",
defaultValue: false,
},
errorMessage: {
control: "text",
},
hint: {
control: "text",
},
id: {
control: "text",
},
label: {
control: "text",
defaultValue: "Destination",
},
onBlur: {
control: "function",
},
onChange: {
control: "function",
},
onFocus: {
control: "function",
},
placeholder: {
control: "text",
},
value: {
control: "text",
},
},
decorators: [MuiThemeDecorator],
};

export default storybookMeta;

const Template: ComponentStory<typeof SearchField> = (args) => {
return <SearchField {...args} />;
};

export const Default = Template.bind({});
Default.args = {
label: "Search",
placeholder: "Search planets",
};
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ The values of read-only inputs will be submitted.
<Story id="mui-components-forms-textfield--read-only" />
</Canvas>

### Optional

Odyssey assumes inputs are required by default. Optional inputs should be used to indicate when data is not required for the user to complete a task.

**STORY MISSING**

### Invalid

The invalid state is for inputs with incorrect values or values of the wrong format.
Expand Down Expand Up @@ -119,53 +113,3 @@ Unlike email fields, tel inputs are not automatically validated because global f
<Canvas>
<Story id="mui-components-forms-textfield--tel" />
</Canvas>

### Password

Passwords inputs ensure that sensitive content is safely obscured.

<Canvas>
<Story id="mui-components-forms-textfield--password" />
</Canvas>

### Search

Search inputs allow the user to submit queries. This is the only input type where `placeholder` may be used.

<Canvas>
<Story id="mui-components-forms-textfield--search" />
</Canvas>

## Accessibility

### Placeholders

Except for Search inputs, we advise against using placeholder text for inputs.

#### Translation

To prevent triggering a change in page layout, browsers don't translate certain attributes. Because of this, users will see untranslated placeholder text.

#### Recall

Placeholder text disappears when a field is interacted with. For this reason, it's not suitable for formatting guidelines or necessary context.

#### Utility

Placeholder content is limited to static text. Additionally, placeholder text is truncated beyond the width of its input.

#### Field value confusion

Low-contrast placeholders may be illegible for some users. Yet, placeholders with compliant contrast can be mistaken for field values. High Contrast Mode will make placeholders and values appear identical.

Finally, Users with low digital literacy may not understand the purpose or behavior of placeholder text.

### Purpose

When collecting an individual's personal data, you must define the input's purpose via the `autocomplete` attribute. This allows users to automate the filling of fields and ensures the purpose is known, regardless of the label. A complete list of fields this is required for may be found <a href="https://www.w3.org/TR/WCAG21/#input-purposes">in the WCAG spec</a>.

### Autofocus

Except for very specific cases, we advise against using the `autoFocus` prop; unless used considerately, the sense of focus being "teleported" to an unexpected part of the page can be jarring to users, especially those using screen readers.

More details can be found [on MDN's `autofocus` page](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus#accessibility_considerations).
Loading

0 comments on commit 9a8de6f

Please sign in to comment.