import { ArgsTable, Meta, Story } from "@storybook/addon-docs";
import { Checkbox, CheckboxGroup } from "@components/checkbox";
import { ComponentInfo, Preview, Tagline } from "@stories/components";
import { Field, GroupField, HelpMessage, InnerErrorMessage, InnerField, InnerGroupField, InnerHelpMessage, InnerLabel, InnerValidMessage, Label } from "@components/field";
import { Inline } from "@components/layout";
import { TextInput } from "@components/text-input";

<Meta
    title="Components/Field"
    id="field"
/>

# Field

<Tagline>A field add a label and a message to an input. They are typically used in forms and dialogs.</Tagline>

<ComponentInfo
    usage={"import { Field, GroupField, Label, HelpMessage, ErrorMessage, ValidMessage, FieldContext, useFieldInputProps } from \"@sharegate/orbit-ui\";"}
    githubPath="/packages/components/src/field/src"
/>

## Guidelines

### Accessibility

- When combined with a [form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) element, a field component follows the [WAI specifications for forms](https://www.w3.org/WAI/tutorials/forms/).

## Usage

A field can be composed of Orbit input components or integrate with custom inputs from your app.

### Input

For *non-group* input use a `Field` component.

<Preview>
    <Story name="input">
        <Field>
            <Label>Space ID</Label>
            <TextInput placeholder="999-999-999" />
            <HelpMessage>Your space id is a 9-digit number available on the top right corner of your membership card.</HelpMessage>
        </Field>
    </Story>
</Preview>

### Group input

When the input is a *group*, use a `GroupField` instead of a `Field`.

<Preview>
    <Story name="group">
        <Inline alignX="start" gap={13}>
            <GroupField>
                <Label>Your favorite galaxies?</Label>
                <CheckboxGroup>
                    <Checkbox value="milky-way">Milky Way</Checkbox>
                    <Checkbox value="andromeda">Andromeda</Checkbox>
                    <Checkbox value="medusa">Medusa</Checkbox>
                </CheckboxGroup>
                <HelpMessage>You must at least have travelled once to the galaxy.</HelpMessage>
            </GroupField>
            <GroupField>
                <Label>Your favorite galaxies?</Label>
                <CheckboxGroup orientation="vertical">
                    <Checkbox value="milky-way">Milky Way</Checkbox>
                    <Checkbox value="andromeda">Andromeda</Checkbox>
                    <Checkbox value="medusa">Medusa</Checkbox>
                </CheckboxGroup>
                <HelpMessage>You must at least have travelled once to the galaxy.</HelpMessage>
            </GroupField>
        </Inline>
    </Story>
</Preview>

### Required

A field can show a required state.

<Preview>
    <Story name="required">
        <Field required>
            <Label>Space ID</Label>
            <TextInput placeholder="999-999-999" />
            <HelpMessage>Your space id is a 9-digit number available at the top right corner of your membership card.</HelpMessage>
        </Field>
    </Story>
</Preview>

### Disabled

A field can be disabled.

<Preview>
    <Story name="disabled">
        <Field disabled>
            <Label>Space ID</Label>
            <TextInput placeholder="999-999-999" />
            <HelpMessage>Your space id is a 9-digit number available the top right corner of your membership card.</HelpMessage>
        </Field>
    </Story>
</Preview>

### Fluid

A field can take the width of its container.

<Preview>
    <Story name="fluid">
        <Field fluid>
            <Label>Space ID</Label>
            <TextInput placeholder="999-999-999" />
            <HelpMessage>Your space id is a 9-digit number available the top right corner of your membership card.</HelpMessage>
        </Field>
    </Story>
</Preview>

### Validation

A field can display a validation state to communicate to the user whether the current value is valid or invalid. Implement your own validation logic in your app and pass either `"valid"` or `"invalid"` to the field via the `validationState` prop.

When valid or invalid, a field can display a specific message by declaring either a `ValidMessage` or an `ErrorMessage` component.

The example below illustrates how one would validate if the user has entered a valid email and display a message matching the current validation state.

<Preview filePath="/field/docs/EmailValidation" />

### Custom input

Any input implementing the `FieldContext` can integrate with a field component. This is usually done by using the `useFieldInputProps` hook.

<Preview filePath="/field/docs/CustomInput" />

## API

### Field

<ComponentInfo
    usage={"import { Field } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerField.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerField} sort="alpha" />

### GroupField

<ComponentInfo
    usage={"import { GroupField } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerGroupField.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerGroupField} sort="alpha" />

### Label

<ComponentInfo
    usage={"import { Label } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerLabel.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerLabel} sort="alpha" />

### HelpMessage

<ComponentInfo
    usage={"import { HelpMessage } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerHelpMessage.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerHelpMessage} sort="alpha" />

### ErrorMessage

<ComponentInfo
    usage={"import { ErrorMessage } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerErrorMessage.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerErrorMessage} sort="alpha" />

### ValidMessage

<ComponentInfo
    usage={"import { ValidMessage } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerValidMessage.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerValidMessage} sort="alpha" />
