## Feature Examples

### Structure
- description: A form field consists of `label`, `suffix` and `children` areas. Children areas can include any kind of form element.
- example:
```jsx
<FormField
  label="Label"
  suffix={
    <StorybookComponents.Placeholder>
      Suffix area
    </StorybookComponents.Placeholder>
  }
>
  <StorybookComponents.Placeholder>
    Any form element
  </StorybookComponents.Placeholder>
</FormField>;
```

### Label placement
- description: Control the label position with the `labelPlacement` prop. It supports 3 options: - Use `top` in all common cases. - Use `left` to save vertical space in less spacious layouts. This only works well with short labels. When using, be mindful of localization. - For `<ToggleSwitch/>`, use `right`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <FormField label="Top" labelPlacement="top">
    <Input />
  </FormField>
  <FormField label="Left" labelPlacement="left">
    <Input />
  </FormField>
  <FormField label="Right" labelPlacement="right" stretchContent={false}>
    <ToggleSwitch checked />
  </FormField>
</StorybookComponents.Stack>;
```

### Label alignment
- description: When the field label is placed on the side, its vertical position can be controlled with the `labelAlignment` prop. It supports 2 options: - For larger form elements like `<InputArea/>` or `<RadioGroup/>`, use `top`. - Use `middle` for single line inputs.
- example:
```jsx
<StorybookComponents.Stack>
  <FormField label="Top" labelPlacement="left" labelAlignment="top">
    <InputArea minHeight="90px" />
  </FormField>
  <FormField label="Middle" labelPlacement="left" labelAlignment="middle">
    <Input />
  </FormField>
</StorybookComponents.Stack>;
```

### Required
- description: Mark mandatory fields with an asterisk by using `required`.
- example:
```jsx
<StorybookComponents.Stack>
  <FormField label="Mandatory field" required>
    <Input />
  </FormField>
  <FormField label="Not mandatory field (optional)">
    <Input />
  </FormField>
</StorybookComponents.Stack>;
```

### Status and message
- description: To change the status and display an inline message below any component, use the `status` and `statusMessage` props. - For error messages, set the `status` prop to `error`. - For warning messages, set the `status` prop to `warning`. - For loading messages, set the `status` prop to `loading`. - To show helper text, use the `statusMessage` prop with no `status`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <FormField
    labelSize="small"
    label="Label"
    status="error"
    statusMessage="This is an error message."
  >
    <Input />
  </FormField>
  <FormField
    labelSize="small"
    label="Label"
    status="warning"
    statusMessage="This is a warning message."
  >
    <Input />
  </FormField>
  <FormField
    labelSize="small"
    label="Label"
    status="loading"
    statusMessage="This is a loading message."
  >
    <Input />
  </FormField>
  <FormField
    labelSize="small"
    label="Label"
    statusMessage="This is helper text."
  >
    <Input />
  </FormField>
</StorybookComponents.Stack>;
```

### Additional info
- description: Use a tooltip to provide users with more information about the field and what they need to input.
- example:
```jsx
<FormField
  label="Hover over info icon"
  infoContent="This tooltip provides additional info about what the user needs to put in the input field."
>
  <Input />
</FormField>;
```

### Suffix
- description: Add a custom element on the top right of the input to provide more options or information. This area accepts any component as a child. _Note:_ The suffix area replaces the character count; they can’t be used simultaneously.
- example:
```jsx
<FormField
  label="Label"
  suffix={
    <TextButton size="small" suffixIcon={<Icons.ExternalLinkSmall />}>
      Go to External Site
    </TextButton>
  }
>
  <InputArea />
</FormField>;
```

### Character count
- description: Define the maximum length of the field value by using the `charCount` prop. Any value over the allowed character count will not be added.
- example:
```jsx
() => {
  const [charCount, setCharCount] = React.useState(0);
  const [value, setValue] = React.useState('');

  const handleOnChange = (value) => {
    if (value.length <= 20) {
      setValue(value);
      setCharCount(value.length);
    }
  };
  return (
    <FormField label="Enter more than 20 characters" charCount={20 - charCount}>
      <Input
        value={value}
        onChange={(event) => handleOnChange(event.target.value)}
      />
    </FormField>
  );
};
```

### Stretch content
- description: Control the container width with `stretchContent`. This property is enabled by default and must be turned off when the form element has a fixed width, like when a `<ToggleSwitch/>` is used.
- example:
```jsx
<FormField
  label="Not stretched content"
  labelPlacement="right"
  stretchContent={false}
>
  <ToggleSwitch checked />
</FormField>;
```

### Text overflow
- description: Use the `ellipsis` prop for overflow text. The full text will be displayed in a `<Tooltip/>` when a user hovers over the button. Control the style of the tooltip using the `tooltipProps`. To display label in multiple lines, use `maxLines` to define how many lines should be visible. `maxLines` can be used together with `ellipsis` to control after how many lines label would get truncated. NOTE: it's not recommended to have labels longer than two lines, as the content would become too text heavy.
- example:
```jsx
<StorybookComponents.Stack>
  <SidePanel width="288px">
    <SidePanel.Field>
      <FormField label="This is an example text that overflows and is shown in tooltip">
        <Input placeholder="Placeholder" />
      </FormField>
    </SidePanel.Field>
  </SidePanel>
  <SidePanel width="288px">
    <SidePanel.Field>
      <FormField
        ellipsis
        maxLines={2}
        label="This is an example text that fits and is shown in two lines"
      >
        <Input placeholder="Placeholder" />
      </FormField>
    </SidePanel.Field>
  </SidePanel>
</StorybookComponents.Stack>;
```

## Common Use Case Examples

### Regular form
- description: Use a top label on forms whenever possible. This creates a clear hierarchy and is the most readable format.
- example:
```jsx
<Card>
  <Card.Header title="New dish" />
  <Card.Divider />
  <Card.Content>
    <Layout>
      <Cell span={4}>
        <FormField label="Image">
          <ImageViewer width="100%" height="176px" />
        </FormField>
      </Cell>
      <Cell span={8}>
        <Layout gap="24px">
          <Cell span={8}>
            <FormField label="Name">
              <Input value="My New Dish" />
            </FormField>
          </Cell>
          <Cell span={4}>
            <FormField label="Price">
              <Input value="0" prefix={<Input.Affix>$</Input.Affix>} />
            </FormField>
          </Cell>
          <Cell>
            <FormField label="Description">
              <InputArea
                placeholder="Describe your dish in a few sentences."
                resizable
                rows={3}
              />
            </FormField>
          </Cell>
        </Layout>
      </Cell>
      <Cell span={6}>
        <FormField
          label="Dietary preferences"
          infoContent="Choose which dietary preferences your dish is appropriate for."
        >
          <Layout>
            <Cell span={6}>
              <Box direction="vertical" gap="12px">
                <Checkbox>No salt</Checkbox>
                <Checkbox>Vegan</Checkbox>
                <Checkbox>Vegetarian</Checkbox>
              </Box>
            </Cell>
            <Cell span={6}>
              <Box direction="vertical" gap="12px">
                <Checkbox>Gluten free</Checkbox>
                <Checkbox>Organic</Checkbox>
                <Checkbox>Spicy</Checkbox>
              </Box>
            </Cell>
          </Layout>
        </FormField>
      </Cell>
      <Cell span={3}>
        <FormField label="Visibility">
          <Checkbox checked>Visible on site</Checkbox>
        </FormField>
      </Cell>
      <Cell span={3}>
        <FormField label="Availability">
          <Checkbox checked>In stock</Checkbox>
        </FormField>
      </Cell>
    </Layout>
  </Card.Content>
</Card>;
```

### Settings panel
- description: Use a top label or a left label depending on the layout. For example, a left label works best with a single toggle button.
- example:
```jsx
() => {
  const [selectedOption, setSelectedOption] = React.useState(0);
  const [value, setValue] = React.useState(2);
  const [toggleChecked, setToggleChecked] = React.useState(true);

  const options = [
    { id: 0, value: 'Image' },
    { id: 1, value: 'Video' },
    { id: 2, value: 'Image and video' },
    { id: 3, value: 'Document' },
    { id: 4, value: 'Audio' },
  ];
  return (
    <SidePanel maxHeight="576px" width="288px" skin="floating">
      <SidePanel.Header title="Upload Settings" />
      <SidePanel.Content noPadding>
        <SidePanel.Field>
          <FormField label="Supported file type">
            <Dropdown
              placeholder="Select"
              size="small"
              options={options}
              onSelect={(option) => setSelectedOption(Number(option.id))}
              selectedId={selectedOption}
            />
          </FormField>
        </SidePanel.Field>
        <SidePanel.Field>
          <FieldSet
            gap="small"
            legend="Max number of files"
            columns="auto 60px"
          >
            <Slider
              onChange={(newValue) => setValue(Number(newValue))}
              min={0}
              max={10}
              value={value}
              displayMarks={false}
            />
            <Input
              size="small"
              value={value}
              onChange={(e) => setValue(Number(e.target.value))}
            />
          </FieldSet>
        </SidePanel.Field>
        <SidePanel.Field>
          <FormField label="Is required" labelPlacement="left" labelWidth="1fr">
            <ToggleSwitch
              size="small"
              checked={toggleChecked}
              onChange={() => setToggleChecked(!toggleChecked)}
            />
          </FormField>
        </SidePanel.Field>
        <SidePanel.Section title="Display settings">
          <SidePanel.Field>
            <FormField label="Field title">
              <Input size="small" placeholder="Enter field title" />
            </FormField>
          </SidePanel.Field>
          <SidePanel.Field>
            <FormField label="Button text">
              <Input size="small" value="Choose file" />
            </FormField>
          </SidePanel.Field>
        </SidePanel.Section>
      </SidePanel.Content>
    </SidePanel>
  );
};
```
