Implement Basic VSCode Text Area Component (#31)
Implement the basic styles and stories for the VSCode Text Area component.
This commit is contained in:
Родитель
794ca8829b
Коммит
cdcebf8926
|
@ -20,6 +20,7 @@ import { Radio } from '@microsoft/fast-foundation';
|
|||
import { RadioGroup } from '@microsoft/fast-foundation';
|
||||
import { Select } from '@microsoft/fast-foundation';
|
||||
import { Switch } from '@microsoft/fast-foundation';
|
||||
import { TextArea } from '@microsoft/fast-foundation';
|
||||
import { TextField } from '@microsoft/fast-foundation';
|
||||
|
||||
// @public
|
||||
|
@ -64,6 +65,9 @@ export const SelectStyles: ElementStyles;
|
|||
// @public
|
||||
export const SwitchStyles: ElementStyles;
|
||||
|
||||
// @public
|
||||
export const TextAreaStyles: ElementStyles;
|
||||
|
||||
// @public
|
||||
export type TextFieldAppearance = 'filled' | 'outline';
|
||||
|
||||
|
@ -275,6 +279,10 @@ export class VSCodeSelect extends Select {
|
|||
export class VSCodeSwitch extends Switch {
|
||||
}
|
||||
|
||||
// @public
|
||||
export class VSCodeTextArea extends TextArea {
|
||||
}
|
||||
|
||||
// @public
|
||||
export class VSCodeTextField extends TextField {
|
||||
appearance: TextFieldAppearance;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vscode-webview-toolkit",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vscode-webview-toolkit",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"description": "A component library for creating webview-based extensions in Visual Studio Code.",
|
||||
"homepage": "https://github.com/microsoft/vscode-webview-toolkit#readme",
|
||||
"license": "MIT",
|
||||
|
|
|
@ -12,6 +12,7 @@ export * from './radio-group/index';
|
|||
export * from './radio/index';
|
||||
export * from './select/index';
|
||||
export * from './switch/index';
|
||||
export * from './text-area/index';
|
||||
export * from './text-field/index';
|
||||
|
||||
// Export styles and utils
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import {VSCodeTextArea} from '../index';
|
||||
|
||||
export type TextAreaArgs = {
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
resize?: string;
|
||||
minLength?: number;
|
||||
maxLength?: number;
|
||||
isRequired?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isDisabled?: boolean;
|
||||
isAutoFocused?: boolean;
|
||||
};
|
||||
|
||||
export function createTextArea({
|
||||
label,
|
||||
placeholder,
|
||||
value,
|
||||
resize,
|
||||
minLength,
|
||||
maxLength,
|
||||
isRequired,
|
||||
isReadOnly,
|
||||
isDisabled,
|
||||
isAutoFocused,
|
||||
}: TextAreaArgs) {
|
||||
const textArea = new VSCodeTextArea();
|
||||
|
||||
if (label) {
|
||||
textArea.textContent = label;
|
||||
}
|
||||
if (placeholder) {
|
||||
textArea.setAttribute('placeholder', placeholder);
|
||||
}
|
||||
if (value) {
|
||||
textArea.value = value;
|
||||
}
|
||||
if (resize) {
|
||||
textArea.setAttribute('resize', resize.toLowerCase());
|
||||
}
|
||||
if (minLength) {
|
||||
textArea.setAttribute('minlength', minLength.toString());
|
||||
}
|
||||
if (maxLength) {
|
||||
textArea.setAttribute('maxlength', maxLength.toString());
|
||||
}
|
||||
if (isRequired) {
|
||||
textArea.setAttribute('required', '');
|
||||
}
|
||||
if (isReadOnly) {
|
||||
textArea.setAttribute('readonly', '');
|
||||
textArea.setAttribute('value', 'Read Only Text');
|
||||
}
|
||||
if (isDisabled) {
|
||||
textArea.setAttribute('disabled', '');
|
||||
}
|
||||
if (isAutoFocused) {
|
||||
textArea.setAttribute('autofocus', '');
|
||||
}
|
||||
|
||||
return textArea;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import {customElement, ElementStyles} from '@microsoft/fast-element';
|
||||
import {
|
||||
TextAreaTemplate as template,
|
||||
TextArea,
|
||||
} from '@microsoft/fast-foundation';
|
||||
import {TextAreaStyles as styles} from './text-area.styles';
|
||||
|
||||
/**
|
||||
* The VSCode Text Area element. Extends
|
||||
* {@link https://www.fast.design/docs/api/fast-foundation.textarea/ TextArea} and
|
||||
* {@link https://www.fast.design/docs/api/fast-foundation.textareatemplate/ TextAreaTemplate}.
|
||||
*
|
||||
*
|
||||
* @public
|
||||
* @remarks
|
||||
* HTML Element: `<vscode-text-area>`
|
||||
*
|
||||
* Shadow Option: {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus delegatesFocus}
|
||||
*/
|
||||
@customElement({
|
||||
name: 'vscode-text-area',
|
||||
template,
|
||||
styles,
|
||||
shadowOptions: {
|
||||
delegatesFocus: true,
|
||||
},
|
||||
})
|
||||
export class VSCodeTextArea extends TextArea {}
|
||||
|
||||
/**
|
||||
* Styles for TextArea
|
||||
* @public
|
||||
*/
|
||||
export const TextAreaStyles: ElementStyles = styles;
|
|
@ -0,0 +1,49 @@
|
|||
import {VSCodeDesignSystemProvider} from '../design-system-provider/index';
|
||||
import {createTextArea, TextAreaArgs} from './fixtures/createTextArea';
|
||||
import {VSCodeTextArea} from './index';
|
||||
|
||||
// Prevent tree-shaking
|
||||
VSCodeTextArea;
|
||||
VSCodeDesignSystemProvider;
|
||||
|
||||
export default {
|
||||
title: 'Library/Text Area',
|
||||
argTypes: {
|
||||
label: {control: 'text'},
|
||||
placeholder: {control: 'text'},
|
||||
value: {control: 'text'},
|
||||
resize: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['None', 'Both', 'Horizontal', 'Vertical'],
|
||||
},
|
||||
},
|
||||
minLength: {control: 'number'},
|
||||
maxLength: {control: 'number'},
|
||||
isRequired: {control: 'boolean'},
|
||||
isReadOnly: {control: 'boolean'},
|
||||
isDisabled: {control: 'boolean'},
|
||||
isAutoFocused: {control: 'boolean'},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = ({...args}: TextAreaArgs) => {
|
||||
return createTextArea({...args});
|
||||
};
|
||||
|
||||
export const Default: any = Template.bind({});
|
||||
Default.args = {
|
||||
label: 'Text Area Label',
|
||||
placeholder: 'Placeholder Text',
|
||||
resize: 'None',
|
||||
isRequired: false,
|
||||
isReadOnly: false,
|
||||
isDisabled: false,
|
||||
isAutoFocused: false,
|
||||
};
|
||||
|
||||
export const NoLabel: any = Template.bind({});
|
||||
NoLabel.args = {
|
||||
...Default.args,
|
||||
label: '',
|
||||
};
|
|
@ -0,0 +1,81 @@
|
|||
import {css} from '@microsoft/fast-element';
|
||||
import {
|
||||
disabledCursor,
|
||||
display,
|
||||
focusVisible,
|
||||
} from '@microsoft/fast-foundation';
|
||||
import {heightNumber} from '../utilities/styles/index';
|
||||
|
||||
export const TextAreaStyles = css`
|
||||
${display('inline-block')} :host {
|
||||
font-family: var(--body-font);
|
||||
outline: none;
|
||||
user-select: none;
|
||||
}
|
||||
.control {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
color: #cccccc;
|
||||
background: #3c3c3c;
|
||||
border-radius: calc(var(--corner-radius) * 1px);
|
||||
border: calc(var(--border-width) * 1px) solid #3c3c3c;
|
||||
height: calc(${heightNumber} * 2px);
|
||||
font: inherit;
|
||||
font-size: var(--type-ramp-base-font-size);
|
||||
line-height: var(--type-ramp-base-line-height);
|
||||
padding: calc(var(--design-unit) * 2px + 1px);
|
||||
width: 100%;
|
||||
resize: none;
|
||||
}
|
||||
.control:hover:enabled {
|
||||
background: #3c3c3c;
|
||||
border-color: #3c3c3c;
|
||||
}
|
||||
.control:active:enabled {
|
||||
background: #3c3c3c;
|
||||
border-color: var(--focus-border-color);
|
||||
}
|
||||
.control:hover,
|
||||
.control:${focusVisible},
|
||||
.control:disabled,
|
||||
.control:active {
|
||||
outline: none;
|
||||
}
|
||||
:host(:focus-within:not([disabled])) .control {
|
||||
border-color: var(--focus-border-color);
|
||||
box-shadow: 0 0 0 1px var(--focus-border-color) inset;
|
||||
}
|
||||
:host([resize='both']) .control {
|
||||
resize: both;
|
||||
}
|
||||
:host([resize='horizontal']) .control {
|
||||
resize: horizontal;
|
||||
}
|
||||
:host([resize='vertical']) .control {
|
||||
resize: vertical;
|
||||
}
|
||||
.label {
|
||||
display: block;
|
||||
color: #cccccc;
|
||||
cursor: pointer;
|
||||
font-size: var(--type-ramp-base-font-size);
|
||||
line-height: var(--type-ramp-base-line-height);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.label__hidden {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
:host([disabled]) .label,
|
||||
:host([readonly]) .label,
|
||||
:host([readonly]) .control,
|
||||
:host([disabled]) .control {
|
||||
cursor: ${disabledCursor};
|
||||
}
|
||||
:host([disabled]) {
|
||||
opacity: var(--disabled-opacity);
|
||||
}
|
||||
:host([disabled]) .control {
|
||||
border-color: #3c3c3c;
|
||||
}
|
||||
`;
|
|
@ -3,6 +3,7 @@ import {VSCodeTextField} from '../index';
|
|||
export type TextFieldArgs = {
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
minLength?: number;
|
||||
maxLength?: number;
|
||||
isRequired?: boolean;
|
||||
|
@ -14,6 +15,7 @@ export type TextFieldArgs = {
|
|||
export function createTextField({
|
||||
label,
|
||||
placeholder,
|
||||
value,
|
||||
minLength,
|
||||
maxLength,
|
||||
isRequired,
|
||||
|
@ -29,6 +31,9 @@ export function createTextField({
|
|||
if (placeholder) {
|
||||
textField.setAttribute('placeholder', placeholder);
|
||||
}
|
||||
if (value) {
|
||||
textField.value = value;
|
||||
}
|
||||
if (minLength) {
|
||||
textField.setAttribute('minlength', minLength.toString());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ export default {
|
|||
argTypes: {
|
||||
label: {control: 'text'},
|
||||
placeholder: {control: 'text'},
|
||||
value: {control: 'text'},
|
||||
minLength: {control: 'number'},
|
||||
maxLength: {control: 'number'},
|
||||
isRequired: {control: 'boolean'},
|
||||
|
|
Загрузка…
Ссылка в новой задаче