## Feature Examples

### Size
- description: Adjust the size of the input using the `size` prop. 3 sizes are supported: - For most common cases, use the default `medium`. - Use `large` when the time input needs emphasis. - In more dense and compact layouts, use `small`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <TimeInput size="large" placeholder="Large" />
  <TimeInput size="medium" placeholder="Medium" />
  <TimeInput size="small" placeholder="Small" />
</StorybookComponents.Stack>;
```

### Width
- description: Control the width of the input with the `width` property. 2 values are supported: - To adjust the width of the field according to the size of the value use the default `auto`. - Fill the parent container completely with `100%`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <StorybookComponents.Stack>
    <TimeInput width="auto" placeholder="Auto" />
  </StorybookComponents.Stack>
  <TimeInput width="100%" placeholder="Full width" />
</StorybookComponents.Stack>;
```

### Border
- description: Style the component using the `border` prop. It supports 4 styles: - For most common cases, use `standard`. - To build inputs that can be used to filter data, use `round`. - Use `bottomLine` to create an editable, underlined title field. - When a component provides its own hover and focus styles, such as a table or spreadsheet cells, use `none`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <TimeInput border="standard" placeholder="Standard" />
  <TimeInput border="round" placeholder="Round" />
  <TimeInput border="bottomLine" placeholder="Bottom Line" />
  <TimeInput border="none" placeholder="None" />
</StorybookComponents.Stack>;
```

### Status
- description: Control the status of the time input using the `status` prop. It supports 3 states: - `error` demonstrates that something is missing or the entry was invalid. The conditions for an error status must be defined when using this prop. - `warning` highlights an input value that might have a significant impact to the user or it can't be validated. - `loading` shows when an input value is being uploaded to the server.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <TimeInput status="error" placeholder="Error" />
  <TimeInput status="warning" placeholder="Warning" />
  <TimeInput status="loading" placeholder="Loading" />
</StorybookComponents.Stack>;
```

### Status message
- description: Add text that explains the status or what action the user should take with the `statusMessage` prop. Showing the status message inline, directly below the input is preferred in all default cases. - To add an accessible inline message, wrap the component in a `<FormField/>` and add the `statusMessage`. - To add a status message in a tooltip that requires users to hover on the icon, use the `statusMessage` prop. Control tooltip placement with `tooltipPlacement` prop. View more inline status message examples in `<FormField/>`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <StorybookComponents.Stack flexDirection="column" gap="12px">
    <Text secondary>For all default cases:</Text>{' '}
    <FormField status="error" statusMessage="This is an error message.">
      <TimeInput placeholder="See message below" />
    </FormField>
  </StorybookComponents.Stack>
  <StorybookComponents.Stack flexDirection="column" gap="12px">
    <Text secondary>For narrow layouts only:</Text>
    <TimeInput
      placeholder="Hover on status icon"
      status="error"
      statusMessage="This is an error message."
    />
  </StorybookComponents.Stack>
</StorybookComponents.Stack>;
```

### Invalid message
- description: To add predefined validations to the Time Input, use the `invalidMessage` prop. The error icon and tooltip message are triggered when a user enters an invalid syntax, e.g., 15:99 am. To exclude past times from the calendar view, use the `excludePastTimes` prop. To exclude specific times, use the `filterTime` prop. The error message shows in a tooltip on hover over the icon by default. The message can be updated or removed. Note: When both `statusMessage` and `invalidMessage` props are used, the input will display the `statusMessage`, unless internal validation fails. Then it would display the `invalidMessage`.
- example:
```jsx
<TimeInput invalidMessage="Enter a time in 12 hour format using AM or PM." />;
```

### Disabled
- description: Disable all input interactions with the `disabled` prop. Use it to demonstrate that the user cannot select the time.
- example:
```jsx
<TimeInput disabled />;
```

### Prefix & suffix
- description: Add text, icons or a button at the beginning or end of an input field using `prefix` and `suffix`.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <TimeInput
    prefix={<Input.Affix>From</Input.Affix>}
    suffix={<Input.Affix>GMT+1</Input.Affix>}
  />
</StorybookComponents.Stack>;
```

### Locale
- description: Specify a correct time formatting (e.g., AM/PM or military time) per country using the `locale` prop.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <TimeInput locale="en" />
  <TimeInput locale="de" />
</StorybookComponents.Stack>;
```

### Time style
- description: Control whether to display the time zone info with `timeStyle`. It supports 2 values: - `short` (the default) displays the time only. - `long` shows the time together with the time zone.
- example:
```jsx
<StorybookComponents.Stack flexDirection="column">
  <TimeInput timeStyle="short" />
  <TimeInput timeStyle="long" />
</StorybookComponents.Stack>;
```

### Step
- description: In a dropdown layout, control the interval between timestamps using the `step` prop. By default, the interval between timestamps is 15 minutes.
- example:
```jsx
<StorybookComponents.Stack>
  <StorybookComponents.Stack flexDirection="column" gap="6px">
    15 min (default):
    <TimeInput step={15} />
  </StorybookComponents.Stack>
  <StorybookComponents.Stack flexDirection="column" gap="6px">
    5 min:
    <TimeInput step={5} />
  </StorybookComponents.Stack>
  <StorybookComponents.Stack flexDirection="column" gap="6px">
    30 min:
    <TimeInput step={30} />
  </StorybookComponents.Stack>
  <StorybookComponents.Stack flexDirection="column" gap="6px">
    60 min:
    <TimeInput step={60} />
  </StorybookComponents.Stack>
</StorybookComponents.Stack>;
```

## Developer Examples

### Predefined time validations
- description: The component's validations cover the following cases: - `formatError`: when a user enters a time that's invalid and impossible to parse. - `outOfBoundsError`: when a user types in a time out of the accepted range. This validation is triggered when the `excludePastTimes` or `filterTime` props are enabled. Note: In order for the error to be cleared, use `onChange`. This way, the error will not show when the user enters a valid time.
- example:
```jsx
() => {
  const [error, setError] = React.useState(null);

  const onChange = (value) => {
    setError(undefined);
  };

  const onInvalid = (errorInfo) => {
    if (errorInfo.validationType === 'outOfBoundsError') {
      setError('Past time values are not allowed');
    } else if (errorInfo.validationType === 'formatError') {
      setError('Invalid format');
    }
  };

  return (
    <StorybookComponents.Stack flexDirection="column">
      <FormField
        status={error ? 'error' : undefined}
        statusMessage={
          error
            ? error
            : 'Try entering invalid (e.g. 12:99 PM) or past time values to see different error messages'
        }
      >
        <TimeInput excludePastTimes onChange={onChange} onInvalid={onInvalid} />
      </FormField>
    </StorybookComponents.Stack>
  );
};
```

### Custom time validations
- description: To apply custom validations to the component, use information returned by `onChange` and `onInvalid` props. The `onInvalid` prop provides `validationType` and input `value` parameters.
- example:
```jsx
() => {
  const [error, setError] = React.useState(null);

  const onChange = (value) => {
    if (value.date?.getMinutes() !== 0) {
      setError('Value must match 1 hour interval');
    } else {
      setError(undefined);
    }
  };

  const onInvalid = (errorInfo) => {
    if (errorInfo) {
      setError('Invalid value');
    }
  };

  return (
    <StorybookComponents.Stack flexDirection="column">
      <FormField
        status={error ? 'error' : undefined}
        statusMessage={
          error ?? 'Try entering a value with minutes (e.g. 12:15 PM)'
        }
      >
        <TimeInput step={60} onChange={onChange} onInvalid={onInvalid} />
      </FormField>
    </StorybookComponents.Stack>
  );
};
```

### Masked TimeInput using use-mask-input
- description: _Requires use of external package. In this example `use-mask-input` package is used._
- example:
```jsx
() => {
  const { withMask } = require('use-mask-input');
  const maskRef = React.useMemo(
    () =>
      withMask('99:99', {
        placeholder: '_',
        showMaskOnHover: false,
      }),
    [],
  );
  return (
    <TimeInput
      locale="en-GB"
      inputRef={maskRef}
      disableAutoComplete
      autoSelect={false}
      invalidMessage="Enter a valid time"
    />
  );
};
```

## Common Use Case Examples

### Scheduling
- description: Use the time input together with a `<DatePicker/>` to schedule specific times for events, appointments, delivery hours, etc.
- example:
```jsx
() => {
  const [startDate, setStartDate] = React.useState(null);
  const [endDate, setEndDate] = React.useState(null);

  return (
    <Layout>
      <Cell span={6}>
        <Box gap={2}>
          <FormField label="Start date">
            <DatePicker
              width="100%"
              placeholderText="Select"
              value={startDate}
              onChange={(value) => setStartDate(value)}
            />
          </FormField>
          <FormField label="Start time">
            <TimeInput />
          </FormField>
        </Box>
      </Cell>
      <Cell span={6}>
        <Box gap={2}>
          <FormField label="Start date">
            <DatePicker
              width="100%"
              placeholderText="Select"
              value={startDate}
              onChange={(value) => setStartDate(value)}
            />
          </FormField>
          <FormField label="Start time">
            <TimeInput />
          </FormField>
        </Box>
      </Cell>
    </Layout>
  );
};
```

### Range
- description: Use the `<Range/>` component to merge two input fields to specify a time duration.
- example:
```jsx
<FormField label="Duration">
  <Range>
    <TimeInput />
    <TimeInput />
  </Range>
</FormField>;
```
