diff --git a/package.json b/package.json
index 98b5110b..f4769619 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "version": "0.3.4",
+ "version": "0.4.0",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
@@ -55,11 +55,11 @@
"size-limit": [
{
"path": "dist/components.cjs.production.min.js",
- "limit": "100 KB"
+ "limit": "150 KB"
},
{
"path": "dist/components.esm.js",
- "limit": "100 KB"
+ "limit": "150 KB"
}
],
"devDependencies": {
@@ -79,11 +79,12 @@
"@types/react-transition-group": "^4.4.1",
"babel-loader": "^8.1.0",
"babel-plugin-polished": "^1.1.0",
- "chromatic": "^5.2.0",
+ "chromatic": "^6.5.1",
"husky": "^4.3.0",
"polished": "^4.1.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
+ "react-hook-form": "^7.27.1",
"react-is": "^17.0.1",
"size-limit": "^4.6.2",
"storybook-addon-designs": "^5.4.5",
@@ -107,6 +108,7 @@
"@react-aria/radio": "^3.1.3",
"@react-aria/select": "^3.5.0",
"@react-aria/separator": "^3.1.3",
+ "@react-aria/textfield": "^3.5.2",
"@react-aria/tooltip": "^3.1.1",
"@react-aria/utils": "^3.6.0",
"@react-aria/virtualizer": "^3.3.4",
diff --git a/src/Form.tsx b/src/Form.tsx
deleted file mode 100644
index a2635bdd..00000000
--- a/src/Form.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import React, { ReactNode } from 'react';
-import { css } from '@emotion/core';
-import theme from './theme';
-
-export type FormProps = {
- children: ReactNode;
- className?: string;
-};
-
-function Form({ children, className }: FormProps) {
- return (
-
- {children}
-
- );
-}
-
-export const RequiredFieldsDisclosure = () => (
-
- * Required fields
-
-);
-
-const formLabelText = css`
- margin-bottom: 4px;
- margin-top: 8px;
- font-size: ${theme.typography.sizes.medium};
- color: ${theme.colors.text1};
-`;
-
-const formLabelHelper = css`
- padding-left: 4px;
- color: #bbbdbf;
- font-size: ${theme.typography.sizes.medium};
-`;
-
-const formLabelContents = css`
- margin-bottom: 8px;
-`;
-
-export const FormLabel = ({
- children,
- text,
- required = false,
- helperText,
-}: {
- children: ReactNode;
- text: ReactNode;
- required?: boolean;
- helperText?: string; // Text the describe the field or display limits
-}) => {
- return (
-
- );
-};
-
-Form.RequiredFieldsDisclosure = RequiredFieldsDisclosure;
-Form.FormLabel = FormLabel;
-
-export default Form;
diff --git a/src/dropdown/DropdownButton.tsx b/src/dropdown/DropdownButton.tsx
index abbbebf5..59455fec 100644
--- a/src/dropdown/DropdownButton.tsx
+++ b/src/dropdown/DropdownButton.tsx
@@ -8,27 +8,10 @@ import { FocusableRef } from '../types';
import { useFocusableRef } from '../utils/useDOMRef';
import theme from '../theme';
import { Text } from '../content';
+import { AddonBefore } from '../field';
import { Icon, ArrowIosDownwardOutline } from '../icon';
import { AddonableProps } from '../types';
-const addonBeforeCSS = css`
- background-color: ${theme.colors.gray400};
- padding: ${theme.spacing.padding8}px;
- flex: none;
-`;
-
-/**
- * A label element that describes the button
- */
-function AddonBefore({ children }: { children: ReactNode }) {
- return (
-
-
- {children}
-
-
- );
-}
export interface DropdownButtonProps extends AddonableProps {
/** Whether the button is disabled. */
isDisabled?: boolean;
@@ -66,7 +49,7 @@ function DropdownButton(
background-color: ${theme.colors.gray500};
min-width: 200px;
border: none;
- border-radius: 4px;
+ border-radius: ${theme.borderRadius.medium}px;
color: ${theme.textColors.white90};
display: flex;
justify-content: center;
@@ -78,8 +61,11 @@ function DropdownButton(
transition: all 0.2s ease-in-out;
/** provide an alternate highlight */
outline: none;
+ &.is-hovered {
+ border: 1px solid ${theme.components.dropdown.hoverBorderColor};
+ background-color: ${theme.components.dropdown.activeBackgroundColor};
+ }
&.is-active,
- &.is-hovered,
&:focus {
border: 1px solid ${theme.components.dropdown.activeBorderColor};
background-color: ${theme.components.dropdown.activeBackgroundColor};
diff --git a/src/field/Addon.tsx b/src/field/Addon.tsx
new file mode 100644
index 00000000..2903043c
--- /dev/null
+++ b/src/field/Addon.tsx
@@ -0,0 +1,27 @@
+import React, { ReactNode } from 'react';
+import { css } from '@emotion/core';
+import theme from '../theme';
+import { Text } from '../content/Text';
+
+const addonBeforeCSS = css`
+ background-color: ${theme.colors.gray400};
+ padding: 0 ${theme.spacing.padding8}px;
+ flex: none;
+ box-sizing: border-box;
+ height: ${theme.singleLineHeight}px;
+ display: flex;
+ align-items: center;
+`;
+
+/**
+ * A label element that describes a button or an input field
+ */
+export function AddonBefore({ children }: { children: ReactNode }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/field/Field.tsx b/src/field/Field.tsx
new file mode 100644
index 00000000..2adced51
--- /dev/null
+++ b/src/field/Field.tsx
@@ -0,0 +1,137 @@
+import { css, keyframes } from '@emotion/core';
+import { classNames } from '../utils';
+import { HelpText, HelpTextComponentProps } from './HelpText';
+import { FieldLabel, FieldLabelProps } from './FieldLabel';
+import { LabelPosition } from '@react-types/shared';
+import { mergeProps } from '@react-aria/utils';
+import { Validation } from '../types';
+import React, {
+ RefObject,
+ HTMLAttributes,
+ ReactNode,
+ ReactElement,
+} from 'react';
+import { useFormProps } from '../form';
+
+const appearKeyframes = keyframes`
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+`;
+
+export interface FieldProps
+ extends FieldLabelProps,
+ HelpTextComponentProps,
+ Validation {
+ children: ReactElement;
+ label?: ReactNode;
+ labelProps?: HTMLAttributes;
+ wrapperClassName?: string;
+}
+
+function Field(props: FieldProps, ref: RefObject) {
+ props = useFormProps(props);
+ let {
+ label,
+ labelExtra,
+ labelPosition = 'top' as LabelPosition,
+ labelAlign,
+ isRequired,
+ necessityIndicator,
+ includeNecessityIndicatorInAccessibilityName,
+ validationState,
+ description,
+ errorMessage,
+ isDisabled,
+ showErrorIcon,
+ children,
+ labelProps,
+ // Not every component that uses supports help text.
+ descriptionProps = {},
+ errorMessageProps = {},
+ elementType,
+ wrapperClassName,
+ } = props;
+ let hasHelpText =
+ !!description || (errorMessage && validationState === 'invalid');
+
+ if (label || hasHelpText) {
+ let labelWrapperClass = classNames(
+ 'ac-field',
+ {
+ 'ac-field--positionTop': labelPosition === 'top',
+ 'ac-field--positionSide': labelPosition === 'side',
+ 'ac-field--hasHelpText': hasHelpText,
+ },
+ wrapperClassName
+ );
+
+ children = React.cloneElement(
+ children,
+ // @ts-ignore
+ mergeProps(children.props, {
+ className: 'ac-field__field',
+ })
+ );
+
+ let renderHelpText = () => (
+
+ );
+
+ return (
+ }
+ className={labelWrapperClass}
+ css={css`
+ /* For now assume vertical alignment of labels */
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ .ac-help-text--danger {
+ /* Animate in the help text */
+ animation: ${appearKeyframes} ${0.3}s forwards ease-in-out;
+ }
+ `}
+ >
+ {label && (
+
+ {label}
+
+ )}
+ {children}
+ {hasHelpText && renderHelpText()}
+
+ );
+ }
+
+ return React.cloneElement(
+ children,
+ // @ts-ignore
+ mergeProps(children.props, {
+ ref,
+ })
+ );
+}
+
+// @ts-ignore
+let _Field = React.forwardRef(Field);
+export { _Field as Field };
diff --git a/src/field/FieldLabel.tsx b/src/field/FieldLabel.tsx
new file mode 100644
index 00000000..de435db7
--- /dev/null
+++ b/src/field/FieldLabel.tsx
@@ -0,0 +1,103 @@
+import { classNames, useDOMRef } from '../utils';
+import { DOMRef } from '@react-types/shared';
+import { css } from '@emotion/core';
+import { filterDOMProps } from '@react-aria/utils';
+import React, { ReactNode, ElementType, HTMLAttributes } from 'react';
+import { DOMProps, LabelableProps, ExtendableLabelProps } from '../types';
+import theme from '../theme';
+
+interface LabelProps {
+ children?: ReactNode;
+ htmlFor?: string; // for compatibility with React
+ for?: string;
+ elementType?: ElementType;
+}
+
+interface FieldLabelPropsBase
+ extends LabelProps,
+ LabelableProps,
+ ExtendableLabelProps,
+ DOMProps {
+ includeNecessityIndicatorInAccessibilityName?: boolean;
+}
+
+export interface FieldLabelProps
+ extends FieldLabelPropsBase,
+ HTMLAttributes {}
+
+function FieldLabel(props: FieldLabelProps, ref: DOMRef) {
+ let {
+ children,
+ labelPosition = 'top',
+ labelAlign = labelPosition === 'side' ? 'start' : null,
+ labelExtra,
+ isRequired,
+ necessityIndicator = 'icon',
+ includeNecessityIndicatorInAccessibilityName = false,
+ htmlFor,
+ for: labelFor,
+ elementType: ElementType = 'label',
+ onClick,
+ ...otherProps
+ } = props;
+
+ let domRef = useDOMRef(ref);
+ let necessityLabel = isRequired ? '(required)' : '(optional)';
+ let icon = '*';
+
+ let labelClassNames = classNames('ac-field-label', {
+ 'ac-field-label--positionSide': labelPosition === 'side',
+ 'ac-field-label--alignEnd': labelAlign === 'end',
+ });
+
+ return (
+
+ {children}
+ {(necessityIndicator === 'label' ||
+ (necessityIndicator === 'icon' && isRequired)) &&
+ ' \u200b'}
+ {/* necessityLabel is hidden to screen readers if the field is required because
+ * aria-required is set on the field in that case. That will already be announced,
+ * so no need to duplicate it here. If optional, we do want it to be announced here. */}
+ {necessityIndicator === 'label' && (
+
+ {necessityLabel}
+
+ )}
+ {necessityIndicator === 'icon' && isRequired && icon}
+ {labelExtra && (
+
+ {labelExtra}
+
+ )}
+
+ );
+}
+
+let _FieldLabel = React.forwardRef(FieldLabel);
+export { _FieldLabel as FieldLabel };
diff --git a/src/field/HelpText.tsx b/src/field/HelpText.tsx
new file mode 100644
index 00000000..65dce7b4
--- /dev/null
+++ b/src/field/HelpText.tsx
@@ -0,0 +1,73 @@
+// import AlertMedium from '@spectrum-icons/ui/AlertMedium';
+import { classNames, useDOMRef } from '../utils';
+import { DOMRef, HelpTextProps, Validation } from '../types';
+import React, { HTMLAttributes } from 'react';
+import { css } from '@emotion/core';
+import theme from '../theme';
+
+export interface HelpTextComponentProps extends HelpTextProps, Validation {
+ /** Props for the help text description element. */
+ descriptionProps?: HTMLAttributes;
+ /** Props for the help text error message element. */
+ errorMessageProps?: HTMLAttributes;
+ /** Whether the description is displayed with lighter text. */
+ isDisabled?: boolean;
+ /** Whether an error icon is rendered. */
+ showErrorIcon?: boolean;
+}
+
+function HelpText(props: HelpTextComponentProps, ref: DOMRef) {
+ let {
+ description,
+ errorMessage,
+ validationState,
+ isDisabled,
+ showErrorIcon,
+ descriptionProps,
+ errorMessageProps,
+ } = props;
+ let domRef = useDOMRef(ref);
+ let isErrorMessage = errorMessage && validationState === 'invalid';
+
+ return (
+
+ {isErrorMessage ? (
+ <>
+ {/* TODO support icons */}
+ {showErrorIcon && 'error icon here'}
+
+ {errorMessage}
+
+ >
+ ) : (
+
+ {description}
+
+ )}
+
+ );
+}
+
+/**
+ * Help text provides either an informative description or an error message that gives more context about what a user needs to input. It's commonly used in forms.
+ */
+const _HelpText = React.forwardRef(HelpText);
+export { _HelpText as HelpText };
diff --git a/src/field/index.tsx b/src/field/index.tsx
new file mode 100644
index 00000000..bb7f4b70
--- /dev/null
+++ b/src/field/index.tsx
@@ -0,0 +1,2 @@
+export * from './Field';
+export * from './Addon';
diff --git a/src/form/Form.tsx b/src/form/Form.tsx
new file mode 100644
index 00000000..f9e79344
--- /dev/null
+++ b/src/form/Form.tsx
@@ -0,0 +1,114 @@
+import {
+ Alignment,
+ DOMRef,
+ LabelPosition,
+ LabelableProps,
+ DOMProps,
+ AriaLabelingProps,
+} from '../types';
+import { classNames, useDOMRef } from '../utils';
+import { filterDOMProps } from '@react-aria/utils';
+import React, { useContext, ReactElement, FormEventHandler } from 'react';
+import { css } from '@emotion/core';
+import { Provider } from '../provider';
+
+let FormContext = React.createContext({});
+
+export function useFormProps(props: T): T {
+ let ctx = useContext(FormContext);
+ return { ...ctx, ...props };
+}
+
+const formPropNames = new Set([
+ 'action',
+ 'autoComplete',
+ 'encType',
+ 'method',
+ 'target',
+ 'onSubmit',
+]);
+
+export interface FormProps extends DOMProps, AriaLabelingProps, LabelableProps {
+ /** The contents of the Form. */
+ children: ReactElement | ReactElement[];
+
+ /** Whether the Form elements are disabled. */
+ isDisabled?: boolean;
+ /** Whether the Form elements can be selected but not changed by the user. */
+ isReadOnly?: boolean;
+ /**
+ * Where to send the form-data when the form is submitted.
+ */
+ action?: string;
+ /**
+ * The enctype attribute specifies how the form-data should be encoded when submitting it to the server.
+ */
+ encType?:
+ | 'application/x-www-form-urlencoded'
+ | 'multipart/form-data'
+ | 'text/plain';
+ /**
+ * The form-data can be sent as URL variables (with method="get") or as HTTP post transaction (with method="post").
+ */
+ method?: 'get' | 'post';
+ /**
+ * The target attribute specifies a name or a keyword that indicates where to display the response that is received after submitting the form.
+ */
+ target?: '_blank' | '_self' | '_parent' | '_top';
+ /**
+ * Fired on form submission.
+ */
+ onSubmit?: FormEventHandler;
+}
+
+function Form(props: FormProps, ref: DOMRef) {
+ let {
+ children,
+ labelPosition = 'top' as LabelPosition,
+ labelAlign = 'start' as Alignment,
+ isRequired,
+ necessityIndicator,
+ isDisabled,
+ isReadOnly,
+ ...otherProps
+ } = props;
+ let domRef = useDOMRef(ref);
+
+ let ctx = {
+ labelPosition,
+ labelAlign,
+ necessityIndicator,
+ };
+
+ return (
+
+ );
+}
+
+/**
+ * Forms allow users to enter data that can be submitted while providing alignment and styling for form fields.
+ */
+const _Form = React.forwardRef(Form);
+export { _Form as Form };
diff --git a/src/form/index.tsx b/src/form/index.tsx
new file mode 100644
index 00000000..b690c60a
--- /dev/null
+++ b/src/form/index.tsx
@@ -0,0 +1 @@
+export * from './Form';
diff --git a/src/icon/Icon.tsx b/src/icon/Icon.tsx
index 924827e8..ab928989 100644
--- a/src/icon/Icon.tsx
+++ b/src/icon/Icon.tsx
@@ -1,4 +1,5 @@
import React, { ReactNode, HTMLAttributes } from 'react';
+import { classNames } from '../utils';
import { css } from '@emotion/core';
interface IconProps extends HTMLAttributes {
@@ -8,10 +9,10 @@ interface IconProps extends HTMLAttributes {
/**
* Wraps the svg in a reasonable size and applies a color
*/
-export const Icon = ({ svg, style, ...restProps }: IconProps) => {
+export const Icon = ({ svg, style, className, ...restProps }: IconProps) => {
return (
{
// /** custom content, defaults to 'the snozzberries taste like snozzberries' */
// children?: ReactChild;
diff --git a/src/provider/Provider.tsx b/src/provider/Provider.tsx
new file mode 100644
index 00000000..62f75eca
--- /dev/null
+++ b/src/provider/Provider.tsx
@@ -0,0 +1,37 @@
+import React, { useContext } from 'react';
+import { OverlayProvider } from '@react-aria/overlays';
+import { ProviderProps, ProviderContext } from '../types';
+
+const Context = React.createContext(null);
+
+export function Provider(props: ProviderProps) {
+ const { children, ...context } = props;
+ return (
+
+ {children}
+
+ );
+}
+
+export function useProvider(): ProviderContext {
+ const context = useContext(Context);
+ if (!context) {
+ throw new Error('useProvider must be used within a Provider');
+ }
+ return context;
+}
+
+export function useProviderProps(props: T): T {
+ let context = useProvider();
+ if (!context) {
+ return props;
+ }
+ return Object.assign(
+ {},
+ {
+ isDisabled: context.isDisabled,
+ isReadOnly: context.isReadOnly,
+ },
+ props
+ );
+}
diff --git a/src/provider/index.tsx b/src/provider/index.tsx
new file mode 100644
index 00000000..50509410
--- /dev/null
+++ b/src/provider/index.tsx
@@ -0,0 +1 @@
+export * from './Provider';
diff --git a/src/textfield/TextField.tsx b/src/textfield/TextField.tsx
new file mode 100644
index 00000000..679348b7
--- /dev/null
+++ b/src/textfield/TextField.tsx
@@ -0,0 +1,47 @@
+import React, { forwardRef, RefObject, useRef } from 'react';
+import {
+ TextFieldBase,
+ AriaTextFieldProps,
+ TextFieldRef,
+} from './TextFieldBase';
+import { useTextField } from '@react-aria/textfield';
+import { AddonableProps } from '../types';
+import { useProviderProps } from '../provider';
+
+export interface TextFieldProps extends AriaTextFieldProps, AddonableProps {
+ className?: string;
+}
+function TextField(props: TextFieldProps, ref: RefObject) {
+ // Call use provider props so the textfield can inherit from the provider
+ // E.x. disabled, readOnly, etc.
+ props = useProviderProps(props);
+ let inputRef = useRef();
+ let {
+ labelProps,
+ inputProps,
+ descriptionProps,
+ errorMessageProps,
+ // @ts-ignore
+ } = useTextField(props, inputRef);
+ return (
+
+ );
+}
+
+/**
+ * TextFields are text inputs that allow users to input custom text entries
+ * with a keyboard. Various decorations can be displayed around the field to
+ * communicate the entry requirements.
+ */
+// @ts-ignore
+const _TextField = forwardRef(TextField);
+export { _TextField as TextField };
diff --git a/src/textfield/TextFieldBase.tsx b/src/textfield/TextFieldBase.tsx
new file mode 100644
index 00000000..80e5184b
--- /dev/null
+++ b/src/textfield/TextFieldBase.tsx
@@ -0,0 +1,284 @@
+import { css, keyframes } from '@emotion/core';
+import { classNames, createFocusableRef } from '../utils';
+import { Field } from '../field';
+import { FocusRing } from '@react-aria/focus';
+import { mergeProps } from '@react-aria/utils';
+import { PressEvents } from '@react-types/shared';
+import { Icon, AlertCircleOutline } from '../icon';
+import React, {
+ HTMLAttributes,
+ InputHTMLAttributes,
+ LabelHTMLAttributes,
+ ReactElement,
+ Ref,
+ RefObject,
+ TextareaHTMLAttributes,
+ useImperativeHandle,
+ useRef,
+ forwardRef,
+} from 'react';
+import {
+ InputBase,
+ LabelableProps,
+ ExtendableLabelProps,
+ ValueBase,
+ TextInputBase,
+ FocusableProps,
+ HelpTextProps,
+ Validation,
+ AriaLabelingProps,
+ FocusableDOMProps,
+ TextInputDOMProps,
+ AriaValidationProps,
+ FocusableRefValue,
+ AddonableProps,
+} from '../types';
+import { AddonBefore } from '../field';
+import { useHover } from '@react-aria/interactions';
+import theme from '../theme';
+
+const appearKeyframes = keyframes`
+ 0% { opacity: 0; }
+ 100% { opacity: 1; }
+`;
+
+export interface TextFieldProps
+ extends InputBase,
+ Validation,
+ HelpTextProps,
+ FocusableProps,
+ TextInputBase,
+ ValueBase,
+ LabelableProps,
+ ExtendableLabelProps {}
+
+/**
+ * Extend the base interface with a11y props
+ */
+
+export interface AriaTextFieldProps
+ extends TextFieldProps,
+ AriaLabelingProps,
+ FocusableDOMProps,
+ TextInputDOMProps,
+ AriaValidationProps {
+ // https://www.w3.org/TR/wai-aria-1.2/#textbox
+ /** Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. */
+ 'aria-activedescendant'?: string;
+ /**
+ * Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be
+ * presented if they are made.
+ */
+ 'aria-autocomplete'?: 'none' | 'inline' | 'list' | 'both';
+ /** Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. */
+ 'aria-haspopup'?:
+ | boolean
+ | 'false'
+ | 'true'
+ | 'menu'
+ | 'listbox'
+ | 'tree'
+ | 'grid'
+ | 'dialog';
+}
+
+interface TextFieldBaseProps
+ extends Omit,
+ AddonableProps,
+ PressEvents {
+ wrapperChildren?: ReactElement | ReactElement[];
+ inputClassName?: string;
+ validationIconClassName?: string;
+ multiLine?: boolean;
+ labelProps?: LabelHTMLAttributes;
+ inputProps:
+ | InputHTMLAttributes
+ | TextareaHTMLAttributes;
+ descriptionProps?: HTMLAttributes;
+ errorMessageProps?: HTMLAttributes;
+ inputRef?: RefObject;
+ loadingIndicator?: ReactElement;
+ isLoading?: boolean;
+ className?: string;
+}
+
+export interface TextFieldRef
+ extends FocusableRefValue<
+ HTMLInputElement | HTMLTextAreaElement,
+ HTMLDivElement
+ > {
+ select(): void;
+ getInputElement(): HTMLInputElement | HTMLTextAreaElement;
+}
+
+function TextFieldBase(props: TextFieldBaseProps, ref: Ref) {
+ let {
+ label,
+ validationState,
+ isDisabled,
+ isReadOnly,
+ multiLine,
+ autoFocus,
+ inputClassName,
+ wrapperChildren,
+ labelProps = {},
+ inputProps,
+ descriptionProps = {},
+ errorMessageProps = {},
+ inputRef,
+ isLoading,
+ loadingIndicator,
+ addonBefore,
+ className,
+ } = props;
+ let { hoverProps, isHovered } = useHover({ isDisabled });
+ let [isFocused, setIsFocused] = React.useState(false);
+ let domRef = useRef(null);
+ let defaultInputRef = useRef(null);
+ inputRef = inputRef || defaultInputRef;
+
+ // Expose imperative interface for ref
+ useImperativeHandle(ref, () => ({
+ ...createFocusableRef(domRef, inputRef),
+ select() {
+ if (inputRef?.current) {
+ inputRef?.current.select();
+ }
+ },
+ // @ts-ignore
+ getInputElement() {
+ return inputRef?.current;
+ },
+ }));
+
+ let ElementType: React.ElementType = multiLine ? 'textarea' : 'input';
+ let isInvalid = validationState === 'invalid';
+
+ const validation = (
+ }
+ />
+ );
+
+ let textField = (
+
+ {addonBefore != null ?
{addonBefore} : null}
+
+ {
+ setIsFocused(true);
+ },
+ onBlur: () => setIsFocused(false),
+ })}
+ ref={inputRef as any}
+ rows={multiLine ? 1 : undefined}
+ className={classNames('ac-textfield__input', inputClassName)}
+ />
+
+ {validationState && !isLoading ? validation : null}
+ {isLoading && loadingIndicator}
+ {wrapperChildren}
+
+ );
+
+ if (label) {
+ textField = React.cloneElement(
+ textField,
+ mergeProps(textField.props, {
+ // TODO support muli-line text areas
+ className: multiLine ? 'ac-text-field--multiline' : '',
+ })
+ );
+ }
+
+ return (
+
+ {textField}
+
+ );
+}
+
+const _TextFieldBase = forwardRef(TextFieldBase);
+export { _TextFieldBase as TextFieldBase };
diff --git a/src/textfield/index.tsx b/src/textfield/index.tsx
new file mode 100644
index 00000000..665fa3cb
--- /dev/null
+++ b/src/textfield/index.tsx
@@ -0,0 +1 @@
+export * from './TextField';
diff --git a/src/theme.ts b/src/theme.ts
index 1ce9cff4..665d6e53 100644
--- a/src/theme.ts
+++ b/src/theme.ts
@@ -1,3 +1,4 @@
+import { lighten, darken } from 'polished';
const baseColors = {
dark1: '#0B1015', // body bg
dark2: '#17202A', // nav bg
@@ -25,6 +26,12 @@ const arizeColors = {
arizeLightBlue: '#72D9FF',
};
+const borderColors = {
+ grayBorder: '#2e363e',
+ lightGrayBorder: '#768CA3',
+ lightGrayHoverBorder: lighten(0.2, '#768CA3'),
+};
+
const textColors = {
white90: `rgba(255, 255, 255, 0.9)`,
white70: `rgba(255, 255, 255, 0.7)`,
@@ -48,9 +55,9 @@ const theme = {
...baseColors,
...arizeColors,
...grayColors,
+ ...borderColors,
primary: '#db247c', // pink
secondary: '#db247c', // blue
- grayBorder: '#2e363e',
statusInfo: '#72D9FF',
statusSuccess: '#7EE787', // RGB independent success color
statusWarning: '#E69958',
@@ -73,14 +80,22 @@ const theme = {
borderColor: '#6F7D8C',
},
dropdown: {
- borderColor: 'rgba(118, 140, 163, .6)',
- activeBorderColor: 'rgba(118, 140, 163, 1)',
- activeBackgroundColor: '#313A44',
+ borderColor: borderColors.lightGrayBorder,
+ hoverBorderColor: borderColors.lightGrayHoverBorder,
+ activeBorderColor: arizeColors.arizeLightBlue,
+ activeBackgroundColor: darken(0.02, grayColors.gray500),
+ },
+ textField: {
+ borderColor: borderColors.lightGrayBorder,
+ hoverBorderColor: borderColors.lightGrayHoverBorder,
+ activeBorderColor: arizeColors.arizeLightBlue,
+ backgroundColor: grayColors.gray500,
+ activeBackgroundColor: darken(0.02, grayColors.gray500),
},
button: {
primaryBorderColor: '#5BAECC',
primaryHoverBackgroundColor: '#5BAECC',
- defaultBorderColor: '#768CA3',
+ defaultBorderColor: borderColors.lightGrayBorder,
defaultHoverBackgroundColor: '#64768A',
},
},
@@ -154,6 +169,13 @@ const theme = {
duration: 200,
},
},
+ /**
+ * The height of a single line of form input etc.
+ */
+ singleLineHeight: 36,
+ borderRadius: {
+ medium: 4,
+ },
};
export default theme;
diff --git a/src/types/index.ts b/src/types/index.ts
index e88f5c22..b19b8a95 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -5,3 +5,7 @@ export * from './selection';
export * from './select';
export * from './labelable';
export * from './severity';
+export * from './input';
+export * from './events';
+export * from './dom';
+export * from './provider';
diff --git a/src/types/labelable.ts b/src/types/labelable.ts
index 2740e9b1..a69559b3 100644
--- a/src/types/labelable.ts
+++ b/src/types/labelable.ts
@@ -28,6 +28,13 @@ export interface LabelableProps {
isRequired?: boolean;
}
+export interface ExtendableLabelProps {
+ /**
+ * An extra element to add at the end of the label
+ */
+ labelExtra?: ReactNode;
+}
+
/**
* An interface for things that support addon labels
*/
diff --git a/src/types/provider.ts b/src/types/provider.ts
new file mode 100644
index 00000000..315512a1
--- /dev/null
+++ b/src/types/provider.ts
@@ -0,0 +1,15 @@
+import { ReactNode } from 'react';
+
+interface ContextProps {
+ /** Whether descendants should be disabled. */
+ isDisabled?: boolean;
+ /** Whether descendants should be read only. */
+ isReadOnly?: boolean;
+}
+
+export interface ProviderProps extends ContextProps {
+ /** The content of the Provider. */
+ children: ReactNode;
+}
+
+export interface ProviderContext extends ContextProps {}
diff --git a/stories/Form.stories.tsx b/stories/Form.stories.tsx
index 9bf7319a..699fbdaa 100644
--- a/stories/Form.stories.tsx
+++ b/stories/Form.stories.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
-import Form, { FormProps } from '../src/Form';
+import { Form, FormProps, TextField, Picker, Item, Field } from '../src';
+import { useForm, Controller } from 'react-hook-form';
const meta: Meta = {
title: 'Form',
@@ -19,23 +20,84 @@ const meta: Meta = {
export default meta;
-const Template: Story = args => (
-
-
-
-
-
-
-
-
-
-
-
-);
+const Template: Story = args => {
+ const { control, handleSubmit } = useForm();
+ const onSubmit = (d: any) => {
+ alert(JSON.stringify(d));
+ };
+ return (
+ // @ts-ignore
+
+ );
+};
// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
// https://storybook.js.org/docs/react/workflows/unit-testing
export const Default = Template.bind({});
+export const Disabled = Template.bind({}, { isDisabled: true });
+
Default.args = { type: 'primary', children: 'Button' };
diff --git a/stories/Gallery.stories.tsx b/stories/Gallery.stories.tsx
index f1f6c74f..c9eb2be3 100644
--- a/stories/Gallery.stories.tsx
+++ b/stories/Gallery.stories.tsx
@@ -1,8 +1,16 @@
import React from 'react';
import { css } from '@emotion/core';
import { Meta, Story } from '@storybook/react';
-import { Alert, Card, useNotification, Button } from '../src';
-
+import {
+ Alert,
+ Card,
+ useNotification,
+ Button,
+ TextField,
+ Dropdown,
+ Provider,
+ Field,
+} from '../src';
// @ts-ignore
import chartFile from './images/chart.png';
@@ -23,54 +31,95 @@ export default meta;
const Template: Story = args => {
const [notify, holder] = useNotification();
return (
-
-
{
- notify({
- variant: 'success',
- title: 'Awesome!',
- message: 'Things worked as expected',
- action: {
- text: 'Try This',
- onClick: () => {},
- },
- });
- }}
- >
- Notify
-
- }
+
+
-
{
+ notify({
+ variant: 'success',
+ title: 'Awesome!',
+ message: 'Things worked as expected',
+ action: {
+ text: 'Try This',
+ onClick: () => {},
+ },
+ });
+ }}
+ >
+ Notify
+
+ }
>
-
- Your predictions may be delayed by up to 10 minutes
-
+
+
+ Your predictions may be delayed by up to 10 minutes
+
-

+
+
+
+
-
-
- {holder}
-
+ >
+
+
+
+ Hello }>Action
+
+
+
+
+ {holder}
+
+
);
};
diff --git a/stories/Picker.stories.tsx b/stories/Picker.stories.tsx
index cea9ec83..a58060ae 100644
--- a/stories/Picker.stories.tsx
+++ b/stories/Picker.stories.tsx
@@ -162,3 +162,36 @@ const Gallery: Story = () => {
// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
// https://storybook.js.org/docs/react/workflows/unit-testing
export const gallery = Gallery.bind({});
+
+const ItemsViaProps: Story> = args => {
+ const [frequency, setFrequency] = React.useState('rarely');
+ return (
+
+ setFrequency(selected as string)}
+ items={[
+ { id: 1, name: 'Aardvark' },
+ { id: 2, name: 'Cat' },
+ { id: 3, name: 'Dog' },
+ { id: 4, name: 'Kangaroo' },
+ { id: 5, name: 'Koala' },
+ { id: 6, name: 'Penguin' },
+ { id: 7, name: 'Snake' },
+ { id: 8, name: 'Turtle' },
+ { id: 9, name: 'Wombat' },
+ ]}
+ >
+ {item => - {item.name}
}
+
+
+ Selected Value: {frequency}
+
+ );
+};
+
+// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
+// https://storybook.js.org/docs/react/workflows/unit-testing
+export const itemsViaProps = ItemsViaProps.bind({});
diff --git a/stories/TextField.stories.tsx b/stories/TextField.stories.tsx
new file mode 100644
index 00000000..b79c30fe
--- /dev/null
+++ b/stories/TextField.stories.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+import { Meta, Story } from '@storybook/react';
+import { withDesign } from 'storybook-addon-designs';
+import { Form, TextField, TextFieldProps } from '../src';
+import InfoTip from './components/InfoTip';
+
+const meta: Meta = {
+ title: 'TextField',
+ component: TextField,
+ decorators: [withDesign],
+ parameters: {
+ controls: { expanded: true },
+ design: {
+ type: 'figma',
+ url:
+ 'https://www.figma.com/file/5mMInYH9JdJY389s8iBVQm/Component-Library?node-id=76%3A505',
+ },
+ },
+};
+
+export default meta;
+
+/**
+ * A gallery of all the variants
+ */
+export const Gallery = () => (
+
+);
+
+const Template: Story = args => (
+
+);
+
+// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
+// https://storybook.js.org/docs/react/workflows/unit-testing
+export const Default = Template.bind({});
diff --git a/stories/components/InfoTip.tsx b/stories/components/InfoTip.tsx
index 500eddec..f2079575 100644
--- a/stories/components/InfoTip.tsx
+++ b/stories/components/InfoTip.tsx
@@ -50,6 +50,7 @@ function InfoTip({ children, postfix = true }: InfoTipProps) {
background: 'transparent',
cursor: 'pointer',
color: 'inherit',
+ verticalAlign: 'bottom',
}}
>
=2.76.0 <3.0.0"
-
node-modules-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
@@ -10528,16 +10111,6 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.5.0:
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
-normalize-package-data@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.2.tgz#cae5c410ae2434f9a6c1baa65d5bc3b9366c8699"
- integrity sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==
- dependencies:
- hosted-git-info "^4.0.1"
- resolve "^1.20.0"
- semver "^7.3.4"
- validate-npm-package-license "^3.0.1"
-
normalize-path@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
@@ -10567,7 +10140,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
-npm-run-path@^4.0.0, npm-run-path@^4.0.1:
+npm-run-path@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
@@ -10732,7 +10305,7 @@ onetime@^2.0.0:
dependencies:
mimic-fn "^1.0.0"
-onetime@^5.1.0, onetime@^5.1.2:
+onetime@^5.1.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
@@ -10757,11 +10330,6 @@ opener@^1.5.2:
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
-openurl@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387"
- integrity sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=
-
optimize-css-assets-webpack-plugin@^5.0.4:
version "5.0.4"
resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90"
@@ -10862,13 +10430,6 @@ p-finally@^2.0.0:
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561"
integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==
-p-limit@3.1.0, p-limit@^3.0.2:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
- integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
- dependencies:
- yocto-queue "^0.1.0"
-
p-limit@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
@@ -10883,6 +10444,13 @@ p-limit@^2.0.0, p-limit@^2.2.0:
dependencies:
p-try "^2.0.0"
+p-limit@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+ integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+ dependencies:
+ yocto-queue "^0.1.0"
+
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
@@ -11152,11 +10720,6 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-picomatch@2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
- integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
-
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d"
@@ -11212,7 +10775,7 @@ pkg-dir@^5.0.0:
dependencies:
find-up "^5.0.0"
-pkg-up@3.1.0, pkg-up@^3.1.0:
+pkg-up@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==
@@ -11226,11 +10789,6 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
-pluralize@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
- integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
-
pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
@@ -11721,14 +11279,6 @@ progress-estimator@^0.2.2:
humanize-duration "^3.15.3"
log-update "^2.3.0"
-progress-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-2.0.0.tgz#fac63a0b3d11deacbb0969abcc93b214bce19ed5"
- integrity sha1-+sY6Cz0R3qy7CWmrzJOyFLzhntU=
- dependencies:
- speedometer "~1.0.0"
- through2 "~2.0.3"
-
progress@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
@@ -11911,11 +11461,6 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
-quick-lru@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
- integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
-
ramda@^0.21.0:
version "0.21.0"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35"
@@ -12108,6 +11653,11 @@ react-helmet-async@^1.0.2, react-helmet-async@^1.0.7:
react-fast-compare "^3.2.0"
shallowequal "^1.1.0"
+react-hook-form@^7.27.1:
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.27.1.tgz#fe5fbcb6bf58751f66d9569e998d671480cc57f6"
+ integrity sha512-N3a7A6zIQ8DJeThisVZGtOUabTbJw+7DHJidmB9w8m3chckv2ZWKb5MHps9d2pPJqmCDoWe53Bos56bYmJms5w==
+
react-inspector@^5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8"
@@ -12356,14 +11906,6 @@ recursive-readdir@2.2.2:
dependencies:
minimatch "3.0.4"
-redent@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
- integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==
- dependencies:
- indent-string "^4.0.0"
- strip-indent "^3.0.0"
-
refractor@^2.4.1:
version "2.10.1"
resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.1.tgz#166c32f114ed16fd96190ad21d5193d3afc7d34e"
@@ -12571,7 +12113,7 @@ request-promise-native@^1.0.7:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
-"request@>=2.76.0 <3.0.0", request@^2.88.0:
+request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -12651,7 +12193,7 @@ resolve@1.17.0:
dependencies:
path-parse "^1.0.6"
-resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2:
+resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.3.2:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
@@ -12688,11 +12230,6 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
-retry@0.12.0:
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
- integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
-
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
@@ -12807,7 +12344,7 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
-rxjs@^6.3.3, rxjs@^6.6.0:
+rxjs@^6.6.0:
version "6.6.7"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
@@ -13121,7 +12658,7 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
-signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
+signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
@@ -13191,11 +12728,6 @@ slash@^3.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-slice-ansi@0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
- integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
-
slice-ansi@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
@@ -13323,11 +12855,6 @@ spdx-license-ids@^3.0.0:
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==
-speedometer@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-1.0.0.tgz#cd671cb06752c22bca3370e2f334440be4fc62e2"
- integrity sha1-zWccsGdSwivKM3Di8zREC+T8YuI=
-
split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
@@ -13654,11 +13181,6 @@ stylis@^4.0.3:
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
-supports-color@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
- integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@@ -13707,11 +13229,6 @@ svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
-symbol-observable@^1.1.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
- integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
-
symbol-tree@^3.2.2:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@@ -13858,7 +13375,7 @@ throttle-debounce@^3.0.1:
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==
-through2@^2.0.0, through2@~2.0.3:
+through2@^2.0.0:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
@@ -13896,13 +13413,6 @@ tiny-glob@^0.2.6:
globalyzer "0.1.0"
globrex "^0.1.2"
-tmp-promise@3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.2.tgz#6e933782abff8b00c3119d63589ca1fb9caaa62a"
- integrity sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==
- dependencies:
- tmp "^0.2.0"
-
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -13910,13 +13420,6 @@ tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
-tmp@^0.2.0:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
- integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
- dependencies:
- rimraf "^3.0.0"
-
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
@@ -14003,16 +13506,6 @@ tr46@^1.0.1:
dependencies:
punycode "^2.1.0"
-tree-kill@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
- integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
-
-trim-newlines@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30"
- integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==
-
trim-trailing-lines@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0"
@@ -14028,7 +13521,7 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
-ts-dedent@^1.0.0, ts-dedent@^1.1.0:
+ts-dedent@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.2.0.tgz#6aa2229d837159bb6d635b6b233002423b91e0b0"
integrity sha512-6zSJp23uQI+Txyz5LlXMXAHpUhY4Hi0oluXny0OgIR7g/Cromq4vDBnhtbBdyIV34g0pgwxUvnvg+jLJe4c1NA==
@@ -14175,11 +13668,6 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
-tunnel@0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
- integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@@ -14197,11 +13685,6 @@ type-detect@4.0.8:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
-type-fest@^0.18.0:
- version "0.18.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f"
- integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==
-
type-fest@^0.21.3:
version "0.21.3"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
@@ -14407,11 +13890,6 @@ unist-util-visit@2.0.3, unist-util-visit@^2.0.0:
unist-util-is "^4.0.0"
unist-util-visit-parents "^3.0.0"
-universal-user-agent@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
- integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
-
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
@@ -14568,11 +14046,6 @@ uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-uuid@^8.3.2:
- version "8.3.2"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
- integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
-
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
@@ -14919,15 +14392,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -14960,11 +14424,6 @@ xml-name-validator@^3.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
-xmlbuilder@^10.0.0:
- version "10.1.1"
- resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0"
- integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==
-
xmlchars@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
@@ -14980,11 +14439,6 @@ y18n@^4.0.0:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
-y18n@^5.0.5:
- version "5.0.8"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
- integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
-
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
@@ -15008,24 +14462,6 @@ yargs-parser@18.x, yargs-parser@^18.1.2:
camelcase "^5.0.0"
decamelize "^1.2.0"
-yargs-parser@^20.2.2, yargs-parser@^20.2.3:
- version "20.2.7"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
- integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
-
-yargs@16.2.0:
- version "16.2.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
- integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
- dependencies:
- cliui "^7.0.2"
- escalade "^3.1.1"
- get-caller-file "^2.0.5"
- require-directory "^2.1.1"
- string-width "^4.2.0"
- y18n "^5.0.5"
- yargs-parser "^20.2.2"
-
yargs@^15.3.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
@@ -15043,14 +14479,6 @@ yargs@^15.3.1:
y18n "^4.0.0"
yargs-parser "^18.1.2"
-yarn-or-npm@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/yarn-or-npm/-/yarn-or-npm-3.0.1.tgz#6336eea4dff7e23e226acc98c1a8ada17a1b8666"
- integrity sha512-fTiQP6WbDAh5QZAVdbMQkecZoahnbOjClTQhzv74WX5h2Uaidj1isf9FDes11TKtsZ0/ZVfZsqZ+O3x6aLERHQ==
- dependencies:
- cross-spawn "^6.0.5"
- pkg-dir "^4.2.0"
-
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"