From 7f9af9e7d13c4aadc6a8b6a1f48d46c7bd64c745 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 3 Mar 2023 10:45:00 -0800 Subject: [PATCH 01/46] radio init --- .../web-components/src/radio-group/define.ts | 4 + .../web-components/src/radio-group/index.ts | 4 + .../src/radio-group/radio-group.definition.ts | 18 +++ .../src/radio-group/radio-group.styles.ts | 31 +++++ .../src/radio-group/radio-group.template.ts | 5 + .../src/radio-group/radio-group.ts | 8 ++ packages/web-components/src/radio/define.ts | 4 + packages/web-components/src/radio/index.ts | 5 + .../src/radio/radio.definition.ts | 18 +++ .../web-components/src/radio/radio.stories.ts | 24 ++++ .../web-components/src/radio/radio.styles.ts | 118 ++++++++++++++++++ .../src/radio/radio.template.ts | 7 ++ packages/web-components/src/radio/radio.ts | 8 ++ 13 files changed, 254 insertions(+) create mode 100644 packages/web-components/src/radio-group/define.ts create mode 100644 packages/web-components/src/radio-group/index.ts create mode 100644 packages/web-components/src/radio-group/radio-group.definition.ts create mode 100644 packages/web-components/src/radio-group/radio-group.styles.ts create mode 100644 packages/web-components/src/radio-group/radio-group.template.ts create mode 100644 packages/web-components/src/radio-group/radio-group.ts create mode 100644 packages/web-components/src/radio/define.ts create mode 100644 packages/web-components/src/radio/index.ts create mode 100644 packages/web-components/src/radio/radio.definition.ts create mode 100644 packages/web-components/src/radio/radio.stories.ts create mode 100644 packages/web-components/src/radio/radio.styles.ts create mode 100644 packages/web-components/src/radio/radio.template.ts create mode 100644 packages/web-components/src/radio/radio.ts diff --git a/packages/web-components/src/radio-group/define.ts b/packages/web-components/src/radio-group/define.ts new file mode 100644 index 00000000000000..2da64783f83419 --- /dev/null +++ b/packages/web-components/src/radio-group/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './radio-group.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/radio-group/index.ts b/packages/web-components/src/radio-group/index.ts new file mode 100644 index 00000000000000..967f498a393fbf --- /dev/null +++ b/packages/web-components/src/radio-group/index.ts @@ -0,0 +1,4 @@ +export * from './radio-group.js'; +export { definition as RadioGroupDefinition } from './radio-group.definition.js'; +export { styles as RadioGroupStyles } from './radio-group.styles.js'; +export { template as RadioGroupTemplate } from './radio-group.template.js'; diff --git a/packages/web-components/src/radio-group/radio-group.definition.ts b/packages/web-components/src/radio-group/radio-group.definition.ts new file mode 100644 index 00000000000000..0e3f17541c84b8 --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { RadioGroup } from './radio-group.js'; +import { styles } from './radio-group.styles.js'; +import { template } from './radio-group.template.js'; + +/** + * The Fluent RadioGroup Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = RadioGroup.compose({ + name: `${FluentDesignSystem.prefix}-radio-group`, + template, + styles, +}); diff --git a/packages/web-components/src/radio-group/radio-group.styles.ts b/packages/web-components/src/radio-group/radio-group.styles.ts new file mode 100644 index 00000000000000..d15d9061179e6d --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.styles.ts @@ -0,0 +1,31 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import {} from '../theme/design-tokens.js'; + +/** Radio styles + * @public + */ +export const styles = css` + :host([hidden]) { + display: none; + } + :host { + align-items: flex-start; + display: flex; + flex-direction: column; + margin: 2px 0; + } + .positioning-region { + display: flex; + flex-wrap: wrap; + } + :host([orientation='vertical']) .positioning-region { + flex-direction: column; + } + :host([orientation='horizontal']) .positioning-region { + flex-direction: row; + } + :host([disabled]) { + opacity: 0.5; + } +`; diff --git a/packages/web-components/src/radio-group/radio-group.template.ts b/packages/web-components/src/radio-group/radio-group.template.ts new file mode 100644 index 00000000000000..d13afcb79a5c00 --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.template.ts @@ -0,0 +1,5 @@ +import type { ElementViewTemplate } from '@microsoft/fast-element'; +import { radioGroupTemplate } from '@microsoft/fast-foundation'; +import type { Radio } from './radio-group.js'; + +export const template: ElementViewTemplate = radioGroupTemplate(); diff --git a/packages/web-components/src/radio-group/radio-group.ts b/packages/web-components/src/radio-group/radio-group.ts new file mode 100644 index 00000000000000..d21a5ad81f0e6f --- /dev/null +++ b/packages/web-components/src/radio-group/radio-group.ts @@ -0,0 +1,8 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTRadioGroup } from '@microsoft/fast-foundation'; + +/** + * The base class used for constructing a fluent-radio-group custom element + * @public + */ +export class RadioGroup extends FASTRadioGroup {} diff --git a/packages/web-components/src/radio/define.ts b/packages/web-components/src/radio/define.ts new file mode 100644 index 00000000000000..66ca2a55ac25be --- /dev/null +++ b/packages/web-components/src/radio/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './radio.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/radio/index.ts b/packages/web-components/src/radio/index.ts new file mode 100644 index 00000000000000..dc9ccc345f6885 --- /dev/null +++ b/packages/web-components/src/radio/index.ts @@ -0,0 +1,5 @@ +export * from './radio.js'; +export * from './radio.options.js'; +export { definition as RadioDefinition } from './radio.definition.js'; +export { styles as RadioStyles } from './radio.styles.js'; +export { template as RadioTemplate } from './radio.template.js'; diff --git a/packages/web-components/src/radio/radio.definition.ts b/packages/web-components/src/radio/radio.definition.ts new file mode 100644 index 00000000000000..479c8c1bb37c05 --- /dev/null +++ b/packages/web-components/src/radio/radio.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Radio } from './radio.js'; +import { styles } from './radio.styles.js'; +import { template } from './radio.template.js'; + +/** + * The Fluent Radio Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Radio.compose({ + name: `${FluentDesignSystem.prefix}-radio`, + template, + styles, +}); diff --git a/packages/web-components/src/radio/radio.stories.ts b/packages/web-components/src/radio/radio.stories.ts new file mode 100644 index 00000000000000..7a12c218197cea --- /dev/null +++ b/packages/web-components/src/radio/radio.stories.ts @@ -0,0 +1,24 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Radio as FluentRadio } from './radio.js'; +import './define.js'; +import '../radio-group/define.js'; + +type RadioStoryArgs = Args & FluentRadio; +type RadioStoryMeta = Meta; + +const storyTemplate = html` + + Label + Label 2 + +`; + +export default { + title: 'Components/Radio', + args: {}, + argTypes: {}, +} as RadioStoryMeta; + +export const Radio = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/src/radio/radio.styles.ts b/packages/web-components/src/radio/radio.styles.ts new file mode 100644 index 00000000000000..750fae32d4f4dc --- /dev/null +++ b/packages/web-components/src/radio/radio.styles.ts @@ -0,0 +1,118 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + colorNeutralForeground3, + colorNeutralStrokeAccessible, + fontFamilyBase, + fontSizeBase300, + fontWeightRegular, + lineHeightBase300, + spacingHorizontalS, + spacingHorizontalXS, + spacingVerticalS, +} from '../theme/design-tokens.js'; + +/** Radio styles + * @public + */ +export const styles = css` + ${display('inline-flex')} + + :host { + align-items: center; + flex-direction: row; + margin: 4px; + outline: none; + position: relative; + user-select: none; + } + .label { + color: ${colorNeutralForeground3}; + cursor: pointer; + padding: ${spacingVerticalS} ${spacingHorizontalS} ${spacingVerticalS} ${spacingHorizontalXS}; + font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase300}; + font-weight: ${fontWeightRegular}; + line-height: ${lineHeightBase300}; + } + .label__hidden { + display: none; + visibility: hidden; + } + .control, + .checked-indicator { + flex-shrink: 0; + } + .control { + position: relative; + display: inline-block; + width: 16px; + height: 16px; + border-radius: 50%; + border: 1px solid ${colorNeutralStrokeAccessible}; + top: 0; + left: 0; + } + .checked-indicator { + opacity: 0; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 10px; + height: 10px; + border-radius: 5px; + background-color: #ccc; + } + :host(:not([disabled])) .control:hover { + background: darkblue; + border-color: lightblue; + } + :host(:not([disabled])) .control:active { + background: gray; + border-color: darkgray; + } + :host(:focus-visible) .control { + box-shadow: 0 0 0 2px green, 0 0 0 4px green; + } + :host([aria-checked='true']) .control { + background: purple; + border: 1px solid yellow; + } + :host([aria-checked='true']) .checked-indicator { + opacity: 1; + } + :host([aria-checked='true']:not([disabled])) .control:hover { + background: darkpurple; + border: 1px solid darkyellow; + } + :host([aria-checked='true']:not([disabled])) .control:hover .checked-indicator { + background: green; + fill: lightgreen; + } + :host([aria-checked='true']:not([disabled])) .control:active { + background: orange; + border: 1px solid cyan; + } + :host([aria-checked='true']:not([disabled])) .control:active .checked-indicator { + background: magenta; + fill: pink; + } + :host([aria-checked='true']:focus-visible:not([disabled])) .control { + box-shadow: 0 0 0 2px red, 0 0 0 4px red; + } + :host([disabled]) .label, + :host([readonly]) .label, + :host([readonly]) .control, + :host([disabled]) .control { + cursor: not-allowed; + } + + :host([disabled]) { + opacity: 0.5; + } + + :host([aria-checked='true']) .checked-indicator { + display: block; + } +`; diff --git a/packages/web-components/src/radio/radio.template.ts b/packages/web-components/src/radio/radio.template.ts new file mode 100644 index 00000000000000..ceb729eb8e4426 --- /dev/null +++ b/packages/web-components/src/radio/radio.template.ts @@ -0,0 +1,7 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { radioTemplate } from '@microsoft/fast-foundation'; +import type { Radio } from './radio.js'; + +export const template: ElementViewTemplate = radioTemplate({ + checkedIndicator: html`
`, +}); diff --git a/packages/web-components/src/radio/radio.ts b/packages/web-components/src/radio/radio.ts new file mode 100644 index 00000000000000..de75e9633e6e12 --- /dev/null +++ b/packages/web-components/src/radio/radio.ts @@ -0,0 +1,8 @@ +import { attr } from '@microsoft/fast-element'; +import { FASTRadio } from '@microsoft/fast-foundation'; + +/** + * The base class used for constructing a fluent-radio custom element + * @public + */ +export class Radio extends FASTRadio {} From 70c55e0bbd66fb05df7d79b89fe13b13dcbebc37 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 3 Mar 2023 12:34:59 -0800 Subject: [PATCH 02/46] styles radio --- packages/web-components/src/radio/index.ts | 1 - packages/web-components/src/radio/radio.styles.ts | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/web-components/src/radio/index.ts b/packages/web-components/src/radio/index.ts index dc9ccc345f6885..e1af0f69389a11 100644 --- a/packages/web-components/src/radio/index.ts +++ b/packages/web-components/src/radio/index.ts @@ -1,5 +1,4 @@ export * from './radio.js'; -export * from './radio.options.js'; export { definition as RadioDefinition } from './radio.definition.js'; export { styles as RadioStyles } from './radio.styles.js'; export { template as RadioTemplate } from './radio.template.js'; diff --git a/packages/web-components/src/radio/radio.styles.ts b/packages/web-components/src/radio/radio.styles.ts index 750fae32d4f4dc..7f45a5d3136a48 100644 --- a/packages/web-components/src/radio/radio.styles.ts +++ b/packages/web-components/src/radio/radio.styles.ts @@ -1,8 +1,10 @@ import { css } from '@microsoft/fast-element'; import { display } from '@microsoft/fast-foundation'; import { + colorNeutralForeground2, colorNeutralForeground3, colorNeutralStrokeAccessible, + colorNeutralStrokeAccessibleHover, fontFamilyBase, fontSizeBase300, fontWeightRegular, @@ -35,6 +37,9 @@ export const styles = css` font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; } + :host(:hover) .label { + color: ${colorNeutralForeground2}; + } .label__hidden { display: none; visibility: hidden; @@ -53,6 +58,9 @@ export const styles = css` top: 0; left: 0; } + :host(:hover) .control { + border-color: ${colorNeutralStrokeAccessibleHover}; + } .checked-indicator { opacity: 0; position: absolute; From a72d10fee8de396c3d2c841813ee494cd08a89d0 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 3 Mar 2023 15:26:46 -0800 Subject: [PATCH 03/46] reverts branch --- .../web-components/src/radio-group/define.ts | 4 - .../web-components/src/radio-group/index.ts | 4 - .../src/radio-group/radio-group.definition.ts | 18 --- .../src/radio-group/radio-group.styles.ts | 31 ----- .../src/radio-group/radio-group.template.ts | 5 - .../src/radio-group/radio-group.ts | 8 -- packages/web-components/src/radio/define.ts | 4 - packages/web-components/src/radio/index.ts | 4 - .../src/radio/radio.definition.ts | 18 --- .../web-components/src/radio/radio.stories.ts | 24 ---- .../web-components/src/radio/radio.styles.ts | 126 ------------------ .../src/radio/radio.template.ts | 7 - packages/web-components/src/radio/radio.ts | 8 -- 13 files changed, 261 deletions(-) delete mode 100644 packages/web-components/src/radio-group/define.ts delete mode 100644 packages/web-components/src/radio-group/index.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.definition.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.styles.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.template.ts delete mode 100644 packages/web-components/src/radio-group/radio-group.ts delete mode 100644 packages/web-components/src/radio/define.ts delete mode 100644 packages/web-components/src/radio/index.ts delete mode 100644 packages/web-components/src/radio/radio.definition.ts delete mode 100644 packages/web-components/src/radio/radio.stories.ts delete mode 100644 packages/web-components/src/radio/radio.styles.ts delete mode 100644 packages/web-components/src/radio/radio.template.ts delete mode 100644 packages/web-components/src/radio/radio.ts diff --git a/packages/web-components/src/radio-group/define.ts b/packages/web-components/src/radio-group/define.ts deleted file mode 100644 index 2da64783f83419..00000000000000 --- a/packages/web-components/src/radio-group/define.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { FluentDesignSystem } from '../fluent-design-system.js'; -import { definition } from './radio-group.definition.js'; - -definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/radio-group/index.ts b/packages/web-components/src/radio-group/index.ts deleted file mode 100644 index 967f498a393fbf..00000000000000 --- a/packages/web-components/src/radio-group/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './radio-group.js'; -export { definition as RadioGroupDefinition } from './radio-group.definition.js'; -export { styles as RadioGroupStyles } from './radio-group.styles.js'; -export { template as RadioGroupTemplate } from './radio-group.template.js'; diff --git a/packages/web-components/src/radio-group/radio-group.definition.ts b/packages/web-components/src/radio-group/radio-group.definition.ts deleted file mode 100644 index 0e3f17541c84b8..00000000000000 --- a/packages/web-components/src/radio-group/radio-group.definition.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { FluentDesignSystem } from '../fluent-design-system.js'; -import { RadioGroup } from './radio-group.js'; -import { styles } from './radio-group.styles.js'; -import { template } from './radio-group.template.js'; - -/** - * The Fluent RadioGroup Element. - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const definition = RadioGroup.compose({ - name: `${FluentDesignSystem.prefix}-radio-group`, - template, - styles, -}); diff --git a/packages/web-components/src/radio-group/radio-group.styles.ts b/packages/web-components/src/radio-group/radio-group.styles.ts deleted file mode 100644 index d15d9061179e6d..00000000000000 --- a/packages/web-components/src/radio-group/radio-group.styles.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { css } from '@microsoft/fast-element'; -import { display } from '@microsoft/fast-foundation'; -import {} from '../theme/design-tokens.js'; - -/** Radio styles - * @public - */ -export const styles = css` - :host([hidden]) { - display: none; - } - :host { - align-items: flex-start; - display: flex; - flex-direction: column; - margin: 2px 0; - } - .positioning-region { - display: flex; - flex-wrap: wrap; - } - :host([orientation='vertical']) .positioning-region { - flex-direction: column; - } - :host([orientation='horizontal']) .positioning-region { - flex-direction: row; - } - :host([disabled]) { - opacity: 0.5; - } -`; diff --git a/packages/web-components/src/radio-group/radio-group.template.ts b/packages/web-components/src/radio-group/radio-group.template.ts deleted file mode 100644 index d13afcb79a5c00..00000000000000 --- a/packages/web-components/src/radio-group/radio-group.template.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { ElementViewTemplate } from '@microsoft/fast-element'; -import { radioGroupTemplate } from '@microsoft/fast-foundation'; -import type { Radio } from './radio-group.js'; - -export const template: ElementViewTemplate = radioGroupTemplate(); diff --git a/packages/web-components/src/radio-group/radio-group.ts b/packages/web-components/src/radio-group/radio-group.ts deleted file mode 100644 index d21a5ad81f0e6f..00000000000000 --- a/packages/web-components/src/radio-group/radio-group.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { FASTRadioGroup } from '@microsoft/fast-foundation'; - -/** - * The base class used for constructing a fluent-radio-group custom element - * @public - */ -export class RadioGroup extends FASTRadioGroup {} diff --git a/packages/web-components/src/radio/define.ts b/packages/web-components/src/radio/define.ts deleted file mode 100644 index 66ca2a55ac25be..00000000000000 --- a/packages/web-components/src/radio/define.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { FluentDesignSystem } from '../fluent-design-system.js'; -import { definition } from './radio.definition.js'; - -definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/radio/index.ts b/packages/web-components/src/radio/index.ts deleted file mode 100644 index e1af0f69389a11..00000000000000 --- a/packages/web-components/src/radio/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './radio.js'; -export { definition as RadioDefinition } from './radio.definition.js'; -export { styles as RadioStyles } from './radio.styles.js'; -export { template as RadioTemplate } from './radio.template.js'; diff --git a/packages/web-components/src/radio/radio.definition.ts b/packages/web-components/src/radio/radio.definition.ts deleted file mode 100644 index 479c8c1bb37c05..00000000000000 --- a/packages/web-components/src/radio/radio.definition.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { FluentDesignSystem } from '../fluent-design-system.js'; -import { Radio } from './radio.js'; -import { styles } from './radio.styles.js'; -import { template } from './radio.template.js'; - -/** - * The Fluent Radio Element. - * - * - * @public - * @remarks - * HTML Element: \ - */ -export const definition = Radio.compose({ - name: `${FluentDesignSystem.prefix}-radio`, - template, - styles, -}); diff --git a/packages/web-components/src/radio/radio.stories.ts b/packages/web-components/src/radio/radio.stories.ts deleted file mode 100644 index 7a12c218197cea..00000000000000 --- a/packages/web-components/src/radio/radio.stories.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { html } from '@microsoft/fast-element'; -import type { Args, Meta } from '@storybook/html'; -import { renderComponent } from '../helpers.stories.js'; -import type { Radio as FluentRadio } from './radio.js'; -import './define.js'; -import '../radio-group/define.js'; - -type RadioStoryArgs = Args & FluentRadio; -type RadioStoryMeta = Meta; - -const storyTemplate = html` - - Label - Label 2 - -`; - -export default { - title: 'Components/Radio', - args: {}, - argTypes: {}, -} as RadioStoryMeta; - -export const Radio = renderComponent(storyTemplate).bind({}); diff --git a/packages/web-components/src/radio/radio.styles.ts b/packages/web-components/src/radio/radio.styles.ts deleted file mode 100644 index 7f45a5d3136a48..00000000000000 --- a/packages/web-components/src/radio/radio.styles.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { css } from '@microsoft/fast-element'; -import { display } from '@microsoft/fast-foundation'; -import { - colorNeutralForeground2, - colorNeutralForeground3, - colorNeutralStrokeAccessible, - colorNeutralStrokeAccessibleHover, - fontFamilyBase, - fontSizeBase300, - fontWeightRegular, - lineHeightBase300, - spacingHorizontalS, - spacingHorizontalXS, - spacingVerticalS, -} from '../theme/design-tokens.js'; - -/** Radio styles - * @public - */ -export const styles = css` - ${display('inline-flex')} - - :host { - align-items: center; - flex-direction: row; - margin: 4px; - outline: none; - position: relative; - user-select: none; - } - .label { - color: ${colorNeutralForeground3}; - cursor: pointer; - padding: ${spacingVerticalS} ${spacingHorizontalS} ${spacingVerticalS} ${spacingHorizontalXS}; - font-family: ${fontFamilyBase}; - font-size: ${fontSizeBase300}; - font-weight: ${fontWeightRegular}; - line-height: ${lineHeightBase300}; - } - :host(:hover) .label { - color: ${colorNeutralForeground2}; - } - .label__hidden { - display: none; - visibility: hidden; - } - .control, - .checked-indicator { - flex-shrink: 0; - } - .control { - position: relative; - display: inline-block; - width: 16px; - height: 16px; - border-radius: 50%; - border: 1px solid ${colorNeutralStrokeAccessible}; - top: 0; - left: 0; - } - :host(:hover) .control { - border-color: ${colorNeutralStrokeAccessibleHover}; - } - .checked-indicator { - opacity: 0; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 10px; - height: 10px; - border-radius: 5px; - background-color: #ccc; - } - :host(:not([disabled])) .control:hover { - background: darkblue; - border-color: lightblue; - } - :host(:not([disabled])) .control:active { - background: gray; - border-color: darkgray; - } - :host(:focus-visible) .control { - box-shadow: 0 0 0 2px green, 0 0 0 4px green; - } - :host([aria-checked='true']) .control { - background: purple; - border: 1px solid yellow; - } - :host([aria-checked='true']) .checked-indicator { - opacity: 1; - } - :host([aria-checked='true']:not([disabled])) .control:hover { - background: darkpurple; - border: 1px solid darkyellow; - } - :host([aria-checked='true']:not([disabled])) .control:hover .checked-indicator { - background: green; - fill: lightgreen; - } - :host([aria-checked='true']:not([disabled])) .control:active { - background: orange; - border: 1px solid cyan; - } - :host([aria-checked='true']:not([disabled])) .control:active .checked-indicator { - background: magenta; - fill: pink; - } - :host([aria-checked='true']:focus-visible:not([disabled])) .control { - box-shadow: 0 0 0 2px red, 0 0 0 4px red; - } - :host([disabled]) .label, - :host([readonly]) .label, - :host([readonly]) .control, - :host([disabled]) .control { - cursor: not-allowed; - } - - :host([disabled]) { - opacity: 0.5; - } - - :host([aria-checked='true']) .checked-indicator { - display: block; - } -`; diff --git a/packages/web-components/src/radio/radio.template.ts b/packages/web-components/src/radio/radio.template.ts deleted file mode 100644 index ceb729eb8e4426..00000000000000 --- a/packages/web-components/src/radio/radio.template.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import { radioTemplate } from '@microsoft/fast-foundation'; -import type { Radio } from './radio.js'; - -export const template: ElementViewTemplate = radioTemplate({ - checkedIndicator: html`
`, -}); diff --git a/packages/web-components/src/radio/radio.ts b/packages/web-components/src/radio/radio.ts deleted file mode 100644 index de75e9633e6e12..00000000000000 --- a/packages/web-components/src/radio/radio.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { attr } from '@microsoft/fast-element'; -import { FASTRadio } from '@microsoft/fast-foundation'; - -/** - * The base class used for constructing a fluent-radio custom element - * @public - */ -export class Radio extends FASTRadio {} From 2cf59cec2397391c19329246ba4bff40d47db385 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 20 Mar 2023 12:35:35 -0700 Subject: [PATCH 04/46] input spec init --- packages/web-components/src/input/README.md | 177 ++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 packages/web-components/src/input/README.md diff --git a/packages/web-components/src/input/README.md b/packages/web-components/src/input/README.md new file mode 100644 index 00000000000000..1ae4c1b1765c1b --- /dev/null +++ b/packages/web-components/src/input/README.md @@ -0,0 +1,177 @@ +# Input + +> An implementation of an [input](https://w3c.github.io/html-reference/input.text.html) as a form-connected web-component. + +
+ +## **Design Spec** + +[Link to Input Design Spec in Figma](https://www.figma.com/file/TvHmWjZYxwtI9Tz6v5BT7E/Input?node-id=2366-657&t=UNSOfCD3St9ffppx-0) + +
+ +## **Engineering Spec** + +Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/components/fast-text-field) and is intended to be as close to the Fluent UI React 9 Input implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +
+ +## Class: `Input` + +
+ +### **Component Name** + +`` + +
+ +### **Variables** + +| Name | Description | Type | +| ----------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `InputSize` | Size variations for input | `{ small: "small", medium: "medium", large: "large" }` | +| `InputAppearance` | Appearance variations for input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | +| `TextFieldType` | Input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | +| `InputLayout` | Layout variations for input | `{ block: "block", inline: "inline"` | + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| ------------- | ------- | ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `appearance` | public | `InputAppearance` | `outline` | Sets appearance of input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables input | +| `layout` | public | `InputLayout` | `InputLayout.block` | Sets layout display property on input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `number` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text field should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the field as required | +| `size` | public | `InputSize` | `medium` | Sets the size of the text input | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used | +| `type` | public | `TextFieldType` | `TextFieldType.text` | Sets the size of the text input | +| `value` | public | `string` | | String value of the text field, can be an empty string | + +
+ +### **Events** + +| Name | Type | Description | Inherited From | +| -------- | ---- | ---------------------------------- | -------------- | +| `change` | | Fires a custom change event | | +| `input` | | Fires a custom input changed event | | + +
+ +### **Attributes** + +| Name | Field | +| ------------- | ----------- | +| `appearance` | appearance | +| `autofocus` | autofocus | +| `disabled` | disabled | +| `list` | list | +| `maxlength` | maxlength | +| `minlength` | minlength | +| `name` | name | +| `pattern` | pattern | +| `placeholder` | placeholder | +| `readonly ` | readonly | +| `required ` | required | +| `size` | size | +| `spellcheck` | spellcheck | +| `type` | type | +| `value ` | value | + +
+ +### **Slots** + +| Name | Description | +| ------- | ----------------------------------------------------------------------- | +| `start` | used to place content at the start of the input within the input border | +| `end` | used to place content at the end of the input within the input border | +| | The default slot for accordion item content | + +
+
+
+ +## **Accessibility** + +[W3C Text Input Spec](https://w3c.github.io/html-reference/input.text.html) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +- `aria-atomic` + - In ARIA live regions, the global aria-atomic attribute indicates whether assistive technologies such as a screen reader will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute. +- `aria-busy` + - Indicates an element is being modified and that assistive technologies may want to wait until the changes are complete before informing the user about the update. +- `aria-controls` + - Identifies the element (or elements) whose contents or presence are controlled by the element on which this attribute is set. +- `aria-current` + - A non-null `aria-current` state on an element indicates that this element represents the current item within a container or set of related elements. +- `aria-describedby` + - Identifies the element (or elements) that describes the element on which the attribute is set. +- `aria-details` + - The global `aria-details` attribute identifies the element (or elements) that provide additional information related to the object. +- `aria-disabled` + - Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable. +- `aria-errormessage` + - Identifies the element that provides an error message for that object. +- `aria-flowto` + - Identifies the next element (or elements) in an alternate reading order of content. This allows assistive technology to override the general default of reading in document source order at the user's discretion. +- `aria-haspopup` + - Indicates the availability and type of interactive popup element that can be triggered by the element on which the attribute is set. +- `aria-hidden` + - Indicates whether the element is exposed to an accessibility API. +- `aria-invalid` + - Indicates the entered value does not conform to the format expected by the application. +- `aria-keyshortcuts` + - Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. +- `aria-label` + - Defines a string value that labels an interactive element. +- `aria-labelledby` + - Identifies the element (or elements) that labels the element it is applied to. +- `aria-live` + - Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region. +- `aria-owns` + - Identifies an element (or elements) in order to define a visual, functional, or contextual relationship between a parent and its child elements when the DOM hierarchy cannot be used to represent the relationship. +- `aria-relevant` + - Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified. +- `aria-roledescription` + - Defines a human-readable, author-localized description for the role of an element. + +
+
+
+ +## **Preparation** + +
+ +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | +| `contentBefore` | `start` | +| `contentAfter` | `end` | + +
+ +**Property Mapping** +| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | +| ------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------- | From 79b6bffb115a9b3f0c6fe2f207491ea508d6655e Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 20 Mar 2023 12:52:39 -0700 Subject: [PATCH 05/46] cleans up spec --- packages/web-components/src/input/README.md | 87 +++++++++++---------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/packages/web-components/src/input/README.md b/packages/web-components/src/input/README.md index 1ae4c1b1765c1b..bd6e7aaac17c8d 100644 --- a/packages/web-components/src/input/README.md +++ b/packages/web-components/src/input/README.md @@ -39,55 +39,58 @@ Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/ ### **Fields** -| Name | Privacy | Type | Default | Description | -| ------------- | ------- | ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `appearance` | public | `InputAppearance` | `outline` | Sets appearance of input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables input | -| `layout` | public | `InputLayout` | `InputLayout.block` | Sets layout display property on input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `number` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text field should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the field as required | -| `size` | public | `InputSize` | `medium` | Sets the size of the text input | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used | -| `type` | public | `TextFieldType` | `TextFieldType.text` | Sets the size of the text input | -| `value` | public | `string` | | String value of the text field, can be an empty string | - -
+| Name | Privacy | Type | Default | Description | +| --------------- | ------- | ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `appearance` | public | `InputAppearance` | `outline` | Sets appearance of input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables input | +| `labelPosition` | public | `boolean` | `false` | Disables input | +| `layout` | public | `InputLayout` | `InputLayout.block` | Sets layout display property on input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `number` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text field should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the field as required | +| `size` | public | `InputSize` | `medium` | Sets the size of the text input | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used | +| `type` | public | `TextFieldType` | `TextFieldType.text` | Sets the size of the text input | + +
+ +### **Methods** + +| Name | Privacy | Description | +| ---------- | ------- | ------------------------------------------------- | +| `select` | public | Selects all the text in the text field | +| `validate` | public | {@inheritDoc (FormAssociated:interface).validate} | ### **Events** -| Name | Type | Description | Inherited From | -| -------- | ---- | ---------------------------------- | -------------- | -| `change` | | Fires a custom change event | | -| `input` | | Fires a custom input changed event | | +| Name | Type | Description | Inherited From | +| -------- | ---- | --------------------------- | -------------- | +| `change` | | Fires a custom change event | |
### **Attributes** -| Name | Field | -| ------------- | ----------- | -| `appearance` | appearance | -| `autofocus` | autofocus | -| `disabled` | disabled | -| `list` | list | -| `maxlength` | maxlength | -| `minlength` | minlength | -| `name` | name | -| `pattern` | pattern | -| `placeholder` | placeholder | -| `readonly ` | readonly | -| `required ` | required | -| `size` | size | -| `spellcheck` | spellcheck | -| `type` | type | -| `value ` | value | +| Name | Field | +| ---------------- | -------------- | +| `appearance` | appearance | +| `autofocus` | autofocus | +| `label-position` | label-position | +| `list` | list | +| `maxlength` | maxlength | +| `minlength` | minlength | +| `pattern` | pattern | +| `placeholder` | placeholder | +| `readonly ` | readonly | +| `size` | size | +| `spellcheck` | spellcheck | +| `type` | type |
@@ -156,8 +159,6 @@ Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/ ## **Preparation** -
- ### **Fluent Web Component v3 v.s Fluent React 9**
From 5558b9324da0bdc5ae9604c911e352382f5f3fc8 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 20 Mar 2023 12:55:29 -0700 Subject: [PATCH 06/46] formatting --- packages/web-components/src/input/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-components/src/input/README.md b/packages/web-components/src/input/README.md index bd6e7aaac17c8d..84a237905b9107 100644 --- a/packages/web-components/src/input/README.md +++ b/packages/web-components/src/input/README.md @@ -175,4 +175,4 @@ Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/ **Property Mapping** | Fluent UI React 9 | Fluent Web Components 3 | Description of difference | -| ------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------- | +| ----------------- | ----------------------- | ------------------------- | From 3c045c3b13f0199bb16450044c0d48a4623b1746 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 20 Mar 2023 13:25:49 -0700 Subject: [PATCH 07/46] updates component name to text input --- packages/web-components/src/input/README.md | 115 ++++++-------------- 1 file changed, 36 insertions(+), 79 deletions(-) diff --git a/packages/web-components/src/input/README.md b/packages/web-components/src/input/README.md index 84a237905b9107..45cb8e0784083f 100644 --- a/packages/web-components/src/input/README.md +++ b/packages/web-components/src/input/README.md @@ -1,62 +1,62 @@ -# Input +# TextInput -> An implementation of an [input](https://w3c.github.io/html-reference/input.text.html) as a form-connected web-component. +> An implementation of a [text input](https://w3c.github.io/html-reference/input.text.html) as a form-connected web-component.
## **Design Spec** -[Link to Input Design Spec in Figma](https://www.figma.com/file/TvHmWjZYxwtI9Tz6v5BT7E/Input?node-id=2366-657&t=UNSOfCD3St9ffppx-0) +[Link to Text Input Design Spec in Figma](https://www.figma.com/file/TvHmWjZYxwtI9Tz6v5BT7E/Input?node-id=2366-657&t=UNSOfCD3St9ffppx-0)
## **Engineering Spec** -Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/components/fast-text-field) and is intended to be as close to the Fluent UI React 9 Input implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. +Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.design/components/fast-text-field) and is intended to be as close to the Fluent UI React 9 Input implementation as possible. However, due to the nature of web components there will not be 100% parity between the two.
-## Class: `Input` +## Class: `TextInput`
### **Component Name** -`` +``
### **Variables** -| Name | Description | Type | -| ----------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| `InputSize` | Size variations for input | `{ small: "small", medium: "medium", large: "large" }` | -| `InputAppearance` | Appearance variations for input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | -| `TextFieldType` | Input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | -| `InputLayout` | Layout variations for input | `{ block: "block", inline: "inline"` | +| Name | Description | Type | +| ------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | +| `size` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | +| `appearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | +| `type` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | +| `layout` | Layout variations for text input | `{ block: "block", inline: "inline"` |
### **Fields** -| Name | Privacy | Type | Default | Description | -| --------------- | ------- | ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `appearance` | public | `InputAppearance` | `outline` | Sets appearance of input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables input | -| `labelPosition` | public | `boolean` | `false` | Disables input | -| `layout` | public | `InputLayout` | `InputLayout.block` | Sets layout display property on input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `number` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text field should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the field as required | -| `size` | public | `InputSize` | `medium` | Sets the size of the text input | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the input field, or if the default spell checking configuration should be used | -| `type` | public | `TextFieldType` | `TextFieldType.text` | Sets the size of the text input | +| Name | Privacy | Type | Default | Description | +| --------------- | ------- | ----------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `appearance` | public | `InputAppearance` | `outline` | Sets appearance of text input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables text input | +| `labelPosition` | public | `boolean` | `false` | Disables text input | +| `layout` | public | `InputLayout` | `TextInputLayout.block` | Sets layout display property on text input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `number` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the text input as required | +| `size` | public | `InputSize` | `medium` | Sets the size of the text input | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | +| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input |
@@ -96,11 +96,11 @@ Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/ ### **Slots** -| Name | Description | -| ------- | ----------------------------------------------------------------------- | -| `start` | used to place content at the start of the input within the input border | -| `end` | used to place content at the end of the input within the input border | -| | The default slot for accordion item content | +| Name | Description | +| ------- | ---------------------------------------------------------------------------- | +| `start` | used to place content at the start of the text input within the input border | +| `end` | used to place content at the end of the text input within the input border | +| | The default slot for text input content |

@@ -114,44 +114,7 @@ Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/ ### **WAI-ARIA Roles, States, and Properties** -- `aria-atomic` - - In ARIA live regions, the global aria-atomic attribute indicates whether assistive technologies such as a screen reader will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute. -- `aria-busy` - - Indicates an element is being modified and that assistive technologies may want to wait until the changes are complete before informing the user about the update. -- `aria-controls` - - Identifies the element (or elements) whose contents or presence are controlled by the element on which this attribute is set. -- `aria-current` - - A non-null `aria-current` state on an element indicates that this element represents the current item within a container or set of related elements. -- `aria-describedby` - - Identifies the element (or elements) that describes the element on which the attribute is set. -- `aria-details` - - The global `aria-details` attribute identifies the element (or elements) that provide additional information related to the object. -- `aria-disabled` - - Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable. -- `aria-errormessage` - - Identifies the element that provides an error message for that object. -- `aria-flowto` - - Identifies the next element (or elements) in an alternate reading order of content. This allows assistive technology to override the general default of reading in document source order at the user's discretion. -- `aria-haspopup` - - Indicates the availability and type of interactive popup element that can be triggered by the element on which the attribute is set. -- `aria-hidden` - - Indicates whether the element is exposed to an accessibility API. -- `aria-invalid` - - Indicates the entered value does not conform to the format expected by the application. -- `aria-keyshortcuts` - - Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. -- `aria-label` - - Defines a string value that labels an interactive element. -- `aria-labelledby` - - Identifies the element (or elements) that labels the element it is applied to. -- `aria-live` - - Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region. -- `aria-owns` - - Identifies an element (or elements) in order to define a visual, functional, or contextual relationship between a parent and its child elements when the DOM hierarchy cannot be used to represent the relationship. -- `aria-relevant` - - Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified. -- `aria-roledescription` - - Defines a human-readable, author-localized description for the role of an element. +This component supports ARIA attributes that inherit from the [ARIA Global States and Properties](https://www.w3.org/TR/wai-aria-1.2/#global_states).

@@ -170,9 +133,3 @@ Fluent WC3 Input extends from the [FAST Text Field](https://explore.fast.design/ | `` | `` | | `contentBefore` | `start` | | `contentAfter` | `end` | - -
- -**Property Mapping** -| Fluent UI React 9 | Fluent Web Components 3 | Description of difference | -| ----------------- | ----------------------- | ------------------------- | From 237096724298e6e09218b2f2e25caf2bebad0e2c Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 20 Mar 2023 13:39:31 -0700 Subject: [PATCH 08/46] updates component name in spec --- packages/web-components/src/input/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-components/src/input/README.md b/packages/web-components/src/input/README.md index 45cb8e0784083f..1461fca61850bc 100644 --- a/packages/web-components/src/input/README.md +++ b/packages/web-components/src/input/README.md @@ -130,6 +130,6 @@ This component supports ARIA attributes that inherit from the [ARIA Global State | Fluent UI React 9 | Fluent Web Components 3 | | ----------------- | ----------------------- | -| `` | `` | +| `` | `` | | `contentBefore` | `start` | | `contentAfter` | `end` | From 0040fbd61a38b8f5d5be9b6a32bb3bbd47721c25 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Wed, 22 Mar 2023 12:07:03 -0700 Subject: [PATCH 09/46] text input init --- .../web-components/src/text-input/define.ts | 4 + .../web-components/src/text-input/index.ts | 5 + .../src/text-input/text-input.definition.ts | 18 ++ .../src/text-input/text-input.options.ts | 75 ++++++ .../src/text-input/text-input.stories.ts | 217 ++++++++++++++++++ .../src/text-input/text-input.styles.ts | 139 +++++++++++ .../src/text-input/text-input.template.ts | 7 + .../src/text-input/text-input.ts | 111 +++++++++ 8 files changed, 576 insertions(+) create mode 100644 packages/web-components/src/text-input/define.ts create mode 100644 packages/web-components/src/text-input/index.ts create mode 100644 packages/web-components/src/text-input/text-input.definition.ts create mode 100644 packages/web-components/src/text-input/text-input.options.ts create mode 100644 packages/web-components/src/text-input/text-input.stories.ts create mode 100644 packages/web-components/src/text-input/text-input.styles.ts create mode 100644 packages/web-components/src/text-input/text-input.template.ts create mode 100644 packages/web-components/src/text-input/text-input.ts diff --git a/packages/web-components/src/text-input/define.ts b/packages/web-components/src/text-input/define.ts new file mode 100644 index 00000000000000..d211104eff0125 --- /dev/null +++ b/packages/web-components/src/text-input/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { definition } from './text-input.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/web-components/src/text-input/index.ts b/packages/web-components/src/text-input/index.ts new file mode 100644 index 00000000000000..804b0fcb5c2fab --- /dev/null +++ b/packages/web-components/src/text-input/index.ts @@ -0,0 +1,5 @@ +export * from './text-input.js'; +export * from './text-input.options.js'; +export { template as TextTemplate } from './text-input.template.js'; +export { styles as TextStyles } from './text-input.styles.js'; +export { definition as TextDefinition } from './text-input.definition.js'; diff --git a/packages/web-components/src/text-input/text-input.definition.ts b/packages/web-components/src/text-input/text-input.definition.ts new file mode 100644 index 00000000000000..1309800b7cf253 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '../fluent-design-system.js'; +import { Text } from './text-input.js'; +import { styles } from './text-input.styles.js'; +import { template } from './text-input.template.js'; + +/** + * The Fluent TextInput Element. + * + * + * @public + * @remarks + * HTML Element: \ + */ +export const definition = Text.compose({ + name: `${FluentDesignSystem.prefix}-text-input`, + template, + styles, +}); diff --git a/packages/web-components/src/text-input/text-input.options.ts b/packages/web-components/src/text-input/text-input.options.ts new file mode 100644 index 00000000000000..8d1683c4949a18 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.options.ts @@ -0,0 +1,75 @@ +import { ValuesOf } from '@microsoft/fast-foundation'; + +/** + * TextInputSize constants + * @public + */ +export const TextInputSize = { + _100: '100', + _200: '200', + _300: '300', + _400: '400', + _500: '500', + _600: '600', + _700: '700', + _800: '800', + _900: '900', + _1000: '1000', +} as const; + +/** + * The type for TextSize + * The font size and line height based on the theme tokens + * @public + */ +export type TextSize = ValuesOf; + +/** + * TextFont Constants + * @public + */ +export const TextFont = { + base: 'base', + numeric: 'numeric', + monospace: 'monospace', +} as const; + +/** + * Applies font family to the content + * @public + */ +export type TextFont = ValuesOf; + +/** + * TextWeight Constants + * @public + */ +export const TextWeight = { + medium: 'medium', + regular: 'regular', + semibold: 'semibold', + bold: 'bold', +} as const; + +/** + * Applies font weight to the content + * @public + */ +export type TextWeight = ValuesOf; + +/** + * TextAlign Constants + * @public + */ +export const TextAlign = { + start: 'start', + end: 'end', + center: 'center', + justify: 'justify', +} as const; + +/** + * Aligns the content + * @public + */ +export type TextAlign = ValuesOf; diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts new file mode 100644 index 00000000000000..2886931c12fe55 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -0,0 +1,217 @@ +import { html } from '@microsoft/fast-element'; +import type { Args, Meta } from '@storybook/html'; +import { renderComponent } from '../helpers.stories.js'; +import type { Text as FluentText } from './text-input.js'; +import './define.js'; +import { TextAlign, TextFont, TextSize, TextWeight } from './text-input.options.js'; + +type TextStoryArgs = Args & FluentText; +type TextStoryMeta = Meta; + +/** + * Used to generate slotted content for stories + * @param as - the element to generate + * @param content - the content for the element + * @returns ViewTemplate + */ +const generateSemanticElementTemplate = (as: string, content) => { + switch (as) { + case 'h1': + return html`

${content}

`; + case 'h2': + return html`

${content}

`; + case 'h3': + return html`

${content}

`; + case 'h4': + return html`

${content}

`; + case 'h5': + return html`
${content}
`; + case 'h6': + return html`
${content}
`; + case 'p': + return html`

${content}

`; + case 'pre': + return html`
${content}
`; + case 'span': + default: + return html`${content}`; + } +}; + +const storyTemplate = html` + x.align} + font=${x => x.font} + size=${x => x.size} + weight=${x => x.weight} + ?nowrap=${x => x.nowrap} + ?truncate=${x => x.truncate} + ?italic=${x => x.italic} + ?underline=${x => x.underline} + ?strikethrough=${x => x.strikethrough} + ?block=${x => x.block} + >${x => generateSemanticElementTemplate(x.as, x.content)} +`; + +export default { + title: 'Components/Text', + args: { + content: 'Text', + nowrap: false, + truncate: false, + italic: false, + underline: false, + strikethrough: false, + block: false, + }, + argTypes: { + as: { + options: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'span'], + control: { + type: 'select', + }, + }, + size: { + options: Object.values(TextSize), + control: { + type: 'select', + }, + }, + weight: { + options: Object.keys(TextWeight), + control: { + type: 'select', + }, + }, + align: { + options: Object.keys(TextAlign), + control: { + type: 'select', + }, + }, + font: { + options: Object.keys(TextFont), + control: { + type: 'select', + }, + }, + nowrap: { + control: 'boolean', + }, + truncate: { + control: 'boolean', + }, + italic: { + control: 'boolean', + }, + underline: { + control: 'boolean', + }, + strikethrough: { + control: 'boolean', + }, + block: { + control: 'boolean', + }, + }, +} as TextStoryMeta; + +export const Text = renderComponent(storyTemplate).bind({}); + +// +// Attribute stories +// + +export const Nowrap = renderComponent(html` + +
+ This text will not wrap lines when it overflows the container. +
+
+`); + +export const Truncate = renderComponent(html` + +
+ Setting truncate and nowrap will truncate when it overflows the container. +
+
+`); + +export const Italic = renderComponent(html` + + Italics are emphasized text. + +`); + +export const Underline = renderComponent(html` + + Underlined text draws the reader's attention to the words. + +`); + +export const Strikethrough = renderComponent(html` + + Strikethrough text is used to indicate something that is no longer relevant. + +`); + +export const Block = renderComponent(html` + + Fluent text is inline by default. Setting + block + will make it behave as a block element. + +`); + +export const Size = renderComponent(html` +
+ 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800 + 900 + 1000 +
+`); + +export const Weight = renderComponent(html` +
+ This text is regular. + This text is medium. + This text is semibold. + This text is bold. +
+`); + +export const Align = renderComponent(html` +
+ + Start aligned block. + + + End aligned block. + + + Center aligned block. + + + Justify aligned block text stretches wrapped lines to meet container edges. + +
+`); + +export const Font = renderComponent(html` +
+ Font base. + Font numeric 0123456789. + Font monospace. +
+`); diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts new file mode 100644 index 00000000000000..8593b9ee070116 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -0,0 +1,139 @@ +import { css } from '@microsoft/fast-element'; +import { display } from '@microsoft/fast-foundation'; +import { + fontFamilyBase, + fontFamilyMonospace, + fontFamilyNumeric, + fontSizeBase100, + fontSizeBase200, + fontSizeBase300, + fontSizeBase400, + fontSizeBase500, + fontSizeBase600, + fontSizeHero1000, + fontSizeHero700, + fontSizeHero800, + fontSizeHero900, + fontWeightBold, + fontWeightMedium, + fontWeightRegular, + fontWeightSemibold, + lineHeightBase100, + lineHeightBase200, + lineHeightBase300, + lineHeightBase400, + lineHeightBase500, + lineHeightBase600, + lineHeightHero1000, + lineHeightHero700, + lineHeightHero800, + lineHeightHero900, +} from '../theme/design-tokens.js'; + +/** Text styles + * @public + */ +export const styles = css` + ${display('inline')} + + :host { + contain: content; + } + + ::slotted(*) { + font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase300}; + line-height: ${lineHeightBase300}; + font-weight: ${fontWeightRegular}; + text-align: start; + white-space: normal; + overflow: visible; + text-overflow: clip; + margin: 0; + display: inline; + } + + :host([nowrap]) ::slotted(*) { + white-space: nowrap; + overflow: hidden; + } + :host([truncate]) ::slotted(*) { + text-overflow: ellipsis; + } + :host([block]), + :host([block]) ::slotted(*) { + display: block; + } + :host([italic]) ::slotted(*) { + font-style: italic; + } + :host([underline]) ::slotted(*) { + text-decoration-line: underline; + } + :host([strikethrough]) ::slotted(*) { + text-decoration-line: line-through; + } + :host([underline][strikethrough]) ::slotted(*) { + text-decoration-line: line-through underline; + } + :host([size='100']) ::slotted(*) { + font-size: ${fontSizeBase100}; + line-height: ${lineHeightBase100}; + } + :host([size='200']) ::slotted(*) { + font-size: ${fontSizeBase200}; + line-height: ${lineHeightBase200}; + } + :host([size='400']) ::slotted(*) { + font-size: ${fontSizeBase400}; + line-height: ${lineHeightBase400}; + } + :host([size='500']) ::slotted(*) { + font-size: ${fontSizeBase500}; + line-height: ${lineHeightBase500}; + } + :host([size='600']) ::slotted(*) { + font-size: ${fontSizeBase600}; + line-height: ${lineHeightBase600}; + } + :host([size='700']) ::slotted(*) { + font-size: ${fontSizeHero700}; + line-height: ${lineHeightHero700}; + } + :host([size='800']) ::slotted(*) { + font-size: ${fontSizeHero800}; + line-height: ${lineHeightHero800}; + } + :host([size='900']) ::slotted(*) { + font-size: ${fontSizeHero900}; + line-height: ${lineHeightHero900}; + } + :host([size='1000']) ::slotted(*) { + font-size: ${fontSizeHero1000}; + line-height: ${lineHeightHero1000}; + } + :host([font='monospace']) ::slotted(*) { + font-family: ${fontFamilyMonospace}; + } + :host([font='numeric']) ::slotted(*) { + font-family: ${fontFamilyNumeric}; + } + :host([weight='medium']) ::slotted(*) { + font-weight: ${fontWeightMedium}; + } + :host([weight='semibold']) ::slotted(*) { + font-weight: ${fontWeightSemibold}; + } + :host([weight='bold']) ::slotted(*) { + font-weight: ${fontWeightBold}; + } + :host([align='center']) ::slotted(*) { + text-align: center; + } + :host([align='end']) ::slotted(*) { + text-align: end; + } + :host([align='justify']) ::slotted(*) { + text-align: justify; + } +`; diff --git a/packages/web-components/src/text-input/text-input.template.ts b/packages/web-components/src/text-input/text-input.template.ts new file mode 100644 index 00000000000000..90556f6a6ba168 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.template.ts @@ -0,0 +1,7 @@ +import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import type { Text } from './text-input.js'; + +/** + * @internal + */ +export const template: ElementViewTemplate = html``; diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts new file mode 100644 index 00000000000000..111a4d82a53c02 --- /dev/null +++ b/packages/web-components/src/text-input/text-input.ts @@ -0,0 +1,111 @@ +import { attr, FASTElement } from '@microsoft/fast-element'; +import type { TextAlign, TextFont, TextSize, TextWeight } from './text-input.options.js'; + +/** + * The base class used for constructing a fluent-text custom element + * @public + */ +export class Text extends FASTElement { + /** + * The text will not wrap + * NOTE: In Fluent UI React v9 this is "wrap" + * Boolean attributes which default to true in HTML can't be switched off in the DOM + * + * @public + * @remarks + * HTML Attribute: nowrap + */ + @attr({ mode: 'boolean' }) + nowrap: boolean = false; + + /** + * The text truncates + * + * @public + * @remarks + * HTML Attribute: truncate + */ + @attr({ mode: 'boolean' }) + truncate: boolean = false; + + /** + * The text style is italic + * + * @public + * @remarks + * HTML Attribute: italic + */ + @attr({ mode: 'boolean' }) + italic: boolean = false; + + /** + * The text style is underline + * + * @public + * @remarks + * HTML Attribute: underline + */ + @attr({ mode: 'boolean' }) + underline: boolean = false; + + /** + * The text style is strikethrough + * + * @public + * @remarks + * HTML Attribute: strikethrough + */ + @attr({ mode: 'boolean' }) + strikethrough: boolean = false; + + /** + * An text can take up the width of its container. + * + * @public + * @remarks + * HTML Attribute: block + */ + @attr({ mode: 'boolean' }) + block: boolean = false; + + /** + * THe Text size + * + * @public + * @remarks + * HTML Attribute: size + * + */ + @attr + size?: TextSize; + + /** + * THe Text font + * + * @public + * @remarks + * HTML Attribute: font + */ + @attr + font?: TextFont; + + /** + * THe Text weight + * + * @public + * @remarks + * HTML Attribute: weight + */ + @attr + weight?: TextWeight; + + /** + * THe Text align + * + * @public + * @remarks + * HTML Attribute: align + */ + @attr + align?: TextAlign; +} From f36d8c6b17b169fac47603be77b70fd7cd48827a Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Wed, 22 Mar 2023 12:17:21 -0700 Subject: [PATCH 10/46] adds text input options --- .../src/text-input/text-input.options.ts | 66 ++++++------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.options.ts b/packages/web-components/src/text-input/text-input.options.ts index 8d1683c4949a18..f22499d6d59e54 100644 --- a/packages/web-components/src/text-input/text-input.options.ts +++ b/packages/web-components/src/text-input/text-input.options.ts @@ -1,75 +1,49 @@ import { ValuesOf } from '@microsoft/fast-foundation'; /** - * TextInputSize constants + * TextInput size constants * @public */ export const TextInputSize = { - _100: '100', - _200: '200', - _300: '300', - _400: '400', - _500: '500', - _600: '600', - _700: '700', - _800: '800', - _900: '900', - _1000: '1000', -} as const; - -/** - * The type for TextSize - * The font size and line height based on the theme tokens - * @public - */ -export type TextSize = ValuesOf; - -/** - * TextFont Constants - * @public - */ -export const TextFont = { - base: 'base', - numeric: 'numeric', - monospace: 'monospace', + small: 'small', + medium: 'medium', + large: 'large', } as const; /** - * Applies font family to the content + * The type for TextInputSize * @public */ -export type TextFont = ValuesOf; +export type TextInputSize = ValuesOf; /** - * TextWeight Constants + * TextInput appearance Constants * @public */ -export const TextWeight = { - medium: 'medium', - regular: 'regular', - semibold: 'semibold', - bold: 'bold', +export const TextInputAppearance = { + outline: 'base', + underline: 'numeric', + filledLighter: 'filled-lighter', + filledDarker: 'filled-darker', } as const; /** - * Applies font weight to the content + * Applies styling to TextInput * @public */ -export type TextWeight = ValuesOf; +export type TextInputAppearance = ValuesOf; /** - * TextAlign Constants + * TextInput layout Constants * @public */ -export const TextAlign = { - start: 'start', - end: 'end', - center: 'center', - justify: 'justify', +export const TextInputLayout = { + block: 'block', + inline: 'inline', } as const; /** - * Aligns the content + * Applies display style property * @public */ -export type TextAlign = ValuesOf; +export type TextInputLayout = ValuesOf; From 9be3a2eaaa0ff55ba66e84d73747d80c67f9440d Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 23 Mar 2023 11:49:53 -0700 Subject: [PATCH 11/46] styles text input --- .../web-components/src/text-input/index.ts | 1 + .../src/text-input/text-input.definition.ts | 4 +- .../src/text-input/text-input.stories.ts | 259 +++++----------- .../src/text-input/text-input.styles.ts | 282 ++++++++++++------ .../src/text-input/text-input.template.ts | 5 +- .../src/text-input/text-input.ts | 112 +------ 6 files changed, 272 insertions(+), 391 deletions(-) diff --git a/packages/web-components/src/text-input/index.ts b/packages/web-components/src/text-input/index.ts index 804b0fcb5c2fab..8fa6d074b74e72 100644 --- a/packages/web-components/src/text-input/index.ts +++ b/packages/web-components/src/text-input/index.ts @@ -3,3 +3,4 @@ export * from './text-input.options.js'; export { template as TextTemplate } from './text-input.template.js'; export { styles as TextStyles } from './text-input.styles.js'; export { definition as TextDefinition } from './text-input.definition.js'; +export { TextFieldType } from '@microsoft/fast-foundation'; diff --git a/packages/web-components/src/text-input/text-input.definition.ts b/packages/web-components/src/text-input/text-input.definition.ts index 1309800b7cf253..7b527337b634f7 100644 --- a/packages/web-components/src/text-input/text-input.definition.ts +++ b/packages/web-components/src/text-input/text-input.definition.ts @@ -1,5 +1,5 @@ import { FluentDesignSystem } from '../fluent-design-system.js'; -import { Text } from './text-input.js'; +import { TextInput } from './text-input.js'; import { styles } from './text-input.styles.js'; import { template } from './text-input.template.js'; @@ -11,7 +11,7 @@ import { template } from './text-input.template.js'; * @remarks * HTML Element: \ */ -export const definition = Text.compose({ +export const definition = TextInput.compose({ name: `${FluentDesignSystem.prefix}-text-input`, template, styles, diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 2886931c12fe55..6ff2ec91bcd39e 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -1,217 +1,104 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; -import type { Text as FluentText } from './text-input.js'; +import type { TextInput as FluentTextInput } from './text-input.js'; +import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-input.options.js'; +import { TextFieldType } from '@microsoft/fast-foundation'; + import './define.js'; -import { TextAlign, TextFont, TextSize, TextWeight } from './text-input.options.js'; - -type TextStoryArgs = Args & FluentText; -type TextStoryMeta = Meta; - -/** - * Used to generate slotted content for stories - * @param as - the element to generate - * @param content - the content for the element - * @returns ViewTemplate - */ -const generateSemanticElementTemplate = (as: string, content) => { - switch (as) { - case 'h1': - return html`

${content}

`; - case 'h2': - return html`

${content}

`; - case 'h3': - return html`

${content}

`; - case 'h4': - return html`

${content}

`; - case 'h5': - return html`
${content}
`; - case 'h6': - return html`
${content}
`; - case 'p': - return html`

${content}

`; - case 'pre': - return html`
${content}
`; - case 'span': - default: - return html`${content}`; - } -}; - -const storyTemplate = html` - x.align} - font=${x => x.font} - size=${x => x.size} - weight=${x => x.weight} - ?nowrap=${x => x.nowrap} - ?truncate=${x => x.truncate} - ?italic=${x => x.italic} - ?underline=${x => x.underline} - ?strikethrough=${x => x.strikethrough} + +type TextInputStoryArgs = Args & FluentTextInput; +type TextInputStoryMeta = Meta; + +const Person20Regular = html``; + +const storyTemplate = html` + x.type} + ?disabled=${x => x.disabled} ?block=${x => x.block} - >${x => generateSemanticElementTemplate(x.as, x.content)} x.size} + appearance=${x => x.appearance} + layout=${x => x.layout} + placeholder=${x => x.placeholder} > + ${Person20Regular} + ${Person20Regular}${Person20Regular} + First Name +
`; export default { - title: 'Components/Text', - args: { - content: 'Text', - nowrap: false, - truncate: false, - italic: false, - underline: false, - strikethrough: false, - block: false, - }, + title: 'Components/TextInput', argTypes: { - as: { - options: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'span'], + type: { + options: Object.values(TextFieldType), control: { type: 'select', }, }, size: { - options: Object.values(TextSize), - control: { - type: 'select', - }, - }, - weight: { - options: Object.keys(TextWeight), + options: Object.values(TextInputSize), control: { type: 'select', }, }, - align: { - options: Object.keys(TextAlign), + appearance: { + options: Object.keys(TextInputAppearance), control: { type: 'select', }, }, - font: { - options: Object.keys(TextFont), + layout: { + options: Object.keys(TextInputLayout), + defaultValue: TextInputLayout.block, control: { type: 'select', }, }, - nowrap: { - control: 'boolean', - }, - truncate: { - control: 'boolean', - }, - italic: { - control: 'boolean', - }, - underline: { + disabled: { control: 'boolean', }, - strikethrough: { - control: 'boolean', - }, - block: { - control: 'boolean', + placeholder: { + control: 'text', }, }, -} as TextStoryMeta; - -export const Text = renderComponent(storyTemplate).bind({}); - -// -// Attribute stories -// - -export const Nowrap = renderComponent(html` - -
- This text will not wrap lines when it overflows the container. -
-
-`); - -export const Truncate = renderComponent(html` - -
- Setting truncate and nowrap will truncate when it overflows the container. -
-
-`); - -export const Italic = renderComponent(html` - - Italics are emphasized text. - -`); - -export const Underline = renderComponent(html` - - Underlined text draws the reader's attention to the words. - -`); - -export const Strikethrough = renderComponent(html` - - Strikethrough text is used to indicate something that is no longer relevant. - -`); - -export const Block = renderComponent(html` - - Fluent text is inline by default. Setting - block - will make it behave as a block element. - -`); - -export const Size = renderComponent(html` -
- 100 - 200 - 300 - 400 - 500 - 600 - 700 - 800 - 900 - 1000 -
-`); - -export const Weight = renderComponent(html` -
- This text is regular. - This text is medium. - This text is semibold. - This text is bold. -
-`); - -export const Align = renderComponent(html` -
- - Start aligned block. - - - End aligned block. - - - Center aligned block. - - - Justify aligned block text stretches wrapped lines to meet container edges. - -
-`); - -export const Font = renderComponent(html` -
- Font base. - Font numeric 0123456789. - Font monospace. -
-`); +} as TextInputStoryMeta; + +export const TextInput = renderComponent(storyTemplate).bind({}); + +// // +// // Attribute stories +// // + +// export const Appearance = renderComponent(html` + +// `); + +// export const Size = renderComponent(html` + +// `); + +// export const Layout = renderComponent(html` + +// `); + +// export const Disabled = renderComponent(html` + +// `); + +// export const Placeholder = renderComponent(html` + +// `); diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 8593b9ee070116..cd102d812d49c5 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -1,139 +1,233 @@ import { css } from '@microsoft/fast-element'; import { display } from '@microsoft/fast-foundation'; import { + borderRadiusMedium, + colorCompoundBrandStroke, + colorCompoundBrandStrokePressed, + colorNeutralBackground1, + colorNeutralBackground3, + colorNeutralBackgroundInverted, + colorNeutralForeground1, + colorNeutralForeground3, + colorNeutralForeground4, + colorNeutralForegroundDisabled, + colorNeutralForegroundInverted, + colorNeutralStroke1, + colorNeutralStroke1Hover, + colorNeutralStroke1Pressed, + colorNeutralStrokeAccessible, + colorNeutralStrokeAccessibleHover, + colorNeutralStrokeAccessiblePressed, + colorNeutralStrokeDisabled, + colorTransparentBackground, + colorTransparentStroke, + colorTransparentStrokeInteractive, + curveAccelerateMid, + curveDecelerateMid, + durationNormal, + durationUltraFast, fontFamilyBase, - fontFamilyMonospace, - fontFamilyNumeric, - fontSizeBase100, - fontSizeBase200, fontSizeBase300, - fontSizeBase400, - fontSizeBase500, - fontSizeBase600, - fontSizeHero1000, - fontSizeHero700, - fontSizeHero800, - fontSizeHero900, - fontWeightBold, - fontWeightMedium, fontWeightRegular, - fontWeightSemibold, - lineHeightBase100, - lineHeightBase200, lineHeightBase300, - lineHeightBase400, - lineHeightBase500, - lineHeightBase600, - lineHeightHero1000, - lineHeightHero700, - lineHeightHero800, - lineHeightHero900, + shadow2, + spacingHorizontalMNudge, + spacingHorizontalXS, + spacingHorizontalXXS, + spacingVerticalS, + spacingVerticalXS, + strokeWidthThick, + strokeWidthThin, } from '../theme/design-tokens.js'; -/** Text styles +/** TextInput styles * @public */ export const styles = css` - ${display('inline')} + ${display('inline-flex')} :host { - contain: content; + align-items: center; + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-start; } - - ::slotted(*) { + .label { + line-height: ${lineHeightBase300}; + font-size: ${fontSizeBase300}; + font-family: ${fontFamilyBase}; + font-weight: ${fontWeightRegular}; + color: ${colorNeutralForeground1}; + padding-bottom: ${spacingVerticalXS}; + } + .root { + box-sizing: border-box; + display: inline-flex; + align-items: center; + flex-direction: row; + border: ${strokeWidthThin} solid ${colorNeutralStroke1}; + border-bottom-color: ${colorNeutralStrokeAccessible}; + border-radius: ${borderRadiusMedium}; + gap: ${spacingHorizontalXXS}; + padding: 0 ${spacingHorizontalMNudge}; + width: 100%; + position: relative; + } + .control { + box-sizing: border-box; + height: 32px; + vertical-align: center; + background: transparent; + color: ${colorNeutralForeground1}; font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; - line-height: ${lineHeightBase300}; font-weight: ${fontWeightRegular}; - text-align: start; - white-space: normal; - overflow: visible; - text-overflow: clip; - margin: 0; - display: inline; + line-height: ${lineHeightBase300}; + border-radius: ${borderRadiusMedium}; + background: ${colorTransparentBackground}; + border: none; + width: 100%; + } + .control:focus-visible { + outline: 0; + border: 0; + } + .control::placeholder { + color: ${colorNeutralForeground4}; + } + :host ::slotted([slot='start']) { + padding-right: ${spacingHorizontalXXS}; + } + :host ::slotted([slot='end']) { + padding-left: ${spacingHorizontalXXS}; + gap: ${spacingHorizontalXS}; + } + :host ::slotted([slot='start']), + :host ::slotted([slot='end']) { + display: flex; + align-items: center; + justify-content: center; + color: ${colorNeutralForeground3}; } - :host([nowrap]) ::slotted(*) { - white-space: nowrap; - overflow: hidden; + :host(:hover) .root { + border-color: ${colorNeutralStroke1Hover}; + border-bottom-color: ${colorNeutralStrokeAccessibleHover}; } - :host([truncate]) ::slotted(*) { - text-overflow: ellipsis; + :host(:active) .root { + border-color: ${colorNeutralStroke1Pressed}; } - :host([block]), - :host([block]) ::slotted(*) { - display: block; + + :host(:focus-within:not([disabled])) .control { + color: ${colorNeutralForeground1}; } - :host([italic]) ::slotted(*) { - font-style: italic; + :host(:focus-within:not([disabled])) .root { + border: ${strokeWidthThin} solid ${colorNeutralStroke1}; + border-bottom-width: ${strokeWidthThick}; } - :host([underline]) ::slotted(*) { - text-decoration-line: underline; + + .root::after { + box-sizing: border-box; + content: ''; + position: absolute; + left: -1px; + bottom: -1px; + right: -1px; + height: max(2px, ${borderRadiusMedium}); + border-bottom-left-radius: ${borderRadiusMedium}; + border-bottom-right-radius: ${borderRadiusMedium}; + border-bottom: 2px solid ${colorCompoundBrandStroke}; + clip-path: inset(calc(100% - 2px) 0px 0px); + transform: scaleX(0); + transition-property: transform; + transition-duration: ${durationUltraFast}; + transition-delay: ${curveAccelerateMid}; } - :host([strikethrough]) ::slotted(*) { - text-decoration-line: line-through; + + .root:focus-within::after { + transform: scaleX(1); + transition-property: transform; + transition-duration: ${durationNormal}; + transition-delay: ${curveDecelerateMid}; } - :host([underline][strikethrough]) ::slotted(*) { - text-decoration-line: line-through underline; + + .root:focus-within:active::after { + border-bottom-color: ${colorCompoundBrandStrokePressed}; } - :host([size='100']) ::slotted(*) { - font-size: ${fontSizeBase100}; - line-height: ${lineHeightBase100}; + + :host([layout='inline']) { + display: inline-flex; + flex-direction: row; + align-items: center; } - :host([size='200']) ::slotted(*) { - font-size: ${fontSizeBase200}; - line-height: ${lineHeightBase200}; + :host([layout='inline']) .root, + :host([layout='inline']) .control { + width: fit-content; } - :host([size='400']) ::slotted(*) { - font-size: ${fontSizeBase400}; - line-height: ${lineHeightBase400}; + :host([layout='inline']) .label { + padding-inline-end: 12px; } - :host([size='500']) ::slotted(*) { - font-size: ${fontSizeBase500}; - line-height: ${lineHeightBase500}; + + :host([appearance='underline']) .root { + background: ${colorTransparentBackground}; + border: 0; + border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessible}; } - :host([size='600']) ::slotted(*) { - font-size: ${fontSizeBase600}; - line-height: ${lineHeightBase600}; + :host([appearance='underline']:hover) .root { + border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessibleHover}; } - :host([size='700']) ::slotted(*) { - font-size: ${fontSizeHero700}; - line-height: ${lineHeightHero700}; + :host([appearance='underline']:active) .root { + border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessiblePressed}; } - :host([size='800']) ::slotted(*) { - font-size: ${fontSizeHero800}; - line-height: ${lineHeightHero800}; + :host([appearance='underline']:focus-within) .root { + border: 0; + border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessiblePressed}; } - :host([size='900']) ::slotted(*) { - font-size: ${fontSizeHero900}; - line-height: ${lineHeightHero900}; + :host([appearance='underline'][disabled]) .root { + border-bottom-color: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; } - :host([size='1000']) ::slotted(*) { - font-size: ${fontSizeHero1000}; - line-height: ${lineHeightHero1000}; + + :host([appearance='filledLighter']) .root { + border: ${strokeWidthThin} solid ${colorTransparentStroke}; + background: ${colorNeutralBackground1}; + box-shadow: ${shadow2}; } - :host([font='monospace']) ::slotted(*) { - font-family: ${fontFamilyMonospace}; + :host([appearance='filledLighter']:hover):not(:active) .root { + border-color: ${colorTransparentStrokeInteractive}; } - :host([font='numeric']) ::slotted(*) { - font-family: ${fontFamilyNumeric}; + :host([appearance='filledLighter']:active) .root { + border-color: ${colorTransparentStrokeInteractive}; } - :host([weight='medium']) ::slotted(*) { - font-weight: ${fontWeightMedium}; + + :host([appearance='filledDarker']) .root { + border: ${strokeWidthThin} solid ${colorTransparentStroke}; + background: ${colorNeutralBackground3}; + box-shadow: ${shadow2}; } - :host([weight='semibold']) ::slotted(*) { - font-weight: ${fontWeightSemibold}; + :host([appearance='filledDarker']:hover):not(:active) .root { + border-color: ${colorTransparentStrokeInteractive}; } - :host([weight='bold']) ::slotted(*) { - font-weight: ${fontWeightBold}; + :host([appearance='filledDarker']:active) .root { + border-color: ${colorTransparentStrokeInteractive}; + background: ${colorNeutralBackground3}; } - :host([align='center']) ::slotted(*) { - text-align: center; + + :host([disabled]) .root { + background: ${colorTransparentBackground}; + border: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; } - :host([align='end']) ::slotted(*) { - text-align: end; + :host([disabled]) .control::placeholder { + color: ${colorNeutralForegroundDisabled}; } - :host([align='justify']) ::slotted(*) { - text-align: justify; + :host([disabled]) .control::placeholder, + :host([disabled]) ::slotted([slot='start']), + :host([disabled]) ::slotted([slot='end']) { + color: ${colorNeutralForegroundDisabled}; + } + + ::selection { + color: ${colorNeutralForegroundInverted}; + background-color: ${colorNeutralBackgroundInverted}; } `; diff --git a/packages/web-components/src/text-input/text-input.template.ts b/packages/web-components/src/text-input/text-input.template.ts index 90556f6a6ba168..cf86aa5028b588 100644 --- a/packages/web-components/src/text-input/text-input.template.ts +++ b/packages/web-components/src/text-input/text-input.template.ts @@ -1,7 +1,8 @@ import { ElementViewTemplate, html } from '@microsoft/fast-element'; -import type { Text } from './text-input.js'; +import { textFieldTemplate } from '@microsoft/fast-foundation'; +import type { TextInput } from './text-input.js'; /** * @internal */ -export const template: ElementViewTemplate = html``; +export const template: ElementViewTemplate = textFieldTemplate({}); diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index 111a4d82a53c02..e649a4a4040998 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -1,111 +1,9 @@ -import { attr, FASTElement } from '@microsoft/fast-element'; -import type { TextAlign, TextFont, TextSize, TextWeight } from './text-input.options.js'; +import { attr } from '@microsoft/fast-element'; +import { FASTTextField } from '@microsoft/fast-foundation'; +import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-input.options.js'; /** - * The base class used for constructing a fluent-text custom element + * The base class used for constructing a fluent-text-input custom element * @public */ -export class Text extends FASTElement { - /** - * The text will not wrap - * NOTE: In Fluent UI React v9 this is "wrap" - * Boolean attributes which default to true in HTML can't be switched off in the DOM - * - * @public - * @remarks - * HTML Attribute: nowrap - */ - @attr({ mode: 'boolean' }) - nowrap: boolean = false; - - /** - * The text truncates - * - * @public - * @remarks - * HTML Attribute: truncate - */ - @attr({ mode: 'boolean' }) - truncate: boolean = false; - - /** - * The text style is italic - * - * @public - * @remarks - * HTML Attribute: italic - */ - @attr({ mode: 'boolean' }) - italic: boolean = false; - - /** - * The text style is underline - * - * @public - * @remarks - * HTML Attribute: underline - */ - @attr({ mode: 'boolean' }) - underline: boolean = false; - - /** - * The text style is strikethrough - * - * @public - * @remarks - * HTML Attribute: strikethrough - */ - @attr({ mode: 'boolean' }) - strikethrough: boolean = false; - - /** - * An text can take up the width of its container. - * - * @public - * @remarks - * HTML Attribute: block - */ - @attr({ mode: 'boolean' }) - block: boolean = false; - - /** - * THe Text size - * - * @public - * @remarks - * HTML Attribute: size - * - */ - @attr - size?: TextSize; - - /** - * THe Text font - * - * @public - * @remarks - * HTML Attribute: font - */ - @attr - font?: TextFont; - - /** - * THe Text weight - * - * @public - * @remarks - * HTML Attribute: weight - */ - @attr - weight?: TextWeight; - - /** - * THe Text align - * - * @public - * @remarks - * HTML Attribute: align - */ - @attr - align?: TextAlign; -} +export class TextInput extends FASTTextField {} From 630632f5d5d7f2f013b5052d92301e31ad3a6122 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 23 Mar 2023 12:13:17 -0700 Subject: [PATCH 12/46] updates text input styles --- .../src/text-input/text-input.styles.ts | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index cd102d812d49c5..8b34f9f3821d04 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -47,64 +47,72 @@ export const styles = css` ${display('inline-flex')} :host { - align-items: center; width: 100%; display: flex; flex-direction: column; + align-items: center; align-items: flex-start; } + .label { - line-height: ${lineHeightBase300}; - font-size: ${fontSizeBase300}; font-family: ${fontFamilyBase}; + font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; + line-height: ${lineHeightBase300}; color: ${colorNeutralForeground1}; padding-bottom: ${spacingVerticalXS}; } + .root { - box-sizing: border-box; display: inline-flex; align-items: center; flex-direction: row; + width: 100%; + padding: 0 ${spacingHorizontalMNudge}; + position: relative; + box-sizing: border-box; border: ${strokeWidthThin} solid ${colorNeutralStroke1}; border-bottom-color: ${colorNeutralStrokeAccessible}; border-radius: ${borderRadiusMedium}; gap: ${spacingHorizontalXXS}; - padding: 0 ${spacingHorizontalMNudge}; - width: 100%; - position: relative; } + .control { - box-sizing: border-box; height: 32px; - vertical-align: center; - background: transparent; - color: ${colorNeutralForeground1}; + width: 100%; + box-sizing: border-box; font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; + color: ${colorNeutralForeground1}; border-radius: ${borderRadiusMedium}; background: ${colorTransparentBackground}; border: none; - width: 100%; + background: transparent; + vertical-align: center; } + .control:focus-visible { outline: 0; border: 0; } + .control::placeholder { color: ${colorNeutralForeground4}; } + :host ::slotted([slot='start']) { padding-right: ${spacingHorizontalXXS}; + display: flex; + align-items: center; + justify-content: center; + color: ${colorNeutralForeground3}; } + :host ::slotted([slot='end']) { padding-left: ${spacingHorizontalXXS}; gap: ${spacingHorizontalXS}; - } - :host ::slotted([slot='start']), - :host ::slotted([slot='end']) { display: flex; align-items: center; justify-content: center; @@ -115,6 +123,7 @@ export const styles = css` border-color: ${colorNeutralStroke1Hover}; border-bottom-color: ${colorNeutralStrokeAccessibleHover}; } + :host(:active) .root { border-color: ${colorNeutralStroke1Pressed}; } @@ -122,13 +131,13 @@ export const styles = css` :host(:focus-within:not([disabled])) .control { color: ${colorNeutralForeground1}; } + :host(:focus-within:not([disabled])) .root { border: ${strokeWidthThin} solid ${colorNeutralStroke1}; border-bottom-width: ${strokeWidthThick}; } .root::after { - box-sizing: border-box; content: ''; position: absolute; left: -1px; @@ -145,17 +154,6 @@ export const styles = css` transition-delay: ${curveAccelerateMid}; } - .root:focus-within::after { - transform: scaleX(1); - transition-property: transform; - transition-duration: ${durationNormal}; - transition-delay: ${curveDecelerateMid}; - } - - .root:focus-within:active::after { - border-bottom-color: ${colorCompoundBrandStrokePressed}; - } - :host([layout='inline']) { display: inline-flex; flex-direction: row; @@ -180,7 +178,7 @@ export const styles = css` :host([appearance='underline']:active) .root { border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessiblePressed}; } - :host([appearance='underline']:focus-within) .root { + :host([appearance='underline']):focus-within .root { border: 0; border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessiblePressed}; } @@ -188,27 +186,23 @@ export const styles = css` border-bottom-color: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; } - :host([appearance='filledLighter']) .root { + :host([appearance='filledLighter']) .root, + :host([appearance='filledDarker']) .root { border: ${strokeWidthThin} solid ${colorTransparentStroke}; - background: ${colorNeutralBackground1}; box-shadow: ${shadow2}; } - :host([appearance='filledLighter']:hover):not(:active) .root { - border-color: ${colorTransparentStrokeInteractive}; - } - :host([appearance='filledLighter']:active) .root { - border-color: ${colorTransparentStrokeInteractive}; + :host([appearance='filledLighter']) .root { + background: ${colorNeutralBackground1}; } - :host([appearance='filledDarker']) .root { - border: ${strokeWidthThin} solid ${colorTransparentStroke}; background: ${colorNeutralBackground3}; - box-shadow: ${shadow2}; } - :host([appearance='filledDarker']:hover):not(:active) .root { + :host([appearance='filledLighter']):hover:not(:active) .root, + :host([appearance='filledDarker']):hover:not(:active) .root { border-color: ${colorTransparentStrokeInteractive}; } - :host([appearance='filledDarker']:active) .root { + :host([appearance='filledLighter']):active .root, + :host([appearance='filledDarker']):active .root { border-color: ${colorTransparentStrokeInteractive}; background: ${colorNeutralBackground3}; } @@ -217,15 +211,21 @@ export const styles = css` background: ${colorTransparentBackground}; border: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; } - :host([disabled]) .control::placeholder { - color: ${colorNeutralForegroundDisabled}; - } :host([disabled]) .control::placeholder, :host([disabled]) ::slotted([slot='start']), :host([disabled]) ::slotted([slot='end']) { color: ${colorNeutralForegroundDisabled}; } + :host(:focus-within) .root::after { + transform: scaleX(1); + transition: transform ${durationNormal} ${curveDecelerateMid}; + } + + :host(:focus-within:active) .root::after { + border-bottom-color: ${colorCompoundBrandStrokePressed}; + } + ::selection { color: ${colorNeutralForegroundInverted}; background-color: ${colorNeutralBackgroundInverted}; From 5786394f5cfd36f3734c0652f9c7dd357fa48b7b Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 23 Mar 2023 13:08:43 -0700 Subject: [PATCH 13/46] adds input size attribute and styles --- .../src/text-input/text-input.stories.ts | 6 +- .../src/text-input/text-input.styles.ts | 61 ++++++++++++++++--- .../src/text-input/text-input.ts | 13 +++- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 6ff2ec91bcd39e..e68164d7892fde 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -29,8 +29,8 @@ const storyTemplate = html` type=${x => x.type} ?disabled=${x => x.disabled} ?block=${x => x.block} - size=${x => x.size} - appearance=${x => x.appearance} + input-size="${x => x.inputSize}" + appearance="${x => x.appearance}" layout=${x => x.layout} placeholder=${x => x.placeholder} > @@ -49,7 +49,7 @@ export default { type: 'select', }, }, - size: { + inputSize: { options: Object.values(TextInputSize), control: { type: 'select', diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 8b34f9f3821d04..41a80483dde342 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -27,11 +27,18 @@ import { durationNormal, durationUltraFast, fontFamilyBase, + fontSizeBase200, fontSizeBase300, + fontSizeBase400, + fontSizeBase600, fontWeightRegular, + lineHeightBase200, lineHeightBase300, + lineHeightBase400, shadow2, spacingHorizontalMNudge, + spacingHorizontalS, + spacingHorizontalSNudge, spacingHorizontalXS, spacingHorizontalXXS, spacingVerticalS, @@ -64,6 +71,7 @@ export const styles = css` } .root { + height: 32px; display: inline-flex; align-items: center; flex-direction: row; @@ -78,16 +86,15 @@ export const styles = css` } .control { - height: 32px; width: 100%; box-sizing: border-box; + color: ${colorNeutralForeground1}; + border-radius: ${borderRadiusMedium}; + background: ${colorTransparentBackground}; font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; - color: ${colorNeutralForeground1}; - border-radius: ${borderRadiusMedium}; - background: ${colorTransparentBackground}; border: none; background: transparent; vertical-align: center; @@ -102,21 +109,55 @@ export const styles = css` color: ${colorNeutralForeground4}; } - :host ::slotted([slot='start']) { - padding-right: ${spacingHorizontalXXS}; + :host([input-size='small']) .control { + font-size: ${fontSizeBase200}; + font-weight: ${fontWeightRegular}; + line-height: ${lineHeightBase200}; + } + + :host([input-size='small']) .root { + height: 24px; + gap: ${spacingHorizontalXXS}; + padding: 0 ${spacingHorizontalSNudge}; + } + + :host([input-size='small']) ::slotted([slot='start']), + :host([input-size='small']) ::slotted([slot='end']) { + font-size: ${fontSizeBase400}; + } + + :host([input-size='large']) .control { + font-size: ${fontSizeBase400}; + font-weight: ${fontWeightRegular}; + line-height: ${lineHeightBase400}; + } + + :host([input-size='large']) .root { + height: 40px; + gap: ${spacingHorizontalS}; + padding: 0 ${spacingHorizontalMNudge}; + } + + :host([input-size='large']) ::slotted([slot='start']), + :host([input-size='large']) ::slotted([slot='end']) { + font-size: ${fontSizeBase600}; + } + + :host ::slotted([slot='start']), + :host ::slotted([slot='end']) { display: flex; align-items: center; justify-content: center; color: ${colorNeutralForeground3}; } + :host ::slotted([slot='start']) { + padding-right: ${spacingHorizontalXXS}; + } + :host ::slotted([slot='end']) { padding-left: ${spacingHorizontalXXS}; gap: ${spacingHorizontalXS}; - display: flex; - align-items: center; - justify-content: center; - color: ${colorNeutralForeground3}; } :host(:hover) .root { diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index e649a4a4040998..475acd527b01f4 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -6,4 +6,15 @@ import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-inpu * The base class used for constructing a fluent-text-input custom element * @public */ -export class TextInput extends FASTTextField {} +export class TextInput extends FASTTextField { + /** + * Defines accordion header font size. + * + * @public + * @default 'medium' + * @remarks + * HTML Attribute: size + */ + @attr({ attribute: 'input-size' }) + public inputSize?: TextInputSize = TextInputSize.medium; +} From 0d9fa2e4d8640fdccac21618e293c2ed070bbdb0 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 27 Mar 2023 11:47:24 -0700 Subject: [PATCH 14/46] updates text input storybook --- .../web-components/src/text-input/README.md | 133 ++++++++++++++++++ .../src/text-input/text-input.stories.ts | 100 ++++++++++--- 2 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 packages/web-components/src/text-input/README.md diff --git a/packages/web-components/src/text-input/README.md b/packages/web-components/src/text-input/README.md new file mode 100644 index 00000000000000..236e304ad0b02b --- /dev/null +++ b/packages/web-components/src/text-input/README.md @@ -0,0 +1,133 @@ +# TextInput + +> An implementation of a [text input](https://w3c.github.io/html-reference/input.text.html) as a form-connected web-component. +>
+ +## **Design Spec** + +[Link to Text Input Design Spec in Figma](https://www.figma.com/file/TvHmWjZYxwtI9Tz6v5BT7E/Input?node-id=2366-657&t=UNSOfCD3St9ffppx-0) + +
+ +## **Engineering Spec** + +Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.design/components/fast-text-field) and is intended to be as close to the Fluent UI React 9 Input implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. + +
+ +## Class: `TextInput` + +
+ +### **Component Name** + +`` + +
+ +### **Variables** + +| Name | Description | Type | +| --------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | +| `TextInputSize` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | +| `TextInputAppearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | +| `TextInputType` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | +| `TextInputLayout` | Layout variations for text input | `{ block: "block", inline: "inline"` | + +
+ +### **Fields** + +| Name | Privacy | Type | Default | Description | +| ------------- | ------- | --------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `appearance` | public | `TextInputAppearance` | `outline` | Sets appearance of text input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables text input | +| `layout` | public | `TextInputLayout` | `TextInputLayout.block` | Sets layout display property on text input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `number` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the text input as required | +| `size` | public | `InputSize` | `medium` | Sets the size of the text input | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | +| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | + +
+ +### **Methods** + +| Name | Privacy | Description | +| ---------- | ------- | ------------------------------------------------- | +| `select` | public | Selects all the text in the text field | +| `validate` | public | {@inheritDoc (FormAssociated:interface).validate} | + +### **Events** + +| Name | Type | Description | Inherited From | +| -------- | ---- | --------------------------- | -------------- | +| `change` | | Fires a custom change event | | + +
+ +### **Attributes** + +| Name | Field | +| ---------------- | -------------- | +| `appearance` | appearance | +| `autofocus` | autofocus | +| `label-position` | label-position | +| `list` | list | +| `maxlength` | maxlength | +| `minlength` | minlength | +| `pattern` | pattern | +| `placeholder` | placeholder | +| `readonly ` | readonly | +| `size` | size | +| `spellcheck` | spellcheck | +| `type` | type | + +
+ +### **Slots** + +| Name | Description | +| ------- | ---------------------------------------------------------------------------- | +| `start` | used to place content at the start of the text input within the input border | +| `end` | used to place content at the end of the text input within the input border | +| | The default slot for text input content | + +
+
+
+ +## **Accessibility** + +[W3C Text Input Spec](https://w3c.github.io/html-reference/input.text.html) + +
+ +### **WAI-ARIA Roles, States, and Properties** + +This component supports ARIA attributes that inherit from the [ARIA Global States and Properties](https://www.w3.org/TR/wai-aria-1.2/#global_states). + +
+
+
+ +## **Preparation** + +### **Fluent Web Component v3 v.s Fluent React 9** + +
+ +**Component and Slot Mapping** + +| Fluent UI React 9 | Fluent Web Components 3 | +| ----------------- | ----------------------- | +| `` | `` | +| `contentBefore` | `start` | +| `contentAfter` | `end` | diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index e68164d7892fde..b9f38f6e121ccc 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -36,7 +36,7 @@ const storyTemplate = html` > ${Person20Regular} ${Person20Regular}${Person20Regular} - First Name + Sample Input `; @@ -79,26 +79,84 @@ export default { export const TextInput = renderComponent(storyTemplate).bind({}); -// // -// // Attribute stories -// // - -// export const Appearance = renderComponent(html` - -// `); - -// export const Size = renderComponent(html` - -// `); - -// export const Layout = renderComponent(html` - -// `); - -// export const Disabled = renderComponent(html` +export const Appearance = renderComponent(html` +
+ + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Outlined Input + + + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Underlined Input + + + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Filled Lighter Input + + + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Filled Darker Input + +
+`); + +export const Size = renderComponent(html` +
+ + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Small Input + + + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Medium Input + + + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Large Input + +
+`); + +export const LayoutBlock = renderComponent(html` + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Layout Block Input + +`); -// `); +export const LayoutInline = renderComponent(html` + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Layout Inline Input + +`); -// export const Placeholder = renderComponent(html` +export const Disabled = renderComponent(html` + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Disabled Input + +`); -// `); +export const Required = renderComponent(html` + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Required Input + +`); From c04acf4eae65417454397089badb192114bb9578 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 27 Mar 2023 13:57:17 -0700 Subject: [PATCH 15/46] text input: adds properties to class --- .../src/text-input/text-input.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index 475acd527b01f4..3d09b9e5d91b45 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -8,7 +8,7 @@ import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-inpu */ export class TextInput extends FASTTextField { /** - * Defines accordion header font size. + * Defines TextInput size * * @public * @default 'medium' @@ -17,4 +17,26 @@ export class TextInput extends FASTTextField { */ @attr({ attribute: 'input-size' }) public inputSize?: TextInputSize = TextInputSize.medium; + + /** + * Defines TextInput appearance. + * + * @public + * @default 'outline' + * @remarks + * HTML Attribute: appearance + */ + @attr + public appearance?: TextInputAppearance = TextInputAppearance.outline; + + /** + * Defines TextInput display property. + * + * @public + * @default 'block' + * @remarks + * HTML Attribute: layout + */ + @attr + public layout?: TextInputLayout = TextInputLayout.block; } From 8afab54ec8ee6226fe9ef0de4d69e81867f0f1f7 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 27 Mar 2023 14:01:54 -0700 Subject: [PATCH 16/46] text-input: re-exports TextFieldType as TextInputType --- packages/web-components/src/text-input/index.ts | 2 +- packages/web-components/src/text-input/text-input.stories.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-components/src/text-input/index.ts b/packages/web-components/src/text-input/index.ts index 8fa6d074b74e72..b4abe1506c92fc 100644 --- a/packages/web-components/src/text-input/index.ts +++ b/packages/web-components/src/text-input/index.ts @@ -3,4 +3,4 @@ export * from './text-input.options.js'; export { template as TextTemplate } from './text-input.template.js'; export { styles as TextStyles } from './text-input.styles.js'; export { definition as TextDefinition } from './text-input.definition.js'; -export { TextFieldType } from '@microsoft/fast-foundation'; +export { TextFieldType as TextInputType } from '@microsoft/fast-foundation'; diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index b9f38f6e121ccc..290fd2ee3cd99b 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -3,7 +3,7 @@ import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; import type { TextInput as FluentTextInput } from './text-input.js'; import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-input.options.js'; -import { TextFieldType } from '@microsoft/fast-foundation'; +import { TextInputType } from './index.js'; import './define.js'; @@ -44,7 +44,7 @@ export default { title: 'Components/TextInput', argTypes: { type: { - options: Object.values(TextFieldType), + options: Object.values(TextInputType), control: { type: 'select', }, From 7a001f5ea30b7d840cd98ca280beb5a57ae1df8f Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 27 Mar 2023 14:42:52 -0700 Subject: [PATCH 17/46] text input: fixes export names --- packages/web-components/src/text-input/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-components/src/text-input/index.ts b/packages/web-components/src/text-input/index.ts index b4abe1506c92fc..91f1e523895121 100644 --- a/packages/web-components/src/text-input/index.ts +++ b/packages/web-components/src/text-input/index.ts @@ -1,6 +1,6 @@ export * from './text-input.js'; export * from './text-input.options.js'; -export { template as TextTemplate } from './text-input.template.js'; -export { styles as TextStyles } from './text-input.styles.js'; -export { definition as TextDefinition } from './text-input.definition.js'; +export { template as TextInputTemplate } from './text-input.template.js'; +export { styles as TextInputStyles } from './text-input.styles.js'; +export { definition as TextInputDefinition } from './text-input.definition.js'; export { TextFieldType as TextInputType } from '@microsoft/fast-foundation'; From bb80c4983620e303aa4e9c0777d0fb16a02fffb4 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 27 Mar 2023 14:43:45 -0700 Subject: [PATCH 18/46] text input: updates underline styles --- packages/web-components/src/text-input/text-input.styles.ts | 2 +- packages/web-components/src/text-input/text-input.template.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 41a80483dde342..c289a6a165cea7 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -41,7 +41,6 @@ import { spacingHorizontalSNudge, spacingHorizontalXS, spacingHorizontalXXS, - spacingVerticalS, spacingVerticalXS, strokeWidthThick, strokeWidthThin, @@ -211,6 +210,7 @@ export const styles = css` :host([appearance='underline']) .root { background: ${colorTransparentBackground}; border: 0; + border-radius: 0; border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessible}; } :host([appearance='underline']:hover) .root { diff --git a/packages/web-components/src/text-input/text-input.template.ts b/packages/web-components/src/text-input/text-input.template.ts index cf86aa5028b588..1981a3c41a03b4 100644 --- a/packages/web-components/src/text-input/text-input.template.ts +++ b/packages/web-components/src/text-input/text-input.template.ts @@ -5,4 +5,4 @@ import type { TextInput } from './text-input.js'; /** * @internal */ -export const template: ElementViewTemplate = textFieldTemplate({}); +export const template: ElementViewTemplate = textFieldTemplate(); From 0d8f5da0c1eccca615131a961346da6d93411c81 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 28 Mar 2023 15:43:56 -0700 Subject: [PATCH 19/46] text-input: exports text-input from package.json --- packages/web-components/package.json | 4 ++++ packages/web-components/src/index.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/packages/web-components/package.json b/packages/web-components/package.json index 4cf0ba0e4aa3bb..22ace9cdc6c676 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -56,6 +56,10 @@ "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" }, + "./text-input": { + "types": "./dist/esm/text-input/define.d.ts", + "default": "./dist/esm/text-input/define.js" + }, "./progress-bar": { "types": "./dist/esm/progress-bar/define.d.ts", "default": "./dist/esm/progress-bar/define.js" diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 041cf1b6983643..fdbe36bca3b642 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -9,5 +9,6 @@ export * from './progress-bar/index.js'; export * from './spinner/index.js'; export * from './switch/index.js'; export * from './text/index.js'; +export * from './text-input/index.js'; export * from './theme/index.js'; From 827cd992aee64ce63e433bcaf0f5f87c759b230f Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 28 Mar 2023 15:46:29 -0700 Subject: [PATCH 20/46] removes dead code --- packages/web-components/src/input/README.md | 135 -------------------- 1 file changed, 135 deletions(-) delete mode 100644 packages/web-components/src/input/README.md diff --git a/packages/web-components/src/input/README.md b/packages/web-components/src/input/README.md deleted file mode 100644 index 1461fca61850bc..00000000000000 --- a/packages/web-components/src/input/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# TextInput - -> An implementation of a [text input](https://w3c.github.io/html-reference/input.text.html) as a form-connected web-component. - -
- -## **Design Spec** - -[Link to Text Input Design Spec in Figma](https://www.figma.com/file/TvHmWjZYxwtI9Tz6v5BT7E/Input?node-id=2366-657&t=UNSOfCD3St9ffppx-0) - -
- -## **Engineering Spec** - -Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.design/components/fast-text-field) and is intended to be as close to the Fluent UI React 9 Input implementation as possible. However, due to the nature of web components there will not be 100% parity between the two. - -
- -## Class: `TextInput` - -
- -### **Component Name** - -`` - -
- -### **Variables** - -| Name | Description | Type | -| ------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| `size` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | -| `appearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | -| `type` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | -| `layout` | Layout variations for text input | `{ block: "block", inline: "inline"` | - -
- -### **Fields** - -| Name | Privacy | Type | Default | Description | -| --------------- | ------- | ----------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `appearance` | public | `InputAppearance` | `outline` | Sets appearance of text input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables text input | -| `labelPosition` | public | `boolean` | `false` | Disables text input | -| `layout` | public | `InputLayout` | `TextInputLayout.block` | Sets layout display property on text input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `number` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the text input as required | -| `size` | public | `InputSize` | `medium` | Sets the size of the text input | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | -| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | - -
- -### **Methods** - -| Name | Privacy | Description | -| ---------- | ------- | ------------------------------------------------- | -| `select` | public | Selects all the text in the text field | -| `validate` | public | {@inheritDoc (FormAssociated:interface).validate} | - -### **Events** - -| Name | Type | Description | Inherited From | -| -------- | ---- | --------------------------- | -------------- | -| `change` | | Fires a custom change event | | - -
- -### **Attributes** - -| Name | Field | -| ---------------- | -------------- | -| `appearance` | appearance | -| `autofocus` | autofocus | -| `label-position` | label-position | -| `list` | list | -| `maxlength` | maxlength | -| `minlength` | minlength | -| `pattern` | pattern | -| `placeholder` | placeholder | -| `readonly ` | readonly | -| `size` | size | -| `spellcheck` | spellcheck | -| `type` | type | - -
- -### **Slots** - -| Name | Description | -| ------- | ---------------------------------------------------------------------------- | -| `start` | used to place content at the start of the text input within the input border | -| `end` | used to place content at the end of the text input within the input border | -| | The default slot for text input content | - -
-
-
- -## **Accessibility** - -[W3C Text Input Spec](https://w3c.github.io/html-reference/input.text.html) - -
- -### **WAI-ARIA Roles, States, and Properties** - -This component supports ARIA attributes that inherit from the [ARIA Global States and Properties](https://www.w3.org/TR/wai-aria-1.2/#global_states). - -
-
-
- -## **Preparation** - -### **Fluent Web Component v3 v.s Fluent React 9** - -
- -**Component and Slot Mapping** - -| Fluent UI React 9 | Fluent Web Components 3 | -| ----------------- | ----------------------- | -| `` | `` | -| `contentBefore` | `start` | -| `contentAfter` | `end` | From 821ccdbac049d9ebb05f5b01b2ae11dbdf429f72 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 28 Mar 2023 15:53:49 -0700 Subject: [PATCH 21/46] text-input: removes default attr values --- .../web-components/src/text-input/text-input.stories.ts | 4 ++-- packages/web-components/src/text-input/text-input.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 290fd2ee3cd99b..73bb04dde5d923 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -146,7 +146,7 @@ export const LayoutInline = renderComponent(html` `); export const Disabled = renderComponent(html` - + ${Person20Regular} ${Person20Regular}${Person20Regular} Disabled Input @@ -154,7 +154,7 @@ export const Disabled = renderComponent(html` `); export const Required = renderComponent(html` - + ${Person20Regular} ${Person20Regular}${Person20Regular} Required Input diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index 3d09b9e5d91b45..25d1c32088b0dc 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -16,7 +16,7 @@ export class TextInput extends FASTTextField { * HTML Attribute: size */ @attr({ attribute: 'input-size' }) - public inputSize?: TextInputSize = TextInputSize.medium; + public inputSize?: TextInputSize; /** * Defines TextInput appearance. @@ -27,7 +27,7 @@ export class TextInput extends FASTTextField { * HTML Attribute: appearance */ @attr - public appearance?: TextInputAppearance = TextInputAppearance.outline; + public appearance?: TextInputAppearance; /** * Defines TextInput display property. @@ -38,5 +38,5 @@ export class TextInput extends FASTTextField { * HTML Attribute: layout */ @attr - public layout?: TextInputLayout = TextInputLayout.block; + public layout?: TextInputLayout; } From 4504f6e7937008288c11d2a840d915812e243bbf Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 28 Mar 2023 16:11:01 -0700 Subject: [PATCH 22/46] text-input: updates icon sizes --- .../src/text-input/text-input.stories.ts | 6 +- .../src/text-input/text-input.styles.ts | 158 ++++++++---------- 2 files changed, 69 insertions(+), 95 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 73bb04dde5d923..3a6a15af19872d 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -81,7 +81,7 @@ export const TextInput = renderComponent(storyTemplate).bind({}); export const Appearance = renderComponent(html`
- + ${Person20Regular} ${Person20Regular}${Person20Regular} Outlined Input @@ -115,7 +115,7 @@ export const Size = renderComponent(html` Small Input - + ${Person20Regular} ${Person20Regular}${Person20Regular} Medium Input @@ -130,7 +130,7 @@ export const Size = renderComponent(html` `); export const LayoutBlock = renderComponent(html` - + ${Person20Regular} ${Person20Regular}${Person20Regular} Layout Block Input diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index c289a6a165cea7..0bfcbc9d63f223 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -30,6 +30,7 @@ import { fontSizeBase200, fontSizeBase300, fontSizeBase400, + fontSizeBase500, fontSizeBase600, fontWeightRegular, lineHeightBase200, @@ -59,7 +60,6 @@ export const styles = css` align-items: center; align-items: flex-start; } - .label { font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; @@ -68,7 +68,6 @@ export const styles = css` color: ${colorNeutralForeground1}; padding-bottom: ${spacingVerticalXS}; } - .root { height: 32px; display: inline-flex; @@ -83,7 +82,22 @@ export const styles = css` border-radius: ${borderRadiusMedium}; gap: ${spacingHorizontalXXS}; } - + .root::after { + content: ''; + position: absolute; + left: -1px; + bottom: -1px; + right: -1px; + height: max(2px, ${borderRadiusMedium}); + border-bottom-left-radius: ${borderRadiusMedium}; + border-bottom-right-radius: ${borderRadiusMedium}; + border-bottom: 2px solid ${colorCompoundBrandStroke}; + clip-path: inset(calc(100% - 2px) 0px 0px); + transform: scaleX(0); + transition-property: transform; + transition-duration: ${durationUltraFast}; + transition-delay: ${curveAccelerateMid}; + } .control { width: 100%; box-sizing: border-box; @@ -91,109 +105,95 @@ export const styles = css` border-radius: ${borderRadiusMedium}; background: ${colorTransparentBackground}; font-family: ${fontFamilyBase}; - font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; - line-height: ${lineHeightBase300}; border: none; background: transparent; vertical-align: center; } - .control:focus-visible { outline: 0; border: 0; } - .control::placeholder { color: ${colorNeutralForeground4}; } - + :host ::slotted([slot='start']), + :host ::slotted([slot='end']) { + display: flex; + align-items: center; + justify-content: center; + color: ${colorNeutralForeground3}; + font-size: ${fontSizeBase500}; + } + :host ::slotted([slot='start']) { + padding-right: ${spacingHorizontalXXS}; + } + :host ::slotted([slot='end']) { + padding-left: ${spacingHorizontalXXS}; + gap: ${spacingHorizontalXS}; + } + :host(:hover) .root { + border-color: ${colorNeutralStroke1Hover}; + border-bottom-color: ${colorNeutralStrokeAccessibleHover}; + } + :host(:active) .root { + border-color: ${colorNeutralStroke1Pressed}; + } + :host(:focus-within:not([disabled])) .root { + border: ${strokeWidthThin} solid ${colorNeutralStroke1}; + border-bottom-width: ${strokeWidthThick}; + } + :host(:focus-within:not([disabled])) .control { + color: ${colorNeutralForeground1}; + } + :host([disabled]) .root { + background: ${colorTransparentBackground}; + border: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; + } + :host([disabled]) .control::placeholder, + :host([disabled]) ::slotted([slot='start']), + :host([disabled]) ::slotted([slot='end']) { + color: ${colorNeutralForegroundDisabled}; + } + :host(:focus-within) .root::after { + transform: scaleX(1); + transition: transform ${durationNormal} ${curveDecelerateMid}; + } + :host(:focus-within:active) .root::after { + border-bottom-color: ${colorCompoundBrandStrokePressed}; + } + ::selection { + color: ${colorNeutralForegroundInverted}; + background-color: ${colorNeutralBackgroundInverted}; + } :host([input-size='small']) .control { font-size: ${fontSizeBase200}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase200}; } - :host([input-size='small']) .root { height: 24px; gap: ${spacingHorizontalXXS}; padding: 0 ${spacingHorizontalSNudge}; } - :host([input-size='small']) ::slotted([slot='start']), :host([input-size='small']) ::slotted([slot='end']) { font-size: ${fontSizeBase400}; } - :host([input-size='large']) .control { font-size: ${fontSizeBase400}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase400}; } - :host([input-size='large']) .root { height: 40px; gap: ${spacingHorizontalS}; padding: 0 ${spacingHorizontalMNudge}; } - :host([input-size='large']) ::slotted([slot='start']), :host([input-size='large']) ::slotted([slot='end']) { font-size: ${fontSizeBase600}; } - - :host ::slotted([slot='start']), - :host ::slotted([slot='end']) { - display: flex; - align-items: center; - justify-content: center; - color: ${colorNeutralForeground3}; - } - - :host ::slotted([slot='start']) { - padding-right: ${spacingHorizontalXXS}; - } - - :host ::slotted([slot='end']) { - padding-left: ${spacingHorizontalXXS}; - gap: ${spacingHorizontalXS}; - } - - :host(:hover) .root { - border-color: ${colorNeutralStroke1Hover}; - border-bottom-color: ${colorNeutralStrokeAccessibleHover}; - } - - :host(:active) .root { - border-color: ${colorNeutralStroke1Pressed}; - } - - :host(:focus-within:not([disabled])) .control { - color: ${colorNeutralForeground1}; - } - - :host(:focus-within:not([disabled])) .root { - border: ${strokeWidthThin} solid ${colorNeutralStroke1}; - border-bottom-width: ${strokeWidthThick}; - } - - .root::after { - content: ''; - position: absolute; - left: -1px; - bottom: -1px; - right: -1px; - height: max(2px, ${borderRadiusMedium}); - border-bottom-left-radius: ${borderRadiusMedium}; - border-bottom-right-radius: ${borderRadiusMedium}; - border-bottom: 2px solid ${colorCompoundBrandStroke}; - clip-path: inset(calc(100% - 2px) 0px 0px); - transform: scaleX(0); - transition-property: transform; - transition-duration: ${durationUltraFast}; - transition-delay: ${curveAccelerateMid}; - } - :host([layout='inline']) { display: inline-flex; flex-direction: row; @@ -206,7 +206,6 @@ export const styles = css` :host([layout='inline']) .label { padding-inline-end: 12px; } - :host([appearance='underline']) .root { background: ${colorTransparentBackground}; border: 0; @@ -226,7 +225,6 @@ export const styles = css` :host([appearance='underline'][disabled]) .root { border-bottom-color: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; } - :host([appearance='filledLighter']) .root, :host([appearance='filledDarker']) .root { border: ${strokeWidthThin} solid ${colorTransparentStroke}; @@ -247,28 +245,4 @@ export const styles = css` border-color: ${colorTransparentStrokeInteractive}; background: ${colorNeutralBackground3}; } - - :host([disabled]) .root { - background: ${colorTransparentBackground}; - border: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; - } - :host([disabled]) .control::placeholder, - :host([disabled]) ::slotted([slot='start']), - :host([disabled]) ::slotted([slot='end']) { - color: ${colorNeutralForegroundDisabled}; - } - - :host(:focus-within) .root::after { - transform: scaleX(1); - transition: transform ${durationNormal} ${curveDecelerateMid}; - } - - :host(:focus-within:active) .root::after { - border-bottom-color: ${colorCompoundBrandStrokePressed}; - } - - ::selection { - color: ${colorNeutralForegroundInverted}; - background-color: ${colorNeutralBackgroundInverted}; - } `; From 3dbcaf57b8b9517152b854cfa1ac5fd75a1e7ee4 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Wed, 29 Mar 2023 13:55:37 -0700 Subject: [PATCH 23/46] text-input: updates block vs inline implimentation --- .../web-components/src/text-input/README.md | 61 +++++++++---------- .../src/text-input/text-input.stories.ts | 30 ++++----- .../src/text-input/text-input.styles.ts | 28 +++------ .../src/text-input/text-input.ts | 11 ---- 4 files changed, 51 insertions(+), 79 deletions(-) diff --git a/packages/web-components/src/text-input/README.md b/packages/web-components/src/text-input/README.md index 236e304ad0b02b..2e44f70d5d3067 100644 --- a/packages/web-components/src/text-input/README.md +++ b/packages/web-components/src/text-input/README.md @@ -32,29 +32,27 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de | `TextInputSize` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | | `TextInputAppearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | | `TextInputType` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | -| `TextInputLayout` | Layout variations for text input | `{ block: "block", inline: "inline"` |
### **Fields** -| Name | Privacy | Type | Default | Description | -| ------------- | ------- | --------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `appearance` | public | `TextInputAppearance` | `outline` | Sets appearance of text input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables text input | -| `layout` | public | `TextInputLayout` | `TextInputLayout.block` | Sets layout display property on text input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `number` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the text input as required | -| `size` | public | `InputSize` | `medium` | Sets the size of the text input | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | -| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | +| Name | Privacy | Type | Default | Description | +| ------------- | ------- | --------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| `appearance` | public | `TextInputAppearance` | `outline` | Sets appearance of text input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables text input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `number` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the text input as required | +| `size` | public | `InputSize` | `medium` | Sets the size of the text input | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | +| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input |
@@ -75,20 +73,19 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de ### **Attributes** -| Name | Field | -| ---------------- | -------------- | -| `appearance` | appearance | -| `autofocus` | autofocus | -| `label-position` | label-position | -| `list` | list | -| `maxlength` | maxlength | -| `minlength` | minlength | -| `pattern` | pattern | -| `placeholder` | placeholder | -| `readonly ` | readonly | -| `size` | size | -| `spellcheck` | spellcheck | -| `type` | type | +| Name | Field | +| ------------- | ----------- | +| `appearance` | appearance | +| `autofocus` | autofocus | +| `list` | list | +| `maxlength` | maxlength | +| `minlength` | minlength | +| `pattern` | pattern | +| `placeholder` | placeholder | +| `readonly ` | readonly | +| `size` | size | +| `spellcheck` | spellcheck | +| `type` | type |
diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 3a6a15af19872d..ec2e258d28f535 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -6,6 +6,7 @@ import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-inpu import { TextInputType } from './index.js'; import './define.js'; +import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; type TextInputStoryArgs = Args & FluentTextInput; type TextInputStoryMeta = Meta; @@ -61,13 +62,6 @@ export default { type: 'select', }, }, - layout: { - options: Object.keys(TextInputLayout), - defaultValue: TextInputLayout.block, - control: { - type: 'select', - }, - }, disabled: { control: 'boolean', }, @@ -129,20 +123,20 @@ export const Size = renderComponent(html`
`); -export const LayoutBlock = renderComponent(html` - - ${Person20Regular} - ${Person20Regular}${Person20Regular} - Layout Block Input - -`); - -export const LayoutInline = renderComponent(html` - +export const Inline = renderComponent(html` + ${Person20Regular} ${Person20Regular}${Person20Regular} - Layout Inline Input + Inline Input +

+ This input is + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + + with a paragraph of text. +

`); export const Disabled = renderComponent(html` diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 0bfcbc9d63f223..969441f604555f 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -51,22 +51,26 @@ import { * @public */ export const styles = css` - ${display('inline-flex')} + ${display('block')} :host { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - align-items: flex-start; + vertical-align: middle; + gap: 4px; } .label { + display: flex; font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; color: ${colorNeutralForeground1}; padding-bottom: ${spacingVerticalXS}; + flex-shrink: 0; + vertical-align: middle; + padding-inline-end: ${spacingHorizontalXS}; + } + .label__hidden { + display: none; } .root { height: 32px; @@ -194,18 +198,6 @@ export const styles = css` :host([input-size='large']) ::slotted([slot='end']) { font-size: ${fontSizeBase600}; } - :host([layout='inline']) { - display: inline-flex; - flex-direction: row; - align-items: center; - } - :host([layout='inline']) .root, - :host([layout='inline']) .control { - width: fit-content; - } - :host([layout='inline']) .label { - padding-inline-end: 12px; - } :host([appearance='underline']) .root { background: ${colorTransparentBackground}; border: 0; diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index 25d1c32088b0dc..abe4c698d6e29a 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -28,15 +28,4 @@ export class TextInput extends FASTTextField { */ @attr public appearance?: TextInputAppearance; - - /** - * Defines TextInput display property. - * - * @public - * @default 'block' - * @remarks - * HTML Attribute: layout - */ - @attr - public layout?: TextInputLayout; } From a0d7c349903be18d53bd90c48ae490afecf3086f Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Wed, 29 Mar 2023 14:16:36 -0700 Subject: [PATCH 24/46] text-input: updates docs --- .../web-components/src/text-input/README.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/web-components/src/text-input/README.md b/packages/web-components/src/text-input/README.md index 2e44f70d5d3067..0f8494f6d37c61 100644 --- a/packages/web-components/src/text-input/README.md +++ b/packages/web-components/src/text-input/README.md @@ -97,6 +97,34 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de | `end` | used to place content at the end of the text input within the input border | | | The default slot for text input content | +
+ +### **Additional Styling Variations** + +For performance considerations, we have avoided the addition of explicit attributes for appearance variations that modify only one CSS property. Instead, opting to provide guidance for users to apply their own CSS to achieve these appearance variations. + +
+ +**Block v.s Inline** + +The Fluent UI `TextInput` component offers two appearance variations for the display property - block (default) and inline. To achieve the inline variation, users should apply their own custom CSS. + +```css +/* all instances */ + +fluent-text-input { + display: inline-flex; + align-items: center; +} + +/* class instances */ + +fluent-text-input.inline { + display: inline-flex; + align-items: center; +} +``` +


From 170aa1722ff4014b856df2ab381bb5b7d055846d Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Wed, 29 Mar 2023 15:33:55 -0700 Subject: [PATCH 25/46] text-input: adds styling support for icons and text passed through start/end slots --- .../src/text-input/text-input.stories.ts | 65 +++++++++++++++---- .../src/text-input/text-input.styles.ts | 24 +++++-- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index ec2e258d28f535..ec068346607707 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -25,6 +25,18 @@ const Person20Regular = html` `; +const Mic16Regular = html``; + const storyTemplate = html` x.type} @@ -32,7 +44,6 @@ const storyTemplate = html` ?block=${x => x.block} input-size="${x => x.inputSize}" appearance="${x => x.appearance}" - layout=${x => x.layout} placeholder=${x => x.placeholder} > ${Person20Regular} @@ -73,27 +84,53 @@ export default { export const TextInput = renderComponent(storyTemplate).bind({}); +export const ContentStartAfter = renderComponent(html` +
+ + ${Person20Regular} + Content Start + + + ${Mic16Regular} + Content After + + + $ + .00 + Content After + +
+`); + +export const Placeholder = renderComponent(html` + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Disabled Input + +`); + export const Appearance = renderComponent(html`
- + ${Person20Regular} ${Person20Regular}${Person20Regular} Outlined Input - + ${Person20Regular} ${Person20Regular}${Person20Regular} Underlined Input - + ${Person20Regular} ${Person20Regular}${Person20Regular} Filled Lighter Input - + ${Person20Regular} ${Person20Regular}${Person20Regular} Filled Darker Input @@ -103,28 +140,28 @@ export const Appearance = renderComponent(html` export const Size = renderComponent(html`
- + ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Small Input - + ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Medium Input - + ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Large Input
`); export const Inline = renderComponent(html` - + ${Person20Regular} ${Person20Regular}${Person20Regular} Inline Input @@ -140,7 +177,7 @@ export const Inline = renderComponent(html` `); export const Disabled = renderComponent(html` - + ${Person20Regular} ${Person20Regular}${Person20Regular} Disabled Input @@ -148,7 +185,7 @@ export const Disabled = renderComponent(html` `); export const Required = renderComponent(html` - + ${Person20Regular} ${Person20Regular}${Person20Regular} Required Input diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 969441f604555f..fdc15110dfca36 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -55,14 +55,14 @@ export const styles = css` :host { vertical-align: middle; - gap: 4px; - } - .label { - display: flex; font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; + gap: 4px; + } + .label { + display: flex; color: ${colorNeutralForeground1}; padding-bottom: ${spacingVerticalXS}; flex-shrink: 0; @@ -127,6 +127,10 @@ export const styles = css` align-items: center; justify-content: center; color: ${colorNeutralForeground3}; + font-size: ${fontSizeBase400}; + } + :host ::slotted([slot='start']) svg, + :host ::slotted([slot='end']) svg { font-size: ${fontSizeBase500}; } :host ::slotted([slot='start']) { @@ -180,9 +184,13 @@ export const styles = css` gap: ${spacingHorizontalXXS}; padding: 0 ${spacingHorizontalSNudge}; } + :host([input-size='small']) ::slotted([slot='start']) svg, + :host([input-size='small']) ::slotted([slot='end']) svg { + font-size: ${fontSizeBase400}; + } :host([input-size='small']) ::slotted([slot='start']), :host([input-size='small']) ::slotted([slot='end']) { - font-size: ${fontSizeBase400}; + font-size: ${fontSizeBase200}; } :host([input-size='large']) .control { font-size: ${fontSizeBase400}; @@ -194,9 +202,13 @@ export const styles = css` gap: ${spacingHorizontalS}; padding: 0 ${spacingHorizontalMNudge}; } + :host([input-size='large']) ::slotted([slot='start']) svg, + :host([input-size='large']) ::slotted([slot='end']) svg { + font-size: ${fontSizeBase600}; + } :host([input-size='large']) ::slotted([slot='start']), :host([input-size='large']) ::slotted([slot='end']) { - font-size: ${fontSizeBase600}; + font-size: ${fontSizeBase400}; } :host([appearance='underline']) .root { background: ${colorTransparentBackground}; From 9eba38725e4c5be0e788d8cd71e3ffe03122744b Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 30 Mar 2023 10:53:43 -0700 Subject: [PATCH 26/46] text-input: updates border styles --- .../src/text-input/text-input.styles.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index fdc15110dfca36..0b2e2523313ad0 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -89,10 +89,10 @@ export const styles = css` .root::after { content: ''; position: absolute; - left: -1px; + left: 0px; bottom: -1px; - right: -1px; - height: max(2px, ${borderRadiusMedium}); + right: 0px; + height: 2px; border-bottom-left-radius: ${borderRadiusMedium}; border-bottom-right-radius: ${borderRadiusMedium}; border-bottom: 2px solid ${colorCompoundBrandStroke}; @@ -149,7 +149,6 @@ export const styles = css` } :host(:focus-within:not([disabled])) .root { border: ${strokeWidthThin} solid ${colorNeutralStroke1}; - border-bottom-width: ${strokeWidthThick}; } :host(:focus-within:not([disabled])) .control { color: ${colorNeutralForeground1}; @@ -163,13 +162,13 @@ export const styles = css` :host([disabled]) ::slotted([slot='end']) { color: ${colorNeutralForegroundDisabled}; } + :host:focus-within) .root { + outline: transparent solid 2px; + } :host(:focus-within) .root::after { transform: scaleX(1); transition: transform ${durationNormal} ${curveDecelerateMid}; } - :host(:focus-within:active) .root::after { - border-bottom-color: ${colorCompoundBrandStrokePressed}; - } ::selection { color: ${colorNeutralForegroundInverted}; background-color: ${colorNeutralBackgroundInverted}; From f8d58f076a28c80e9daaac6ecd351c0f5a6197bc Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 30 Mar 2023 12:36:39 -0700 Subject: [PATCH 27/46] input: updates storybook content --- .../src/text-input/text-input.stories.ts | 70 +++++++++++-------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index ec068346607707..53e66f4edff4ce 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -38,18 +38,20 @@ const Mic16Regular = html``; const storyTemplate = html` - x.type} - ?disabled=${x => x.disabled} - ?block=${x => x.block} - input-size="${x => x.inputSize}" - appearance="${x => x.appearance}" - placeholder=${x => x.placeholder} - > - ${Person20Regular} - ${Person20Regular}${Person20Regular} - Sample Input - +
+ x.type} + ?disabled=${x => x.disabled} + ?block=${x => x.block} + input-size="${x => x.inputSize}" + appearance="${x => x.appearance}" + placeholder=${x => x.placeholder} + > + ${Person20Regular} + ${Person20Regular} + Sample Input + +
`; export default { @@ -85,7 +87,7 @@ export default { export const TextInput = renderComponent(storyTemplate).bind({}); export const ContentStartAfter = renderComponent(html` -
+
${Person20Regular} Content Start @@ -94,7 +96,7 @@ export const ContentStartAfter = renderComponent(html` ${Mic16Regular} Content After - + $ .00 Content After @@ -103,15 +105,17 @@ export const ContentStartAfter = renderComponent(html` `); export const Placeholder = renderComponent(html` - - ${Person20Regular} - ${Person20Regular}${Person20Regular} - Disabled Input - +
+ + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Disabled Input + +
`); export const Appearance = renderComponent(html` -
+
${Person20Regular} ${Person20Regular}${Person20Regular} @@ -139,7 +143,7 @@ export const Appearance = renderComponent(html` `); export const Size = renderComponent(html` -
+
${Person20Regular} ${Person20Regular} @@ -177,17 +181,21 @@ export const Inline = renderComponent(html` `); export const Disabled = renderComponent(html` - - ${Person20Regular} - ${Person20Regular}${Person20Regular} - Disabled Input - +
+ + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Disabled Input + +
`); export const Required = renderComponent(html` - - ${Person20Regular} - ${Person20Regular}${Person20Regular} - Required Input - +
+ + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Required Input + +
`); From b1f644e19efbede76e64ada93256ce672f66c059 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 30 Mar 2023 12:39:04 -0700 Subject: [PATCH 28/46] updates README --- .../web-components/src/text-input/README.md | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/web-components/src/text-input/README.md b/packages/web-components/src/text-input/README.md index 0f8494f6d37c61..c91f63d55f5261 100644 --- a/packages/web-components/src/text-input/README.md +++ b/packages/web-components/src/text-input/README.md @@ -37,22 +37,23 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de ### **Fields** -| Name | Privacy | Type | Default | Description | -| ------------- | ------- | --------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `appearance` | public | `TextInputAppearance` | `outline` | Sets appearance of text input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables text input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `number` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the text input as required | -| `size` | public | `InputSize` | `medium` | Sets the size of the text input | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | -| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | +| Name | Privacy | Type | Default | Description | +| --------------- | ------- | --------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `appearance` | public | `TextInputAppearance` | `outline` | Sets appearance of text input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables text input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `string` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the text input as required | +| `size` | public | `InputSize` | `medium` | Sets the size of the text input | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | +| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | +| `current-value` | public | | | Stores the current value of an input element. This attribute is commonly used in web development frameworks like Angular and React, where the value of the input element is managed by the framework. By using the current-value attribute, you can ensure that the input element always displays the correct value, even if it is changed by the framework or another JavaScript code. This attribute can also be used to set the initial value of an input element. [link: `current-value` RFC](https://github.com/microsoft/fast/issues/5119) |
From 6ac34cf84344f20cd5c336f107399a45ae1ea0e8 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 30 Mar 2023 15:14:49 -0700 Subject: [PATCH 29/46] text-input: adds filled non shadow variants --- .../src/text-input/text-input.options.ts | 6 ++- .../src/text-input/text-input.stories.ts | 43 ++++++++------- .../src/text-input/text-input.styles.ts | 52 ++++++++++--------- 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.options.ts b/packages/web-components/src/text-input/text-input.options.ts index f22499d6d59e54..fa3f256eacc0f0 100644 --- a/packages/web-components/src/text-input/text-input.options.ts +++ b/packages/web-components/src/text-input/text-input.options.ts @@ -21,10 +21,12 @@ export type TextInputSize = ValuesOf; * @public */ export const TextInputAppearance = { - outline: 'base', - underline: 'numeric', + outline: 'outline', + underline: 'underline', filledLighter: 'filled-lighter', + filledLighterShadow: 'filled-lighter--shadow', filledDarker: 'filled-darker', + filledDarkerShadow: 'filled-darker--shadow', } as const; /** diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 53e66f4edff4ce..2cc7244e915e96 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -2,9 +2,8 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; import type { TextInput as FluentTextInput } from './text-input.js'; -import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-input.options.js'; +import { TextInputAppearance, TextInputSize } from './text-input.options.js'; import { TextInputType } from './index.js'; - import './define.js'; import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; @@ -25,18 +24,6 @@ const Person20Regular = html` `; -const Mic16Regular = html``; - const storyTemplate = html`
` ?block=${x => x.block} input-size="${x => x.inputSize}" appearance="${x => x.appearance}" - placeholder=${x => x.placeholder} + placeholder="${x => x.placeholder}" > ${Person20Regular} ${Person20Regular} @@ -70,7 +57,7 @@ export default { }, }, appearance: { - options: Object.keys(TextInputAppearance), + options: Object.values(TextInputAppearance), control: { type: 'select', }, @@ -93,13 +80,13 @@ export const ContentStartAfter = renderComponent(html` Content Start - ${Mic16Regular} + ${Person20Regular} Content After - $ - .00 - Content After + $ + .00 + Content Before + After
`); @@ -128,17 +115,29 @@ export const Appearance = renderComponent(html` Underlined Input
- + ${Person20Regular} ${Person20Regular}${Person20Regular} Filled Lighter Input - + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Filled Lighter with Shadow Input + + + ${Person20Regular} ${Person20Regular}${Person20Regular} Filled Darker Input + + + ${Person20Regular} + ${Person20Regular}${Person20Regular} + Filled Darker with Shadow Input +
`); diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 0b2e2523313ad0..18db9d8e8955d2 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -37,6 +37,7 @@ import { lineHeightBase300, lineHeightBase400, shadow2, + spacingHorizontalM, spacingHorizontalMNudge, spacingHorizontalS, spacingHorizontalSNudge, @@ -95,7 +96,7 @@ export const styles = css` height: 2px; border-bottom-left-radius: ${borderRadiusMedium}; border-bottom-right-radius: ${borderRadiusMedium}; - border-bottom: 2px solid ${colorCompoundBrandStroke}; + border-bottom: ${strokeWidthThick} solid ${colorCompoundBrandStroke}; clip-path: inset(calc(100% - 2px) 0px 0px); transform: scaleX(0); transition-property: transform; @@ -110,6 +111,7 @@ export const styles = css` background: ${colorTransparentBackground}; font-family: ${fontFamilyBase}; font-weight: ${fontWeightRegular}; + font-size: ${fontSizeBase300}; border: none; background: transparent; vertical-align: center; @@ -127,10 +129,6 @@ export const styles = css` align-items: center; justify-content: center; color: ${colorNeutralForeground3}; - font-size: ${fontSizeBase400}; - } - :host ::slotted([slot='start']) svg, - :host ::slotted([slot='end']) svg { font-size: ${fontSizeBase500}; } :host ::slotted([slot='start']) { @@ -147,7 +145,7 @@ export const styles = css` :host(:active) .root { border-color: ${colorNeutralStroke1Pressed}; } - :host(:focus-within:not([disabled])) .root { + :host([appearance='outline']:focus-within:not([disabled])) .root { border: ${strokeWidthThin} solid ${colorNeutralStroke1}; } :host(:focus-within:not([disabled])) .control { @@ -183,13 +181,9 @@ export const styles = css` gap: ${spacingHorizontalXXS}; padding: 0 ${spacingHorizontalSNudge}; } - :host([input-size='small']) ::slotted([slot='start']) svg, - :host([input-size='small']) ::slotted([slot='end']) svg { - font-size: ${fontSizeBase400}; - } :host([input-size='small']) ::slotted([slot='start']), :host([input-size='small']) ::slotted([slot='end']) { - font-size: ${fontSizeBase200}; + font-size: ${fontSizeBase400}; } :host([input-size='large']) .control { font-size: ${fontSizeBase400}; @@ -199,15 +193,11 @@ export const styles = css` :host([input-size='large']) .root { height: 40px; gap: ${spacingHorizontalS}; - padding: 0 ${spacingHorizontalMNudge}; - } - :host([input-size='large']) ::slotted([slot='start']) svg, - :host([input-size='large']) ::slotted([slot='end']) svg { - font-size: ${fontSizeBase600}; + padding: 0 ${spacingHorizontalM}; } :host([input-size='large']) ::slotted([slot='start']), :host([input-size='large']) ::slotted([slot='end']) { - font-size: ${fontSizeBase400}; + font-size: ${fontSizeBase600}; } :host([appearance='underline']) .root { background: ${colorTransparentBackground}; @@ -228,23 +218,35 @@ export const styles = css` :host([appearance='underline'][disabled]) .root { border-bottom-color: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; } - :host([appearance='filledLighter']) .root, - :host([appearance='filledDarker']) .root { + :host([appearance='filled-lighter']) .root, + :host([appearance='filled-lighter--shadow']) .root, + :host([appearance='filled-darker']) .root, + :host([appearance='filled-darker--shadow']) .root { border: ${strokeWidthThin} solid ${colorTransparentStroke}; + } + :host([appearance='filled-lighter--shadow']) .root, + :host([appearance='filled-darker--shadow']) .root { box-shadow: ${shadow2}; } - :host([appearance='filledLighter']) .root { + + :host([appearance='filled-lighter']) .root, + :host([appearance='filled-lighter--shadow']) .root { background: ${colorNeutralBackground1}; } - :host([appearance='filledDarker']) .root { + :host([appearance='filled-darker']) .root, + :host([appearance='filled-darker--shadow']) .root { background: ${colorNeutralBackground3}; } - :host([appearance='filledLighter']):hover:not(:active) .root, - :host([appearance='filledDarker']):hover:not(:active) .root { + :host([appearance='filled-lighter']):hover:not(:active) .root, + :host([appearance='filled-lighter--shadow']):hover:not(:active) .root, + :host([appearance='filled-darker']):hover:not(:active) .root, + :host([appearance='filled-darkers--shadow']):hover:not(:active) .root { border-color: ${colorTransparentStrokeInteractive}; } - :host([appearance='filledLighter']):active .root, - :host([appearance='filledDarker']):active .root { + :host([appearance='filled-lighter']):active .root, + :host([appearance='filled-lighter-shadow']):active .root, + :host([appearance='filled-darker']):active .root, + :host([appearance='filled-darker-shadow']):active .root { border-color: ${colorTransparentStrokeInteractive}; background: ${colorNeutralBackground3}; } From 78eceaf099c0292cdc56678bfdce691293e1efbe Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 31 Mar 2023 11:34:31 -0700 Subject: [PATCH 30/46] text-input: modifies storybook examples --- .../src/text-input/text-input.stories.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 2cc7244e915e96..465a4f61925458 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -95,7 +95,7 @@ export const Placeholder = renderComponent(html`
${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Disabled Input
@@ -105,37 +105,37 @@ export const Appearance = renderComponent(html`
${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Outlined Input ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Underlined Input ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Filled Lighter Input ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Filled Lighter with Shadow Input ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Filled Darker Input ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Filled Darker with Shadow Input
@@ -166,14 +166,14 @@ export const Size = renderComponent(html` export const Inline = renderComponent(html` ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Inline Input

This input is ${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} with a paragraph of text.

@@ -183,7 +183,7 @@ export const Disabled = renderComponent(html`
${Person20Regular} - ${Person20Regular}${Person20Regular} + ${Person20Regular} Disabled Input
From e630555e9b335c25d4362d868ea5910fba184c0d Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 31 Mar 2023 11:37:04 -0700 Subject: [PATCH 31/46] text-input: removes dead import --- packages/web-components/src/text-input/text-input.styles.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index 18db9d8e8955d2..fdafd2dc6f5179 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -3,7 +3,6 @@ import { display } from '@microsoft/fast-foundation'; import { borderRadiusMedium, colorCompoundBrandStroke, - colorCompoundBrandStrokePressed, colorNeutralBackground1, colorNeutralBackground3, colorNeutralBackgroundInverted, From fb734758a4107d1b67fc7966f4838549b03aaa3e Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 4 Apr 2023 11:27:27 -0700 Subject: [PATCH 32/46] addresses PR feedback --- .../src/text-input/text-input.stories.ts | 6 ++++-- .../src/text-input/text-input.styles.ts | 16 ++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 465a4f61925458..563daca578dfd2 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -164,12 +164,14 @@ export const Size = renderComponent(html` `); export const Inline = renderComponent(html` - + ${Person20Regular} ${Person20Regular} Inline Input -

+

This input is ${Person20Regular} diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index fdafd2dc6f5179..f471b1223d37e8 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -90,11 +90,10 @@ export const styles = css` content: ''; position: absolute; left: 0px; - bottom: -1px; + bottom: 1px; right: 0px; height: 2px; - border-bottom-left-radius: ${borderRadiusMedium}; - border-bottom-right-radius: ${borderRadiusMedium}; + border-bottom-radius: ${borderRadiusMedium}; border-bottom: ${strokeWidthThick} solid ${colorCompoundBrandStroke}; clip-path: inset(calc(100% - 2px) 0px 0px); transform: scaleX(0); @@ -159,8 +158,9 @@ export const styles = css` :host([disabled]) ::slotted([slot='end']) { color: ${colorNeutralForegroundDisabled}; } - :host:focus-within) .root { + :host(:focus-within) .root { outline: transparent solid 2px; + border-bottom: 0; } :host(:focus-within) .root::after { transform: scaleX(1); @@ -205,17 +205,17 @@ export const styles = css` border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessible}; } :host([appearance='underline']:hover) .root { - border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessibleHover}; + border-bottom-color: ${colorNeutralStrokeAccessibleHover}; } :host([appearance='underline']:active) .root { - border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessiblePressed}; + border-bottom-color: ${colorNeutralStrokeAccessiblePressed}; } :host([appearance='underline']):focus-within .root { border: 0; - border-bottom: ${strokeWidthThin} solid ${colorNeutralStrokeAccessiblePressed}; + border-bottom-color: ${colorNeutralStrokeAccessiblePressed}; } :host([appearance='underline'][disabled]) .root { - border-bottom-color: ${strokeWidthThin} solid ${colorNeutralStrokeDisabled}; + border-bottom-color: ${colorNeutralStrokeDisabled}; } :host([appearance='filled-lighter']) .root, :host([appearance='filled-lighter--shadow']) .root, From 939536cc3a3935353ab438dd925bb12cacea30e4 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 6 Apr 2023 13:43:53 -0700 Subject: [PATCH 33/46] text input: updates styles --- .../src/text-input/text-input.stories.ts | 2 +- .../src/text-input/text-input.styles.ts | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 563daca578dfd2..9204e5ce507b98 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -164,7 +164,7 @@ export const Size = renderComponent(html` `); export const Inline = renderComponent(html` - + ${Person20Regular} ${Person20Regular} Inline Input diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index f471b1223d37e8..b3fd0a893ef200 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -3,6 +3,7 @@ import { display } from '@microsoft/fast-foundation'; import { borderRadiusMedium, colorCompoundBrandStroke, + colorCompoundBrandStrokePressed, colorNeutralBackground1, colorNeutralBackground3, colorNeutralBackgroundInverted, @@ -87,15 +88,17 @@ export const styles = css` gap: ${spacingHorizontalXXS}; } .root::after { + box-sizing: border-box; content: ''; position: absolute; - left: 0px; - bottom: 1px; - right: 0px; - height: 2px; - border-bottom-radius: ${borderRadiusMedium}; - border-bottom: ${strokeWidthThick} solid ${colorCompoundBrandStroke}; - clip-path: inset(calc(100% - 2px) 0px 0px); + left: -1px; + bottom: 0px; + right: -1px; + height: max(2px, ${borderRadiusMedium}); + border-bottom-left-radius: ${borderRadiusMedium}; + border-bottom-right-radius: ${borderRadiusMedium}; + border-bottom: 2px solid ${colorCompoundBrandStroke}; + clip-path: inset(calc(100% - 2px) 1px 0px); transform: scaleX(0); transition-property: transform; transition-duration: ${durationUltraFast}; @@ -143,6 +146,19 @@ export const styles = css` :host(:active) .root { border-color: ${colorNeutralStroke1Pressed}; } + :host(:focus-within) .root { + outline: transparent solid 2px; + border-bottom: 0; + } + :host(:focus-within) .root::after { + transform: scaleX(1); + transition-property: transform; + transition-duration: ${durationNormal}; + transition-delay: ${curveDecelerateMid}; + } + :host(:focus-within:active) .root:after { + border-bottom-color: ${colorCompoundBrandStrokePressed}; + } :host([appearance='outline']:focus-within:not([disabled])) .root { border: ${strokeWidthThin} solid ${colorNeutralStroke1}; } @@ -158,14 +174,6 @@ export const styles = css` :host([disabled]) ::slotted([slot='end']) { color: ${colorNeutralForegroundDisabled}; } - :host(:focus-within) .root { - outline: transparent solid 2px; - border-bottom: 0; - } - :host(:focus-within) .root::after { - transform: scaleX(1); - transition: transform ${durationNormal} ${curveDecelerateMid}; - } ::selection { color: ${colorNeutralForegroundInverted}; background-color: ${colorNeutralBackgroundInverted}; From e97bec8acb432fc17ebd3745b6a73cd866dedc11 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 6 Apr 2023 13:46:46 -0700 Subject: [PATCH 34/46] text input: yarn change --- ...eb-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json diff --git a/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json b/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json new file mode 100644 index 00000000000000..41335b727c8126 --- /dev/null +++ b/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat(text input): adds TextInput as a new web component", + "packageName": "@fluentui/web-components", + "email": "brianbrady@microsoft.com", + "dependentChangeType": "patch" +} From 54cb7c4b5d6891db912fa929cb053b177a55e450 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Thu, 6 Apr 2023 14:26:42 -0700 Subject: [PATCH 35/46] text input: updates README and styles --- .../src/text-input/text-input.styles.ts | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index b3fd0a893ef200..d04574c697bae1 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -44,7 +44,6 @@ import { spacingHorizontalXS, spacingHorizontalXXS, spacingVerticalXS, - strokeWidthThick, strokeWidthThin, } from '../theme/design-tokens.js'; @@ -55,33 +54,30 @@ export const styles = css` ${display('block')} :host { - vertical-align: middle; font-family: ${fontFamilyBase}; font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; - gap: 4px; } .label { display: flex; color: ${colorNeutralForeground1}; padding-bottom: ${spacingVerticalXS}; flex-shrink: 0; - vertical-align: middle; padding-inline-end: ${spacingHorizontalXS}; } .label__hidden { display: none; } .root { + position: relative; + box-sizing: border-box; height: 32px; display: inline-flex; align-items: center; flex-direction: row; width: 100%; padding: 0 ${spacingHorizontalMNudge}; - position: relative; - box-sizing: border-box; border: ${strokeWidthThin} solid ${colorNeutralStroke1}; border-bottom-color: ${colorNeutralStrokeAccessible}; border-radius: ${borderRadiusMedium}; @@ -159,10 +155,10 @@ export const styles = css` :host(:focus-within:active) .root:after { border-bottom-color: ${colorCompoundBrandStrokePressed}; } - :host([appearance='outline']:focus-within:not([disabled])) .root { + :host([appearance='outline']:focus-within) .root { border: ${strokeWidthThin} solid ${colorNeutralStroke1}; } - :host(:focus-within:not([disabled])) .control { + :host(:focus-within) .control { color: ${colorNeutralForeground1}; } :host([disabled]) .root { @@ -218,7 +214,7 @@ export const styles = css` :host([appearance='underline']:active) .root { border-bottom-color: ${colorNeutralStrokeAccessiblePressed}; } - :host([appearance='underline']):focus-within .root { + :host([appearance='underline']:focus-within) .root { border: 0; border-bottom-color: ${colorNeutralStrokeAccessiblePressed}; } @@ -244,16 +240,16 @@ export const styles = css` :host([appearance='filled-darker--shadow']) .root { background: ${colorNeutralBackground3}; } - :host([appearance='filled-lighter']):hover:not(:active) .root, - :host([appearance='filled-lighter--shadow']):hover:not(:active) .root, - :host([appearance='filled-darker']):hover:not(:active) .root, - :host([appearance='filled-darkers--shadow']):hover:not(:active) .root { + :host([appearance='filled-lighter']:hover) .root, + :host([appearance='filled-lighter--shadow']:hover) .root, + :host([appearance='filled-darker']:hover) .root, + :host([appearance='filled-darkers--shadow']:hover) .root { border-color: ${colorTransparentStrokeInteractive}; } - :host([appearance='filled-lighter']):active .root, - :host([appearance='filled-lighter-shadow']):active .root, - :host([appearance='filled-darker']):active .root, - :host([appearance='filled-darker-shadow']):active .root { + :host([appearance='filled-lighter']:active) .root, + :host([appearance='filled-lighter-shadow']:active) .root, + :host([appearance='filled-darker']:active) .root, + :host([appearance='filled-darker-shadow']:active) .root { border-color: ${colorTransparentStrokeInteractive}; background: ${colorNeutralBackground3}; } From 3de0b20e353aa41e6e1c53b0119d488fa68b9deb Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 10 Apr 2023 10:51:51 -0700 Subject: [PATCH 36/46] text input: shorthands css property --- packages/web-components/src/text-input/text-input.styles.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index d04574c697bae1..ccd4305c8cd5a3 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -91,8 +91,7 @@ export const styles = css` bottom: 0px; right: -1px; height: max(2px, ${borderRadiusMedium}); - border-bottom-left-radius: ${borderRadiusMedium}; - border-bottom-right-radius: ${borderRadiusMedium}; + border-radius: 0 0 ${borderRadiusMedium} ${borderRadiusMedium}; border-bottom: 2px solid ${colorCompoundBrandStroke}; clip-path: inset(calc(100% - 2px) 1px 0px); transform: scaleX(0); From 5b58ec47e8830ff87a64fd41416bbd99cdb9530d Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 5 May 2023 13:10:50 -0700 Subject: [PATCH 37/46] textinput: fixes ts errors --- packages/web-components/src/text-input/text-input.stories.ts | 2 +- packages/web-components/src/text-input/text-input.template.ts | 2 +- packages/web-components/src/text-input/text-input.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 9204e5ce507b98..6ff4380c69964d 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -1,11 +1,11 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; +import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; import type { TextInput as FluentTextInput } from './text-input.js'; import { TextInputAppearance, TextInputSize } from './text-input.options.js'; import { TextInputType } from './index.js'; import './define.js'; -import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; type TextInputStoryArgs = Args & FluentTextInput; type TextInputStoryMeta = Meta; diff --git a/packages/web-components/src/text-input/text-input.template.ts b/packages/web-components/src/text-input/text-input.template.ts index 1981a3c41a03b4..5407488f02289d 100644 --- a/packages/web-components/src/text-input/text-input.template.ts +++ b/packages/web-components/src/text-input/text-input.template.ts @@ -1,4 +1,4 @@ -import { ElementViewTemplate, html } from '@microsoft/fast-element'; +import { ElementViewTemplate } from '@microsoft/fast-element'; import { textFieldTemplate } from '@microsoft/fast-foundation'; import type { TextInput } from './text-input.js'; diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index abe4c698d6e29a..d3a3721cf5b41d 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -1,6 +1,6 @@ import { attr } from '@microsoft/fast-element'; import { FASTTextField } from '@microsoft/fast-foundation'; -import { TextInputAppearance, TextInputLayout, TextInputSize } from './text-input.options.js'; +import { TextInputAppearance, TextInputSize } from './text-input.options.js'; /** * The base class used for constructing a fluent-text-input custom element From 0581dc57fdd92fd43be13a28e9766375da7111f7 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 5 May 2023 14:17:35 -0700 Subject: [PATCH 38/46] textinput: updates attribute name --- .../web-components/src/text-input/README.md | 72 ++++++------- .../src/text-input/text-input.options.ts | 25 +---- .../src/text-input/text-input.stories.ts | 101 +++++++++--------- .../src/text-input/text-input.styles.ts | 18 ++-- .../src/text-input/text-input.ts | 10 +- 5 files changed, 105 insertions(+), 121 deletions(-) diff --git a/packages/web-components/src/text-input/README.md b/packages/web-components/src/text-input/README.md index c91f63d55f5261..5b412ed8719776 100644 --- a/packages/web-components/src/text-input/README.md +++ b/packages/web-components/src/text-input/README.md @@ -29,7 +29,7 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de | Name | Description | Type | | --------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| `TextInputSize` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | +| `TextControlSize` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | | `TextInputAppearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | | `TextInputType` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | @@ -37,23 +37,24 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de ### **Fields** -| Name | Privacy | Type | Default | Description | -| --------------- | ------- | --------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `appearance` | public | `TextInputAppearance` | `outline` | Sets appearance of text input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables text input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `string` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the text input as required | -| `size` | public | `InputSize` | `medium` | Sets the size of the text input | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | -| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | -| `current-value` | public | | | Stores the current value of an input element. This attribute is commonly used in web development frameworks like Angular and React, where the value of the input element is managed by the framework. By using the current-value attribute, you can ensure that the input element always displays the correct value, even if it is changed by the framework or another JavaScript code. This attribute can also be used to set the initial value of an input element. [link: `current-value` RFC](https://github.com/microsoft/fast/issues/5119) | +| Name | Privacy | Type | Default | Description | +| --------------- | ------- | --------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `appearance` | public | `TextInputAppearance` | `TextInputAppearance.outline` | Sets appearance of text input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables text input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `string` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the text input as required | +| `size` | public | `number` | | A number indicating how many characters wide the input field should be | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | +| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | +| `current-value` | public | | | Stores the current value of an input element. This attribute is commonly used in web development frameworks like Angular and React, where the value of the input element is managed by the framework. By using the current-value attribute, you can ensure that the input element always displays the correct value, even if it is changed by the framework or another JavaScript code. This attribute can also be used to set the initial value of an input element. [link: `current-value` RFC](https://github.com/microsoft/fast/issues/5119) | +| `control-size` | public | `TextControlSize` | `TextControlSize.medium` | Sets the size of the component |
@@ -74,19 +75,20 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de ### **Attributes** -| Name | Field | -| ------------- | ----------- | -| `appearance` | appearance | -| `autofocus` | autofocus | -| `list` | list | -| `maxlength` | maxlength | -| `minlength` | minlength | -| `pattern` | pattern | -| `placeholder` | placeholder | -| `readonly ` | readonly | -| `size` | size | -| `spellcheck` | spellcheck | -| `type` | type | +| Name | Field | +| -------------- | ----------- | +| `appearance` | appearance | +| `autofocus` | autofocus | +| `list` | list | +| `maxlength` | maxlength | +| `minlength` | minlength | +| `pattern` | pattern | +| `placeholder` | placeholder | +| `readonly ` | readonly | +| `size` | size | +| `spellcheck` | spellcheck | +| `type` | type | +| `control-size` | type |
@@ -100,15 +102,9 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de
-### **Additional Styling Variations** - -For performance considerations, we have avoided the addition of explicit attributes for appearance variations that modify only one CSS property. Instead, opting to provide guidance for users to apply their own CSS to achieve these appearance variations. - -
- **Block v.s Inline** -The Fluent UI `TextInput` component offers two appearance variations for the display property - block (default) and inline. To achieve the inline variation, users should apply their own custom CSS. +The Fluent UI `TextInput` component design spec offers two appearance variations for the display property - block (default) and inline. To achieve the inline variation, users should apply their own custom CSS. ```css /* all instances */ diff --git a/packages/web-components/src/text-input/text-input.options.ts b/packages/web-components/src/text-input/text-input.options.ts index fa3f256eacc0f0..953543cf92fc4a 100644 --- a/packages/web-components/src/text-input/text-input.options.ts +++ b/packages/web-components/src/text-input/text-input.options.ts @@ -4,20 +4,20 @@ import { ValuesOf } from '@microsoft/fast-foundation'; * TextInput size constants * @public */ -export const TextInputSize = { +export const TextControlSize = { small: 'small', medium: 'medium', large: 'large', } as const; /** - * The type for TextInputSize + * Applies size styling to TextInput * @public */ -export type TextInputSize = ValuesOf; +export type TextControlSize = ValuesOf; /** - * TextInput appearance Constants + * TextInput appearance constants * @public */ export const TextInputAppearance = { @@ -30,22 +30,7 @@ export const TextInputAppearance = { } as const; /** - * Applies styling to TextInput + * Applies appearance styling to TextInput * @public */ export type TextInputAppearance = ValuesOf; - -/** - * TextInput layout Constants - * @public - */ -export const TextInputLayout = { - block: 'block', - inline: 'inline', -} as const; - -/** - * Applies display style property - * @public - */ -export type TextInputLayout = ValuesOf; diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 6ff4380c69964d..48e076d1150788 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -3,7 +3,7 @@ import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; import type { TextInput as FluentTextInput } from './text-input.js'; -import { TextInputAppearance, TextInputSize } from './text-input.options.js'; +import { TextControlSize, TextInputAppearance } from './text-input.options.js'; import { TextInputType } from './index.js'; import './define.js'; @@ -25,17 +25,15 @@ const Person20Regular = html``; const storyTemplate = html` -

+
x.type} ?disabled=${x => x.disabled} ?block=${x => x.block} - input-size="${x => x.inputSize}" + control-size="${x => x.controlSize}" appearance="${x => x.appearance}" placeholder="${x => x.placeholder}" > - ${Person20Regular} - ${Person20Regular} Sample Input
@@ -45,28 +43,52 @@ export default { title: 'Components/TextInput', argTypes: { type: { + description: 'Sets the input type', + table: { + defaultValue: { summary: 'text' }, + }, options: Object.values(TextInputType), control: { type: 'select', }, }, - inputSize: { - options: Object.values(TextInputSize), + controlSize: { + description: 'Sets the size of the control', + table: { + defaultValue: { summary: 'medium' }, + }, control: { type: 'select', + options: Object.values(TextControlSize), }, }, appearance: { - options: Object.values(TextInputAppearance), + description: 'Sets the visual appearance of the control', + table: { + defaultValue: { summary: 'outline' }, + }, control: { type: 'select', + options: Object.values(TextInputAppearance), }, }, disabled: { - control: 'boolean', + description: 'Sets the disabled state', + table: { + defaultValue: { summary: 'false' }, + }, + control: { + type: 'boolean', + }, }, placeholder: { - control: 'text', + description: 'Sets the placeholder text', + table: { + defaultValue: { summary: 'undefined' }, + }, + control: { + type: 'text', + }, }, }, } as TextInputStoryMeta; @@ -74,7 +96,7 @@ export default { export const TextInput = renderComponent(storyTemplate).bind({}); export const ContentStartAfter = renderComponent(html` -
+
${Person20Regular} Content Start @@ -92,71 +114,59 @@ export const ContentStartAfter = renderComponent(html` `); export const Placeholder = renderComponent(html` -
- - ${Person20Regular} - ${Person20Regular} - Disabled Input - -
+ + ${Person20Regular} + Disabled Input + `); export const Appearance = renderComponent(html` -
+
${Person20Regular} - ${Person20Regular} Outlined Input ${Person20Regular} - ${Person20Regular} Underlined Input ${Person20Regular} - ${Person20Regular} Filled Lighter Input ${Person20Regular} - ${Person20Regular} Filled Lighter with Shadow Input ${Person20Regular} - ${Person20Regular} Filled Darker Input ${Person20Regular} - ${Person20Regular} Filled Darker with Shadow Input
`); export const Size = renderComponent(html` -
- - ${Person20Regular} +
+ ${Person20Regular} Small Input - ${Person20Regular} ${Person20Regular} Medium Input - - ${Person20Regular} + ${Person20Regular} Large Input @@ -165,38 +175,29 @@ export const Size = renderComponent(html` export const Inline = renderComponent(html` - ${Person20Regular} ${Person20Regular} Inline Input

- This input is - - ${Person20Regular} - ${Person20Regular} + This input is an + with a paragraph of text.

`); export const Disabled = renderComponent(html` -
- - ${Person20Regular} - ${Person20Regular} - Disabled Input - -
+ + ${Person20Regular} + Disabled Input + `); export const Required = renderComponent(html` -
- - ${Person20Regular} - ${Person20Regular}${Person20Regular} - Required Input - -
+ + ${Person20Regular}${Person20Regular} + Required Input + `); diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index ccd4305c8cd5a3..b69ade89d3f899 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -58,6 +58,7 @@ export const styles = css` font-size: ${fontSizeBase300}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase300}; + max-width: 400px; } .label { display: flex; @@ -101,6 +102,7 @@ export const styles = css` } .control { width: 100%; + height: 100%; box-sizing: border-box; color: ${colorNeutralForeground1}; border-radius: ${borderRadiusMedium}; @@ -173,32 +175,32 @@ export const styles = css` color: ${colorNeutralForegroundInverted}; background-color: ${colorNeutralBackgroundInverted}; } - :host([input-size='small']) .control { + :host([control-size='small']) .control { font-size: ${fontSizeBase200}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase200}; } - :host([input-size='small']) .root { + :host([control-size='small']) .root { height: 24px; gap: ${spacingHorizontalXXS}; padding: 0 ${spacingHorizontalSNudge}; } - :host([input-size='small']) ::slotted([slot='start']), - :host([input-size='small']) ::slotted([slot='end']) { + :host([control-size='small']) ::slotted([slot='start']), + :host([control-size='small']) ::slotted([slot='end']) { font-size: ${fontSizeBase400}; } - :host([input-size='large']) .control { + :host([control-size='large']) .control { font-size: ${fontSizeBase400}; font-weight: ${fontWeightRegular}; line-height: ${lineHeightBase400}; } - :host([input-size='large']) .root { + :host([control-size='large']) .root { height: 40px; gap: ${spacingHorizontalS}; padding: 0 ${spacingHorizontalM}; } - :host([input-size='large']) ::slotted([slot='start']), - :host([input-size='large']) ::slotted([slot='end']) { + :host([control-size='large']) ::slotted([slot='start']), + :host([control-size='large']) ::slotted([slot='end']) { font-size: ${fontSizeBase600}; } :host([appearance='underline']) .root { diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index d3a3721cf5b41d..adb81ff5584968 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -1,6 +1,6 @@ import { attr } from '@microsoft/fast-element'; import { FASTTextField } from '@microsoft/fast-foundation'; -import { TextInputAppearance, TextInputSize } from './text-input.options.js'; +import { TextControlSize, TextInputAppearance } from './text-input.options.js'; /** * The base class used for constructing a fluent-text-input custom element @@ -8,15 +8,15 @@ import { TextInputAppearance, TextInputSize } from './text-input.options.js'; */ export class TextInput extends FASTTextField { /** - * Defines TextInput size + * Defines TextInput control size * * @public * @default 'medium' * @remarks - * HTML Attribute: size + * HTML Attribute: control-size */ - @attr({ attribute: 'input-size' }) - public inputSize?: TextInputSize; + @attr({ attribute: 'control-size' }) + public controlSize?: TextControlSize; /** * Defines TextInput appearance. From efe267463bf5541b586df85106e7c8621a97aa60 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Fri, 5 May 2023 14:24:23 -0700 Subject: [PATCH 39/46] textinput: uses fluent-label in stories --- .../src/text-input/text-input.stories.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 48e076d1150788..58e4f6c18336a4 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -34,7 +34,7 @@ const storyTemplate = html` appearance="${x => x.appearance}" placeholder="${x => x.placeholder}" > - Sample Input + Sample Input
`; @@ -99,16 +99,16 @@ export const ContentStartAfter = renderComponent(html`
${Person20Regular} - Content Start + Content Start ${Person20Regular} - Content After + Content After $ .00 - Content Before + After + Content Before + After
`); @@ -116,7 +116,7 @@ export const ContentStartAfter = renderComponent(html` export const Placeholder = renderComponent(html` ${Person20Regular} - Disabled Input + Disabled Input `); @@ -124,32 +124,32 @@ export const Appearance = renderComponent(html`
${Person20Regular} - Outlined Input + Outline (default) Input ${Person20Regular} - Underlined Input + Underlined Input ${Person20Regular} - Filled Lighter Input + Filled Lighter Input ${Person20Regular} - Filled Lighter with Shadow Input + Filled Lighter with Shadow Input ${Person20Regular} - Filled Darker Input + Filled Darker Input ${Person20Regular} - Filled Darker with Shadow Input + Filled Darker with Shadow Input
`); @@ -158,17 +158,17 @@ export const Size = renderComponent(html`
${Person20Regular} - Small Input + Small Input ${Person20Regular} - Medium Input + Medium (default) Input ${Person20Regular} - Large Input + Large Input
`); @@ -176,7 +176,7 @@ export const Size = renderComponent(html` export const Inline = renderComponent(html` ${Person20Regular} - Inline Input + Inline Input

` export const Disabled = renderComponent(html` ${Person20Regular} - Disabled Input + Disabled Input `); export const Required = renderComponent(html` ${Person20Regular}${Person20Regular} - Required Input + Required Input `); From 2154362264b0f12a851853f1e56386331051c74c Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 9 May 2023 11:52:50 -0700 Subject: [PATCH 40/46] textinput: updates control size type name --- .../web-components/src/text-input/README.md | 46 +++++++++---------- .../src/text-input/text-input.options.ts | 4 +- .../src/text-input/text-input.stories.ts | 17 ++++--- .../src/text-input/text-input.ts | 6 +-- 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/packages/web-components/src/text-input/README.md b/packages/web-components/src/text-input/README.md index 5b412ed8719776..f7b1f5b08945e7 100644 --- a/packages/web-components/src/text-input/README.md +++ b/packages/web-components/src/text-input/README.md @@ -27,34 +27,34 @@ Fluent WC3 Text Input extends from the [FAST Text Field](https://explore.fast.de ### **Variables** -| Name | Description | Type | -| --------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| `TextControlSize` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | -| `TextInputAppearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | -| `TextInputType` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` | +| Name | Description | Type | +| ---------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | +| `TextInputControlSize` | Size variations for text input | `{ small: "small", medium: "medium", large: "large" }` | +| `TextInputAppearance` | Appearance variations for text input | `{ outline: "outline", underline: "underline", filledLighter: "filled-lighter", filledDarker: "filled-darker" }` | +| `TextInputType` | Text input types | `{ email: "email", password: "password", tel: "tel", text: "text", url: "url" }` |
### **Fields** -| Name | Privacy | Type | Default | Description | -| --------------- | ------- | --------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `appearance` | public | `TextInputAppearance` | `TextInputAppearance.outline` | Sets appearance of text input. | -| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | -| `disabled` | public | `boolean` | `false` | Disables text input | -| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | -| `maxlength` | public | `number` | | The maximum number of characters a user can enter | -| `minlength` | public | `number` | | The minimum number of characters a user can enter | -| `name` | public | `string` | | The name of the control | -| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | -| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | -| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | -| `required` | public | `boolean` | `false` | Sets the text input as required | -| `size` | public | `number` | | A number indicating how many characters wide the input field should be | -| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | -| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | -| `current-value` | public | | | Stores the current value of an input element. This attribute is commonly used in web development frameworks like Angular and React, where the value of the input element is managed by the framework. By using the current-value attribute, you can ensure that the input element always displays the correct value, even if it is changed by the framework or another JavaScript code. This attribute can also be used to set the initial value of an input element. [link: `current-value` RFC](https://github.com/microsoft/fast/issues/5119) | -| `control-size` | public | `TextControlSize` | `TextControlSize.medium` | Sets the size of the component | +| Name | Privacy | Type | Default | Description | +| --------------- | ------- | ---------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `appearance` | public | `TextInputAppearance` | `TextInputAppearance.outline` | Sets appearance of text input. | +| `autofocus` | public | `boolean` | `false` | Indicates element should get focus after the page finishes loading.. | +| `disabled` | public | `boolean` | `false` | Disables text input | +| `list` | public | `string` | | Allows associating a `datalist` to an element by `id` | +| `maxlength` | public | `number` | | The maximum number of characters a user can enter | +| `minlength` | public | `number` | | The minimum number of characters a user can enter | +| `name` | public | `string` | | The name of the control | +| `pattern` | public | `string` | | A regular expression the text input's contents must match in order to be valid | +| `placeholder` | public | `string` | | An exemplar value to display in the text input field whenever it is empty | +| `readonly` | public | `boolean` | `false` | The text input should be submitted with the form but should not be editable | +| `required` | public | `boolean` | `false` | Sets the text input as required | +| `size` | public | `number` | | A number indicating how many characters wide the input field should be | +| `spellcheck` | public | `boolean` | `false` | Controls whether or not to enable spell checking for the text input, or if the default spell checking configuration should be used | +| `type` | public | `TextInputType` | `TextInputType.text` | Sets the size of the text input | +| `current-value` | public | | | Stores the current value of an input element. This attribute is commonly used in web development frameworks like Angular and React, where the value of the input element is managed by the framework. By using the current-value attribute, you can ensure that the input element always displays the correct value, even if it is changed by the framework or another JavaScript code. This attribute can also be used to set the initial value of an input element. [link: `current-value` RFC](https://github.com/microsoft/fast/issues/5119) | +| `control-size` | public | `TextInputControlSize` | `TextInputControlSize.medium` | Sets the size of the component |
diff --git a/packages/web-components/src/text-input/text-input.options.ts b/packages/web-components/src/text-input/text-input.options.ts index 953543cf92fc4a..ebe2124f9335a8 100644 --- a/packages/web-components/src/text-input/text-input.options.ts +++ b/packages/web-components/src/text-input/text-input.options.ts @@ -4,7 +4,7 @@ import { ValuesOf } from '@microsoft/fast-foundation'; * TextInput size constants * @public */ -export const TextControlSize = { +export const TextInputControlSize = { small: 'small', medium: 'medium', large: 'large', @@ -14,7 +14,7 @@ export const TextControlSize = { * Applies size styling to TextInput * @public */ -export type TextControlSize = ValuesOf; +export type TextInputControlSize = ValuesOf; /** * TextInput appearance constants diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 58e4f6c18336a4..63329f3101463e 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -3,7 +3,7 @@ import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; import type { TextInput as FluentTextInput } from './text-input.js'; -import { TextControlSize, TextInputAppearance } from './text-input.options.js'; +import { TextInputAppearance, TextInputControlSize } from './text-input.options.js'; import { TextInputType } from './index.js'; import './define.js'; @@ -29,10 +29,9 @@ const storyTemplate = html` x.type} ?disabled=${x => x.disabled} - ?block=${x => x.block} + ?placeholder="${x => x.placeholder}" control-size="${x => x.controlSize}" appearance="${x => x.appearance}" - placeholder="${x => x.placeholder}" > Sample Input @@ -41,6 +40,13 @@ const storyTemplate = html` export default { title: 'Components/TextInput', + args: { + type: TextInputType.text, + controlSize: TextInputControlSize.medium, + appearance: TextInputAppearance.outline, + disabled: false, + placeholder: undefined, + }, argTypes: { type: { description: 'Sets the input type', @@ -59,7 +65,7 @@ export default { }, control: { type: 'select', - options: Object.values(TextControlSize), + options: Object.values(TextInputControlSize), }, }, appearance: { @@ -83,9 +89,6 @@ export default { }, placeholder: { description: 'Sets the placeholder text', - table: { - defaultValue: { summary: 'undefined' }, - }, control: { type: 'text', }, diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index adb81ff5584968..c6f38d770f5229 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -1,6 +1,6 @@ import { attr } from '@microsoft/fast-element'; import { FASTTextField } from '@microsoft/fast-foundation'; -import { TextControlSize, TextInputAppearance } from './text-input.options.js'; +import { TextInputAppearance, TextInputControlSize } from './text-input.options.js'; /** * The base class used for constructing a fluent-text-input custom element @@ -16,7 +16,7 @@ export class TextInput extends FASTTextField { * HTML Attribute: control-size */ @attr({ attribute: 'control-size' }) - public controlSize?: TextControlSize; + public controlSize?: TextInputControlSize = TextInputControlSize.medium; /** * Defines TextInput appearance. @@ -27,5 +27,5 @@ export class TextInput extends FASTTextField { * HTML Attribute: appearance */ @attr - public appearance?: TextInputAppearance; + public appearance?: TextInputAppearance = TextInputAppearance.outline; } From c3c2313574d63fad92dfe6cca4d0ddc371c2e913 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 9 May 2023 11:56:58 -0700 Subject: [PATCH 41/46] textinput: updates storybook --- .../web-components/src/text-input/text-input.stories.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index 63329f3101463e..cde434bbf9ad71 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -51,7 +51,7 @@ export default { type: { description: 'Sets the input type', table: { - defaultValue: { summary: 'text' }, + defaultValue: { summary: `${TextInputType.text}` }, }, options: Object.values(TextInputType), control: { @@ -61,7 +61,7 @@ export default { controlSize: { description: 'Sets the size of the control', table: { - defaultValue: { summary: 'medium' }, + defaultValue: { summary: `${TextInputControlSize.medium}` }, }, control: { type: 'select', @@ -71,7 +71,7 @@ export default { appearance: { description: 'Sets the visual appearance of the control', table: { - defaultValue: { summary: 'outline' }, + defaultValue: { summary: `${TextInputAppearance.outline}` }, }, control: { type: 'select', From 5f8be4181c6c94160a01123fba54071d9b1d302c Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 9 May 2023 12:16:01 -0700 Subject: [PATCH 42/46] textinput: updates type --- .../web-components/src/text-input/text-input.stories.ts | 6 +++--- packages/web-components/src/text-input/text-input.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index cde434bbf9ad71..fcdf3274b01cf3 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -29,7 +29,7 @@ const storyTemplate = html` x.type} ?disabled=${x => x.disabled} - ?placeholder="${x => x.placeholder}" + placeholder="${x => x.placeholder}" control-size="${x => x.controlSize}" appearance="${x => x.appearance}" > @@ -161,7 +161,7 @@ export const Size = renderComponent(html`

${Person20Regular} - Small Input + Small Input @@ -171,7 +171,7 @@ export const Size = renderComponent(html` ${Person20Regular} - Large Input + Large Input
`); diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index c6f38d770f5229..600fa0c1da4ce7 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -16,7 +16,7 @@ export class TextInput extends FASTTextField { * HTML Attribute: control-size */ @attr({ attribute: 'control-size' }) - public controlSize?: TextInputControlSize = TextInputControlSize.medium; + public controlSize: TextInputControlSize = TextInputControlSize.medium; /** * Defines TextInput appearance. @@ -27,5 +27,5 @@ export class TextInput extends FASTTextField { * HTML Attribute: appearance */ @attr - public appearance?: TextInputAppearance = TextInputAppearance.outline; + public appearance: TextInputAppearance = TextInputAppearance.outline; } From 1f87e192bb9c092b0672741014b8696c689e5d2b Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Tue, 9 May 2023 12:42:13 -0700 Subject: [PATCH 43/46] textinput: updates story styles --- .../src/text-input/text-input.stories.ts | 78 +++++++++++-------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index fcdf3274b01cf3..b21ac524f10683 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -1,7 +1,13 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; -import { fontFamilyBase, fontSizeBase300, lineHeightBase300 } from '../theme/design-tokens.js'; +import { + colorNeutralBackgroundInverted, + colorNeutralForegroundInverted2, + fontFamilyBase, + fontSizeBase300, + lineHeightBase300, +} from '../theme/design-tokens.js'; import type { TextInput as FluentTextInput } from './text-input.js'; import { TextInputAppearance, TextInputControlSize } from './text-input.options.js'; import { TextInputType } from './index.js'; @@ -124,36 +130,46 @@ export const Placeholder = renderComponent(html` `); export const Appearance = renderComponent(html` -
- - ${Person20Regular} - Outline (default) Input - - - - ${Person20Regular} - Underlined Input - - - - ${Person20Regular} - Filled Lighter Input - - - - ${Person20Regular} - Filled Lighter with Shadow Input - - - - ${Person20Regular} - Filled Darker Input - - - - ${Person20Regular} - Filled Darker with Shadow Input - +
+
+ + ${Person20Regular} + Outline (default) Input + +
+
+ + ${Person20Regular} + Underlined Input + +
+
+ + ${Person20Regular} + Filled Lighter Input + +
+ +
+ + ${Person20Regular} + Filled Lighter with Shadow Input + +
+ +
+ + ${Person20Regular} + Filled Darker Input + +
+ +
+ + ${Person20Regular} + Filled Darker with Shadow Input + +
`); From 6f9584f8d8491f5aa9c88ab36371d266ab9a978d Mon Sep 17 00:00:00 2001 From: BrdyBrn Date: Mon, 22 May 2023 12:01:38 -0700 Subject: [PATCH 44/46] Update change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json Co-authored-by: Miroslav Stastny --- ...tui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json b/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json index 41335b727c8126..6f61af5fd35bc7 100644 --- a/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json +++ b/change/@fluentui-web-components-ec003fd2-a453-4e83-b620-9ec9f3ddffa0.json @@ -1,6 +1,6 @@ { "type": "prerelease", - "comment": "feat(text input): adds TextInput as a new web component", + "comment": "feat(text-input): add TextInput as a new web component", "packageName": "@fluentui/web-components", "email": "brianbrady@microsoft.com", "dependentChangeType": "patch" From cb1a2d25212e4ff5f2dfea6e5aaeb2ef6fd93ea2 Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 22 May 2023 14:40:49 -0700 Subject: [PATCH 45/46] text-input: addresses feedback --- packages/web-components/package.json | 8 +-- .../src/text-input/text-input.options.ts | 2 - .../src/text-input/text-input.stories.ts | 58 ++++++++----------- .../src/text-input/text-input.styles.ts | 22 ++----- 4 files changed, 33 insertions(+), 57 deletions(-) diff --git a/packages/web-components/package.json b/packages/web-components/package.json index cc3c4a6eedc4b1..1c1c9769668063 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -116,14 +116,14 @@ "types": "./dist/esm/tab-panel/define.d.ts", "default": "./dist/esm/tab-panel/define.js" }, - "./text-input": { - "types": "./dist/esm/text-input/define.d.ts", - "default": "./dist/esm/text-input/define.js" - }, "./text": { "types": "./dist/esm/text/define.d.ts", "default": "./dist/esm/text/define.js" }, + "./text-input": { + "types": "./dist/esm/text-input/define.d.ts", + "default": "./dist/esm/text-input/define.js" + }, "./toggle-button": { "types": "./dist/esm/toggle-button/define.d.ts", "default": "./dist/esm/toggle-button/define.js" diff --git a/packages/web-components/src/text-input/text-input.options.ts b/packages/web-components/src/text-input/text-input.options.ts index ebe2124f9335a8..9a5f3db5fa4c33 100644 --- a/packages/web-components/src/text-input/text-input.options.ts +++ b/packages/web-components/src/text-input/text-input.options.ts @@ -24,9 +24,7 @@ export const TextInputAppearance = { outline: 'outline', underline: 'underline', filledLighter: 'filled-lighter', - filledLighterShadow: 'filled-lighter--shadow', filledDarker: 'filled-darker', - filledDarkerShadow: 'filled-darker--shadow', } as const; /** diff --git a/packages/web-components/src/text-input/text-input.stories.ts b/packages/web-components/src/text-input/text-input.stories.ts index b21ac524f10683..e1ba299ab0470c 100644 --- a/packages/web-components/src/text-input/text-input.stories.ts +++ b/packages/web-components/src/text-input/text-input.stories.ts @@ -1,17 +1,12 @@ import { html } from '@microsoft/fast-element'; import type { Args, Meta } from '@storybook/html'; import { renderComponent } from '../helpers.stories.js'; -import { - colorNeutralBackgroundInverted, - colorNeutralForegroundInverted2, - fontFamilyBase, - fontSizeBase300, - lineHeightBase300, -} from '../theme/design-tokens.js'; +import { colorNeutralBackgroundInverted, colorNeutralForegroundInverted2 } from '../theme/design-tokens.js'; import type { TextInput as FluentTextInput } from './text-input.js'; import { TextInputAppearance, TextInputControlSize } from './text-input.options.js'; import { TextInputType } from './index.js'; import './define.js'; +import '../text/define.js'; type TextInputStoryArgs = Args & FluentTextInput; type TextInputStoryMeta = Meta; @@ -149,27 +144,12 @@ export const Appearance = renderComponent(html` Filled Lighter Input
- -
- - ${Person20Regular} - Filled Lighter with Shadow Input - -
-
${Person20Regular} Filled Darker Input
- -
- - ${Person20Regular} - Filled Darker with Shadow Input - -
`); @@ -193,18 +173,28 @@ export const Size = renderComponent(html` `); export const Inline = renderComponent(html` - - ${Person20Regular} - Inline Input - -

- This input is an - +

+ + ${Person20Regular} + Inline Input - with a paragraph of text. -

+ + This input is an + + with a paragraph of text. + +
`); export const Disabled = renderComponent(html` @@ -216,7 +206,7 @@ export const Disabled = renderComponent(html` export const Required = renderComponent(html` - ${Person20Regular}${Person20Regular} + ${Person20Regular} Required Input `); diff --git a/packages/web-components/src/text-input/text-input.styles.ts b/packages/web-components/src/text-input/text-input.styles.ts index b69ade89d3f899..492a01d4089ffe 100644 --- a/packages/web-components/src/text-input/text-input.styles.ts +++ b/packages/web-components/src/text-input/text-input.styles.ts @@ -223,34 +223,22 @@ export const styles = css` border-bottom-color: ${colorNeutralStrokeDisabled}; } :host([appearance='filled-lighter']) .root, - :host([appearance='filled-lighter--shadow']) .root, - :host([appearance='filled-darker']) .root, - :host([appearance='filled-darker--shadow']) .root { + :host([appearance='filled-darker']) .root { border: ${strokeWidthThin} solid ${colorTransparentStroke}; - } - :host([appearance='filled-lighter--shadow']) .root, - :host([appearance='filled-darker--shadow']) .root { box-shadow: ${shadow2}; } - - :host([appearance='filled-lighter']) .root, - :host([appearance='filled-lighter--shadow']) .root { + :host([appearance='filled-lighter']) .root { background: ${colorNeutralBackground1}; } - :host([appearance='filled-darker']) .root, - :host([appearance='filled-darker--shadow']) .root { + :host([appearance='filled-darker']) .root { background: ${colorNeutralBackground3}; } :host([appearance='filled-lighter']:hover) .root, - :host([appearance='filled-lighter--shadow']:hover) .root, - :host([appearance='filled-darker']:hover) .root, - :host([appearance='filled-darkers--shadow']:hover) .root { + :host([appearance='filled-darker']:hover) .root { border-color: ${colorTransparentStrokeInteractive}; } :host([appearance='filled-lighter']:active) .root, - :host([appearance='filled-lighter-shadow']:active) .root, - :host([appearance='filled-darker']:active) .root, - :host([appearance='filled-darker-shadow']:active) .root { + :host([appearance='filled-darker']:active) .root { border-color: ${colorTransparentStrokeInteractive}; background: ${colorNeutralBackground3}; } From bf6d213b28921876088862ad51e87076b23fba8e Mon Sep 17 00:00:00 2001 From: Brian Brady Date: Mon, 22 May 2023 14:42:55 -0700 Subject: [PATCH 46/46] text-input: alphabetize exports, removes setting default attr value --- packages/web-components/src/index.ts | 2 +- packages/web-components/src/text-input/text-input.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index fe4c607e39a1a4..b8a598ef4e9d66 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -21,8 +21,8 @@ export * from './switch/index.js'; export * from './tabs/index.js'; export * from './tab/index.js'; export * from './tab-panel/index.js'; -export * from './text-input/index.js'; export * from './text/index.js'; +export * from './text-input/index.js'; export * from './toggle-button/index.js'; export * from './theme/index.js'; diff --git a/packages/web-components/src/text-input/text-input.ts b/packages/web-components/src/text-input/text-input.ts index 600fa0c1da4ce7..5a69d713c92e4d 100644 --- a/packages/web-components/src/text-input/text-input.ts +++ b/packages/web-components/src/text-input/text-input.ts @@ -16,7 +16,7 @@ export class TextInput extends FASTTextField { * HTML Attribute: control-size */ @attr({ attribute: 'control-size' }) - public controlSize: TextInputControlSize = TextInputControlSize.medium; + public controlSize?: TextInputControlSize; /** * Defines TextInput appearance. @@ -27,5 +27,5 @@ export class TextInput extends FASTTextField { * HTML Attribute: appearance */ @attr - public appearance: TextInputAppearance = TextInputAppearance.outline; + public appearance?: TextInputAppearance; }