-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(textfield,textarea): migrating docs to storybook (#3204)
Migrating the textfield and textarea documentation to the Storybook.
- Loading branch information
1 parent
b84b93e
commit d8d2127
Showing
6 changed files
with
575 additions
and
49 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import { Template as FieldLabel } from "@spectrum-css/fieldlabel/stories/template.js"; | ||
import { Template as HelpText } from "@spectrum-css/helptext/stories/template.js"; | ||
import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; | ||
import { getRandomId } from "@spectrum-css/preview/decorators"; | ||
import { Container, getRandomId } from "@spectrum-css/preview/decorators"; | ||
import { Template as ProgressCircle } from "@spectrum-css/progresscircle/stories/template.js"; | ||
import { html } from "lit"; | ||
import { classMap } from "lit/directives/class-map.js"; | ||
|
@@ -72,11 +73,13 @@ export const Template = ({ | |
displayLabel = false, | ||
labelPosition = "top", | ||
labelText, | ||
characterCount, | ||
iconName, | ||
iconSet, | ||
pattern, | ||
placeholder, | ||
name, | ||
helpText = "", | ||
id = getRandomId("textfield"), | ||
value = "", | ||
type = "text", | ||
|
@@ -134,6 +137,8 @@ export const Template = ({ | |
size, | ||
label: labelText, | ||
}, context))} | ||
${when(typeof characterCount !== "undefined", () => html` | ||
<span class="${rootClass}-characterCount">${characterCount}</span>`)} | ||
${when(iconName, () => Icon({ | ||
size, | ||
iconName, | ||
|
@@ -183,6 +188,90 @@ export const Template = ({ | |
size: "s", | ||
customClasses: customProgressCircleClasses, | ||
}, context))} | ||
${when(helpText, () => | ||
HelpText({ | ||
text: helpText, | ||
variant: isInvalid ? "negative" : "neutral", | ||
size, | ||
hideIcon: true, | ||
isDisabled | ||
}, context ))} | ||
</div> | ||
`; | ||
}; | ||
|
||
export const HelpTextOptions = (args, context) => Container({ | ||
direction: "column", | ||
withBorder: false, | ||
withHeading: false, | ||
content: html` | ||
${Container({ | ||
withBorder: false, | ||
heading: "Description", | ||
content: Template({...args, isRequired: true, labelText: "Username", value: "lisawilson24", helpText: "Username must be at least 8 characters."}, context), | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
heading: "Error message", | ||
content: Template({...args, isRequired: true, labelText: "Email address", value: "[email protected]", helpText: "Enter your email address", isInvalid: true }, context), | ||
})} | ||
` | ||
}); | ||
|
||
export const TextFieldOptions = (args, context) => Container({ | ||
direction: "row", | ||
withBorder: false, | ||
wrapperStyles: { | ||
rowGap: "12px", | ||
}, | ||
content: html` | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Default", | ||
content: Template({...args, context}) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Invalid", | ||
content: Template({...args, isInvalid: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Focused", | ||
content: Template({...args, isFocused: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Invalid, focused", | ||
content: Template({...args, isInvalid: true, isFocused: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Keyboard-focused", | ||
content: Template({...args, isKeyboardFocused: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Invalid, keyboard-focused", | ||
content: Template({...args, isInvalid: true, isKeyboardFocused: true}, context) | ||
})} | ||
` | ||
}); |
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,155 @@ | ||
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 { 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", | ||
argTypes: { | ||
...Textfield.argTypes | ||
}, | ||
args: { | ||
...Textfield.args, | ||
labelText: "Comments" | ||
}, | ||
parameters: { | ||
packageJson, | ||
metadata, | ||
} | ||
}; | ||
|
||
export const Default = TextAreaGroup.bind({}); | ||
Default.args = {}; | ||
Default.tags = ["!autodocs"]; | ||
|
||
// ********* DOCS ONLY ********* // | ||
|
||
export const Standard = TextAreaOptions.bind({}); | ||
Standard.tags = ["!dev"]; | ||
Standard.storyName = "Default"; | ||
Standard.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
|
||
export const CharacterCount = Template.bind({}); | ||
CharacterCount.tags = ["!dev"]; | ||
CharacterCount.args = { | ||
hasCharacterCount: true, | ||
characterCount: 50, | ||
value: "Duis mollit ut laboris est labore sunt ipsum. Proident nostrud in ea reprehenderit proident nostrud. Anim ut est anim ex amet." | ||
}; | ||
CharacterCount.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
|
||
/** | ||
* 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 = { | ||
isDisabled: true | ||
}; | ||
Disabled.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
|
||
/** | ||
* 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 = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
|
||
export const Quiet = TextAreaOptions.bind({}); | ||
Quiet.tags = ["!dev"]; | ||
Quiet.args = { | ||
isQuiet: true, | ||
}; | ||
Quiet.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
|
||
/** | ||
* 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 = { | ||
isReadOnly: true, | ||
value: "Adipisicing dolor quis ad non ad ipsum irure ullamco." | ||
}; | ||
Readonly.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
Readonly.storyName = "Read-only"; | ||
|
||
/** | ||
* Side labels are most useful when vertical space is limited. | ||
*/ | ||
export const SideLabel = Template.bind({}); | ||
SideLabel.tags = ["!dev"]; | ||
SideLabel.args = { | ||
labelPosition: "side", | ||
value: "Qui nulla cupidatat do ex laborum ipsum et culpa reprehenderit dolore.", | ||
displayCounter: true, | ||
characterCount: 50, | ||
helpText: "Example help text. Lorem ipsum dolor sit amet." | ||
}; | ||
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 = { | ||
isValid: true | ||
}; | ||
Validation.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
Validation.storyName = "Validation icon"; | ||
|
||
|
||
export const Sizing = (args, context) => Sizes({ | ||
Template: Template, | ||
withHeading: false, | ||
withBorder: false, | ||
...args, | ||
}, context); | ||
Sizing.args = { | ||
helpText: "Example help text. Lorem ipsum dolor sit amet.", | ||
hasCharacterCount: true | ||
}; | ||
Sizing.tags = ["!dev"]; | ||
Sizing.parameters = { | ||
chromatic: { disableSnapshot: true } | ||
}; | ||
|
||
// ********* VRT ONLY ********* // | ||
// @todo should this show text field and text area in the same snapshot? | ||
export const WithForcedColors = TextAreaGroup.bind({}); | ||
WithForcedColors.args = Default.args; | ||
WithForcedColors.tags = ["!autodocs", "!dev"]; | ||
WithForcedColors.parameters = { | ||
chromatic: { | ||
forcedColors: "active", | ||
modes: disableDefaultModes | ||
}, | ||
}; |
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,96 @@ | ||
import { Container } from "@spectrum-css/preview/decorators"; | ||
import { html } from "lit"; | ||
import { Template as Textfield } from "./template"; | ||
|
||
export const Template = ({ | ||
customClasses = [], | ||
rootClass = "spectrum-Textfield", | ||
size = "m", | ||
multiline = true, | ||
...item | ||
} = {}, context = {}) => Textfield({ | ||
customClasses: [ | ||
rootClass, | ||
typeof size !== "undefined" ? `${rootClass}--size${size.toUpperCase()}` : null, | ||
...customClasses | ||
], | ||
size, | ||
multiline, | ||
...item | ||
}, context ); | ||
|
||
export const HelpTextOptionsTextArea = (args, context) => Container({ | ||
direction: "column", | ||
withBorder: false, | ||
withHeading: false, | ||
content: html` | ||
${Container({ | ||
withBorder: false, | ||
heading: "Description", | ||
content: Template({...args, isRequired: true, labelText: "Interests", value: "", helpText: "Describe the interests you'd like to explore through our tutorials."}, context), | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
heading: "Error message", | ||
content: Template({...args, isRequired: true, labelText: "Interests", value: "", helpText: "Enter at least one interest.", isInvalid: true }, context), | ||
})} | ||
` | ||
}); | ||
|
||
export const TextAreaOptions = (args, context) => Container({ | ||
direction: "row", | ||
withBorder: false, | ||
wrapperStyles: { | ||
rowGap: "12px", | ||
}, | ||
content: html` | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Default", | ||
content: Template({...args, context}) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Invalid", | ||
content: Template({...args, isInvalid: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Focused", | ||
content: Template({...args, isFocused: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Invalid, focused", | ||
content: Template({...args, isInvalid: true, isFocused: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Keyboard-focused", | ||
content: Template({...args, isKeyboardFocused: true}, context) | ||
})} | ||
${Container({ | ||
withBorder: false, | ||
containerStyles: { | ||
"gap": "8px", | ||
}, | ||
heading: "Invalid, keyboard-focused", | ||
content: Template({...args, isInvalid: true, isKeyboardFocused: true}, context) | ||
})} | ||
` | ||
}); |
Oops, something went wrong.