Skip to content

Commit

Permalink
docs(textfield,textarea): migrating docs to storybook (#3204)
Browse files Browse the repository at this point in the history
Migrating the textfield and textarea documentation to the Storybook.
  • Loading branch information
aramos-adobe authored Oct 23, 2024
1 parent b84b93e commit d8d2127
Show file tree
Hide file tree
Showing 6 changed files with 575 additions and 49 deletions.
91 changes: 90 additions & 1 deletion components/textfield/stories/template.js
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";
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
})}
`
});
155 changes: 155 additions & 0 deletions components/textfield/stories/textarea.stories.js
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
},
};
96 changes: 96 additions & 0 deletions components/textfield/stories/textarea.template.js
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)
})}
`
});
Loading

0 comments on commit d8d2127

Please sign in to comment.