Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: fix and document use of keyboard focus classes on text fields #3354

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions components/textfield/stories/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,13 @@ export const Template = ({
style=${styleMap(customStyles)}
@click=${onclick}
@focusin=${function() {
updateArgs({
updateArgs?.({
isFocused: true,
isKeyboardFocused: true
});
}}
@focusout=${function() {
updateArgs({
updateArgs?.({
isFocused: false,
isKeyboardFocused: false
});
}}
id=${ifDefined(id)}
Expand Down Expand Up @@ -231,7 +229,7 @@ export const TextFieldOptions = (args, context) => Container({
"gap": "8px",
},
heading: "Default",
content: Template({...args, context})
content: Template(args, context)
})}
${Container({
withBorder: false,
Expand Down Expand Up @@ -275,3 +273,29 @@ export const TextFieldOptions = (args, context) => Container({
})}
`
});

export const KeyboardFocusTemplate = (args, context) => Container({
direction: "column",
withBorder: false,
wrapperStyles: {
rowGap: "12px",
},
content: html`
${Container({
withBorder: false,
containerStyles: {
"gap": "8px",
},
heading: "Default",
content: Template({...args, isKeyboardFocused: true}, context)
})}
${Container({
withBorder: false,
containerStyles: {
"gap": "8px",
},
heading: "Quiet",
content: Template({...args, isKeyboardFocused: true, isQuiet: true}, context)
})}
`
});
30 changes: 20 additions & 10 deletions components/textfield/stories/textarea.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import { Sizes } from "@spectrum-css/preview/decorators";
import { disableDefaultModes } from "@spectrum-css/preview/modes";
import metadata from "../metadata/metadata.json";
import packageJson from "../package.json";
import { HelpTextOptionsTextArea, Template, TextAreaOptions } from "./textarea.template.js";
import { HelpTextOptionsTextArea, KeyboardFocusTemplate, Template, TextAreaOptions } from "./textarea.template.js";
import { TextAreaGroup } from "./textarea.test.js";
import { default as Textfield } from "./textfield.stories.js";

/**
* A text area is multi-line text field using the `<textarea>` element that lets a user input a longer amount of text than a standard text field. It can include all of the standard validation options supported by the text field component.
*/

*/
export default {
title: "Text area",
component: "TextArea",
Expand Down Expand Up @@ -52,7 +51,7 @@ CharacterCount.parameters = {

/**
* A text area in a disabled state shows that an input field exists, but is not available in that circumstance. This can be used to maintain layout continuity and communicate that a field may become available later.
*/
*/
export const Disabled = Template.bind({});
Disabled.tags = ["!dev"];
Disabled.args = {
Expand All @@ -66,7 +65,7 @@ Disabled.parameters = {
* A text area can have [help text](/docs/components-help-text--docs) below the field to give extra context or instruction about what a user should input in the field. The help text area has two options: a description and an error message. The description communicates a hint or helpful information, such as specific requirements for correctly filling out the field. The error message communicates an error for when the field requirements aren’t met, prompting a user to adjust what they had originally input.
*
* Instead of placeholder text, use the help text description to convey requirements or to show any formatting examples that would help user comprehension. Putting instructions for how to complete an input, requirements, or any other essential information into placeholder text is not accessible.
*/
*/
export const HelpText = HelpTextOptionsTextArea.bind({});
HelpText.tags = ["!dev"];
HelpText.parameters = {
Expand All @@ -84,7 +83,7 @@ Quiet.parameters = {

/**
* Text area has a read-only option for when content in the disabled state still needs to be shown. This allows for content to be copied, but not interacted with or changed.
*/
*/
export const Readonly = Template.bind({});
Readonly.tags = ["!dev"];
Readonly.args = {
Expand All @@ -98,7 +97,7 @@ Readonly.storyName = "Read-only";

/**
* Side labels are most useful when vertical space is limited.
*/
*/
export const SideLabel = Template.bind({});
SideLabel.tags = ["!dev"];
SideLabel.args = {
Expand All @@ -112,10 +111,9 @@ SideLabel.parameters = {
chromatic: { disableSnapshot: true }
};


/**
* Text area can display a validation icon when the text entry is expected to conform to a specific format (e.g., email address, credit card number, password creation requirements, etc.). The icon appears as soon as a user types a valid entry in the field.
*/
*/
export const Validation = Template.bind({});
Validation.tags = ["!dev"];
Validation.args = {
Expand All @@ -126,7 +124,6 @@ Validation.parameters = {
};
Validation.storyName = "Validation icon";


export const Sizing = (args, context) => Sizes({
Template: Template,
withHeading: false,
Expand All @@ -142,6 +139,19 @@ Sizing.parameters = {
chromatic: { disableSnapshot: true }
};

/**
* When the text area was focused using the keyboard (e.g. with the tab key), the implementation must add the `is-keyboardFocused` class, which
* displays the focus indicator. This indicator should not appear on focus from a click or tap.
*/
export const KeyboardFocus = KeyboardFocusTemplate.bind({});
KeyboardFocus.tags = ["!dev"];
KeyboardFocus.args = {
isKeyboardFocused: true,
};
KeyboardFocus.parameters = {
chromatic: { disableSnapshot: true }
};

// ********* VRT ONLY ********* //
// @todo should this show text field and text area in the same snapshot?
export const WithForcedColors = TextAreaGroup.bind({});
Expand Down
28 changes: 27 additions & 1 deletion components/textfield/stories/textarea.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const TextAreaOptions = (args, context) => Container({
"gap": "8px",
},
heading: "Default",
content: Template({...args, context})
content: Template(args, context)
})}
${Container({
withBorder: false,
Expand Down Expand Up @@ -94,3 +94,29 @@ export const TextAreaOptions = (args, context) => Container({
})}
`
});

export const KeyboardFocusTemplate = (args, context) => Container({
direction: "column",
withBorder: false,
wrapperStyles: {
rowGap: "12px",
},
content: html`
${Container({
withBorder: false,
containerStyles: {
"gap": "8px",
},
heading: "Default",
content: Template({...args, isKeyboardFocused: true}, context)
})}
${Container({
withBorder: false,
containerStyles: {
"gap": "8px",
},
heading: "Quiet",
content: Template({...args, isKeyboardFocused: true, isQuiet: true}, context)
})}
`
});
30 changes: 21 additions & 9 deletions components/textfield/stories/textfield.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { disableDefaultModes } from "@spectrum-css/preview/modes";
import { isDisabled, isFocused, isInvalid, isKeyboardFocused, isLoading, isQuiet, isReadOnly, isRequired, isValid, size } from "@spectrum-css/preview/types";
import metadata from "../metadata/metadata.json";
import packageJson from "../package.json";
import { HelpTextOptions, Template, TextFieldOptions } from "./template.js";
import { HelpTextOptions, KeyboardFocusTemplate, Template, TextFieldOptions } from "./template.js";
import { TextFieldGroup } from "./textfield.test.js";

/**
Expand Down Expand Up @@ -143,7 +143,7 @@ export default {

/**
* Text fields should always have a label. In rare cases where context is sufficient and an accessibility expert has reviewed the design, the label could be undefined. These text fields without a visible label should still include an aria-label in HTML (depending on the context, “aria-label” or “aria-labelledby”).
*/
*/

export const Default = TextFieldGroup.bind({});
Default.tags = ["!autodocs"];
Expand All @@ -160,7 +160,7 @@ Standard.parameters = {

/**
* Text fields can display a character count indicator when the length of the text entry needs to be kept under a predefined value. Character count indicators can be used in conjunction with other indicators (validation icon, “optional” or “required” indicators) when necessary.
*/
*/
export const CharacterCount = Template.bind({});
CharacterCount.tags = ["!dev"];
CharacterCount.args = {
Expand All @@ -174,7 +174,7 @@ CharacterCount.parameters = {

/**
* A text field in a disabled state shows that an input field exists, but is not available in that circumstance. This can be used to maintain layout continuity and communicate that a field may become available later.
*/
*/
export const Disabled = Template.bind({});
Disabled.tags = ["!dev"];
Disabled.args = {
Expand All @@ -188,7 +188,7 @@ Disabled.parameters = {
* A text field can have [help text](/docs/components-help-text--docs) below the field to give extra context or instruction about what a user should input in the field. The help text area has two options: a description and an error message. The description communicates a hint or helpful information, such as specific requirements for correctly filling out the field. The error message communicates an error for when the field requirements aren’t met, prompting a user to adjust what they had originally input.
*
* Instead of placeholder text, use the help text description to convey requirements or to show any formatting examples that would help user comprehension. Putting instructions for how to complete an input, requirements, or any other essential information into placeholder text is not accessible.
*/
*/
export const HelpText = HelpTextOptions.bind({});
HelpText.tags = ["!dev"];
HelpText.parameters = {
Expand All @@ -197,7 +197,7 @@ HelpText.parameters = {

/**
* Quiet text fields can have no visible background. This style works best when a clear layout (vertical stack, table, grid) makes it easy to parse. Too many quiet components in a small space can be hard to read.
*/
*/
export const Quiet = TextFieldOptions.bind({});
Quiet.tags = ["!dev"];
Quiet.args = {
Expand All @@ -210,7 +210,7 @@ Quiet.parameters = {

/**
* Text fields have a read-only option for when content in the disabled state still needs to be shown. This allows for content to be copied, but not interacted with or changed.
*/
*/
export const Readonly = Template.bind({});
Readonly.tags = ["!dev"];
Readonly.args = {
Expand All @@ -224,7 +224,7 @@ Readonly.storyName = "Read-only";

/**
* Side labels are most useful when vertical space is limited.
*/
*/
export const SideLabel = Template.bind({});
SideLabel.tags = ["!dev"];
SideLabel.args = {
Expand Down Expand Up @@ -254,7 +254,7 @@ Sizing.parameters = {

/**
* Text fields can display a validation icon when the text entry is expected to conform to a specific format (e.g., email address, credit card number, password creation requirements, etc.). The icon appears as soon as a user types a valid entry in the field.
*/
*/
export const Validation = Template.bind({});
Validation.tags = ["!dev"];
Validation.args = {
Expand All @@ -265,6 +265,18 @@ Validation.parameters = {
};
Validation.storyName = "Validation icon";

/**
* When the text field was focused using the keyboard (e.g. with the tab key), the implementation must add the `is-keyboardFocused` class, which
* displays the focus indicator. This indicator should not appear on focus from a click or tap.
*/
export const KeyboardFocus = KeyboardFocusTemplate.bind({});
KeyboardFocus.tags = ["!dev"];
KeyboardFocus.args = {
isKeyboardFocused: true,
};
KeyboardFocus.parameters = {
chromatic: { disableSnapshot: true }
};

// ********* VRT ONLY ********* //
// @todo should this show text field and text area in the same snapshot?
Expand Down
Loading